Files
libreoffice/svx/source/form/fmctrler.cxx

3510 lines
146 KiB
C++
Raw Normal View History

2000-09-18 16:07:07 +00:00
/*************************************************************************
*
* $RCSfile: fmctrler.cxx,v $
*
* $Revision: 1.38 $
2000-09-18 16:07:07 +00:00
*
* last change: $Author: rt $ $Date: 2004-03-02 12:38:26 $
2000-09-18 16:07:07 +00:00
*
* 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): _______________________________________
*
*
************************************************************************/
#pragma hdrstop
#define USE_PROPERTY_HELPER
#ifndef _SVX_FMCTRLER_HXX
#include "fmctrler.hxx"
#endif
#ifndef _SVX_FMTOOLS_HXX
#include "fmtools.hxx"
#endif
#ifndef _SVX_FMPROP_HRC
#include "fmprop.hrc"
#endif
#ifndef _SVX_FMURL_HXX
#include "fmurl.hxx"
#endif
#ifndef _SVX_FMSHELL_HXX
#include "fmshell.hxx"
#endif
#ifndef SVX_FORM_CONFIRMDELETE_HXX
#include "confirmdelete.hxx"
#endif
2000-09-18 16:07:07 +00:00
#ifndef _COM_SUN_STAR_BEANS_NAMEDVALUE_HPP_
#include <com/sun/star/beans/NamedValue.hpp>
#endif
2000-09-18 16:07:07 +00:00
#ifndef _COM_SUN_STAR_SDB_ROWCHANGEACTION_HPP_
#include <com/sun/star/sdb/RowChangeAction.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_COLUMNVALUE_HPP_
#include <com/sun/star/sdbc/ColumnValue.hpp>
#endif
#ifndef _COM_SUN_STAR_FORM_XLOADABLE_HPP_
#include <com/sun/star/form/XLoadable.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XCOMBOBOX_HPP_
#include <com/sun/star/awt/XComboBox.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XCHECKBOX_HPP_
#include <com/sun/star/awt/XCheckBox.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XLISTBOX_HPP_
#include <com/sun/star/awt/XListBox.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_FOCUSCHANGEREASON_HPP_
#include <com/sun/star/awt/FocusChangeReason.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XURLTRANSFORMER_HPP_
#include <com/sun/star/util/XURLTransformer.hpp>
#endif
#ifndef _COM_SUN_STAR_FORM_XRESET_HPP_
#include <com/sun/star/form/XReset.hpp>
#endif
#ifndef _COM_SUN_STAR_FORM_TABULATORCYCLE_HPP_
#include <com/sun/star/form/TabulatorCycle.hpp>
#endif
#ifndef _COM_SUN_STAR_FORM_XBOUNDCONTROL_HPP_
#include <com/sun/star/form/XBoundControl.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XCONTROLLER_HPP_
#include <com/sun/star/frame/XController.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
#include <com/sun/star/beans/PropertyAttribute.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XVCLWINDOWPEER_HPP_
#include <com/sun/star/awt/XVclWindowPeer.hpp>
#endif
#ifndef _COM_SUN_STAR_FORM_XBOUNDCOMPONENT_HPP_
#include <com/sun/star/form/XBoundComponent.hpp>
#endif
#ifndef _COM_SUN_STAR_SDB_XINTERACTIONSUPPLYPARAMETERS_HPP_
#include <com/sun/star/sdb/XInteractionSupplyParameters.hpp>
#endif
#ifndef _COM_SUN_STAR_SDB_PARAMETERSREQUEST_HPP_
#include <com/sun/star/sdb/ParametersRequest.hpp>
#endif
#ifndef _COM_SUN_STAR_TASK_XINTERACTIONHANDLER_HPP_
#include <com/sun/star/task/XInteractionHandler.hpp>
#endif
2000-09-18 16:07:07 +00:00
#ifndef _TOOLS_DEBUG_HXX //autogen
#include <tools/debug.hxx>
#endif
#ifndef _SV_SVAPP_HXX //autogen
#include <vcl/svapp.hxx>
#endif
#ifndef _SVDPAGV_HXX //autogen
#include <svdpagv.hxx>
#endif
#ifndef _SVX_FMSHIMP_HXX
#include <fmshimp.hxx>
#endif
#ifndef _SVX_FMVIEW_HXX
#include <fmview.hxx>
#endif
#ifndef _SV_MSGBOX_HXX //autogen wg. RET_YES
#include <vcl/msgbox.hxx>
#endif
#ifndef _SVX_FMRESIDS_HRC
#include "fmresids.hrc"
#endif
#ifndef _SFXVIEWSH_HXX
#include <sfx2/viewsh.hxx>
#endif
#ifndef _SFXVIEWFRM_HXX
#include <sfx2/viewfrm.hxx>
#endif
#ifndef _SFX_BINDINGS_HXX
#include <sfx2/bindings.hxx>
#endif
2000-09-18 16:07:07 +00:00
#ifndef _SHL_HXX
#include <tools/shl.hxx>
#endif
#ifndef _SVX_DIALMGR_HXX
#include "dialmgr.hxx"
#endif
#ifndef _SVX_FMPROP_HXX
#include "fmprop.hxx"
#endif
#ifndef _SVX_FMSERVS_HXX
#include "fmservs.hxx"
#endif
2000-09-18 16:07:07 +00:00
2000-10-20 13:18:57 +00:00
#ifndef _COMPHELPER_PROPERTY_HXX_
#include <comphelper/property.hxx>
2000-09-18 16:07:07 +00:00
#endif
2000-10-20 13:18:57 +00:00
#ifndef _COMPHELPER_UNO3_HXX_
#include <comphelper/uno3.hxx>
2000-09-18 16:07:07 +00:00
#endif
2000-10-20 13:18:57 +00:00
#ifndef _COMPHELPER_PROPERTY_AGGREGATION_HXX_
#include <comphelper/propagg.hxx>
2000-09-18 16:07:07 +00:00
#endif
2000-10-20 13:18:57 +00:00
#ifndef _COMPHELPER_ENUMHELPER_HXX_
#include <comphelper/enumhelper.hxx>
2000-09-18 16:07:07 +00:00
#endif
2000-10-20 13:18:57 +00:00
#ifndef _COMPHELPER_SEQUENCE_HXX_
#include <comphelper/sequence.hxx>
2000-09-18 16:07:07 +00:00
#endif
#ifndef _CPPUHELPER_QUERYINTERFACE_HXX_
#include <cppuhelper/queryinterface.hxx>
#endif
#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
#include <cppuhelper/typeprovider.hxx>
#endif
#ifndef _COMPHELPER_EXTRACT_HXX_
#include <comphelper/extract.hxx>
2000-09-18 16:07:07 +00:00
#endif
#ifndef _TOOLKIT_UNOHLP_HXX
#include <toolkit/helper/vclunohelper.hxx>
#endif
2000-11-06 06:19:53 +00:00
#ifndef _COMPHELPER_SEQUENCE_HXX_
#include <comphelper/sequence.hxx>
#endif
#ifndef _COMPHELPER_INTERACTION_HXX_
#include <comphelper/interaction.hxx>
#endif
#ifndef _TOOLKIT_CONTROLS_UNOCONTROL_HXX_
#include <toolkit/controls/unocontrol.hxx>
#endif
2000-09-18 16:07:07 +00:00
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::sdb;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::task;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::form;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::beans;
using namespace ::comphelper;
using namespace ::connectivity;
using namespace ::svxform;
using namespace ::connectivity::simple;
2000-09-18 16:07:07 +00:00
extern sal_uInt16 AutoSlotMap[];
//==================================================================
// FmXAutoControl
//==================================================================
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;
}
2000-09-18 16:07:07 +00:00
//==================================================================
// FmXAutoControl
//==================================================================
struct FmFieldInfo
{
rtl::OUString aFieldName;
2000-11-06 06:19:53 +00:00
Reference< XPropertySet > xField;
2000-09-18 16:07:07 +00:00
Reference< ::com::sun::star::awt::XTextComponent > xText;
2000-11-06 06:19:53 +00:00
FmFieldInfo(const Reference< XPropertySet >& _xField, const Reference< ::com::sun::star::awt::XTextComponent >& _xText)
2000-09-18 16:07:07 +00:00
:xField(_xField)
,xText(_xText)
{xField->getPropertyValue(FM_PROP_NAME) >>= aFieldName;}
};
//==================================================================
// FmXAutoControl
//==================================================================
class FmXAutoControl: public UnoControl
{
friend Reference< XInterface > SAL_CALL FmXAutoControl_NewInstance_Impl();
public:
FmXAutoControl(){}
virtual ::rtl::OUString GetComponentServiceName() {return ::rtl::OUString::createFromAscii("Edit");}
2001-09-12 17:11:08 +00:00
virtual void SAL_CALL createPeer( const Reference< ::com::sun::star::awt::XToolkit > & rxToolkit, const Reference< ::com::sun::star::awt::XWindowPeer > & rParentPeer ) throw( ::com::sun::star::uno::RuntimeException );
2000-09-18 16:07:07 +00:00
protected:
virtual void ImplSetPeerProperty( const ::rtl::OUString& rPropName, const Any& rVal );
};
//------------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
void FmXAutoControl::createPeer( const Reference< ::com::sun::star::awt::XToolkit > & rxToolkit, const Reference< ::com::sun::star::awt::XWindowPeer > & rParentPeer ) throw( ::com::sun::star::uno::RuntimeException )
2000-09-18 16:07:07 +00:00
{
UnoControl::createPeer( rxToolkit, rParentPeer );
Reference< ::com::sun::star::awt::XTextComponent > xText(getPeer() , UNO_QUERY);
2000-09-18 16:07:07 +00:00
if (xText.is())
{
xText->setText(::rtl::OUString(SVX_RES(RID_STR_AUTOFIELD)));
xText->setEditable(sal_False);
}
}
//------------------------------------------------------------------------------
void FmXAutoControl::ImplSetPeerProperty( const ::rtl::OUString& rPropName, const Any& rVal )
{
// these properties are ignored
if (rPropName == FM_PROP_TEXT)
return;
UnoControl::ImplSetPeerProperty( rPropName, rVal );
}
//------------------------------------------------------------------------------
IMPL_LINK(FmXFormController, OnTimeout, void*, EMPTYTAG)
{
activateTabOrder();
return 1;
}
/*************************************************************************/
//------------------------------------------------------------------
Reference< XInterface > SAL_CALL
2000-11-06 06:19:53 +00:00
FmXFormController_NewInstance_Impl(const Reference< ::com::sun::star::lang::XMultiServiceFactory > & _rxORB)
2000-09-18 16:07:07 +00:00
{
2000-11-06 06:19:53 +00:00
return *(new FmXFormController(_rxORB));
2000-09-18 16:07:07 +00:00
}
2001-05-21 07:30:40 +00:00
//------------------------------------------------------------------
namespace fmctrlr
{
const ::rtl::OUString& getDataModeIdentifier()
{
static ::rtl::OUString s_sDataModeIdentifier = DATA_MODE;
return s_sDataModeIdentifier;
}
}
using namespace fmctrlr;
DBG_NAME( FmXFormController )
2000-09-18 16:07:07 +00:00
//------------------------------------------------------------------
2000-11-06 06:19:53 +00:00
FmXFormController::FmXFormController(const Reference< ::com::sun::star::lang::XMultiServiceFactory > & _rxORB,
FmFormView* _pView, Window* _pWindow, const UniString& _sDispatchPrefix)
:FmXFormController_BASE1(m_aMutex)
,OPropertySetHelper(FmXFormController_BASE1::rBHelper)
,OSQLParserClient(_rxORB)
2000-11-06 06:19:53 +00:00
,m_xORB(_rxORB)
2000-09-18 16:07:07 +00:00
,m_aActivateListeners(m_aMutex)
,m_aModifyListeners(m_aMutex)
,m_aErrorListeners(m_aMutex)
,m_aDeleteListeners(m_aMutex)
,m_aRowSetApproveListeners(m_aMutex)
,m_aParameterListeners(m_aMutex)
,m_pView(_pView)
,m_pWindow(_pWindow)
,m_bDBConnection(sal_False)
,m_bCycle(sal_False)
,m_bCanUpdate(sal_False)
,m_bCanInsert(sal_False)
,m_bModified(sal_False)
,m_nLoadEvent( 0 )
,m_bCommitLock(sal_False)
,m_bCurrentRecordModified(sal_False)
,m_bCurrentRecordNew(sal_False)
,m_bLocked(sal_False)
2001-05-21 07:30:40 +00:00
,m_aMode(getDataModeIdentifier())
2000-09-18 16:07:07 +00:00
,m_bFiltering(sal_False)
,m_bAttachEvents(sal_True)
,m_bDetachEvents(sal_True)
,m_nCurrentFilterPosition(0)
,m_sDispatchPrefix(_sDispatchPrefix)
,m_nUpdateDispatcherEvent(0)
,m_nToggleEvent(0)
{
DBG_CTOR( FmXFormController, NULL );
2000-10-20 13:18:57 +00:00
::comphelper::increment(m_refCount);
2000-09-18 16:07:07 +00:00
{
2000-11-06 06:19:53 +00:00
m_xAggregate = Reference< XAggregation > (m_xORB->createInstance(::rtl::OUString::createFromAscii("com.sun.star.awt.TabController")), UNO_QUERY);
2000-09-18 16:07:07 +00:00
DBG_ASSERT(m_xAggregate.is(), "FmXFormController::FmXFormController : could not create my aggregate !");
m_xTabController = Reference< ::com::sun::star::awt::XTabController > (m_xAggregate, UNO_QUERY);
}
if ( m_xAggregate.is() )
m_xAggregate->setDelegator(*this);
2000-10-20 13:18:57 +00:00
::comphelper::decrement(m_refCount);
2000-09-18 16:07:07 +00:00
m_aInsertTimer.SetTimeout(500);
m_aInsertTimer.SetTimeoutHdl(LINK(this,FmXFormController,OnTimeout));
}
//------------------------------------------------------------------
FmXFormController::~FmXFormController()
{
{
::osl::MutexGuard aGuard( m_aMutex );
if( m_nLoadEvent )
Application::RemoveUserEvent( m_nLoadEvent );
2000-09-18 16:07:07 +00:00
if (m_nToggleEvent)
Application::RemoveUserEvent( m_nToggleEvent );
2000-09-18 16:07:07 +00:00
if (m_nUpdateDispatcherEvent)
Application::RemoveUserEvent(m_nUpdateDispatcherEvent);
2000-09-18 16:07:07 +00:00
if (m_aInsertTimer.IsActive())
m_aInsertTimer.Stop();
}
2000-09-18 16:07:07 +00:00
// Freigeben der Aggregation
if (m_xAggregate.is())
{
Reference< XInterface > xInt;
m_xAggregate->setDelegator(xInt);
}
DBG_DTOR( FmXFormController, NULL );
2000-09-18 16:07:07 +00:00
}
2000-11-06 06:19:53 +00:00
// -----------------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
using namespace ::cppu;
using namespace ::osl;
2001-09-12 17:11:08 +00:00
void SAL_CALL FmXFormController::acquire() throw ()
2000-11-06 06:19:53 +00:00
{
FmXFormController_BASE1::acquire();
}
// -----------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
void SAL_CALL FmXFormController::release() throw ()
2000-11-06 06:19:53 +00:00
{
FmXFormController_BASE1::release();
}
// -----------------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
// XUnoTunnel
Sequence< sal_Int8 > FmXFormController::getUnoTunnelImplementationId()
{
static OImplementationId * pId = 0;
if (! pId)
{
MutexGuard aGuard( Mutex::getGlobalMutex() );
if (! pId)
{
static OImplementationId aId;
pId = &aId;
}
}
return pId->getImplementationId();
}
//------------------------------------------------------------------------------
sal_Int64 SAL_CALL FmXFormController::getSomething(Sequence<sal_Int8> const& rId)throw( RuntimeException )
{
if (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(), rId.getConstArray(), 16 ) )
return (sal_Int64)this;
return sal_Int64();
}
//------------------------------------------------------------------------------
Sequence< Type > SAL_CALL FmXFormController::getTypes( ) throw(RuntimeException)
{
2000-11-06 06:19:53 +00:00
return comphelper::concatSequences(FmXFormController_BASE1::getTypes(),FmXFormController_BASE2::getTypes(),FmXFormController_BASE3::getTypes());
2000-09-18 16:07:07 +00:00
}
//------------------------------------------------------------------
2000-11-06 06:19:53 +00:00
Any SAL_CALL FmXFormController::queryAggregation( const Type& _rType ) throw(RuntimeException)
{
Any aRet = FmXFormController_BASE1::queryAggregation(_rType);
if(!aRet.hasValue())
{
aRet = OPropertySetHelper::queryInterface(_rType);
if(!aRet.hasValue())
{
aRet = FmXFormController_BASE2::queryInterface(_rType);
if(!aRet.hasValue())
aRet = FmXFormController_BASE3::queryInterface(_rType);
}
}
2000-09-18 16:07:07 +00:00
if(aRet.hasValue())
return aRet;
2000-11-06 06:19:53 +00:00
return m_xAggregate->queryAggregation(_rType);
2000-09-18 16:07:07 +00:00
}
// ::com::sun::star::lang::XServiceInfo
//------------------------------------------------------------------------------
sal_Bool SAL_CALL FmXFormController::supportsService(const ::rtl::OUString& ServiceName) throw( ::com::sun::star::uno::RuntimeException )
{
Sequence< ::rtl::OUString> aSNL(static_getSupportedServiceNames());
const ::rtl::OUString * pArray = aSNL.getConstArray();
for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
if( pArray[i] == ServiceName )
return sal_True;
return sal_False;
}
//------------------------------------------------------------------------------
::rtl::OUString SAL_CALL FmXFormController::getImplementationName() throw( RuntimeException )
{
return ::rtl::OUString::createFromAscii("com.sun.star.form.FmXFormController");
}
//------------------------------------------------------------------------------
Sequence< ::rtl::OUString> SAL_CALL FmXFormController::getSupportedServiceNames(void) throw( RuntimeException )
{
return static_getSupportedServiceNames();
}
//------------------------------------------------------------------------------
sal_Bool SAL_CALL FmXFormController::approveReset(const ::com::sun::star::lang::EventObject& rEvent) throw( RuntimeException )
{
return sal_True;
}
//------------------------------------------------------------------------------
void SAL_CALL FmXFormController::resetted(const ::com::sun::star::lang::EventObject& rEvent) throw( RuntimeException )
{
::osl::MutexGuard aGuard(m_aMutex);
if (getCurrentControl().is() && (getCurrentControl()->getModel() == rEvent.Source))
m_bModified = sal_False;
}
//------------------------------------------------------------------------------
Sequence< ::rtl::OUString> FmXFormController::static_getSupportedServiceNames(void)
{
static Sequence< ::rtl::OUString> aServices;
if (!aServices.getLength())
{
aServices.realloc(2);
aServices.getArray()[0] = ::rtl::OUString::createFromAscii("com.sun.star.form.FormController");
aServices.getArray()[1] = ::rtl::OUString::createFromAscii("com.sun.star.awt.control.TabController");
}
return aServices;
}
//------------------------------------------------------------------------------
void FmXFormController::setCurrentFilterPosition(sal_Int32 nPos)
{
2001-05-16 13:22:30 +00:00
DBG_ASSERT(nPos < (sal_Int32)m_aFilters.size(), "Invalid Position");
2000-09-18 16:07:07 +00:00
if (nPos != m_nCurrentFilterPosition)
{
m_nCurrentFilterPosition = nPos;
// reset the text for all controls
for (FmFilterControls::const_iterator iter = m_aFilterControls.begin();
iter != m_aFilterControls.end(); iter++)
(*iter).first->setText(rtl::OUString());
if (nPos != -1)
{
// set the text for all filters
OSL_ENSURE(m_aFilters.size() > m_nCurrentFilterPosition && m_nCurrentFilterPosition >= 0,"m_nCurrentFilterPosition too big");
if ( m_nCurrentFilterPosition >= 0 && m_nCurrentFilterPosition < m_aFilters.size() )
2000-09-18 16:07:07 +00:00
{
FmFilterRow& rRow = m_aFilters[m_nCurrentFilterPosition];
for (FmFilterRow::const_iterator iter2 = rRow.begin();
iter2 != rRow.end(); iter2++)
{
(*iter2).first->setText((*iter2).second);
}
2000-09-18 16:07:07 +00:00
}
}
}
}
// OPropertySetHelper
//------------------------------------------------------------------------------
sal_Bool FmXFormController::convertFastPropertyValue( Any & rConvertedValue, Any & rOldValue,
sal_Int32 nHandle, const Any& rValue )
throw( ::com::sun::star::lang::IllegalArgumentException )
{
return sal_False;
}
//------------------------------------------------------------------------------
void FmXFormController::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue )
2001-09-12 17:11:08 +00:00
throw( ::com::sun::star::uno::Exception )
2000-09-18 16:07:07 +00:00
{
}
//------------------------------------------------------------------------------
void FmXFormController::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
{
switch (nHandle)
{
case FM_ATTR_FILTER_CRITERIA:
{
2000-11-06 06:19:53 +00:00
::rtl::OUString aFilter;
OStaticDataAccessTools aStaticTools;
Reference<XConnection> xConnection(aStaticTools.getRowSetConnection(Reference< XRowSet>(m_xModelAsIndex, UNO_QUERY)));
2000-09-18 16:07:07 +00:00
if (xConnection.is())
{
Reference< ::com::sun::star::sdbc::XDatabaseMetaData> xMetaData(xConnection->getMetaData());
Reference< ::com::sun::star::util::XNumberFormatsSupplier> xFormatSupplier( aStaticTools.getNumberFormats(xConnection, sal_True));
2000-11-06 06:19:53 +00:00
Reference< ::com::sun::star::util::XNumberFormatter> xFormatter(m_xORB
2000-09-18 16:07:07 +00:00
->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.NumberFormatter")), UNO_QUERY);
xFormatter->attachNumberFormatsSupplier(xFormatSupplier);
Reference< ::com::sun::star::sdbcx::XColumnsSupplier> xSupplyCols(m_xModelAsIndex, UNO_QUERY);
Reference< ::com::sun::star::container::XNameAccess> xFields(xSupplyCols->getColumns(), UNO_QUERY);
2000-11-06 06:19:53 +00:00
::rtl::OUString aQuote( xMetaData->getIdentifierQuoteString() );
2000-09-18 16:07:07 +00:00
// now add the filter rows
for (FmFilterRows::const_iterator i = m_aFilters.begin(); i != m_aFilters.end(); ++i)
2000-09-18 16:07:07 +00:00
{
2000-11-06 06:19:53 +00:00
::rtl::OUString aTest, aErrorMsg, aCriteria;
2000-09-18 16:07:07 +00:00
const FmFilterRow& rRow = *i;
if (!rRow.empty())
{
2000-11-06 06:19:53 +00:00
if (aFilter.getLength())
aFilter += ::rtl::OUString::createFromAscii(" OR ");
2000-09-18 16:07:07 +00:00
2000-11-06 06:19:53 +00:00
aFilter += ::rtl::OUString::createFromAscii("(");
2000-09-18 16:07:07 +00:00
for (FmFilterRow::const_iterator j = rRow.begin(); j != rRow.end(); j++)
{
// get the field of the controls map
Reference< ::com::sun::star::awt::XTextComponent > xText = (*j).first;
2000-11-06 06:19:53 +00:00
Reference< XPropertySet> xField = (*m_aFilterControls.find(xText)).second;
2000-09-18 16:07:07 +00:00
DBG_ASSERT(xField.is(), "NoField found");
if (j != rRow.begin())
2000-11-06 06:19:53 +00:00
aFilter += ::rtl::OUString::createFromAscii(" AND ");
2000-09-18 16:07:07 +00:00
aTest = (*j).second;
2000-11-06 06:19:53 +00:00
aErrorMsg = ::rtl::OUString();
::rtl::Reference< ISQLParseNode > xParseNode = predicateTree(aErrorMsg, aTest, xFormatter, xField);
if (xParseNode.is())
2000-09-18 16:07:07 +00:00
{
2000-11-06 06:19:53 +00:00
aCriteria = ::rtl::OUString();
// don't use a parse context here, we need it unlocalized
xParseNode->parseNodeToStr(aCriteria, xMetaData,NULL);
2000-09-18 16:07:07 +00:00
aFilter += aCriteria;
}
}
2000-11-06 06:19:53 +00:00
aFilter += ::rtl::OUString::createFromAscii(")");
2000-09-18 16:07:07 +00:00
}
}
}
rValue <<= ::rtl::OUString(aFilter);
} break;
}
}
//------------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
Reference< XPropertySetInfo > FmXFormController::getPropertySetInfo() throw( ::com::sun::star::uno::RuntimeException )
2000-09-18 16:07:07 +00:00
{
2000-11-06 06:19:53 +00:00
static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
2000-09-18 16:07:07 +00:00
return xInfo;
}
//------------------------------------------------------------------------------
#define DECL_PROP_CORE(varname, type) \
2000-11-06 06:19:53 +00:00
pDesc[nPos++] = Property(FM_PROP_##varname, FM_ATTR_##varname, ::getCppuType((const type*)0),
2000-09-18 16:07:07 +00:00
#define DECL_PROP1(varname, type, attrib1) \
DECL_PROP_CORE(varname, type) PropertyAttribute::attrib1)
2000-09-18 16:07:07 +00:00
//------------------------------------------------------------------------------
void FmXFormController::fillProperties(
2000-11-06 06:19:53 +00:00
Sequence< Property >& /* [out] */ _rProps,
Sequence< Property >& /* [out] */ _rAggregateProps
2000-09-18 16:07:07 +00:00
) const
{
_rProps.realloc(1);
sal_Int32 nPos = 0;
2000-11-06 06:19:53 +00:00
Property* pDesc = _rProps.getArray();
2000-09-18 16:07:07 +00:00
DECL_PROP1(FILTER_CRITERIA, rtl::OUString, READONLY);
}
//------------------------------------------------------------------------------
::cppu::IPropertyArrayHelper& FmXFormController::getInfoHelper()
{
return *getArrayHelper();
}
// ::com::sun::star::container::XElementAccess
//------------------------------------------------------------------------------
sal_Bool SAL_CALL FmXFormController::hasElements(void) throw( RuntimeException )
{
::osl::MutexGuard aGuard( m_aMutex );
return !m_aChilds.empty();
2000-09-18 16:07:07 +00:00
}
//------------------------------------------------------------------------------
Type SAL_CALL FmXFormController::getElementType(void) throw( RuntimeException )
{
return ::getCppuType((const Reference< ::com::sun::star::form::XFormController>*)0);
}
// ::com::sun::star::container::XEnumerationAccess
//------------------------------------------------------------------------------
Reference< ::com::sun::star::container::XEnumeration > SAL_CALL FmXFormController::createEnumeration(void) throw( RuntimeException )
{
::osl::MutexGuard aGuard( m_aMutex );
2000-10-20 13:18:57 +00:00
return new ::comphelper::OEnumerationByIndex(this);
2000-09-18 16:07:07 +00:00
}
// ::com::sun::star::container::XIndexAccess
//------------------------------------------------------------------------------
sal_Int32 SAL_CALL FmXFormController::getCount(void) throw( RuntimeException )
{
::osl::MutexGuard aGuard( m_aMutex );
2000-09-18 16:07:07 +00:00
return m_aChilds.size();
}
//------------------------------------------------------------------------------
Any SAL_CALL FmXFormController::getByIndex(sal_Int32 Index) throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, RuntimeException )
{
::osl::MutexGuard aGuard( m_aMutex );
2000-09-18 16:07:07 +00:00
if (Index < 0 ||
2001-05-16 13:22:30 +00:00
Index >= (sal_Int32)m_aChilds.size())
2000-09-18 16:07:07 +00:00
throw ::com::sun::star::lang::IndexOutOfBoundsException();
return makeAny(m_aChilds[Index]);
// , ::getCppuType((const ::com::sun::star::form::XFormController*)0));
}
//-----------------------------------------------------------------------------
void FmXFormController::addChild(FmXFormController* pChild)
{
Reference< ::com::sun::star::form::XFormController > xController(pChild);
m_aChilds.push_back(xController);
pChild->setParent(static_cast< ::com::sun::star::form::XFormController* >(this));
Reference< ::com::sun::star::form::XFormComponent > xForm(pChild->getModel(), UNO_QUERY);
// search the position of the model within the form
sal_uInt32 nPos = m_xModelAsIndex->getCount();
2000-11-07 12:16:50 +00:00
Reference< ::com::sun::star::form::XFormComponent > xTemp;
2000-09-18 16:07:07 +00:00
for( ; nPos; )
{
2000-11-07 12:16:50 +00:00
m_xModelAsIndex->getByIndex(--nPos) >>= xTemp;
if ((::com::sun::star::form::XFormComponent*)xForm.get() == (::com::sun::star::form::XFormComponent*)xTemp.get())
2000-09-18 16:07:07 +00:00
{
Reference< XInterface > xIfc(xController, UNO_QUERY);
m_xModelAsManager->attach( nPos, xIfc, makeAny( xController) );
break;
}
}
}
// EventListener
//------------------------------------------------------------------------------
void SAL_CALL FmXFormController::disposing(const ::com::sun::star::lang::EventObject& e) throw( RuntimeException )
{
// Ist der Container disposed worden
::osl::MutexGuard aGuard( m_aMutex );
2000-09-18 16:07:07 +00:00
Reference< ::com::sun::star::awt::XControlContainer > xContainer(e.Source, UNO_QUERY);
if (xContainer.is())
{
setContainer(Reference< ::com::sun::star::awt::XControlContainer > ());
}
else
{
// ist ein Control disposed worden
Reference< ::com::sun::star::awt::XControl > xControl(e.Source, UNO_QUERY);
if (xControl.is())
{
if (getContainer().is())
removeControl(xControl);
}
}
}
// OComponentHelper
//-----------------------------------------------------------------------------
void FmXFormController::disposing(void)
{
::com::sun::star::lang::EventObject aEvt(static_cast< ::com::sun::star::form::XFormController* >(this));
// noch aktiv ?
if (m_xActiveControl.is())
{
NOTIFY_LISTENERS(m_aActivateListeners, ::com::sun::star::form::XFormControllerListener, formDeactivated, aEvt);
}
m_aActivateListeners.disposeAndClear(aEvt);
m_aModifyListeners.disposeAndClear(aEvt);
m_aErrorListeners.disposeAndClear(aEvt);
m_aDeleteListeners.disposeAndClear(aEvt);
m_aRowSetApproveListeners.disposeAndClear(aEvt);
m_aParameterListeners.disposeAndClear(aEvt);
removeBoundFieldListener();
stopFiltering();
2000-09-18 16:07:07 +00:00
m_aFilters.clear();
::osl::MutexGuard aGuard( m_aMutex );
m_xActiveControl = m_xCurrentControl = NULL;
for (FmFormControllers::const_iterator i = m_aChilds.begin();
i != m_aChilds.end(); i++)
{
// search the position of the model within the form
Reference< ::com::sun::star::form::XFormComponent > xForm((*i)->getModel(), UNO_QUERY);
sal_uInt32 nPos = m_xModelAsIndex->getCount();
2000-11-07 12:16:50 +00:00
Reference< ::com::sun::star::form::XFormComponent > xTemp;
2000-09-18 16:07:07 +00:00
for( ; nPos; )
{
2000-11-07 12:16:50 +00:00
m_xModelAsIndex->getByIndex(--nPos) >>= xTemp;
if ((::com::sun::star::form::XFormComponent*)xForm.get() == (::com::sun::star::form::XFormComponent*)xTemp.get())
2000-09-18 16:07:07 +00:00
{
Reference< XInterface > xIfc(*i, UNO_QUERY);
m_xModelAsManager->detach( nPos, xIfc);
break;
}
}
Reference< ::com::sun::star::lang::XComponent > (*i, UNO_QUERY)->dispose();
}
m_aChilds.clear();
if (m_bDBConnection)
unload();
setContainer(Reference< ::com::sun::star::awt::XControlContainer > ());
setModel(Reference< ::com::sun::star::awt::XTabControllerModel > ());
setParent(Reference< XInterface > ());
2000-10-20 13:18:57 +00:00
::comphelper::disposeComponent(m_xComposer);
2000-09-18 16:07:07 +00:00
2000-11-06 06:19:53 +00:00
// the following members shouldn't be set to NULL
// Freigeben der Aggregation
if (m_xAggregate.is())
{
Reference< XInterface > xInt;
m_xAggregate->setDelegator(xInt);
}
m_xAggregate = NULL;
m_xTabController = NULL;
m_xORB = NULL;
2000-09-18 16:07:07 +00:00
m_bDBConnection = sal_False;
}
//------------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
void SAL_CALL FmXFormController::propertyChange(const PropertyChangeEvent& evt) throw( ::com::sun::star::uno::RuntimeException )
2000-09-18 16:07:07 +00:00
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
if ( evt.PropertyName == FM_PROP_BOUNDFIELD )
2000-09-18 16:07:07 +00:00
{
Reference<XPropertySet> xOldBound;
evt.OldValue >>= xOldBound;
if ( !xOldBound.is() && evt.NewValue.hasValue() )
2000-09-18 16:07:07 +00:00
{
Reference< ::com::sun::star::awt::XControlModel > xControlModel(evt.Source,UNO_QUERY);
Reference< ::com::sun::star::awt::XControl > xControl = findControl(m_aControls,xControlModel,sal_False,sal_False);
if ( xControl.is() )
{
startControlListening(xControl);
Reference<XPropertySet> xProp(xControlModel,UNO_QUERY);
if ( xProp.is() )
xProp->removePropertyChangeListener(FM_PROP_BOUNDFIELD, this);
}
2000-09-18 16:07:07 +00:00
}
}
else
{
sal_Bool bModifiedChanged = (evt.PropertyName == FM_PROP_ISMODIFIED);
sal_Bool bNewChanged = (evt.PropertyName == FM_PROP_ISNEW);
if (bModifiedChanged || bNewChanged)
2000-09-18 16:07:07 +00:00
{
::osl::MutexGuard aGuard( m_aMutex );
if (bModifiedChanged)
m_bCurrentRecordModified = ::comphelper::getBOOL(evt.NewValue);
else
m_bCurrentRecordNew = ::comphelper::getBOOL(evt.NewValue);
// toggle the locking
if (m_bLocked != determineLockState())
{
m_bLocked = !m_bLocked;
setLocks();
if (isListeningForChanges())
startListening();
else
stopListening();
}
if (bNewChanged && m_pView)
{
if (m_nToggleEvent)
Application::RemoveUserEvent( m_nToggleEvent );
m_nToggleEvent = Application::PostUserEvent( LINK(this, FmXFormController,
OnToggleAutoFields) );
}
2000-09-18 16:07:07 +00:00
if (!m_bCurrentRecordModified)
m_bModified = sal_False;
}
2000-09-18 16:07:07 +00:00
}
}
//------------------------------------------------------------------------------
void FmXFormController::toggleAutoFields(sal_Bool bAutoFields)
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
if (!m_pView)
{
DBG_ERROR("FmXFormController::toggleAutoFields : you can't call toggleAutoFields when no view exists !");
2000-09-18 16:07:07 +00:00
return;
}
// Austauschen der Kontrols fuer das aktuelle Formular
Sequence < Reference< ::com::sun::star::awt::XControl > > aControls(m_aControls);
const Reference< ::com::sun::star::awt::XControl > * pControls = m_aControls.getConstArray();
SdrPageView* pCurPageView = m_pView->GetPageViewPvNum(0);
const SdrPageViewWindow* pWindow = pCurPageView ? pCurPageView->FindWindow(*((OutputDevice*)m_pView->GetActualOutDev())) : 0L;
if(!pWindow)
{
2000-09-18 16:07:07 +00:00
return;
}
//sal_uInt16 nPos = pCurPageView ? pCurPageView->GetWinList().Find((OutputDevice*)m_pView->GetActualOutDev()) : SDRPAGEVIEWWIN_NOTFOUND;
//if (nPos == SDRPAGEVIEWWIN_NOTFOUND)
// return;
2000-09-18 16:07:07 +00:00
// the control we have to activate after replacement
Reference< ::com::sun::star::awt::XControl > xNewActiveControl;
if (bAutoFields)
{
// as we don't want new controls to be attached to the scripting environment
// we change attach flags
m_bAttachEvents = sal_False;
for (sal_Int32 i = aControls.getLength(); i > 0;)
{
const Reference< ::com::sun::star::awt::XControl > & xControl = pControls[--i];
if (xControl.is())
{
2000-11-06 06:19:53 +00:00
Reference< XPropertySet > xSet(xControl->getModel(), UNO_QUERY);
2000-10-20 13:18:57 +00:00
if (xSet.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xSet))
2000-09-18 16:07:07 +00:00
{
// does the model use a bound field ?
2000-11-07 12:16:50 +00:00
Reference< XPropertySet > xField;
xSet->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
2000-09-18 16:07:07 +00:00
// is it a autofield?
2000-10-20 13:18:57 +00:00
if (xField.is() && ::comphelper::hasProperty(FM_PROP_AUTOINCREMENT, xField) &&
::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_AUTOINCREMENT)))
2000-09-18 16:07:07 +00:00
{
//const SdrPageViewWinRec& rWR = pCurPageView->GetWinList()[nPos];
const SdrUnoControlList& rControlList = pWindow->GetControlList();
2000-09-18 16:07:07 +00:00
sal_uInt16 nCtrlNum = rControlList.Find(xControl);
2000-09-18 16:07:07 +00:00
if (nCtrlNum != SDRUNOCONTROL_NOTFOUND)
{
// ok create an autocontrol
SdrUnoControlRec& rControlRec = (SdrUnoControlRec&)rControlList[nCtrlNum];
FmXAutoControl* pAutoControl = new FmXAutoControl();
Reference< ::com::sun::star::awt::XControl > xNewControl(pAutoControl);
// setting the focus if the current control
// is the active one
if ((::com::sun::star::awt::XControl*)m_xActiveControl.get() == (::com::sun::star::awt::XControl*)xControl.get())
{
xNewActiveControl = xNewControl;
m_xActiveControl = m_xCurrentControl = NULL;
}
else if ((::com::sun::star::awt::XControl*)m_xCurrentControl.get() == (::com::sun::star::awt::XControl*)xControl.get())
m_xCurrentControl = xNewControl;
rControlRec.ReplaceControl(xNewControl);
}
}
}
}
}
m_bAttachEvents = sal_True;
}
else
{
m_bDetachEvents = sal_False;
for (sal_Int32 i = aControls.getLength(); i > 0;)
{
const Reference< ::com::sun::star::awt::XControl > & xControl = pControls[--i];
if (xControl.is())
{
2000-11-06 06:19:53 +00:00
Reference< XPropertySet > xSet(xControl->getModel(), UNO_QUERY);
2000-10-20 13:18:57 +00:00
if (xSet.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xSet))
2000-09-18 16:07:07 +00:00
{
// does the model use a bound field ?
2000-11-07 12:16:50 +00:00
Reference< XPropertySet > xField;
xSet->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
2000-09-18 16:07:07 +00:00
// is it a autofield?
2000-10-20 13:18:57 +00:00
if (xField.is() && ::comphelper::hasProperty(FM_PROP_AUTOINCREMENT, xField) &&
::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_AUTOINCREMENT)))
2000-09-18 16:07:07 +00:00
{
// const SdrPageViewWinRec& rWR = pCurPageView->GetWinList()[nPos];
// const SdrPageViewWindow& rWindow = pCurPageView->GetPageViewWindows().Get(nPos);
const SdrUnoControlList& rControlList = pWindow->GetControlList();
2000-09-18 16:07:07 +00:00
sal_uInt16 nCtrlNum = rControlList.Find(xControl);
if (nCtrlNum != SDRUNOCONTROL_NOTFOUND)
{
// Zuruecksetzen des Controls auf das Defaultcontrol
SdrUnoControlRec& rControlRec = (SdrUnoControlRec&)rControlList[nCtrlNum];
2000-10-20 13:18:57 +00:00
::rtl::OUString aServiceName = ::comphelper::getString(xSet->getPropertyValue(FM_PROP_DEFAULTCONTROL));
2000-11-06 06:19:53 +00:00
Reference< ::com::sun::star::awt::XControl > xNewControl(m_xORB->createInstance(aServiceName), UNO_QUERY);
2000-09-18 16:07:07 +00:00
// setting the focus if the current control
// is the active one
if ((::com::sun::star::awt::XControl*)m_xActiveControl.get() == (::com::sun::star::awt::XControl*)xControl.get())
{
xNewActiveControl = xNewControl;
m_xActiveControl = m_xCurrentControl = NULL;
}
else if ((::com::sun::star::awt::XControl*)m_xCurrentControl.get() == (::com::sun::star::awt::XControl*)xControl.get())
m_xCurrentControl = xNewControl;
rControlRec.ReplaceControl(xNewControl);
}
}
}
}
}
m_bDetachEvents = sal_True;
}
// set the focus async if possible
// setting the focus to the replacing control
Reference< ::com::sun::star::awt::XWindow > xWindow(xNewActiveControl, UNO_QUERY);
if (xWindow.is())
xWindow->setFocus();
}
//------------------------------------------------------------------------------
IMPL_LINK(FmXFormController, OnToggleAutoFields, void*, EMPTYARG)
{
{
::osl::MutexGuard aGuard( m_aMutex );
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
m_nToggleEvent = 0;
}
2000-09-18 16:07:07 +00:00
toggleAutoFields(m_bCurrentRecordNew);
return 1L;
}
// ::com::sun::star::awt::XTextListener
//------------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
void SAL_CALL FmXFormController::textChanged(const ::com::sun::star::awt::TextEvent& e) throw( ::com::sun::star::uno::RuntimeException )
2000-09-18 16:07:07 +00:00
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
if (m_bFiltering)
{
Reference< ::com::sun::star::awt::XTextComponent > xText(e.Source,UNO_QUERY);
::rtl::OUString aText = xText->getText();
// Suchen der aktuellen Row
OSL_ENSURE(m_aFilters.size() > m_nCurrentFilterPosition && m_nCurrentFilterPosition >= 0,"m_nCurrentFilterPosition too big");
if ( m_nCurrentFilterPosition >= 0 && m_nCurrentFilterPosition < m_aFilters.size() )
2000-09-18 16:07:07 +00:00
{
FmFilterRow& rRow = m_aFilters[m_nCurrentFilterPosition];
// do we have a new filter
if (aText.getLength())
rRow[xText] = aText;
else
{
// do we have the control in the row
FmFilterRow::iterator iter = rRow.find(xText);
// erase the entry out of the row
if (iter != rRow.end())
rRow.erase(iter);
}
2000-09-18 16:07:07 +00:00
}
}
else if (!m_bModified)
onModify( e.Source );
2000-09-18 16:07:07 +00:00
}
// ::com::sun::star::awt::XItemListener
//------------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
void SAL_CALL FmXFormController::itemStateChanged(const ::com::sun::star::awt::ItemEvent& rEvent) throw( ::com::sun::star::uno::RuntimeException )
2000-09-18 16:07:07 +00:00
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
if (!m_bModified)
onModify( rEvent.Source );
2000-09-18 16:07:07 +00:00
}
// XModificationBroadcaster
//------------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
void SAL_CALL FmXFormController::addModifyListener(const Reference< ::com::sun::star::util::XModifyListener > & l) throw( ::com::sun::star::uno::RuntimeException )
2000-09-18 16:07:07 +00:00
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
m_aModifyListeners.addInterface( l );
}
//------------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
void FmXFormController::removeModifyListener(const Reference< ::com::sun::star::util::XModifyListener > & l) throw( ::com::sun::star::uno::RuntimeException )
2000-09-18 16:07:07 +00:00
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
m_aModifyListeners.removeInterface( l );
}
// XModificationListener
//------------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
void FmXFormController::modified(const EventObject& rEvent) throw( ::com::sun::star::uno::RuntimeException )
2000-09-18 16:07:07 +00:00
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
if (!m_bModified)
onModify( rEvent.Source );
2000-09-18 16:07:07 +00:00
}
//------------------------------------------------------------------------------
void FmXFormController::onModify( const Reference< XInterface >& _rxControl )
2000-09-18 16:07:07 +00:00
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
if (!m_bModified)
{
::osl::MutexGuard aGuard( m_aMutex );
m_bModified = sal_True;
}
Reference< XControl > xSourceControl(_rxControl, UNO_QUERY);
if (xSourceControl.get() != m_xCurrentControl.get())
{ // let this control grab the focus
// (this case may happen if somebody moves the scroll wheel of the mouse over a control
// which does not have the focus)
// 85511 - 29.05.2001 - frank.schoenheit@germany.sun.com
Reference< XWindow > xControlWindow(_rxControl, UNO_QUERY);
if (xControlWindow.is())
xControlWindow->setFocus();
}
EventObject aEvt(static_cast<cppu::OWeakObject*>(this));
NOTIFY_LISTENERS(m_aModifyListeners, XModifyListener, modified, aEvt);
2000-09-18 16:07:07 +00:00
}
//------------------------------------------------------------------------------
sal_Bool FmXFormController::determineLockState() const
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
// a.) in filter mode we are always locked
// b.) if we have no valid model or our model (a result set) is not alive -> we're locked
// c.) if we are inserting everything is OK and we are not locked
// d.) if are not updatable or on invalid position
Reference< ::com::sun::star::sdbc::XResultSet > xResultSet(m_xModelAsIndex, UNO_QUERY);
if (m_bFiltering || !xResultSet.is() || !isRowSetAlive(xResultSet))
return sal_True;
else
return (m_bCanInsert && m_bCurrentRecordNew) ? sal_False
: xResultSet->isBeforeFirst() || xResultSet->isAfterLast() || xResultSet->rowDeleted() || !m_bCanUpdate;
}
// FocusListener
//------------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
void FmXFormController::focusGained(const ::com::sun::star::awt::FocusEvent& e) throw( ::com::sun::star::uno::RuntimeException )
2000-09-18 16:07:07 +00:00
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
::osl::MutexGuard aGuard( m_aMutex );
Reference< ::com::sun::star::awt::XControl > xControl(e.Source, UNO_QUERY);
if (m_bDBConnection)
{
// do we need to keep the locking of the commit
// we hold the lock as long as the control differs from the current
// otherwhise we disabled the lock
m_bCommitLock = m_bCommitLock && (::com::sun::star::awt::XControl*)xControl.get() != (::com::sun::star::awt::XControl*)m_xCurrentControl.get();
if (m_bCommitLock)
return;
// when do we have to commit a value to form or a filter
// a.) if the current value is modified
// b.) there must be a current control
// c.) and it must be different from the new focus owning control or
// d.) the focus is moving around (so we have only one control)
if ((m_bModified || m_bFiltering) &&
m_xCurrentControl.is() &&
((xControl.get() != m_xCurrentControl.get()) ||
2000-09-18 16:07:07 +00:00
((e.FocusFlags & ::com::sun::star::awt::FocusChangeReason::AROUND) && (m_bCycle || m_bFiltering)))
)
{
// check the old control if the content is ok
#if (OSL_DEBUG_LEVEL > 1) || DBG_UTIL
2000-09-18 16:07:07 +00:00
Reference< ::com::sun::star::form::XBoundControl > xLockingTest(m_xCurrentControl, UNO_QUERY);
sal_Bool bControlIsLocked = xLockingTest.is() && xLockingTest->getLock();
DBG_ASSERT(!bControlIsLocked, "FmXFormController::focusLost : I'm modified and the current control is locked ? How this ?");
// normalerweise sollte ein gelocktes Control nicht modified sein, also muss wohl mein bModified aus einem anderen Kontext
// gesetzt worden sein, was ich nicht verstehen wuerde ...
#endif
DBG_ASSERT(m_xCurrentControl.is(), "kein CurrentControl gesetzt");
// zunaechst das Control fragen ob es das IFace unterstuetzt
Reference< XBoundComponent > xBound(m_xCurrentControl, UNO_QUERY);
2000-09-18 16:07:07 +00:00
if (!xBound.is() && m_xCurrentControl.is())
xBound = Reference< XBoundComponent > (m_xCurrentControl->getModel(), UNO_QUERY);
2000-09-18 16:07:07 +00:00
// lock if we lose the focus during commit
m_bCommitLock = sal_True;
// Commit nicht erfolgreich, Focus zuruecksetzen
if (xBound.is() && !xBound->commit())
{
// the commit failed and we don't commit again until the current control
// which couldn't be commit gains the focus again
Reference< ::com::sun::star::awt::XWindow > xWindow(m_xCurrentControl, UNO_QUERY);
if (xWindow.is())
xWindow->setFocus();
return;
}
else
{
m_bModified = sal_False;
m_bCommitLock = sal_False;
}
}
if (!m_bFiltering && m_bCycle && (e.FocusFlags & ::com::sun::star::awt::FocusChangeReason::AROUND) && m_xCurrentControl.is())
{
if (e.FocusFlags & ::com::sun::star::awt::FocusChangeReason::FORWARD)
FmXFormShell::CanMoveRight((::com::sun::star::form::XFormController*)this) && FmXFormShell::MoveRight((::com::sun::star::form::XFormController*)this);
else // backward
FmXFormShell::CanMoveLeft((::com::sun::star::form::XFormController*)this) && FmXFormShell::MoveLeft((::com::sun::star::form::XFormController*)this);
}
}
// Immer noch ein und dasselbe Control
if ( (m_xActiveControl.get() == xControl.get())
&& (xControl.get() == m_xCurrentControl.get())
)
2000-09-18 16:07:07 +00:00
{
DBG_ASSERT(m_xCurrentControl.is(), "Kein CurrentControl selektiert");
return;
}
sal_Bool bActivated = !m_xActiveControl.is() && xControl.is();
m_xActiveControl = xControl;
m_xCurrentControl = xControl;
DBG_ASSERT(m_xCurrentControl.is(), "Kein CurrentControl selektiert");
if (bActivated)
onActivate();
if (m_bDBConnection && !m_bFiltering && m_pView)
m_pView->GetFormShell()->GetViewShell()->GetViewFrame()->GetBindings().Invalidate(AutoSlotMap);
2000-09-18 16:07:07 +00:00
if (m_xCurrentControl.is())
{
// Control erhaelt Focus, dann eventuell in den sichtbaren Bereich
Reference< ::com::sun::star::awt::XWindow > xWindow(xControl, UNO_QUERY);
if (xWindow.is() && m_pView && m_pWindow)
{
::com::sun::star::awt::Rectangle aRect = xWindow->getPosSize();
::Rectangle aNewRect(aRect.X,aRect.Y,aRect.X+aRect.Width,aRect.Y+aRect.Height);
2000-09-18 16:07:07 +00:00
aNewRect = m_pWindow->PixelToLogic(aNewRect);
m_pView->MakeVisible(aNewRect, *m_pWindow);
}
}
}
//------------------------------------------------------------------------------
void FmXFormController::onActivate()
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
// benachrichtigen, dass form activiert
::com::sun::star::lang::EventObject aEvt;
aEvt.Source = *this;
NOTIFY_LISTENERS(m_aActivateListeners, ::com::sun::star::form::XFormControllerListener, formActivated, aEvt);
// verschicken ob modified
if (m_bModified)
{
NOTIFY_LISTENERS(m_aModifyListeners, ::com::sun::star::util::XModifyListener, modified, aEvt);
}
}
//------------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
void FmXFormController::focusLost(const ::com::sun::star::awt::FocusEvent& e) throw( ::com::sun::star::uno::RuntimeException )
2000-09-18 16:07:07 +00:00
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
Reference< ::com::sun::star::awt::XControl > xControl(e.Source, UNO_QUERY);
Reference< ::com::sun::star::awt::XWindowPeer > xNext(e.NextFocus, UNO_QUERY);
Reference< ::com::sun::star::awt::XControl > xNextControl = isInList(xNext);
if (!xNextControl.is())
{
m_xActiveControl = NULL;
::com::sun::star::lang::EventObject aEvt;
aEvt.Source = *this;
NOTIFY_LISTENERS(m_aActivateListeners, ::com::sun::star::form::XFormControllerListener, formDeactivated, aEvt);
}
}
//------------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
void FmXFormController::setModel(const Reference< ::com::sun::star::awt::XTabControllerModel > & Model) throw( ::com::sun::star::uno::RuntimeException )
2000-09-18 16:07:07 +00:00
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
::osl::MutexGuard aGuard( m_aMutex );
DBG_ASSERT(m_xTabController.is(), "FmXFormController::setModel : invalid aggregate !");
// disconnect from the old model
if (m_xModelAsIndex.is())
{
if (m_bDBConnection)
{
// we are currently working on the model
::com::sun::star::lang::EventObject aEvt(m_xModelAsIndex);
unloaded(aEvt);
}
Reference< ::com::sun::star::form::XLoadable > xForm(m_xModelAsIndex, UNO_QUERY);
if (xForm.is())
xForm->removeLoadListener(this);
Reference< ::com::sun::star::sdb::XSQLErrorBroadcaster > xBroadcaster(m_xModelAsIndex, UNO_QUERY);
if (xBroadcaster.is())
xBroadcaster->removeSQLErrorListener(this);
Reference< ::com::sun::star::form::XDatabaseParameterBroadcaster > xParamBroadcaster(m_xModelAsIndex, UNO_QUERY);
if (xParamBroadcaster.is())
xParamBroadcaster->removeParameterListener(this);
}
// set the new model wait for the load event
if (m_xTabController.is())
m_xTabController->setModel(Model);
m_xModelAsIndex = Reference< ::com::sun::star::container::XIndexAccess > (Model, UNO_QUERY);
m_xModelAsManager = Reference< ::com::sun::star::script::XEventAttacherManager > (Model, UNO_QUERY);
// only if both ifaces exit, the controller will work successful
if (!m_xModelAsIndex.is() || !m_xModelAsManager.is())
{
m_xModelAsManager = NULL;
m_xModelAsIndex = NULL;
}
if (m_xModelAsIndex.is())
{
// adding load and ui interaction listeners
Reference< ::com::sun::star::form::XLoadable > xForm(Model, UNO_QUERY);
if (xForm.is())
xForm->addLoadListener(this);
Reference< ::com::sun::star::sdb::XSQLErrorBroadcaster > xBroadcaster(Model, UNO_QUERY);
if (xBroadcaster.is())
xBroadcaster->addSQLErrorListener(this);
Reference< ::com::sun::star::form::XDatabaseParameterBroadcaster > xParamBroadcaster(Model, UNO_QUERY);
if (xParamBroadcaster.is())
xParamBroadcaster->addParameterListener(this);
// well, is the database already loaded?
// then we have to simulate a load event
Reference< ::com::sun::star::form::XLoadable > xCursor(m_xModelAsIndex, UNO_QUERY);
if (xCursor.is() && xCursor->isLoaded())
{
::com::sun::star::lang::EventObject aEvt(xCursor);
loaded(aEvt);
}
}
}
//------------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
Reference< ::com::sun::star::awt::XTabControllerModel > FmXFormController::getModel() throw( ::com::sun::star::uno::RuntimeException )
2000-09-18 16:07:07 +00:00
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
DBG_ASSERT(m_xTabController.is(), "FmXFormController::getModel : invalid aggregate !");
if (!m_xTabController.is())
return Reference< ::com::sun::star::awt::XTabControllerModel > ();
return m_xTabController->getModel();
}
//------------------------------------------------------------------------------
void FmXFormController::addToEventAttacher(const Reference< ::com::sun::star::awt::XControl > & xControl)
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
// anmelden beim Eventattacher
Reference< ::com::sun::star::form::XFormComponent > xComp(xControl->getModel(), UNO_QUERY);
if (xComp.is() && m_xModelAsIndex.is())
{
// Und die Position des ControlModel darin suchen
sal_uInt32 nPos = m_xModelAsIndex->getCount();
2000-11-07 12:16:50 +00:00
Reference< ::com::sun::star::form::XFormComponent > xTemp;
2000-09-18 16:07:07 +00:00
for( ; nPos; )
{
2000-11-07 12:16:50 +00:00
m_xModelAsIndex->getByIndex(--nPos) >>= xTemp;
if ((::com::sun::star::form::XFormComponent*)xComp.get() == (::com::sun::star::form::XFormComponent*)xTemp.get())
2000-09-18 16:07:07 +00:00
{
Reference< XInterface > xIfc(xControl, UNO_QUERY);
m_xModelAsManager->attach( nPos, xIfc, makeAny(xControl) );
break;
}
}
}
}
//------------------------------------------------------------------------------
void FmXFormController::removeFromEventAttacher(const Reference< ::com::sun::star::awt::XControl > & xControl)
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
// abmelden beim Eventattacher
Reference< ::com::sun::star::form::XFormComponent > xComp(xControl->getModel(), UNO_QUERY);
if ( xComp.is() && m_xModelAsIndex.is() )
2000-09-18 16:07:07 +00:00
{
// Und die Position des ControlModel darin suchen
sal_uInt32 nPos = m_xModelAsIndex->getCount();
2000-11-07 12:16:50 +00:00
Reference< ::com::sun::star::form::XFormComponent > xTemp;
2000-09-18 16:07:07 +00:00
for( ; nPos; )
{
2000-11-07 12:16:50 +00:00
m_xModelAsIndex->getByIndex(--nPos) >>= xTemp;
if ((::com::sun::star::form::XFormComponent*)xComp.get() == (::com::sun::star::form::XFormComponent*)xTemp.get())
2000-09-18 16:07:07 +00:00
{
Reference< XInterface > xIfc(xControl, UNO_QUERY);
m_xModelAsManager->detach( nPos, xIfc );
break;
}
}
}
}
//------------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
void FmXFormController::setContainer(const Reference< ::com::sun::star::awt::XControlContainer > & xContainer) throw( ::com::sun::star::uno::RuntimeException )
2000-09-18 16:07:07 +00:00
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
Reference< ::com::sun::star::awt::XTabControllerModel > xTabModel(getModel());
DBG_ASSERT(xTabModel.is() || !xContainer.is(), "No Model defined");
// if we have a new container we need a model
DBG_ASSERT(m_xTabController.is(), "FmXFormController::setContainer : invalid aggregate !");
::osl::MutexGuard aGuard( m_aMutex );
Reference< ::com::sun::star::container::XContainer > xCurrentContainer;
if (m_xTabController.is())
xCurrentContainer = Reference< ::com::sun::star::container::XContainer > (m_xTabController->getContainer(), UNO_QUERY);
if (xCurrentContainer.is())
{
xCurrentContainer->removeContainerListener(this);
if (m_aInsertTimer.IsActive())
m_aInsertTimer.Stop();
// bei den Controls abmelden
sal_Int32 nCount = m_aControls.getLength();
const Reference< ::com::sun::star::awt::XControl > * pControls = m_aControls.getConstArray();
// clear the filter map
for (FmFilterControls::const_iterator iter = m_aFilterControls.begin();
iter != m_aFilterControls.end(); ++iter)
2000-09-18 16:07:07 +00:00
(*iter).first->removeTextListener(this);
m_aFilterControls.clear();
// einsammeln der Controls
for (sal_Int32 i = 0; i < nCount; ++i, ++pControls)
{
// bei jedem Control als FocusListener anmelden
Reference< ::com::sun::star::awt::XWindow > xWindow(*pControls, UNO_QUERY);
if (xWindow.is())
{
xWindow->removeFocusListener(this);
// abmelden beim Eventattacher
removeFromEventAttacher(*pControls);
}
Reference< ::com::sun::star::frame::XDispatchProviderInterception > xInterception(*pControls, UNO_QUERY);
if (xInterception.is())
deleteInterceptor(xInterception);
if (pControls->is())
{
Reference< ::com::sun::star::form::XReset > xControlReset((*pControls)->getModel(), UNO_QUERY);
if (xControlReset.is())
xControlReset->removeResetListener((::com::sun::star::form::XResetListener*)this);
}
}
// Datenbank spezifische Dinge vornehmen
if (m_bDBConnection && isListeningForChanges())
stopListening();
m_aControls = Sequence< Reference< ::com::sun::star::awt::XControl > >();
}
if (m_xTabController.is())
m_xTabController->setContainer(xContainer);
// Welche Controls gehoeren zum Container ?
if (xContainer.is() && xTabModel.is())
{
Sequence< Reference< ::com::sun::star::awt::XControlModel > > aModels = xTabModel->getControlModels();
const Reference< ::com::sun::star::awt::XControlModel > * pModels = aModels.getConstArray();
Sequence< Reference< ::com::sun::star::awt::XControl > > xCtrls = xContainer->getControls();
sal_Int32 nCount = aModels.getLength();
m_aControls = Sequence< Reference< ::com::sun::star::awt::XControl > >( nCount );
Reference< ::com::sun::star::awt::XControl > * pControls = m_aControls.getArray();
// einsammeln der Controls
sal_Int32 i, j;
for (i = 0, j = 0; i < nCount; ++i )
2000-09-18 16:07:07 +00:00
{
Reference< ::com::sun::star::awt::XControlModel > xCtrlModel = pModels[i];
// Zum Model passendes Control suchen
Reference< ::com::sun::star::awt::XControl > xCtrl = findControl( xCtrls, xCtrlModel,sal_False );
2000-09-18 16:07:07 +00:00
if (xCtrl.is())
{
pControls[j++] = xCtrl;
// bei jedem Control als FocusListener anmelden
Reference< ::com::sun::star::awt::XWindow > xWindow(xCtrl, UNO_QUERY);
if (xWindow.is())
{
xWindow->addFocusListener(this);
// anmelden beim Eventattacher
addToEventAttacher(xCtrl);
}
// add a dispatch interceptor to the control (if supported)
Reference< ::com::sun::star::frame::XDispatchProviderInterception > xInterception(xCtrl, UNO_QUERY);
if (xInterception.is())
createInterceptor(xInterception);
// we want to know about the reset of the the model of our controls
// (for correctly resetting m_bModified)
Reference< ::com::sun::star::form::XReset > xControlReset(xCtrl->getModel(), UNO_QUERY);
if (xControlReset.is())
xControlReset->addResetListener((::com::sun::star::form::XResetListener*)this);
}
}
// nicht fuer jedes Model ein Control
if (j != i)
m_aControls.realloc(j);
// am Container horchen
Reference< ::com::sun::star::container::XContainer > xNewContainer(xContainer, UNO_QUERY);
if (xNewContainer.is())
xNewContainer->addContainerListener(this);
// Datenbank spezifische Dinge vornehmen
if (m_bDBConnection)
{
m_bLocked = determineLockState();
setLocks();
if (!isLocked())
startListening();
}
}
// befinden sich die Controls in der richtigen Reihenfolge
m_bControlsSorted = sal_True;
}
//------------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
Reference< ::com::sun::star::awt::XControlContainer > FmXFormController::getContainer() throw( ::com::sun::star::uno::RuntimeException )
2000-09-18 16:07:07 +00:00
{
::osl::MutexGuard aGuard( m_aMutex );
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
DBG_ASSERT(m_xTabController.is(), "FmXFormController::getContainer : invalid aggregate !");
if (!m_xTabController.is())
return Reference< ::com::sun::star::awt::XControlContainer > ();
return m_xTabController->getContainer();
}
//------------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
Sequence< Reference< ::com::sun::star::awt::XControl > > FmXFormController::getControls(void) throw( ::com::sun::star::uno::RuntimeException )
2000-09-18 16:07:07 +00:00
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
::osl::MutexGuard aGuard( m_aMutex );
if (!m_bControlsSorted)
{
Reference< ::com::sun::star::awt::XTabControllerModel > xModel = getModel();
if (!xModel.is())
return m_aControls;
Sequence< Reference< ::com::sun::star::awt::XControlModel > > aControlModels = xModel->getControlModels();
const Reference< ::com::sun::star::awt::XControlModel > * pModels = aControlModels.getConstArray();
sal_Int32 nModels = aControlModels.getLength();
Sequence< Reference< ::com::sun::star::awt::XControl > > aNewControls(nModels);
Reference< ::com::sun::star::awt::XControl > * pControls = aNewControls.getArray();
Reference< ::com::sun::star::awt::XControlModel > xCtrlModel;
Reference< ::com::sun::star::awt::XControl > xCtrl;
// Umsortieren der Controls entsprechend der TabReihenfolge
for (sal_Int32 i = 0, j = 0; i < nModels; i++)
{
xCtrlModel = pModels[i];
// Zum Model passendes Control suchen
xCtrl = findControl(m_aControls, xCtrlModel);
if (xCtrl.is())
pControls[j++] = xCtrl;
}
m_aControls = aNewControls;
m_bControlsSorted = sal_True;
}
return m_aControls;
}
//------------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
void FmXFormController::autoTabOrder() throw( ::com::sun::star::uno::RuntimeException )
2000-09-18 16:07:07 +00:00
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
::osl::MutexGuard aGuard( m_aMutex );
DBG_ASSERT(m_xTabController.is(), "FmXFormController::autoTabOrder : invalid aggregate !");
if (m_xTabController.is())
m_xTabController->autoTabOrder();
}
//------------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
void FmXFormController::activateTabOrder() throw( ::com::sun::star::uno::RuntimeException )
2000-09-18 16:07:07 +00:00
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
::osl::MutexGuard aGuard( m_aMutex );
DBG_ASSERT(m_xTabController.is(), "FmXFormController::activateTabOrder : invalid aggregate !");
if (m_xTabController.is())
m_xTabController->activateTabOrder();
}
//------------------------------------------------------------------------------
void FmXFormController::setControlLock(const Reference< ::com::sun::star::awt::XControl > & xControl)
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
sal_Bool bLocked = isLocked();
// es wird gelockt
// a.) wenn der ganze Datensatz gesperrt ist
// b.) wenn das zugehoerige Feld gespeert ist
Reference< ::com::sun::star::form::XBoundControl > xBound(xControl, UNO_QUERY);
if (xBound.is() && ((bLocked && bLocked != xBound->getLock() ||
!bLocked))) // beim entlocken immer einzelne Felder ueberpr<70>fen
{
// gibt es eine Datenquelle
2000-11-06 06:19:53 +00:00
Reference< XPropertySet > xSet(xControl->getModel(), UNO_QUERY);
2000-10-20 13:18:57 +00:00
if (xSet.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xSet))
2000-09-18 16:07:07 +00:00
{
// wie sieht mit den Properties ReadOnly und Enable aus
sal_Bool bTouch = sal_True;
2000-10-20 13:18:57 +00:00
if (::comphelper::hasProperty(FM_PROP_ENABLED, xSet))
bTouch = ::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_ENABLED));
if (::comphelper::hasProperty(FM_PROP_READONLY, xSet))
bTouch = !::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_READONLY));
2000-09-18 16:07:07 +00:00
if (bTouch)
{
2000-11-07 12:16:50 +00:00
Reference< XPropertySet > xField;
xSet->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
2000-09-18 16:07:07 +00:00
if (xField.is())
{
if (bLocked)
xBound->setLock(bLocked);
else
{
try
{
Any aVal = xField->getPropertyValue(FM_PROP_ISREADONLY);
2000-10-20 13:18:57 +00:00
if (aVal.hasValue() && ::comphelper::getBOOL(aVal))
2000-09-18 16:07:07 +00:00
xBound->setLock(sal_True);
else
xBound->setLock(bLocked);
}
catch(...)
{
}
}
}
}
}
}
}
//------------------------------------------------------------------------------
void FmXFormController::setLocks()
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
// alle Controls, die mit einer Datenquelle verbunden sind locken/unlocken
sal_Int32 nLength = m_aControls.getLength();
const Reference< ::com::sun::star::awt::XControl > * pControls = m_aControls.getConstArray();
for (sal_Int32 i = 0; i < nLength; i++)
setControlLock(pControls[i]);
}
//------------------------------------------------------------------------------
void FmXFormController::startControlListening(const Reference< ::com::sun::star::awt::XControl > & xControl)
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
// jetzt anmelden bei gebundenen feldern
sal_Bool bModifyListening = sal_False;
Reference< ::com::sun::star::form::XBoundComponent > xBound(xControl, UNO_QUERY);
if (xBound.is()) // gebundene Controls,
bModifyListening = sal_True;
else
{
xBound = Reference< ::com::sun::star::form::XBoundComponent > (xControl->getModel(), UNO_QUERY);
// gibt es eine Datenquelle
2000-11-06 06:19:53 +00:00
Reference< XPropertySet > xSet(xBound, UNO_QUERY);
2000-10-20 13:18:57 +00:00
if (xSet.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xSet))
2000-09-18 16:07:07 +00:00
{
2000-11-07 12:16:50 +00:00
Reference< XPropertySet > xField;
xSet->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
2000-09-18 16:07:07 +00:00
bModifyListening = (xField.is());
if ( !bModifyListening )
xSet->addPropertyChangeListener( FM_PROP_BOUNDFIELD, this );
2000-09-18 16:07:07 +00:00
}
}
// kuenstliches while
while (bModifyListening)
{
Reference< ::com::sun::star::util::XModifyBroadcaster > xMod(xControl, UNO_QUERY);
if (xMod.is())
{
xMod->addModifyListener(this);
break;
}
// alle die Text um vorzeitig ein modified zu erkennen
Reference< ::com::sun::star::awt::XTextComponent > xText(xControl, UNO_QUERY);
if (xText.is())
{
xText->addTextListener(this);
break;
}
Reference< ::com::sun::star::awt::XCheckBox > xBox(xControl, UNO_QUERY);
if (xBox.is())
{
xBox->addItemListener(this);
break;
}
Reference< ::com::sun::star::awt::XComboBox > xCbBox(xControl, UNO_QUERY);
if (xCbBox.is())
{
xCbBox->addItemListener(this);
break;
}
Reference< ::com::sun::star::awt::XListBox > xListBox(xControl, UNO_QUERY);
if (xListBox.is())
{
xListBox->addItemListener(this);
break;
}
break;
}
}
//------------------------------------------------------------------------------
void FmXFormController::stopControlListening(const Reference< ::com::sun::star::awt::XControl > & xControl)
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
// Reference< ::com::sun::star::data::XDatabaseCursor > xCursor(getModel(), UNO_QUERY);
sal_Bool bModifyListening = sal_False;
Reference< ::com::sun::star::form::XBoundComponent > xBound(xControl, UNO_QUERY);
if (xBound.is()) // gebundene Controls,
bModifyListening = sal_True;
else
{
xBound = Reference< ::com::sun::star::form::XBoundComponent > (xControl->getModel(), UNO_QUERY);
// gibt es eine Datenquelle
2000-11-06 06:19:53 +00:00
Reference< XPropertySet > xSet(xBound, UNO_QUERY);
2000-10-20 13:18:57 +00:00
if (xSet.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xSet))
2000-09-18 16:07:07 +00:00
{
2000-11-07 12:16:50 +00:00
Reference< XPropertySet > xField;
xSet->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
2000-09-18 16:07:07 +00:00
bModifyListening = (xField.is());
}
}
// kuenstliches while
while (bModifyListening)
{
Reference< ::com::sun::star::util::XModifyBroadcaster > xMod(xControl, UNO_QUERY);
if (xMod.is())
{
xMod->removeModifyListener(this);
break;
}
// alle die Text um vorzeitig ein modified zu erkennen
Reference< ::com::sun::star::awt::XTextComponent > xText(xControl, UNO_QUERY);
if (xText.is())
{
xText->removeTextListener(this);
break;
}
Reference< ::com::sun::star::awt::XCheckBox > xBox(xControl, UNO_QUERY);
if (xBox.is())
{
xBox->removeItemListener(this);
break;
}
Reference< ::com::sun::star::awt::XComboBox > xCbBox(xControl, UNO_QUERY);
if (xCbBox.is())
{
xCbBox->removeItemListener(this);
break;
}
Reference< ::com::sun::star::awt::XListBox > xListBox(xControl, UNO_QUERY);
if (xListBox.is())
{
xListBox->removeItemListener(this);
break;
}
break;
}
}
//------------------------------------------------------------------------------
void FmXFormController::startListening()
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
m_bModified = sal_False;
// jetzt anmelden bei gebundenen feldern
const Reference< ::com::sun::star::awt::XControl > * pControls = m_aControls.getConstArray();
for (sal_Int32 i = 0; i < m_aControls.getLength(); i++ )
startControlListening(pControls[i]);
}
//------------------------------------------------------------------------------
void FmXFormController::stopListening()
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
m_bModified = sal_False;
// jetzt anmelden bei gebundenen feldern
const Reference< ::com::sun::star::awt::XControl > * pControls = m_aControls.getConstArray();
for (sal_Int32 i = 0; i < m_aControls.getLength(); i++ )
stopControlListening(pControls[i]);
}
//------------------------------------------------------------------------------
Reference< ::com::sun::star::awt::XControl > FmXFormController::findControl(Sequence< Reference< ::com::sun::star::awt::XControl > >& rCtrls, const Reference< ::com::sun::star::awt::XControlModel > & xCtrlModel ,sal_Bool _bRemove,sal_Bool _bOverWrite) const
2000-09-18 16:07:07 +00:00
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
DBG_ASSERT( xCtrlModel.is(), "findControl - welches ?!" );
Reference< ::com::sun::star::awt::XControl > * pCtrls = rCtrls.getArray();
2000-09-18 16:07:07 +00:00
Reference< ::com::sun::star::awt::XControlModel > xModel;
for ( sal_Int32 i = 0, nCount = rCtrls.getLength(); i < nCount; ++i )
2000-09-18 16:07:07 +00:00
{
// #66449# Speicherueberschreiber durch folgende Zeile
// Reference< ::com::sun::star::awt::XControlModel > xModel(pCtrls[i].is() ? pCtrls[i]->getModel() : Reference< ::com::sun::star::awt::XControlModel > ());
if (pCtrls[i].is())
{
xModel = pCtrls[i]->getModel();
if ((::com::sun::star::awt::XControlModel*)xModel.get() == (::com::sun::star::awt::XControlModel*)xCtrlModel.get())
{
Reference< ::com::sun::star::awt::XControl > xCtrl( pCtrls[i] );
if ( _bRemove )
::comphelper::removeElementAt(rCtrls, i);
else if ( _bOverWrite )
pCtrls[i] = Reference< ::com::sun::star::awt::XControl >();
2000-09-18 16:07:07 +00:00
return xCtrl;
}
}
}
return Reference< ::com::sun::star::awt::XControl > ();
}
//------------------------------------------------------------------------------
void FmXFormController::insertControl(const Reference< ::com::sun::star::awt::XControl > & xControl)
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
m_bControlsSorted = sal_False;
m_aControls.realloc(m_aControls.getLength() + 1);
m_aControls.getArray()[m_aControls.getLength() - 1] = xControl;
Reference< ::com::sun::star::awt::XWindow > xWindow(xControl, UNO_QUERY);
if (xWindow.is())
{
xWindow->addFocusListener(this);
// register at the Eventattacher but not in filter mode
if (m_bAttachEvents)
addToEventAttacher(xControl);
}
Reference< ::com::sun::star::frame::XDispatchProviderInterception > xInterception(xControl, UNO_QUERY);
if (xInterception.is())
createInterceptor(xInterception);
if (xControl.is())
{
// we want to know about the reset of the the model of our controls
// (for correctly resetting m_bModified)
Reference< ::com::sun::star::form::XReset > xControlReset(xControl->getModel(), UNO_QUERY);
if (xControlReset.is())
xControlReset->addResetListener((::com::sun::star::form::XResetListener*)this);
}
if (m_bDBConnection && !m_bFiltering)
setControlLock(xControl);
if (isListeningForChanges() && m_bAttachEvents)
startControlListening(xControl);
}
//------------------------------------------------------------------------------
void FmXFormController::removeControl(const Reference< ::com::sun::star::awt::XControl > & xControl)
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
const Reference< ::com::sun::star::awt::XControl > * pCtrls = m_aControls.getArray();
sal_Int32 nCount = m_aControls.getLength();
2001-05-16 13:22:30 +00:00
for ( sal_uInt32 i = 0; i < (sal_uInt32)nCount; i++ )
2000-09-18 16:07:07 +00:00
{
if ((::com::sun::star::awt::XControl*)xControl.get() == (::com::sun::star::awt::XControl*)pCtrls[i].get())
{
2000-10-20 13:18:57 +00:00
::comphelper::removeElementAt(m_aControls, i);
2000-09-18 16:07:07 +00:00
break;
}
}
if (m_aFilterControls.size())
{
Reference< ::com::sun::star::awt::XTextComponent > xText(xControl, UNO_QUERY);
FmFilterControls::iterator iter = m_aFilterControls.find(xText);
if (iter != m_aFilterControls.end())
m_aFilterControls.erase(iter);
}
Reference< ::com::sun::star::awt::XWindow > xWindow(xControl, UNO_QUERY);
if (xWindow.is())
{
xWindow->removeFocusListener(this);
if (m_bDetachEvents)
removeFromEventAttacher(xControl);
}
Reference< ::com::sun::star::frame::XDispatchProviderInterception > xInterception(xControl, UNO_QUERY);
if (xInterception.is())
deleteInterceptor(xInterception);
if (xControl.is())
{
Reference< ::com::sun::star::form::XReset > xControlReset(xControl->getModel(), UNO_QUERY);
if (xControlReset.is())
xControlReset->removeResetListener((::com::sun::star::form::XResetListener*)this);
}
if (isListeningForChanges() && m_bDetachEvents)
stopControlListening(xControl);
}
//------------------------------------------------------------------------------
IMPL_LINK(FmXFormController, OnUpdateDispatchers, void*, EMPTYARG)
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
m_nUpdateDispatcherEvent = 0;
DBG_ASSERT(m_aControlDispatchInterceptors.size(), "FmXFormController::OnUpdateDispatchers : not intercepting any control dispatches !");
Reference< ::com::sun::star::frame::XModel > xFrameModel = getXModel(getModel());
Reference< ::com::sun::star::frame::XController > xFrameController = xFrameModel.is() ? xFrameModel->getCurrentController() : Reference< ::com::sun::star::frame::XController > ();
Reference< ::com::sun::star::frame::XFrame > xFrame = xFrameController.is() ? xFrameController->getFrame() : Reference< ::com::sun::star::frame::XFrame > ();
if (!xFrame.is())
{ // same as in interceptedQueryDispatch, try again
if ( m_aControlDispatchInterceptors.size() )
m_nUpdateDispatcherEvent = Application::PostUserEvent(LINK(this, FmXFormController, OnUpdateDispatchers));
2000-09-18 16:07:07 +00:00
return 0L;
}
// go through all controls we're intercepting and re-register as interceptor
// (this should cause them to request the dispatches again)
Interceptors aTemp = m_aControlDispatchInterceptors;
for ( ConstInterceptorsIterator aIter = aTemp.begin();
aIter < aTemp.end();
++aIter
)
{
FmXDispatchInterceptorImpl* pInterceptor = *aIter;
pInterceptor->acquire();
Reference< ::com::sun::star::frame::XDispatchProviderInterception > xIntercepted = pInterceptor->getIntercepted();
deleteInterceptor(xIntercepted);
createInterceptor(xIntercepted);
pInterceptor->release();
}
return 0L;
}
// ::com::sun::star::form::XLoadListener
//------------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
void FmXFormController::loaded(const ::com::sun::star::lang::EventObject& rEvent) throw( ::com::sun::star::uno::RuntimeException )
2000-09-18 16:07:07 +00:00
{
OSL_ENSURE( rEvent.Source == m_xModelAsIndex, "FmXFormController::loaded: where did this come from?" );
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
::osl::MutexGuard aGuard( m_aMutex );
Reference< ::com::sun::star::sdbc::XRowSet > xForm(rEvent.Source, UNO_QUERY);
// do we have a connected data source
OStaticDataAccessTools aStaticTools;
if (xForm.is() && aStaticTools.getRowSetConnection(xForm).is())
2000-09-18 16:07:07 +00:00
{
2000-11-06 06:19:53 +00:00
Reference< XPropertySet > xSet(xForm, UNO_QUERY);
2000-09-18 16:07:07 +00:00
if (xSet.is())
{
Any aVal = xSet->getPropertyValue(FM_PROP_CYCLE);
sal_Int32 aVal2;
::cppu::enum2int(aVal2,aVal);
m_bCycle = !aVal.hasValue() || aVal2 == ::com::sun::star::form::TabulatorCycle_RECORDS;
m_bCanUpdate = aStaticTools.canUpdate(xSet);
m_bCanInsert = aStaticTools.canInsert(xSet);
2000-10-20 13:18:57 +00:00
m_bCurrentRecordModified = ::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_ISMODIFIED));
m_bCurrentRecordNew = ::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_ISNEW));
2000-09-18 16:07:07 +00:00
startFormListening( xSet, sal_False );
2000-09-18 16:07:07 +00:00
// set the locks for the current controls
if (getContainer().is())
{
if (m_nLoadEvent)
Application::RemoveUserEvent( m_nLoadEvent );
m_nLoadEvent = Application::PostUserEvent( LINK(this, FmXFormController,
OnLoad) );
}
}
else
{
m_bCanInsert = m_bCanUpdate = m_bCycle = sal_False;
m_bCurrentRecordModified = sal_False;
m_bCurrentRecordNew = sal_False;
m_bLocked = sal_False;
}
m_bDBConnection = sal_True;
}
else
{
m_bDBConnection = sal_False;
m_bCanInsert = m_bCanUpdate = m_bCycle = sal_False;
m_bCurrentRecordModified = sal_False;
m_bCurrentRecordNew = sal_False;
m_bLocked = sal_False;
}
}
//------------------------------------------------------------------------------
IMPL_LINK(FmXFormController, OnLoad, void*, EMPTYARG)
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
m_nLoadEvent = 0;
m_bLocked = determineLockState();
setLocks();
if (!m_bLocked)
startListening();
// just one exception toggle the auto values
if (m_bCurrentRecordNew && m_pView)
2000-09-18 16:07:07 +00:00
toggleAutoFields(sal_True);
return 1L;
}
//------------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
void FmXFormController::unloaded(const ::com::sun::star::lang::EventObject& rEvent) throw( ::com::sun::star::uno::RuntimeException )
2000-09-18 16:07:07 +00:00
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
// not interested in ...
}
//------------------------------------------------------------------------------
void FmXFormController::reloading(const ::com::sun::star::lang::EventObject& aEvent) throw( RuntimeException )
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
::osl::MutexGuard aGuard( m_aMutex );
2000-09-18 16:07:07 +00:00
// do the same like in unloading
// just one exception toggle the auto values
if (m_nToggleEvent)
{
Application::RemoveUserEvent( m_nToggleEvent );
m_nToggleEvent = 0;
}
unload();
}
//------------------------------------------------------------------------------
void FmXFormController::reloaded(const ::com::sun::star::lang::EventObject& aEvent) throw( RuntimeException )
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
loaded(aEvent);
}
//------------------------------------------------------------------------------
void FmXFormController::unloading(const ::com::sun::star::lang::EventObject& aEvent) throw( RuntimeException )
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
unload();
}
//------------------------------------------------------------------------------
void FmXFormController::unload() throw( RuntimeException )
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
::osl::MutexGuard aGuard( m_aMutex );
if (m_nLoadEvent)
{
Application::RemoveUserEvent( m_nLoadEvent );
m_nLoadEvent = 0;
}
// be sure not to have autofields
if (m_bCurrentRecordNew && m_pView)
2000-09-18 16:07:07 +00:00
toggleAutoFields(sal_False);
// remove bound field listing again
removeBoundFieldListener();
2000-09-18 16:07:07 +00:00
if (m_bDBConnection && isListeningForChanges())
stopListening();
Reference< XPropertySet > xSet( m_xModelAsIndex, UNO_QUERY );
if ( m_bDBConnection && xSet.is() )
stopFormListening( xSet, sal_False );
m_bDBConnection = sal_False;
m_bCanInsert = m_bCanUpdate = m_bCycle = sal_False;
m_bCurrentRecordModified = m_bCurrentRecordNew = m_bLocked = sal_False;
}
// -----------------------------------------------------------------------------
void FmXFormController::removeBoundFieldListener()
{
const Reference< ::com::sun::star::awt::XControl > * pControls = m_aControls.getConstArray();
for (sal_Int32 i = 0; i < m_aControls.getLength(); ++i,++pControls )
{
Reference<XPropertySet> xProp(*pControls,UNO_QUERY);
if ( xProp.is() )
xProp->removePropertyChangeListener(FM_PROP_BOUNDFIELD, this);
}
}
//------------------------------------------------------------------------------
void FmXFormController::startFormListening( const Reference< XPropertySet >& _rxForm, sal_Bool _bPropertiesOnly )
{
if ( m_bCanInsert || m_bCanUpdate ) // form can be modified
2000-09-18 16:07:07 +00:00
{
_rxForm->addPropertyChangeListener( FM_PROP_ISNEW, this );
_rxForm->addPropertyChangeListener( FM_PROP_ISMODIFIED, this );
if ( !_bPropertiesOnly )
2000-09-18 16:07:07 +00:00
{
// set the Listener for UI interaction
Reference< XRowSetApproveBroadcaster > xApprove( _rxForm, UNO_QUERY );
if ( xApprove.is() )
xApprove->addRowSetApproveListener( this );
// listener for row set changes
Reference< XRowSet > xRowSet( _rxForm, UNO_QUERY );
if ( xRowSet.is() )
xRowSet->addRowSetListener( this );
}
}
}
//------------------------------------------------------------------------------
void FmXFormController::stopFormListening( const Reference< XPropertySet >& _rxForm, sal_Bool _bPropertiesOnly )
{
if ( m_bCanInsert || m_bCanUpdate )
{
_rxForm->removePropertyChangeListener( FM_PROP_ISNEW, this );
_rxForm->removePropertyChangeListener( FM_PROP_ISMODIFIED, this );
2000-09-18 16:07:07 +00:00
if ( !_bPropertiesOnly )
{
Reference< XRowSetApproveBroadcaster > xApprove( _rxForm, UNO_QUERY );
2000-09-18 16:07:07 +00:00
if (xApprove.is())
xApprove->removeRowSetApproveListener(this);
Reference< XRowSet > xRowSet( _rxForm, UNO_QUERY );
if ( xRowSet.is() )
xRowSet->removeRowSetListener( this );
2000-09-18 16:07:07 +00:00
}
}
}
// com::sun::star::sdbc::XRowSetListener
//------------------------------------------------------------------------------
void FmXFormController::cursorMoved(const ::com::sun::star::lang::EventObject& event) throw( RuntimeException )
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
// toggle the locking ?
if (m_bLocked != determineLockState())
{
::osl::MutexGuard aGuard( m_aMutex );
m_bLocked = !m_bLocked;
setLocks();
if (isListeningForChanges())
startListening();
else
stopListening();
}
// neither the current control nor the current record are modified anymore
m_bCurrentRecordModified = m_bModified = sal_False;
2000-09-18 16:07:07 +00:00
}
//------------------------------------------------------------------------------
void FmXFormController::rowChanged(const ::com::sun::star::lang::EventObject& event) throw( RuntimeException )
{
// not interested in ...
}
//------------------------------------------------------------------------------
void FmXFormController::rowSetChanged(const ::com::sun::star::lang::EventObject& event) throw( RuntimeException )
{
// not interested in ...
}
// ::com::sun::star::container::XContainerListener
//------------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
void SAL_CALL FmXFormController::elementInserted(const ::com::sun::star::container::ContainerEvent& evt) throw( ::com::sun::star::uno::RuntimeException )
2000-09-18 16:07:07 +00:00
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-11-07 12:16:50 +00:00
Reference< ::com::sun::star::awt::XControl > xControl;
evt.Element >>= xControl;
2000-09-18 16:07:07 +00:00
if (!xControl.is())
return;
::osl::MutexGuard aGuard( m_aMutex );
Reference< ::com::sun::star::form::XFormComponent > xModel(xControl->getModel(), UNO_QUERY);
if (xModel.is() && m_xModelAsIndex == xModel->getParent())
{
insertControl(xControl);
if (m_aInsertTimer.IsActive())
m_aInsertTimer.Stop();
m_aInsertTimer.Start();
}
// are we in filtermode and a ::com::sun::star::util::XModeSelector has inserted an element
else if (m_bFiltering && Reference< ::com::sun::star::util::XModeSelector > (evt.Source, UNO_QUERY).is())
{
xModel = Reference< ::com::sun::star::form::XFormComponent > (evt.Source, UNO_QUERY);
if (xModel.is() && m_xModelAsIndex == xModel->getParent())
{
2000-11-06 06:19:53 +00:00
Reference< XPropertySet > xSet(xControl->getModel(), UNO_QUERY);
2000-10-20 13:18:57 +00:00
if (xSet.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xSet))
2000-09-18 16:07:07 +00:00
{
// does the model use a bound field ?
2000-11-07 12:16:50 +00:00
Reference< XPropertySet > xField;
xSet->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
2000-09-18 16:07:07 +00:00
Reference< ::com::sun::star::awt::XTextComponent > xText(xControl, UNO_QUERY);
// may we filter the field?
2000-10-20 13:18:57 +00:00
if (xText.is() && xField.is() && ::comphelper::hasProperty(FM_PROP_SEARCHABLE, xField) &&
::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_SEARCHABLE)))
2000-09-18 16:07:07 +00:00
{
m_aFilterControls[xText] = xField;
xText->addTextListener(this);
}
}
}
}
}
//------------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
void SAL_CALL FmXFormController::elementReplaced(const ::com::sun::star::container::ContainerEvent& evt) throw( ::com::sun::star::uno::RuntimeException )
2000-09-18 16:07:07 +00:00
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
::osl::MutexGuard aGuard( m_aMutex );
// Remove the control
2000-11-07 12:16:50 +00:00
Reference< ::com::sun::star::awt::XControl > xReplControl;
evt.ReplacedElement >>= xReplControl;
2000-09-18 16:07:07 +00:00
Reference< ::com::sun::star::form::XFormComponent > xModel(xReplControl->getModel(), UNO_QUERY);
if (xModel.is() && m_xModelAsIndex == xModel->getParent())
removeControl(xReplControl);
else if (m_aFilterControls.size())
{
Reference< ::com::sun::star::awt::XTextComponent > xText(xReplControl, UNO_QUERY);
FmFilterControls::iterator iter = m_aFilterControls.find(xText);
if (iter != m_aFilterControls.end())
m_aFilterControls.erase(iter);
}
// Add the new one
elementInserted(evt);
}
//------------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
void SAL_CALL FmXFormController::elementRemoved(const ::com::sun::star::container::ContainerEvent& evt) throw( ::com::sun::star::uno::RuntimeException )
2000-09-18 16:07:07 +00:00
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
::osl::MutexGuard aGuard( m_aMutex );
2000-11-07 12:16:50 +00:00
Reference< ::com::sun::star::awt::XControl > xControl;
evt.Element >>= xControl;
2000-09-18 16:07:07 +00:00
if (!xControl.is())
return;
Reference< ::com::sun::star::form::XFormComponent > xModel(xControl->getModel(), UNO_QUERY);
if (xModel.is() && m_xModelAsIndex == xModel->getParent())
{
removeControl(xControl);
// TabOrder nicht neu berechnen, da das intern schon funktionieren mu<6D>!
}
else if (m_aFilterControls.size())
{
Reference< ::com::sun::star::awt::XTextComponent > xText(xControl, UNO_QUERY);
FmFilterControls::iterator iter = m_aFilterControls.find(xText);
if (iter != m_aFilterControls.end())
m_aFilterControls.erase(iter);
}
}
//------------------------------------------------------------------------------
Reference< ::com::sun::star::awt::XControl > FmXFormController::isInList(const Reference< ::com::sun::star::awt::XWindowPeer > & xPeer) const
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
const Reference< ::com::sun::star::awt::XControl > * pCtrls = m_aControls.getConstArray();
sal_uInt32 nCtrls = m_aControls.getLength();
for ( sal_uInt32 n = 0; n < nCtrls && xPeer.is(); n++ )
{
if (pCtrls[n].is())
{
Reference< ::com::sun::star::awt::XVclWindowPeer > xCtrlPeer(pCtrls[n]->getPeer(), UNO_QUERY);
if ((::com::sun::star::awt::XWindowPeer*)xCtrlPeer.get() == (::com::sun::star::awt::XWindowPeer*)xPeer.get() || xCtrlPeer->isChild(xPeer))
return pCtrls[n];
}
}
return Reference< ::com::sun::star::awt::XControl > ();
}
//------------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
void FmXFormController::activateFirst() throw( ::com::sun::star::uno::RuntimeException )
2000-09-18 16:07:07 +00:00
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
::osl::MutexGuard aGuard( m_aMutex );
DBG_ASSERT(m_xTabController.is(), "FmXFormController::activateFirst : invalid aggregate !");
if (m_xTabController.is())
m_xTabController->activateFirst();
}
//------------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
void FmXFormController::activateLast() throw( ::com::sun::star::uno::RuntimeException )
2000-09-18 16:07:07 +00:00
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
::osl::MutexGuard aGuard( m_aMutex );
DBG_ASSERT(m_xTabController.is(), "FmXFormController::activateLast : invalid aggregate !");
if (m_xTabController.is())
m_xTabController->activateLast();
}
// ::com::sun::star::form::XFormController
//------------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
Reference< XControl> SAL_CALL FmXFormController::getCurrentControl(void) throw( ::com::sun::star::uno::RuntimeException )
{
::osl::MutexGuard aGuard( m_aMutex );
return m_xCurrentControl;
}
//------------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
void SAL_CALL FmXFormController::addActivateListener(const Reference< XFormControllerListener > & l) throw( ::com::sun::star::uno::RuntimeException )
2000-09-18 16:07:07 +00:00
{
::osl::MutexGuard aGuard( m_aMutex );
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
m_aActivateListeners.addInterface(l);
}
//------------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
void SAL_CALL FmXFormController::removeActivateListener(const Reference< XFormControllerListener > & l) throw( ::com::sun::star::uno::RuntimeException )
2000-09-18 16:07:07 +00:00
{
::osl::MutexGuard aGuard( m_aMutex );
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
m_aActivateListeners.removeInterface(l);
}
//------------------------------------------------------------------------------
void FmXFormController::setFilter(vector<FmFieldInfo>& rFieldInfos)
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
// create the composer
Reference< XRowSet > xForm(m_xModelAsIndex, UNO_QUERY);
Reference< XConnection > xConnection(OStaticDataAccessTools().getRowSetConnection(xForm));
2000-09-18 16:07:07 +00:00
if (xForm.is())
{
Reference< ::com::sun::star::sdb::XSQLQueryComposerFactory > xFactory(xConnection, UNO_QUERY);
if (xFactory.is())
{
m_xComposer = xFactory->createQueryComposer();
try
{
2000-11-06 06:19:53 +00:00
Reference< XPropertySet > xSet(xForm, UNO_QUERY);
2000-10-20 13:18:57 +00:00
::rtl::OUString aStatement = ::comphelper::getString(xSet->getPropertyValue(FM_PROP_ACTIVECOMMAND));
::rtl::OUString aFilter = ::comphelper::getString(xSet->getPropertyValue(FM_PROP_FILTER_CRITERIA));
2000-09-18 16:07:07 +00:00
m_xComposer->setQuery(aStatement);
m_xComposer->setFilter(aFilter);
}
catch(const Exception&)
2000-09-18 16:07:07 +00:00
{
2000-11-07 12:16:50 +00:00
DBG_ERROR("Exception occured!");
2000-09-18 16:07:07 +00:00
}
}
}
if (m_xComposer.is())
{
2000-11-06 06:19:53 +00:00
Sequence < PropertyValue> aLevel;
Sequence< Sequence < PropertyValue > > aFilterRows = m_xComposer->getStructuredFilter();
2000-09-18 16:07:07 +00:00
// ok, we recieve the list of filters as sequence of fieldnames, value
// now we have to transform the fieldname into UI names, that could be a label of the field or
// a aliasname or the fieldname itself
// first adjust the field names if necessary
Reference< ::com::sun::star::container::XNameAccess> xQueryColumns = Reference< ::com::sun::star::sdbcx::XColumnsSupplier >
(m_xComposer, UNO_QUERY)->getColumns();
for (vector<FmFieldInfo>::iterator iter = rFieldInfos.begin();
iter != rFieldInfos.end(); iter++)
{
if ( xQueryColumns->hasByName((*iter).aFieldName) )
2000-09-18 16:07:07 +00:00
{
if ( (xQueryColumns->getByName((*iter).aFieldName) >>= (*iter).xField) && (*iter).xField.is() )
(*iter).xField->getPropertyValue(FM_PROP_REALNAME) >>= (*iter).aFieldName;
2000-09-18 16:07:07 +00:00
}
}
Reference< ::com::sun::star::sdbc::XDatabaseMetaData> xMetaData(xConnection->getMetaData());
2000-09-18 16:07:07 +00:00
// now transfer the filters into Value/TextComponent pairs
::comphelper::UStringMixEqual aCompare(xMetaData->storesMixedCaseQuotedIdentifiers());
// need to parse criteria localized
OStaticDataAccessTools aStaticTools;
Reference< ::com::sun::star::util::XNumberFormatsSupplier> xFormatSupplier( aStaticTools.getNumberFormats(xConnection, sal_True));
Reference< ::com::sun::star::util::XNumberFormatter> xFormatter(m_xORB
->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.NumberFormatter")), UNO_QUERY);
xFormatter->attachNumberFormatsSupplier(xFormatSupplier);
::com::sun::star::lang::Locale aAppLocale = Application::GetSettings().GetUILocale();
LocaleDataWrapper aLocaleWrapper(m_xORB,aAppLocale);
2000-09-18 16:07:07 +00:00
// retrieving the filter
2000-11-06 06:19:53 +00:00
const Sequence < PropertyValue >* pRow = aFilterRows.getConstArray();
2000-09-18 16:07:07 +00:00
for (sal_Int32 i = 0, nLen = aFilterRows.getLength(); i < nLen; ++i)
{
FmFilterRow aRow;
// search a field for the given name
2000-11-06 06:19:53 +00:00
const PropertyValue* pRefValues = pRow[i].getConstArray();
2000-09-18 16:07:07 +00:00
for (sal_Int32 j = 0, nLen1 = pRow[i].getLength(); j < nLen1; j++)
{
// look for the text component
2000-11-06 06:19:53 +00:00
Reference< XPropertySet > xField;
2000-09-18 16:07:07 +00:00
try
{
2000-11-06 06:19:53 +00:00
Reference< XPropertySet > xSet;
2000-09-18 16:07:07 +00:00
::rtl::OUString aRealName;
// first look with the given name
if (xQueryColumns->hasByName(pRefValues[j].Name))
{
xQueryColumns->getByName(pRefValues[j].Name) >>= xSet;
// get the RealName
xSet->getPropertyValue(::rtl::OUString::createFromAscii("RealName")) >>= aRealName;
// compare the condition field name and the RealName
if (aCompare(aRealName, pRefValues[j].Name))
xField = xSet;
}
if (!xField.is())
{
// no we have to check every column to find the realname
Reference< ::com::sun::star::container::XIndexAccess > xColumnsByIndex(xQueryColumns, UNO_QUERY);
for (sal_Int32 n = 0, nCount = xColumnsByIndex->getCount(); n < nCount; n++)
{
xColumnsByIndex->getByIndex(n) >>= xSet;
xSet->getPropertyValue(::rtl::OUString::createFromAscii("RealName")) >>= aRealName;
if (aCompare(aRealName, pRefValues[j].Name))
{
// get the column by its alias
xField = xSet;
break;
}
}
}
if (!xField.is())
continue;
}
catch (const Exception&)
2000-09-18 16:07:07 +00:00
{
continue;
}
// find the text component
for (vector<FmFieldInfo>::iterator iter = rFieldInfos.begin();
iter != rFieldInfos.end(); iter++)
{
// we found the field so insert a new entry to the filter row
if ((*iter).xField == xField)
{
// do we already have the control ?
if (aRow.find((*iter).xText) != aRow.end())
{
2000-11-06 06:19:53 +00:00
::rtl::OUString aCompText = aRow[(*iter).xText];
aCompText += ::rtl::OUString::createFromAscii(" ");
::rtl::OString aVal = m_xParser->getContext().getIntlKeywordAscii(OParseContext::KEY_AND);
2000-11-06 06:19:53 +00:00
aCompText += ::rtl::OUString(aVal.getStr(),aVal.getLength(),RTL_TEXTENCODING_ASCII_US);
aCompText += ::rtl::OUString::createFromAscii(" ");
aCompText += ::comphelper::getString(pRefValues[j].Value);
2000-09-18 16:07:07 +00:00
aRow[(*iter).xText] = aCompText;
}
else
{
::rtl::OUString sPredicate,sErrorMsg;
pRefValues[j].Value >>= sPredicate;
::rtl::Reference< ISQLParseNode > xParseNode = predicateTree(sErrorMsg, sPredicate, xFormatter, xField);
if ( xParseNode.is() )
{
::rtl::OUString sCriteria;
xParseNode->parseNodeToPredicateStr( sCriteria
,xMetaData
,xFormatter
,xField
,aAppLocale
,(sal_Char)aLocaleWrapper.getNumDecimalSep().GetChar(0)
,getParseContext());
aRow[(*iter).xText] = sCriteria;
}
}
2000-09-18 16:07:07 +00:00
break;
}
}
}
if (aRow.empty())
continue;
m_aFilters.push_back(aRow);
}
}
// now set the filter controls
for (vector<FmFieldInfo>::iterator iter = rFieldInfos.begin();
iter != rFieldInfos.end(); iter++)
{
m_aFilterControls[(*iter).xText] = (*iter).xField;
}
// add an empty row
m_aFilters.push_back(FmFilterRow());
}
//------------------------------------------------------------------------------
void FmXFormController::startFiltering()
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
if (!m_pView)
{
DBG_ERROR("FmXFormController::startFiltering : you can't filter if you created me as service !");
return;
}
OStaticDataAccessTools aStaticTools;
Reference< XConnection > xConnection( aStaticTools.getRowSetConnection( Reference< XRowSet >( m_xModelAsIndex, UNO_QUERY ) ) );
if ( !xConnection.is() )
// nothing to do - can't filter a form which is not connected
// 98023 - 19.03.2002 - fs@openoffice.org
return;
2000-09-18 16:07:07 +00:00
// stop listening for controls
if (isListeningForChanges())
stopListening();
m_bFiltering = sal_True;
// as we don't want new controls to be attached to the scripting environment
// we change attach flags
m_bAttachEvents = sal_False;
// Austauschen der Kontrols fuer das aktuelle Formular
Sequence < Reference< ::com::sun::star::awt::XControl > > aControls(m_aControls);
const Reference< ::com::sun::star::awt::XControl > * pControls = m_aControls.getConstArray();
SdrPageView* pCurPageView = m_pView->GetPageViewPvNum(0);
// the control we have to activate after replacement
Reference< ::com::sun::star::awt::XControl > xNewActiveControl;
Reference< ::com::sun::star::sdbc::XDatabaseMetaData > xMetaData(xConnection->getMetaData());
Reference< ::com::sun::star::util::XNumberFormatsSupplier > xFormatSupplier = aStaticTools.getNumberFormats(xConnection, sal_True);
2000-11-06 06:19:53 +00:00
Reference< ::com::sun::star::util::XNumberFormatter > xFormatter(m_xORB
2000-09-18 16:07:07 +00:00
->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.NumberFormatter")), UNO_QUERY);
xFormatter->attachNumberFormatsSupplier(xFormatSupplier);
// structure for storing the field info
vector<FmFieldInfo> aFieldInfos;
// sal_uInt16 nPos = pCurPageView ? pCurPageView->GetWinList().Find((OutputDevice*)m_pView->GetActualOutDev()) : SDRPAGEVIEWWIN_NOTFOUND;
const SdrPageViewWindow* pWindow = pCurPageView ? pCurPageView->FindWindow(*((OutputDevice*)m_pView->GetActualOutDev())) : 0L;
if(pWindow)
2000-09-18 16:07:07 +00:00
{
for (sal_Int32 i = aControls.getLength(); i > 0;)
{
const Reference< ::com::sun::star::awt::XControl > & xControl = pControls[--i];
if (xControl.is())
{
// no events for the control anymore
removeFromEventAttacher(xControl);
// do we have a mode selector
Reference< ::com::sun::star::util::XModeSelector > xSelector(xControl, UNO_QUERY);
if (xSelector.is())
{
xSelector->setMode(FILTER_MODE);
// listening for new controls of the selector
Reference< ::com::sun::star::container::XContainer > xContainer(xSelector, UNO_QUERY);
if (xContainer.is())
xContainer->addContainerListener(this);
Reference< ::com::sun::star::container::XEnumerationAccess > xElementAccess(xSelector, UNO_QUERY);
if (xElementAccess.is())
{
Reference< ::com::sun::star::container::XEnumeration > xEnumeration(xElementAccess->createEnumeration());
2000-11-07 12:16:50 +00:00
Reference< ::com::sun::star::awt::XControl > xControl;
2000-09-18 16:07:07 +00:00
while (xEnumeration->hasMoreElements())
{
2000-11-07 12:16:50 +00:00
xEnumeration->nextElement() >>= xControl;
2000-09-18 16:07:07 +00:00
if (xControl.is())
{
2000-11-06 06:19:53 +00:00
Reference< XPropertySet > xSet(xControl->getModel(), UNO_QUERY);
2000-10-20 13:18:57 +00:00
if (xSet.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xSet))
2000-09-18 16:07:07 +00:00
{
// does the model use a bound field ?
2000-11-07 12:16:50 +00:00
Reference< XPropertySet > xField;
xSet->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
2000-09-18 16:07:07 +00:00
Reference< ::com::sun::star::awt::XTextComponent > xText(xControl, UNO_QUERY);
// may we filter the field?
2000-10-20 13:18:57 +00:00
if (xText.is() && xField.is() && ::comphelper::hasProperty(FM_PROP_SEARCHABLE, xField) &&
::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_SEARCHABLE)))
2000-09-18 16:07:07 +00:00
{
aFieldInfos.push_back(FmFieldInfo(xField, xText));
xText->addTextListener(this);
}
}
}
}
}
continue;
}
Reference< XPropertySet > xModel( xControl->getModel(), UNO_QUERY );
if (xModel.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xModel))
2000-09-18 16:07:07 +00:00
{
// does the model use a bound field ?
Any aVal = xModel->getPropertyValue(FM_PROP_BOUNDFIELD);
2000-11-07 12:16:50 +00:00
Reference< XPropertySet > xField;
aVal >>= xField;
2000-09-18 16:07:07 +00:00
// may we filter the field?
2000-10-20 13:18:57 +00:00
if (xField.is() && ::comphelper::hasProperty(FM_PROP_SEARCHABLE, xField) &&
::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_SEARCHABLE)))
2000-09-18 16:07:07 +00:00
{
// const SdrPageViewWinRec& rWR = pCurPageView->GetWinList()[nPos];
// const SdrPageViewWindow& rWindow = pCurPageView->GetPageViewWindows().Get(nPos);
const SdrUnoControlList& rControlList = pWindow->GetControlList();
2000-09-18 16:07:07 +00:00
sal_uInt16 nCtrlNum = rControlList.Find(xControl);
if (nCtrlNum != SDRUNOCONTROL_NOTFOUND)
{
// Setzen des FilterControls
SdrUnoControlRec& rControlRec = (SdrUnoControlRec&)rControlList[nCtrlNum];
// create a filter control
Sequence< Any > aCreationArgs( 3 );
aCreationArgs[ 0 ] <<= NamedValue( ::rtl::OUString::createFromAscii( "MessageParent" ), makeAny( VCLUnoHelper::GetInterface( m_pWindow ) ) );
aCreationArgs[ 1 ] <<= NamedValue( ::rtl::OUString::createFromAscii( "NumberFormatter" ), makeAny( xFormatter ) );
aCreationArgs[ 2 ] <<= NamedValue( ::rtl::OUString::createFromAscii( "ControlModel" ), makeAny( xModel ) );
Reference< XControl > xFilterControl(
m_xORB->createInstanceWithArguments(
::rtl::OUString::createFromAscii( "com.sun.star.form.control.FilterControl" ),
aCreationArgs
),
UNO_QUERY
);
DBG_ASSERT( xFilterControl.is(), "FmXFormController::startFiltering: could not create a filter control!" );
Reference< XTextComponent > xText( xFilterControl, UNO_QUERY );
2000-09-18 16:07:07 +00:00
// merken in der Map
aFieldInfos.push_back(FmFieldInfo(xField, xText));
xText->addTextListener(this);
// setting the focus if the current control
// is the active one
if (m_xActiveControl.get() == xControl.get())
2000-09-18 16:07:07 +00:00
{
xNewActiveControl = xFilterControl;
2000-09-18 16:07:07 +00:00
m_xActiveControl = m_xCurrentControl = NULL;
}
else if (m_xCurrentControl.get() == xControl.get())
m_xCurrentControl = xFilterControl;
2000-09-18 16:07:07 +00:00
rControlRec.ReplaceControl( xFilterControl );
2000-09-18 16:07:07 +00:00
}
}
}
else
{
// abmelden vom EventManager
}
}
}
}
// we have all filter controls now, so the next step is to read the filters from the form
// resolve all aliases and set the current filter to the according structure
setFilter(aFieldInfos);
// setting the focus to the replacing control
Reference< ::com::sun::star::awt::XWindow > xWindow(xNewActiveControl, UNO_QUERY);
if (xWindow.is())
xWindow->setFocus();
Reference< XPropertySet > xSet( m_xModelAsIndex, UNO_QUERY );
if ( xSet.is() )
stopFormListening( xSet, sal_True );
2000-09-18 16:07:07 +00:00
// set the text for all filters
OSL_ENSURE(m_aFilters.size() > m_nCurrentFilterPosition && m_nCurrentFilterPosition >= 0,"m_nCurrentFilterPosition too big");
if ( m_nCurrentFilterPosition >= 0 && m_nCurrentFilterPosition < m_aFilters.size() )
2000-09-18 16:07:07 +00:00
{
FmFilterRow& rRow = m_aFilters[m_nCurrentFilterPosition];
for (FmFilterRow::const_iterator iter2 = rRow.begin();
iter2 != rRow.end(); iter2++)
{
(*iter2).first->setText((*iter2).second);
}
2000-09-18 16:07:07 +00:00
}
// lock all controls which are not used for filtering
m_bLocked = determineLockState();
setLocks();
m_bAttachEvents = sal_True;
}
//------------------------------------------------------------------------------
void FmXFormController::stopFiltering()
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
if ( !m_bFiltering ) // #104693# OJ
{ // nothing to do
2000-09-18 16:07:07 +00:00
return;
}
if (!m_pView)
{
DBG_ERROR("FmXFormController::startFiltering : you can't filter if you created me as service !");
return;
}
2000-09-18 16:07:07 +00:00
m_bFiltering = sal_False;
m_bDetachEvents = sal_False;
2000-10-20 13:18:57 +00:00
::comphelper::disposeComponent(m_xComposer);
2000-09-18 16:07:07 +00:00
// Austauschen der Kontrols fuer das aktuelle Formular
Sequence < Reference< ::com::sun::star::awt::XControl > > aControls(m_aControls);
const Reference< ::com::sun::star::awt::XControl > * pControls = m_aControls.getConstArray();
SdrPageView* pCurPageView = m_pView->GetPageViewPvNum(0);
// sal_uInt16 nPos = pCurPageView ? pCurPageView->GetWinList().Find((OutputDevice*)m_pView->GetActualOutDev()) : SDRPAGEVIEWWIN_NOTFOUND;
const SdrPageViewWindow* pWindow = pCurPageView ? pCurPageView->FindWindow(*((OutputDevice*)m_pView->GetActualOutDev())) : 0L;
2000-09-18 16:07:07 +00:00
// the control we have to activate after replacement
Reference< ::com::sun::star::awt::XControl > xNewActiveControl;
// clear the filter control map
for (FmFilterControls::const_iterator iter = m_aFilterControls.begin();
iter != m_aFilterControls.end(); iter++)
(*iter).first->removeTextListener(this);
m_aFilterControls.clear();
if (pWindow)
2000-09-18 16:07:07 +00:00
{
for (sal_Int32 i = aControls.getLength(); i > 0;)
{
const Reference< ::com::sun::star::awt::XControl > & xControl = pControls[--i];
if (xControl.is())
{
// now enable eventhandling again
addToEventAttacher(xControl);
Reference< ::com::sun::star::util::XModeSelector > xSelector(xControl, UNO_QUERY);
if (xSelector.is())
{
xSelector->setMode(DATA_MODE);
// listening for new controls of the selector
Reference< ::com::sun::star::container::XContainer > xContainer(xSelector, UNO_QUERY);
if (xContainer.is())
xContainer->removeContainerListener(this);
continue;
}
2000-11-06 06:19:53 +00:00
Reference< XPropertySet > xSet(xControl->getModel(), UNO_QUERY);
2000-10-20 13:18:57 +00:00
if (xSet.is() && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD, xSet))
2000-09-18 16:07:07 +00:00
{
// does the model use a bound field ?
2000-11-07 12:16:50 +00:00
Reference< XPropertySet > xField;
xSet->getPropertyValue(FM_PROP_BOUNDFIELD) >>= xField;
2000-09-18 16:07:07 +00:00
// may we filter the field?
2000-10-20 13:18:57 +00:00
if (xField.is() && ::comphelper::hasProperty(FM_PROP_SEARCHABLE, xField) &&
::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_SEARCHABLE)))
2000-09-18 16:07:07 +00:00
{
// const SdrPageViewWinRec& rWR = pCurPageView->GetWinList()[nPos];
// const SdrPageViewWindow& rWindow = pCurPageView->GetPageViewWindows().Get(nPos);
const SdrUnoControlList& rControlList = pWindow->GetControlList();
2000-09-18 16:07:07 +00:00
sal_uInt16 nCtrlNum = rControlList.Find(xControl);
if (nCtrlNum != SDRUNOCONTROL_NOTFOUND)
{
// Zuruecksetzen des Controls auf das Defaultcontrol
SdrUnoControlRec& rControlRec = (SdrUnoControlRec&)rControlList[nCtrlNum];
2000-10-20 13:18:57 +00:00
::rtl::OUString aServiceName = ::comphelper::getString(xSet->getPropertyValue(FM_PROP_DEFAULTCONTROL));
2000-11-06 06:19:53 +00:00
Reference< ::com::sun::star::awt::XControl > xNewControl(m_xORB->createInstance(aServiceName), UNO_QUERY);
2000-09-18 16:07:07 +00:00
// setting the focus if the current control
// is the active one
if ((::com::sun::star::awt::XControl*)m_xActiveControl.get() == (::com::sun::star::awt::XControl*)xControl.get())
{
xNewActiveControl = xNewControl;
m_xActiveControl = m_xCurrentControl = NULL;
}
else if ((::com::sun::star::awt::XControl*)m_xCurrentControl.get() == (::com::sun::star::awt::XControl*)xControl.get())
m_xCurrentControl = xNewControl;
rControlRec.ReplaceControl(xNewControl);
}
}
}
}
}
}
// setting the focus to the replacing control
Reference< ::com::sun::star::awt::XWindow > xWindow(xNewActiveControl, UNO_QUERY);
if (xWindow.is())
xWindow->setFocus();
Reference< XPropertySet > xSet( m_xModelAsIndex, UNO_QUERY );
if ( xSet.is() )
startFormListening( xSet, sal_True );
2000-09-18 16:07:07 +00:00
m_bDetachEvents = sal_True;
m_aFilters.clear();
m_nCurrentFilterPosition = 0;
// release the locks if possible
// lock all controls which are not used for filtering
m_bLocked = determineLockState();
setLocks();
// restart listening for control modifications
if (isListeningForChanges())
startListening();
}
// ::com::sun::star::util::XModeSelector
//------------------------------------------------------------------------------
void FmXFormController::setMode(const ::rtl::OUString& Mode) throw( ::com::sun::star::lang::NoSupportException, RuntimeException )
{
::osl::MutexGuard aGuard( m_aMutex );
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
if (!supportsMode(Mode))
throw ::com::sun::star::lang::NoSupportException();
if (Mode == m_aMode)
return;
m_aMode = Mode;
if (Mode == FILTER_MODE)
startFiltering();
else
stopFiltering();
for (FmFormControllers::const_iterator i = m_aChilds.begin();
i != m_aChilds.end(); ++i)
2000-09-18 16:07:07 +00:00
{
Reference< ::com::sun::star::util::XModeSelector > xMode(*i, UNO_QUERY);
if ( xMode.is() )
xMode->setMode(Mode);
2000-09-18 16:07:07 +00:00
}
}
//------------------------------------------------------------------------------
::rtl::OUString SAL_CALL FmXFormController::getMode(void) throw( RuntimeException )
{
::osl::MutexGuard aGuard( m_aMutex );
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
return m_aMode;
}
//------------------------------------------------------------------------------
Sequence< ::rtl::OUString > SAL_CALL FmXFormController::getSupportedModes(void) throw( RuntimeException )
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
static Sequence< ::rtl::OUString > aModes;
if (!aModes.getLength())
{
aModes.realloc(2);
::rtl::OUString* pModes = aModes.getArray();
pModes[0] = DATA_MODE;
pModes[1] = FILTER_MODE;
}
return aModes;
}
//------------------------------------------------------------------------------
sal_Bool SAL_CALL FmXFormController::supportsMode(const ::rtl::OUString& Mode) throw( RuntimeException )
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
Sequence< ::rtl::OUString > aModes(getSupportedModes());
const ::rtl::OUString* pModes = aModes.getConstArray();
for (sal_Int32 i = aModes.getLength(); i > 0; )
{
if (pModes[--i] == Mode)
return sal_True;
}
return sal_False;
}
//------------------------------------------------------------------------------
Window* FmXFormController::getDialogParentWindow()
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
Window* pParent = m_pWindow;
if (!pParent)
{
Reference< ::com::sun::star::awt::XControlContainer > xContainer = getContainer();
Reference< ::com::sun::star::awt::XControl > xCtrl(xContainer, UNO_QUERY);
if (xCtrl.is())
{
Reference< ::com::sun::star::awt::XWindowPeer > xPeer(xCtrl->getPeer(), UNO_QUERY);
if (xPeer.is())
pParent = VCLUnoHelper::GetWindow(xPeer);
}
}
return pParent;
}
// ::com::sun::star::sdb::XRowSetApproveListener
//------------------------------------------------------------------------------
sal_Bool SAL_CALL FmXFormController::approveRowChange(const ::com::sun::star::sdb::RowChangeEvent& aEvent) throw( RuntimeException )
{
::osl::MutexGuard aGuard( m_aMutex );
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
::cppu::OInterfaceIteratorHelper aIter(m_aRowSetApproveListeners);
sal_Bool bValid = sal_True;
if (aIter.hasMoreElements())
{
::com::sun::star::sdb::RowChangeEvent aEvt(aEvent);
aEvt.Source = *this;
bValid = ((::com::sun::star::sdb::XRowSetApproveListener*)aIter.next())->approveRowChange(aEvt);
}
if (bValid && (
aEvent.Action == ::com::sun::star::sdb::RowChangeAction::INSERT ||
aEvent.Action == ::com::sun::star::sdb::RowChangeAction::UPDATE))
{
if (m_pView)
{ // we're working for a FormView
if (!(m_pWindow || (m_pView->GetActualOutDev() == (const OutputDevice*)m_pWindow ||
!m_pView->GetActualOutDev() && m_pWindow->IsActive())))
// we're not active
return sal_True;
}
// default handling
// check Values on NULL and required flag
Reference< ::com::sun::star::sdbcx::XColumnsSupplier > xSupplyCols(aEvent.Source, UNO_QUERY);
Reference< ::com::sun::star::container::XEnumerationAccess > xEnumAccess;
if (xSupplyCols.is())
xEnumAccess = Reference< ::com::sun::star::container::XEnumerationAccess > (xSupplyCols->getColumns(),UNO_QUERY);
if (!xSupplyCols.is() || !xEnumAccess.is())
{
DBG_ERROR("FmXFormController::approveRowChange : source is no columns supplier or columns aren't enumerable !");
// can't do anything here ...
return sal_True;
}
Reference< ::com::sun::star::container::XEnumeration > xEnumeration = xEnumAccess->createEnumeration();
2000-11-07 12:16:50 +00:00
Reference< XPropertySet > xFieldSet;
2000-09-18 16:07:07 +00:00
while (xEnumeration->hasMoreElements())
{
2000-11-07 12:16:50 +00:00
xEnumeration->nextElement() >>= xFieldSet;
2000-09-18 16:07:07 +00:00
Reference< ::com::sun::star::sdb::XColumn > xColumn(xFieldSet, UNO_QUERY);
if (!xFieldSet.is() || !xColumn.is())
{
DBG_ERROR("FmXFormController::approveRowChange : invalid field !");
continue;
}
2000-10-20 13:18:57 +00:00
sal_Bool bRequired = ::comphelper::getINT32(xFieldSet->getPropertyValue(FM_PROP_ISNULLABLE)) == ::com::sun::star::sdbc::ColumnValue::NO_NULLS;
2000-09-18 16:07:07 +00:00
if (!bRequired)
continue;
2000-10-20 13:18:57 +00:00
sal_Bool bAutoIncrement = ::comphelper::getBOOL(xFieldSet->getPropertyValue(FM_PROP_AUTOINCREMENT));
2000-09-18 16:07:07 +00:00
if (bAutoIncrement)
continue;
2000-10-20 13:18:57 +00:00
::rtl::OUString aFieldName(::comphelper::getString(xFieldSet->getPropertyValue(FM_PROP_NAME)));
2000-09-18 16:07:07 +00:00
2001-05-11 15:07:05 +00:00
if (!xColumn->getString().getLength() && xColumn->wasNull())
2000-09-18 16:07:07 +00:00
{
Sequence< Reference< ::com::sun::star::awt::XControl > > aControls(getControls());
sal_Int32 nLength = aControls.getLength();
sal_Int32 i(0);
const Reference< ::com::sun::star::awt::XControl > * pControls = aControls.getConstArray();
for (; i < nLength; i++)
{
if (pControls[i].is())
{
2000-11-06 06:19:53 +00:00
Reference< XPropertySet > xModel(pControls[i]->getModel(), UNO_QUERY);
2000-09-18 16:07:07 +00:00
if (xModel.is())
{
2000-10-20 13:18:57 +00:00
if (::comphelper::hasProperty(FM_PROP_CONTROLSOURCE, xModel))
2000-09-18 16:07:07 +00:00
{
2000-10-20 13:18:57 +00:00
::rtl::OUString aName = ::comphelper::getString(xModel->getPropertyValue(FM_PROP_CONTROLSOURCE));
2000-09-18 16:07:07 +00:00
if (aName == aFieldName) // Control gefunden
break;
}
}
}
}
String aMsg(SVX_RES(RID_ERR_FIELDREQUIRED));
2000-09-18 16:07:07 +00:00
aMsg.SearchAndReplace('#', aFieldName.getStr());
SQLContext aError;
aError.Message = String(SVX_RES(RID_STR_WRITEERROR));
aError.Details = aMsg;
displayException(aError, getDialogParentWindow());
2000-09-18 16:07:07 +00:00
if ( i < nLength)
{
Reference< ::com::sun::star::awt::XWindow > xWindow(pControls[i], UNO_QUERY);
xWindow->setFocus();
}
return sal_False;
}
}
}
return bValid;
}
//------------------------------------------------------------------------------
sal_Bool SAL_CALL FmXFormController::approveCursorMove(const ::com::sun::star::lang::EventObject& event) throw( RuntimeException )
{
::osl::MutexGuard aGuard( m_aMutex );
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
::cppu::OInterfaceIteratorHelper aIter(m_aRowSetApproveListeners);
if (aIter.hasMoreElements())
{
::com::sun::star::lang::EventObject aEvt(event);
aEvt.Source = *this;
return ((::com::sun::star::sdb::XRowSetApproveListener*)aIter.next())->approveCursorMove(aEvt);
}
return sal_True;
}
//------------------------------------------------------------------------------
sal_Bool SAL_CALL FmXFormController::approveRowSetChange(const ::com::sun::star::lang::EventObject& event) throw( RuntimeException )
{
::osl::MutexGuard aGuard( m_aMutex );
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
::cppu::OInterfaceIteratorHelper aIter(m_aRowSetApproveListeners);
if (aIter.hasMoreElements())
{
::com::sun::star::lang::EventObject aEvt(event);
aEvt.Source = *this;
return ((::com::sun::star::sdb::XRowSetApproveListener*)aIter.next())->approveRowSetChange(aEvt);
}
return sal_True;
}
// ::com::sun::star::sdb::XRowSetApproveBroadcaster
//------------------------------------------------------------------------------
void SAL_CALL FmXFormController::addRowSetApproveListener(const Reference< ::com::sun::star::sdb::XRowSetApproveListener > & _rxListener) throw( RuntimeException )
{
::osl::MutexGuard aGuard( m_aMutex );
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
m_aRowSetApproveListeners.addInterface(_rxListener);
}
//------------------------------------------------------------------------------
void SAL_CALL FmXFormController::removeRowSetApproveListener(const Reference< ::com::sun::star::sdb::XRowSetApproveListener > & _rxListener) throw( RuntimeException )
{
::osl::MutexGuard aGuard( m_aMutex );
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
m_aRowSetApproveListeners.removeInterface(_rxListener);
}
// ::com::sun::star::form::XErrorListener
//------------------------------------------------------------------------------
void SAL_CALL FmXFormController::errorOccured(const ::com::sun::star::sdb::SQLErrorEvent& aEvent) throw( RuntimeException )
{
::osl::MutexGuard aGuard( m_aMutex );
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
if (m_pView)
{ // we're working for a FormView
if (!(m_pWindow || (m_pView->GetActualOutDev() == (const OutputDevice*)m_pWindow ||
!m_pView->GetActualOutDev() && m_pWindow->IsActive())))
// we're not active
return;
}
::cppu::OInterfaceIteratorHelper aIter(m_aErrorListeners);
if (aIter.hasMoreElements())
{
::com::sun::star::sdb::SQLErrorEvent aEvt(aEvent);
aEvt.Source = *this;
((::com::sun::star::sdb::XSQLErrorListener*)aIter.next())->errorOccured(aEvt);
}
else
{
displayException(aEvent);
}
}
// ::com::sun::star::form::XErrorBroadcaster
//------------------------------------------------------------------------------
void SAL_CALL FmXFormController::addSQLErrorListener(const Reference< ::com::sun::star::sdb::XSQLErrorListener > & aListener) throw( RuntimeException )
{
::osl::MutexGuard aGuard( m_aMutex );
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
m_aErrorListeners.addInterface(aListener);
}
//------------------------------------------------------------------------------
void SAL_CALL FmXFormController::removeSQLErrorListener(const Reference< ::com::sun::star::sdb::XSQLErrorListener > & aListener) throw( RuntimeException )
{
::osl::MutexGuard aGuard( m_aMutex );
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
m_aErrorListeners.removeInterface(aListener);
}
// ::com::sun::star::form::XDatabaseParameterBroadcaster
//------------------------------------------------------------------------------
void SAL_CALL FmXFormController::addParameterListener(const Reference< ::com::sun::star::form::XDatabaseParameterListener > & aListener) throw( RuntimeException )
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
m_aParameterListeners.addInterface(aListener);
}
//------------------------------------------------------------------------------
void SAL_CALL FmXFormController::removeParameterListener(const Reference< ::com::sun::star::form::XDatabaseParameterListener > & aListener) throw( RuntimeException )
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
m_aParameterListeners.removeInterface(aListener);
}
// ::com::sun::star::form::XDatabaseParameterListener
//------------------------------------------------------------------------------
sal_Bool SAL_CALL FmXFormController::approveParameter(const ::com::sun::star::form::DatabaseParameterEvent& aEvent) throw( RuntimeException )
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
if (m_pView)
{ // we're working for a FormView
if (!(m_pWindow || (m_pView->GetActualOutDev() == (const OutputDevice*)m_pWindow ||
!m_pView->GetActualOutDev() && m_pWindow->IsActive())))
// we're not active
return sal_True;
}
::cppu::OInterfaceIteratorHelper aIter(m_aParameterListeners);
if (aIter.hasMoreElements())
{
::com::sun::star::form::DatabaseParameterEvent aEvt(aEvent);
aEvt.Source = *this;
return ((::com::sun::star::form::XDatabaseParameterListener*)aIter.next())->approveParameter(aEvt);
}
else
{
// default handling: instantiate an interaction handler and let it handle the parameter request
try
{
// two continuations allowed: OK and Cancel
OParameterContinuation* pParamValues = new OParameterContinuation;
OInteractionAbort* pAbort = new OInteractionAbort;
// the request
ParametersRequest aRequest;
aRequest.Parameters = aEvent.Parameters;
aRequest.Connection = OStaticDataAccessTools().getRowSetConnection(Reference< XRowSet >(aEvent.Source, UNO_QUERY));
OInteractionRequest* pParamRequest = new OInteractionRequest(makeAny(aRequest));
Reference< XInteractionRequest > xParamRequest(pParamRequest);
// some knittings
pParamRequest->addContinuation(pParamValues);
pParamRequest->addContinuation(pAbort);
// create the handler, let it handle the request
2000-11-06 06:19:53 +00:00
Reference< XInteractionHandler > xHandler(m_xORB->createInstance(SRV_SDB_INTERACTION_HANDLER), UNO_QUERY);
if (xHandler.is())
{
::vos::OGuard aGuard(Application::GetSolarMutex());
xHandler->handle(xParamRequest);
}
2000-09-18 16:07:07 +00:00
if (!pParamValues->wasSelected())
// canceled
return sal_False;
// transfer the values into the parameter supplier
Sequence< PropertyValue > aFinalValues = pParamValues->getValues();
if (aFinalValues.getLength() != aRequest.Parameters->getCount())
{
DBG_ERROR("FmXFormController::approveParameter: the InteractionHandler returned nonsense!");
return sal_False;
}
const PropertyValue* pFinalValues = aFinalValues.getConstArray();
for (sal_Int32 i=0; i<aFinalValues.getLength(); ++i, ++pFinalValues)
{
Reference< XPropertySet > xParam;
::cppu::extractInterface(xParam, aRequest.Parameters->getByIndex(i));
if (xParam.is())
{
#ifdef DBG_UTIL
::rtl::OUString sName;
xParam->getPropertyValue(FM_PROP_NAME) >>= sName;
DBG_ASSERT(sName.equals(pFinalValues->Name), "FmXFormController::approveParameter: suspicious value names!");
#endif
try { xParam->setPropertyValue(FM_PROP_VALUE, pFinalValues->Value); }
catch(Exception&)
{
DBG_ERROR("FmXFormController::approveParameter: setting one of the properties failed!");
}
}
}
}
catch(Exception&)
{
DBG_ERROR("FmXFormController::approveParameter: caught an Exception (tried to let the InteractionHandler handle it)!");
}
2000-09-18 16:07:07 +00:00
}
return sal_True;
}
// ::com::sun::star::form::XConfirmDeleteBroadcaster
//------------------------------------------------------------------------------
void SAL_CALL FmXFormController::addConfirmDeleteListener(const Reference< ::com::sun::star::form::XConfirmDeleteListener > & aListener) throw( RuntimeException )
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
m_aDeleteListeners.addInterface(aListener);
}
//------------------------------------------------------------------------------
void SAL_CALL FmXFormController::removeConfirmDeleteListener(const Reference< ::com::sun::star::form::XConfirmDeleteListener > & aListener) throw( RuntimeException )
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
m_aDeleteListeners.removeInterface(aListener);
}
// ::com::sun::star::form::XConfirmDeleteListener
//------------------------------------------------------------------------------
sal_Bool SAL_CALL FmXFormController::confirmDelete(const ::com::sun::star::sdb::RowChangeEvent& aEvent) throw( RuntimeException )
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
if (m_pView)
{ // we're working for a FormView
if (!(m_pWindow || (m_pView->GetActualOutDev() == (const OutputDevice*)m_pWindow ||
!m_pView->GetActualOutDev() && m_pWindow->IsActive())))
// we're not active
return sal_True;
}
::cppu::OInterfaceIteratorHelper aIter(m_aDeleteListeners);
if (aIter.hasMoreElements())
{
::com::sun::star::sdb::RowChangeEvent aEvt(aEvent);
aEvt.Source = *this;
return ((::com::sun::star::form::XConfirmDeleteListener*)aIter.next())->confirmDelete(aEvt);
}
else
{
// default handling
UniString aTitle;
sal_Int32 nLength = aEvent.Rows;
if (nLength > 1)
{
2000-09-18 16:07:07 +00:00
aTitle = SVX_RES(RID_STR_DELETECONFIRM_RECORDS);
aTitle.SearchAndReplace('#', String::CreateFromInt32(nLength));
}
2000-09-18 16:07:07 +00:00
else
aTitle = SVX_RES(RID_STR_DELETECONFIRM_RECORD);
ConfirmDeleteDialog aDlg(getDialogParentWindow(), aTitle);
return RET_YES == aDlg.Execute();
2000-09-18 16:07:07 +00:00
}
}
//------------------------------------------------------------------------------
Reference< ::com::sun::star::frame::XDispatch >
FmXFormController::interceptedQueryDispatch(sal_uInt16 _nId, const ::com::sun::star::util::URL& aURL,
const ::rtl::OUString& aTargetFrameName, sal_Int32 nSearchFlags)
throw( RuntimeException )
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
Reference< ::com::sun::star::frame::XDispatch > xReturn;
// dispatches handled by ourself
if (aURL.Complete == FMURL_CONFIRM_DELETION)
xReturn = static_cast<XDispatch*>(this);
2000-09-18 16:07:07 +00:00
// dispatches of FormSlot-URLs we have to translate
if (!xReturn.is() && aURL.Complete.indexOf(FMURL_FORMSLOTS_PREFIX) == 0)
{ // TODO : use an ::com::sun::star::util::URLTransformer to split this ::com::sun::star::util::URL and do a real (safe) check
// get the frame we're residing in
Reference< ::com::sun::star::frame::XModel > xFrameModel = getXModel(getModel());
Reference< ::com::sun::star::frame::XController > xFrameController = xFrameModel.is() ? xFrameModel->getCurrentController() : Reference< ::com::sun::star::frame::XController > ();
Reference< ::com::sun::star::frame::XFrame > xFrame = xFrameController.is() ? xFrameController->getFrame() : Reference< ::com::sun::star::frame::XFrame > ();
if (!xFrame.is())
{
// bad timing : somebody requested a dispatch, but the model we belong to is not attached to a controller, yet
// (or the controller isn't attached to a frame). This sometimes happens if a document is opened read-only.
// As we have no chance to get the "attached" event for the model/controller/frame, we have no chance
// to refresh the dispatchers later as response to such an event.
// So we simply try it asynchron until we have that frame.
if (!m_nUpdateDispatcherEvent)
m_nUpdateDispatcherEvent = Application::PostUserEvent(LINK(this, FmXFormController, OnUpdateDispatchers));
}
else
{
// translate the ::com::sun::star::util::URL : the new ::com::sun::star::util::URL is the old one with a mark : the "path" to our model within it's hierarchy
2001-05-16 08:50:40 +00:00
DBG_ASSERT(aURL.Mark.getLength() == 0, "FmXFormController::interceptedQueryDispatch : the ::com::sun::star::util::URL shouldn't have a mark !");
2000-09-18 16:07:07 +00:00
::rtl::OUString sNewMark;
::rtl::OUString sCurrentPath;
// collect the relative indicies of my model, it's parent, it's parent's parent ..., separate them with a '\'
Reference< ::com::sun::star::container::XChild > xChild(getModel(), UNO_QUERY);
Reference< ::com::sun::star::container::XIndexAccess > xParent;
if (xChild.is())
2000-10-20 13:18:57 +00:00
::comphelper::query_interface(xChild->getParent(), xParent);
2000-09-18 16:07:07 +00:00
while (xChild.is() && xParent.is())
{
sal_Int32 nPos = getElementPos(xParent, xChild);
sCurrentPath = ::rtl::OUString::valueOf(nPos);
if (sNewMark.getLength())
{
sCurrentPath += ::rtl::OUString::createFromAscii("\\");
sNewMark = sCurrentPath + sNewMark;
}
else
sNewMark = sCurrentPath;
2000-10-20 13:18:57 +00:00
::comphelper::query_interface((Reference<XInterface>)xParent, xChild);
2000-09-18 16:07:07 +00:00
if (xChild.is())
2000-10-20 13:18:57 +00:00
::comphelper::query_interface(xChild->getParent(), xParent);
2000-09-18 16:07:07 +00:00
}
::com::sun::star::util::URL aNewUrl = aURL;
// and prepend our dispatch prefix
2000-09-29 13:07:06 +00:00
::rtl::OUString aMark = m_sDispatchPrefix;
aMark += ::rtl::OUString::createFromAscii("\\");
aMark += sNewMark;
2000-09-18 16:07:07 +00:00
// assemble the new url
2000-11-06 06:19:53 +00:00
Reference< ::com::sun::star::util::XURLTransformer > xTransformer(m_xORB->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer") ), UNO_QUERY);
2000-09-18 16:07:07 +00:00
if (xTransformer.is())
{
2000-09-29 13:07:06 +00:00
xTransformer->parseStrict(aNewUrl);
aNewUrl.Mark = aMark;
2000-09-18 16:07:07 +00:00
xTransformer->assemble(aNewUrl);
DBG_ASSERT(aNewUrl.Complete.getLength(), "FmXFormController::interceptedQueryDispatch : transformation of the ::com::sun::star::util::URL failed !");
}
else
{
DBG_ERROR("FmXFormController::interceptedQueryDispatch : could not create a com.sun.star.util.URLTransformer !");
// do it manually ... the service would probably do the same, but to be sure we gave it a chance before doing it ourself
aNewUrl.Complete += ::rtl::OUString::createFromAscii("#");
aNewUrl.Complete += aNewUrl.Mark;
}
Reference< ::com::sun::star::frame::XDispatchProvider > xDispProv(xFrame, UNO_QUERY);
if (xDispProv.is())
xReturn = xDispProv->queryDispatch(aNewUrl, aTargetFrameName, nSearchFlags);
}
}
// no more to offer
return xReturn;
}
//------------------------------------------------------------------------------
void SAL_CALL FmXFormController::dispatch( const URL& _rURL, const Sequence< PropertyValue >& _rArgs ) throw (RuntimeException)
{
OSL_ENSURE(sal_False, "FmXFormController::dispatch: never to be called!");
// we use the dispatch mechanism only for exposing the XConfirmDeleteListener interface
}
//------------------------------------------------------------------------------
void SAL_CALL FmXFormController::addStatusListener( const Reference< XStatusListener >& _rxListener, const URL& _rURL ) throw (RuntimeException)
{
if (_rURL.Complete == FMURL_CONFIRM_DELETION)
{
if (_rxListener.is())
{ // send an initial statusChanged event
FeatureStateEvent aEvent;
aEvent.FeatureURL = _rURL;
aEvent.IsEnabled = sal_True;
_rxListener->statusChanged(aEvent);
// and don't add the listener at all (the status will never change)
}
}
else
OSL_ENSURE(sal_False, "FmXFormController::addStatusListener: invalid (unsupported) URL!");
}
//------------------------------------------------------------------------------
void SAL_CALL FmXFormController::removeStatusListener( const Reference< XStatusListener >& _rxListener, const URL& _rURL ) throw (RuntimeException)
{
OSL_ENSURE(_rURL.Complete == FMURL_CONFIRM_DELETION, "FmXFormController::removeStatusListener: invalid (unsupported) URL!");
// we never really added the listener, so we don't need to remove it
}
2000-09-18 16:07:07 +00:00
//------------------------------------------------------------------------------
Reference< ::com::sun::star::frame::XDispatchProviderInterceptor > FmXFormController::createInterceptor(const Reference< ::com::sun::star::frame::XDispatchProviderInterception > & _xInterception)
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
#if DBG_UTIL
// check if we already have a interceptor for the given object
for ( ConstInterceptorsIterator aIter = m_aControlDispatchInterceptors.begin();
aIter != m_aControlDispatchInterceptors.end();
++aIter
)
{
if ((*aIter)->getIntercepted() == _xInterception)
DBG_ERROR("FmXFormController::createInterceptor : we already do intercept this objects dispatches !");
}
#endif
::rtl::OUString sInterceptorScheme(RTL_CONSTASCII_USTRINGPARAM("*"));
FmXDispatchInterceptorImpl* pInterceptor = new FmXDispatchInterceptorImpl(_xInterception, this, 0, Sequence< ::rtl::OUString >(&sInterceptorScheme, 1));
2000-09-18 16:07:07 +00:00
pInterceptor->acquire();
m_aControlDispatchInterceptors.insert(m_aControlDispatchInterceptors.end(), pInterceptor);
return (::com::sun::star::frame::XDispatchProviderInterceptor*)pInterceptor;
}
//------------------------------------------------------------------------------
void FmXFormController::deleteInterceptor(const Reference< ::com::sun::star::frame::XDispatchProviderInterception > & _xInterception)
{
2001-03-23 15:26:54 +00:00
OSL_ENSURE(!FmXFormController_BASE1::rBHelper.bDisposed,"FmXFormController: Object already disposed!");
2000-09-18 16:07:07 +00:00
// search the interceptor responsible for the given object
InterceptorsIterator aIter;
for ( aIter = m_aControlDispatchInterceptors.begin();
aIter != m_aControlDispatchInterceptors.end();
++aIter
)
{
if ((*aIter)->getIntercepted() == _xInterception)
break;
}
if (aIter == m_aControlDispatchInterceptors.end())
{
return;
}
// log off the interception from it's interception object
FmXDispatchInterceptorImpl* pInterceptorImpl = *aIter;
pInterceptorImpl->dispose();
pInterceptorImpl->release();
// remove the interceptor from our array
m_aControlDispatchInterceptors.erase(aIter);
if ( !m_aControlDispatchInterceptors.size() && m_nUpdateDispatcherEvent)
{
Application::RemoveUserEvent( m_nUpdateDispatcherEvent );
m_nUpdateDispatcherEvent = 0;
}
2000-09-18 16:07:07 +00:00
}