2000-09-18 15:33:13 +00:00
|
|
|
/*************************************************************************
|
|
|
|
*
|
|
|
|
* $RCSfile: FormComponent.cxx,v $
|
|
|
|
*
|
2004-05-07 15:07:05 +00:00
|
|
|
* $Revision: 1.30 $
|
2000-09-18 15:33:13 +00:00
|
|
|
*
|
2004-05-07 15:07:05 +00:00
|
|
|
* last change: $Author: rt $ $Date: 2004-05-07 16:07:05 $
|
2000-09-18 15:33:13 +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): _______________________________________
|
|
|
|
*
|
|
|
|
*
|
|
|
|
************************************************************************/
|
|
|
|
|
|
|
|
#ifndef _FORMS_FORMCOMPONENT_HXX_
|
|
|
|
#include "FormComponent.hxx"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _TOOLS_DEBUG_HXX
|
|
|
|
#include <tools/debug.hxx>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _CPPUHELPER_QUERYINTERFACE_HXX_
|
|
|
|
#include <cppuhelper/queryinterface.hxx>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _COM_SUN_STAR_AWT_XTEXTCOMPONENT_HPP_
|
|
|
|
#include <com/sun/star/awt/XTextComponent.hpp>
|
|
|
|
#endif
|
|
|
|
#ifndef _COM_SUN_STAR_AWT_XWINDOW_HPP_
|
|
|
|
#include <com/sun/star/awt/XWindow.hpp>
|
|
|
|
#endif
|
|
|
|
#ifndef _COM_SUN_STAR_IO_XMARKABLESTREAM_HPP_
|
|
|
|
#include <com/sun/star/io/XMarkableStream.hpp>
|
|
|
|
#endif
|
|
|
|
#ifndef _COM_SUN_STAR_FORM_XLOADABLE_HPP_
|
|
|
|
#include <com/sun/star/form/XLoadable.hpp>
|
|
|
|
#endif
|
|
|
|
#ifndef _COM_SUN_STAR_FORM_XFORM_HPP_
|
|
|
|
#include <com/sun/star/form/XForm.hpp>
|
|
|
|
#endif
|
|
|
|
#ifndef _COM_SUN_STAR_SDBC_DATATYPE_HPP_
|
|
|
|
#include <com/sun/star/sdbc/DataType.hpp>
|
|
|
|
#endif
|
|
|
|
#ifndef _COM_SUN_STAR_SDBC_COLUMNVALUE_HPP_
|
|
|
|
#include <com/sun/star/sdbc/ColumnValue.hpp>
|
|
|
|
#endif
|
2003-10-21 07:57:42 +00:00
|
|
|
#ifndef _COM_SUN_STAR_UTIL_XMODIFYBROADCASTER_HPP_
|
|
|
|
#include <com/sun/star/util/XModifyBroadcaster.hpp>
|
2002-08-01 13:57:01 +00:00
|
|
|
#endif
|
2004-04-02 09:52:14 +00:00
|
|
|
#ifndef _COM_SUN_STAR_AWT_XVCLWINDOWPEER_HPP_
|
|
|
|
#include <com/sun/star/awt/XVclWindowPeer.hpp>
|
|
|
|
#endif
|
|
|
|
#ifndef _COM_SUN_STAR_AWT_FONTUNDERLINE_HPP_
|
|
|
|
#include <com/sun/star/awt/FontUnderline.hpp>
|
|
|
|
#endif
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2000-10-19 10:52:20 +00:00
|
|
|
#ifndef _COMPHELPER_PROPERTY_HXX_
|
|
|
|
#include <comphelper/property.hxx>
|
2000-09-18 15:33:13 +00:00
|
|
|
#endif
|
2000-10-19 10:52:20 +00:00
|
|
|
#ifndef _CONNECTIVITY_DBTOOLS_HXX_
|
|
|
|
#include <connectivity/dbtools.hxx>
|
2000-09-18 15:33:13 +00:00
|
|
|
#endif
|
|
|
|
#ifndef _FRM_PROPERTY_HRC_
|
|
|
|
#include "property.hrc"
|
|
|
|
#endif
|
|
|
|
#ifndef _FRM_SERVICES_HXX_
|
|
|
|
#include "services.hxx"
|
|
|
|
#endif
|
2002-10-02 13:46:57 +00:00
|
|
|
#ifndef _RTL_LOGFILE_HXX_
|
|
|
|
#include <rtl/logfile.hxx>
|
|
|
|
#endif
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2001-12-20 15:16:37 +00:00
|
|
|
#ifndef _COMPHELPER_BASIC_IO_HXX_
|
2001-04-04 11:56:34 +00:00
|
|
|
#include <comphelper/basicio.hxx>
|
2001-12-20 15:16:37 +00:00
|
|
|
#endif
|
2004-04-02 09:52:14 +00:00
|
|
|
#ifndef COMPHELPER_INC_COMPHELPER_LISTENERNOTIFICATION_HXX
|
|
|
|
#include <comphelper/listenernotification.hxx>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _TOOLKIT_HELPER_EMPTYFONTDESCRIPTOR_HXX_
|
|
|
|
#include <toolkit/helper/emptyfontdescriptor.hxx>
|
|
|
|
#endif
|
2001-12-20 15:16:37 +00:00
|
|
|
|
|
|
|
#ifndef _FRM_RESOURCE_HXX_
|
|
|
|
#include "frm_resource.hxx"
|
|
|
|
#endif
|
|
|
|
#ifndef _FRM_RESOURCE_HRC_
|
|
|
|
#include "frm_resource.hrc"
|
|
|
|
#endif
|
|
|
|
|
2001-04-04 11:56:34 +00:00
|
|
|
|
2000-09-18 15:33:13 +00:00
|
|
|
//... namespace frm .......................................................
|
|
|
|
namespace frm
|
|
|
|
{
|
|
|
|
//.........................................................................
|
2004-04-02 09:52:14 +00:00
|
|
|
using namespace ::com::sun::star::uno;
|
|
|
|
using namespace ::com::sun::star::sdb;
|
|
|
|
using namespace ::com::sun::star::sdbc;
|
|
|
|
using namespace ::com::sun::star::sdbcx;
|
|
|
|
using namespace ::com::sun::star::beans;
|
|
|
|
using namespace ::com::sun::star::container;
|
|
|
|
using namespace ::com::sun::star::form;
|
|
|
|
using namespace ::com::sun::star::awt;
|
|
|
|
using namespace ::com::sun::star::io;
|
|
|
|
using namespace ::com::sun::star::lang;
|
|
|
|
using namespace ::com::sun::star::util;
|
|
|
|
using namespace ::com::sun::star::form::binding;
|
|
|
|
using namespace ::com::sun::star::form::validation;
|
|
|
|
using namespace ::dbtools;
|
|
|
|
using namespace ::comphelper;
|
|
|
|
|
|
|
|
//====================================================================
|
|
|
|
//= OFormComponentListeners
|
|
|
|
//====================================================================
|
|
|
|
typedef ::comphelper::OListenerContainerBase < XFormComponentValidityListener
|
|
|
|
, EventObject
|
|
|
|
> OFormComponentListeners_Base;
|
|
|
|
|
|
|
|
class OFormComponentListeners : public OFormComponentListeners_Base
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
OFormComponentListeners( ::osl::Mutex& _rMutex )
|
|
|
|
:OFormComponentListeners_Base( _rMutex )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
virtual bool implNotify(
|
|
|
|
const Reference< XFormComponentValidityListener >& _rxListener,
|
|
|
|
const EventObject& _rEvent
|
|
|
|
) SAL_THROW( ( Exception ) );
|
|
|
|
};
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
bool OFormComponentListeners::implNotify( const Reference< XFormComponentValidityListener >& _rxListener, const EventObject& _rEvent ) SAL_THROW( ( Exception ) )
|
|
|
|
{
|
|
|
|
_rxListener->componentValidityChanged( _rEvent );
|
|
|
|
return true; // continue calling listeners
|
|
|
|
}
|
2001-04-02 09:28:06 +00:00
|
|
|
|
2000-09-18 15:33:13 +00:00
|
|
|
//=========================================================================
|
|
|
|
//= base class for form layer controls
|
|
|
|
//=========================================================================
|
|
|
|
DBG_NAME(frm_OControl)
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
OControl::OControl(const Reference<com::sun::star::lang::XMultiServiceFactory>& _rxFactory, const rtl::OUString& _sService)
|
2000-09-18 15:33:13 +00:00
|
|
|
:OComponentHelper(m_aMutex)
|
|
|
|
,m_aService(_sService)
|
|
|
|
,m_xServiceFactory(_rxFactory)
|
|
|
|
{
|
|
|
|
DBG_CTOR(frm_OControl, NULL);
|
|
|
|
// VCL-Control aggregieren
|
|
|
|
// bei Aggregation den Refcount um eins erhoehen da im setDelegator
|
|
|
|
// das Aggregat selbst den Refcount erhoeht
|
|
|
|
increment(m_refCount);
|
|
|
|
{
|
2001-04-26 11:36:28 +00:00
|
|
|
m_xAggregate = Reference<XAggregation>(_rxFactory->createInstance(_sService), UNO_QUERY);
|
|
|
|
m_xControl = Reference<XControl>(m_xAggregate, UNO_QUERY);
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (m_xAggregate.is())
|
|
|
|
{
|
2001-04-26 11:36:28 +00:00
|
|
|
m_xAggregate->setDelegator(static_cast<XWeak*>(this));
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Refcount wieder bei NULL
|
|
|
|
sal_Int32 n = decrement(m_refCount);
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
OControl::~OControl()
|
|
|
|
{
|
|
|
|
DBG_DTOR(frm_OControl, NULL);
|
|
|
|
// Freigeben der Aggregation
|
|
|
|
if (m_xAggregate.is())
|
|
|
|
{
|
|
|
|
m_xAggregate->setDelegator(InterfaceRef());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// UNO Anbindung
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
Any SAL_CALL OControl::queryAggregation( const Type& _rType ) throw(RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
// ask the base class
|
2003-03-25 17:05:07 +00:00
|
|
|
Any aReturn( OComponentHelper::queryAggregation(_rType) );
|
2000-09-18 15:33:13 +00:00
|
|
|
// ask our own interfaces
|
|
|
|
if (!aReturn.hasValue())
|
2000-11-23 07:48:15 +00:00
|
|
|
{
|
|
|
|
aReturn = OControl_BASE::queryInterface(_rType);
|
|
|
|
// ask our aggregate
|
|
|
|
if (!aReturn.hasValue() && m_xAggregate.is())
|
|
|
|
aReturn = m_xAggregate->queryAggregation(_rType);
|
|
|
|
}
|
2000-09-18 15:33:13 +00:00
|
|
|
|
|
|
|
return aReturn;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
Sequence<sal_Int8> SAL_CALL OControl::getImplementationId() throw(RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
return OImplementationIds::getImplementationId(getTypes());
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
Sequence<Type> SAL_CALL OControl::getTypes() throw(RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2000-11-23 07:48:15 +00:00
|
|
|
Sequence<Type> aOwnTypes = _getTypes();
|
|
|
|
Reference<com::sun::star::lang::XTypeProvider> xProv;
|
2000-09-18 15:33:13 +00:00
|
|
|
|
|
|
|
if (query_aggregation(m_xAggregate, xProv))
|
|
|
|
return concatSequences(aOwnTypes, xProv->getTypes());
|
|
|
|
else
|
|
|
|
return aOwnTypes;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
Sequence<Type> OControl::_getTypes()
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2000-11-23 07:48:15 +00:00
|
|
|
static Sequence<Type> aTypes;
|
2000-09-18 15:33:13 +00:00
|
|
|
if (!aTypes.getLength())
|
2000-11-23 07:48:15 +00:00
|
|
|
aTypes = concatSequences(OComponentHelper::getTypes(), OControl_BASE::getTypes());
|
2000-09-18 15:33:13 +00:00
|
|
|
return aTypes;
|
|
|
|
}
|
|
|
|
|
|
|
|
// OComponentHelper
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void OControl::disposing()
|
|
|
|
{
|
|
|
|
OComponentHelper::disposing();
|
|
|
|
|
2000-11-23 07:48:15 +00:00
|
|
|
Reference<com::sun::star::lang::XComponent> xComp;
|
2000-09-18 15:33:13 +00:00
|
|
|
if (query_aggregation(m_xAggregate, xComp))
|
|
|
|
xComp->dispose();
|
|
|
|
}
|
|
|
|
|
|
|
|
// XServiceInfo
|
|
|
|
//------------------------------------------------------------------------------
|
2003-05-19 12:08:37 +00:00
|
|
|
sal_Bool SAL_CALL OControl::supportsService(const rtl::OUString& _rsServiceName) throw ( RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2000-11-23 07:48:15 +00:00
|
|
|
Sequence<rtl::OUString> aSupported = getSupportedServiceNames();
|
2000-09-18 15:33:13 +00:00
|
|
|
const rtl::OUString* pSupported = aSupported.getConstArray();
|
|
|
|
for (sal_Int32 i=0; i<aSupported.getLength(); ++i, ++pSupported)
|
|
|
|
if (pSupported->equals(_rsServiceName))
|
|
|
|
return sal_True;
|
|
|
|
return sal_False;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2003-12-11 11:28:53 +00:00
|
|
|
Sequence< ::rtl::OUString > OControl::getAggregateServiceNames()
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2003-12-11 11:28:53 +00:00
|
|
|
Sequence< ::rtl::OUString > aAggServices;
|
|
|
|
Reference< XServiceInfo > xInfo;
|
2002-03-04 12:59:21 +00:00
|
|
|
if ( query_aggregation( m_xAggregate, xInfo ) )
|
2003-12-11 11:28:53 +00:00
|
|
|
aAggServices = xInfo->getSupportedServiceNames();
|
|
|
|
return aAggServices;
|
|
|
|
}
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2003-12-11 11:28:53 +00:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
Sequence<rtl::OUString> SAL_CALL OControl::getSupportedServiceNames() throw(RuntimeException)
|
|
|
|
{
|
|
|
|
return ::comphelper::concatSequences(
|
|
|
|
getAggregateServiceNames(),
|
|
|
|
getSupportedServiceNames_Static()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
Sequence< ::rtl::OUString > SAL_CALL OControl::getSupportedServiceNames_Static() throw( RuntimeException )
|
|
|
|
{
|
|
|
|
// no own supported service names
|
|
|
|
return Sequence< ::rtl::OUString >();
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// XEventListener
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
void SAL_CALL OControl::disposing(const com::sun::star::lang::EventObject& _rEvent) throw (RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
InterfaceRef xAggAsIface;
|
|
|
|
query_aggregation(m_xAggregate, xAggAsIface);
|
|
|
|
|
|
|
|
// does the disposing come from the aggregate ?
|
2000-11-23 07:48:15 +00:00
|
|
|
if (xAggAsIface != InterfaceRef(_rEvent.Source, UNO_QUERY))
|
2000-09-18 15:33:13 +00:00
|
|
|
{ // no -> forward it
|
2000-11-23 07:48:15 +00:00
|
|
|
Reference<com::sun::star::lang::XEventListener> xListener;
|
2000-09-18 15:33:13 +00:00
|
|
|
if (query_aggregation(m_xAggregate, xListener))
|
|
|
|
xListener->disposing(_rEvent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// XControl
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
void SAL_CALL OControl::setContext(const InterfaceRef& Context) throw (RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
if (m_xControl.is())
|
|
|
|
m_xControl->setContext(Context);
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
InterfaceRef SAL_CALL OControl::getContext() throw (RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
return m_xControl.is() ? m_xControl->getContext() : InterfaceRef();
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2000-12-06 09:14:22 +00:00
|
|
|
void SAL_CALL OControl::createPeer(const Reference<XToolkit>& Toolkit, const Reference<XWindowPeer>& Parent) throw (RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
if (m_xControl.is())
|
|
|
|
m_xControl->createPeer(Toolkit, Parent);
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2003-05-19 12:08:37 +00:00
|
|
|
Reference<XWindowPeer> SAL_CALL OControl::getPeer() throw ( RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2004-04-02 09:52:14 +00:00
|
|
|
return m_xControl.is() ? m_xControl->getPeer() : Reference<XWindowPeer>();
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2003-05-19 12:08:37 +00:00
|
|
|
sal_Bool SAL_CALL OControl::setModel(const Reference<XControlModel>& Model) throw ( RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
return m_xControl.is() ? m_xControl->setModel( Model ) : sal_False;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2003-05-19 12:08:37 +00:00
|
|
|
Reference<XControlModel> SAL_CALL OControl::getModel() throw ( RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2004-04-02 09:52:14 +00:00
|
|
|
return m_xControl.is() ? m_xControl->getModel() : Reference<XControlModel>();
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2003-05-19 12:08:37 +00:00
|
|
|
Reference<XView> SAL_CALL OControl::getView() throw ( RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2004-04-02 09:52:14 +00:00
|
|
|
return m_xControl.is() ? m_xControl->getView() : Reference<XView>();
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2003-05-19 12:08:37 +00:00
|
|
|
void SAL_CALL OControl::setDesignMode(sal_Bool bOn) throw ( RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
if (m_xControl.is())
|
|
|
|
m_xControl->setDesignMode(bOn);
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2003-05-19 12:08:37 +00:00
|
|
|
sal_Bool SAL_CALL OControl::isDesignMode() throw ( RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
return m_xControl.is() ? m_xControl->isDesignMode() : sal_True;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2003-05-19 12:08:37 +00:00
|
|
|
sal_Bool SAL_CALL OControl::isTransparent() throw ( RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
return m_xControl.is() ? m_xControl->isTransparent() : sal_True;
|
|
|
|
}
|
|
|
|
|
|
|
|
//==================================================================
|
|
|
|
//= OBoundControl
|
|
|
|
//==================================================================
|
|
|
|
DBG_NAME(frm_OBoundControl);
|
|
|
|
//------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
OBoundControl::OBoundControl(const Reference<com::sun::star::lang::XMultiServiceFactory>& _rxFactory, const ::rtl::OUString& _sService)
|
2000-09-18 15:33:13 +00:00
|
|
|
:OControl(_rxFactory, _sService)
|
|
|
|
,m_bLocked(sal_False)
|
2004-04-02 09:52:14 +00:00
|
|
|
,m_bLastKnownValidity( sal_True )
|
|
|
|
,m_aOriginalFont( EmptyFontDescriptor() )
|
|
|
|
,m_nOriginalTextLineColor( 0 )
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
DBG_CTOR(frm_OBoundControl, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
OBoundControl::~OBoundControl()
|
|
|
|
{
|
|
|
|
DBG_DTOR(frm_OBoundControl, NULL);
|
|
|
|
}
|
2000-11-23 07:48:15 +00:00
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
Sequence< Type> OBoundControl::_getTypes()
|
|
|
|
{
|
|
|
|
static Sequence<Type> aTypes;
|
|
|
|
if (!aTypes.getLength())
|
|
|
|
aTypes = concatSequences(OControl::_getTypes(), OBoundControl_BASE::getTypes());
|
|
|
|
return aTypes;
|
|
|
|
}
|
2000-09-18 15:33:13 +00:00
|
|
|
//------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
Any SAL_CALL OBoundControl::queryAggregation(const Type& _rType) throw(RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
// ask our own interfaces
|
2004-04-02 09:52:14 +00:00
|
|
|
// (do this first - we want to "overwrite" XPropertiesChangeListener)
|
|
|
|
Any aReturn( OBoundControl_BASE::queryInterface(_rType) );
|
|
|
|
|
|
|
|
// ask the base class
|
|
|
|
if ( !aReturn.hasValue() )
|
|
|
|
aReturn = OControl::queryAggregation( _rType );
|
2000-09-18 15:33:13 +00:00
|
|
|
|
|
|
|
return aReturn;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
sal_Bool SAL_CALL OBoundControl::getLock() throw(RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
return m_bLocked;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
void SAL_CALL OBoundControl::setLock(sal_Bool _bLock) throw(RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
if (m_bLocked == _bLock)
|
|
|
|
return;
|
|
|
|
|
|
|
|
osl::MutexGuard aGuard(m_aMutex);
|
|
|
|
_setLock(_bLock);
|
|
|
|
m_bLocked = _bLock;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
void OBoundControl::_setLock(sal_Bool _bLock)
|
|
|
|
{
|
|
|
|
// try to set the text component to readonly
|
2004-04-02 09:52:14 +00:00
|
|
|
Reference< XWindowPeer > xPeer = getPeer();
|
|
|
|
Reference< XTextComponent > xText( xPeer, UNO_QUERY );
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2004-04-02 09:52:14 +00:00
|
|
|
if ( xText.is() )
|
|
|
|
xText->setEditable( !_bLock );
|
2000-09-18 15:33:13 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
// disable the window
|
2004-04-02 09:52:14 +00:00
|
|
|
Reference< XWindow > xComp( xPeer, UNO_QUERY );
|
|
|
|
if ( xComp.is() )
|
|
|
|
xComp->setEnable( !_bLock );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
sal_Bool SAL_CALL OBoundControl::setModel( const Reference< XControlModel >& _rxModel ) throw (RuntimeException)
|
|
|
|
{
|
|
|
|
implStartStopModelValidityListening( false );
|
|
|
|
sal_Bool bReturn = OControl::setModel( _rxModel );
|
|
|
|
implStartStopModelValidityListening( true );
|
|
|
|
|
|
|
|
implCheckValidity();
|
|
|
|
|
|
|
|
return bReturn;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
void SAL_CALL OBoundControl::componentValidityChanged( const EventObject& Source ) throw (RuntimeException)
|
|
|
|
{
|
|
|
|
implCheckValidity();
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
bool OBoundControl::implPropertyChanged( const ::rtl::OUString& _rPropertyName, const Any& _rValue )
|
|
|
|
{
|
|
|
|
// if the changed property is one of the properties which we use to indicate "invalidity" at the peer,
|
|
|
|
// we need to
|
|
|
|
// a) remember the value as "original value" (to restore when we're valid, again)
|
|
|
|
// b) ensure that our marking is forwarded to the peer, again (this is done by the caller, who
|
|
|
|
// may collect multiple changes)
|
|
|
|
bool bIsInvalidityIndicatorProperty = false;
|
|
|
|
if ( _rPropertyName == PROPERTY_HELPTEXT )
|
|
|
|
{
|
|
|
|
if ( !m_bLastKnownValidity && ( bIsInvalidityIndicatorProperty = true ) )
|
|
|
|
_rValue >>= m_sOriginalHelpText;
|
|
|
|
}
|
|
|
|
else if ( _rPropertyName == PROPERTY_FONT )
|
|
|
|
{
|
|
|
|
if ( !m_bLastKnownValidity && ( bIsInvalidityIndicatorProperty = true ) )
|
|
|
|
_rValue >>= m_aOriginalFont;
|
|
|
|
}
|
|
|
|
else if ( _rPropertyName == PROPERTY_TEXTLINECOLOR )
|
|
|
|
{
|
|
|
|
if ( !m_bLastKnownValidity && ( bIsInvalidityIndicatorProperty = true ) )
|
|
|
|
_rValue >>= m_nOriginalTextLineColor;
|
|
|
|
}
|
|
|
|
return bIsInvalidityIndicatorProperty;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
void SAL_CALL OBoundControl::propertiesChange( const Sequence< PropertyChangeEvent >& aEvent ) throw (RuntimeException)
|
|
|
|
{
|
|
|
|
// delegate to the aggregate
|
|
|
|
Reference< XPropertiesChangeListener > xAggregateListener;
|
|
|
|
if ( m_xAggregate.is() )
|
|
|
|
m_xAggregate->queryAggregation( ::getCppuType( &xAggregateListener ) ) >>= xAggregateListener;
|
|
|
|
if ( xAggregateListener.is() )
|
|
|
|
xAggregateListener->propertiesChange( aEvent );
|
|
|
|
|
|
|
|
// see if one of the changed properties is used by us to indicate invalidity
|
|
|
|
bool bValidityIndicatorPropertyChanged = false;
|
|
|
|
const PropertyChangeEvent* pEvent = aEvent.getConstArray();
|
|
|
|
const PropertyChangeEvent* pEventEnd = aEvent.getConstArray() + aEvent.getLength();
|
|
|
|
for ( ; pEvent != pEventEnd; ++pEvent )
|
|
|
|
bValidityIndicatorPropertyChanged |= implPropertyChanged( pEvent->PropertyName, pEvent->NewValue );
|
|
|
|
|
|
|
|
if ( bValidityIndicatorPropertyChanged )
|
|
|
|
implMarkInvalid( m_sLastKnownInvalidityExplanation );
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
void SAL_CALL OBoundControl::disposing(const EventObject& Source) throw (RuntimeException)
|
|
|
|
{
|
|
|
|
// just disambiguate
|
|
|
|
OControl::disposing(Source);
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
void OBoundControl::disposing()
|
|
|
|
{
|
|
|
|
implStartStopModelValidityListening( false );
|
|
|
|
|
|
|
|
OControl::disposing();
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
void OBoundControl::implCheckValidity() SAL_THROW(())
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
// the validatable and the validator
|
|
|
|
Reference< XValidatableFormComponent > xValidatable( getModel(), UNO_QUERY );
|
|
|
|
Reference< XValidator > xValidator = xValidatable.is() ? xValidatable->getValidator() : Reference< XValidator >();
|
|
|
|
|
|
|
|
sal_Bool bIsCurrentlyValid = xValidatable.is() ? xValidatable->isValid() : sal_True;
|
|
|
|
::rtl::OUString sCurrentExplanation;
|
|
|
|
if ( !bIsCurrentlyValid && xValidator.is() )
|
|
|
|
sCurrentExplanation = xValidator->explainInvalid( xValidatable->getCurrentValue() );
|
|
|
|
|
|
|
|
if ( ( bIsCurrentlyValid == m_bLastKnownValidity ) && ( sCurrentExplanation == m_sLastKnownInvalidityExplanation ) )
|
|
|
|
// nothing to do
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ( bIsCurrentlyValid )
|
|
|
|
implMarkValid( );
|
|
|
|
else
|
|
|
|
implMarkInvalid( sCurrentExplanation );
|
|
|
|
|
|
|
|
m_bLastKnownValidity = bIsCurrentlyValid;
|
|
|
|
m_sLastKnownInvalidityExplanation = sCurrentExplanation;
|
|
|
|
}
|
|
|
|
catch( const Exception& )
|
|
|
|
{
|
|
|
|
OSL_ENSURE( sal_False, "OBoundControl::implCheckValidity: caught an exception!" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
void OBoundControl::implMarkValid() SAL_THROW(( Exception ))
|
|
|
|
{
|
|
|
|
Reference< XVclWindowPeer > xPeer( getPeer(), UNO_QUERY );
|
|
|
|
if ( !xPeer.is() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
// reset the help text
|
|
|
|
xPeer->setProperty( PROPERTY_HELPTEXT, makeAny( m_sOriginalHelpText ) );
|
|
|
|
m_sOriginalHelpText = ::rtl::OUString();
|
|
|
|
|
|
|
|
// reset the font
|
|
|
|
xPeer->setProperty( PROPERTY_FONT, makeAny( m_aOriginalFont ) );
|
|
|
|
m_aOriginalFont = EmptyFontDescriptor();
|
|
|
|
|
|
|
|
// reset the text line color
|
|
|
|
xPeer->setProperty( PROPERTY_TEXTLINECOLOR, makeAny( m_nOriginalTextLineColor ) );
|
|
|
|
m_nOriginalTextLineColor = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
void OBoundControl::implMarkInvalid( const ::rtl::OUString& _rExplanation ) SAL_THROW(( Exception ))
|
|
|
|
{
|
|
|
|
Reference< XVclWindowPeer > xPeer( getPeer(), UNO_QUERY );
|
|
|
|
if ( !xPeer.is() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ( m_bLastKnownValidity )
|
|
|
|
{
|
|
|
|
// the last we know about validity is that our text/value was valid. So
|
|
|
|
// before doing anythiung, save the properties which we are going to modify
|
|
|
|
xPeer->getProperty( PROPERTY_HELPTEXT ) >>= m_sOriginalHelpText;
|
|
|
|
xPeer->getProperty( PROPERTY_FONT ) >>= m_aOriginalFont;
|
|
|
|
xPeer->getProperty( PROPERTY_TEXTLINECOLOR ) >>= m_nOriginalTextLineColor;
|
|
|
|
}
|
|
|
|
|
|
|
|
// set the invalidity explanation as help text
|
|
|
|
xPeer->setProperty( PROPERTY_HELPTEXT, makeAny( _rExplanation ) );
|
|
|
|
|
|
|
|
// modify the font
|
|
|
|
FontDescriptor aFont = EmptyFontDescriptor();
|
|
|
|
xPeer->getProperty( PROPERTY_FONT ) >>= aFont;
|
|
|
|
aFont.Underline = FontUnderline::WAVE;
|
|
|
|
xPeer->setProperty( PROPERTY_FONT, makeAny( aFont ) );
|
|
|
|
|
|
|
|
// modify the text line color (which is used for underlining)
|
|
|
|
xPeer->setProperty( PROPERTY_TEXTLINECOLOR, makeAny( (sal_Int32)0x00FF0000 ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
void OBoundControl::implStartStopModelValidityListening( bool _bStart )
|
|
|
|
{
|
|
|
|
Reference< XValidatableFormComponent > xValidatable( getModel(), UNO_QUERY );
|
|
|
|
if ( xValidatable.is() )
|
|
|
|
if ( _bStart )
|
|
|
|
xValidatable->addFormComponentValidityListener( this );
|
|
|
|
else
|
|
|
|
xValidatable->removeFormComponentValidityListener( this );
|
|
|
|
|
|
|
|
Reference< XMultiPropertySet > xModelMultiProps( getModel(), UNO_QUERY );
|
|
|
|
if ( xModelMultiProps.is() )
|
|
|
|
{
|
|
|
|
Sequence< ::rtl::OUString > aNames( 3 );
|
|
|
|
aNames[ 0 ] = PROPERTY_HELPTEXT;
|
|
|
|
aNames[ 1 ] = PROPERTY_FONT;
|
|
|
|
aNames[ 2 ] = PROPERTY_TEXTLINECOLOR;
|
|
|
|
if ( _bStart )
|
|
|
|
xModelMultiProps->addPropertiesChangeListener( aNames, this );
|
|
|
|
else
|
|
|
|
xModelMultiProps->removePropertiesChangeListener( this );
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//==================================================================
|
|
|
|
//= OControlModel
|
|
|
|
//==================================================================
|
|
|
|
ConcretInfoService OControlModel::s_aPropInfos;
|
|
|
|
DBG_NAME(OControlModel)
|
|
|
|
//------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
Sequence<sal_Int8> SAL_CALL OControlModel::getImplementationId() throw(RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
return OImplementationIds::getImplementationId(getTypes());
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
Sequence<Type> SAL_CALL OControlModel::getTypes() throw(RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2000-11-23 07:48:15 +00:00
|
|
|
Sequence<Type> aOwnTypes = _getTypes();
|
|
|
|
Reference<com::sun::star::lang::XTypeProvider> xProv;
|
2000-09-18 15:33:13 +00:00
|
|
|
|
|
|
|
if (query_aggregation(m_xAggregate, xProv))
|
|
|
|
return concatSequences(aOwnTypes, xProv->getTypes());
|
|
|
|
else
|
|
|
|
return aOwnTypes;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
Sequence<Type> OControlModel::_getTypes()
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2000-11-23 07:48:15 +00:00
|
|
|
static Sequence<Type> aTypes;
|
2000-09-18 15:33:13 +00:00
|
|
|
if (!aTypes.getLength())
|
|
|
|
{
|
|
|
|
// my two base classes
|
2000-11-23 07:48:15 +00:00
|
|
|
aTypes = concatSequences(OComponentHelper::getTypes(), OPropertySetAggregationHelper::getTypes(), OControlModel_BASE::getTypes());
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
return aTypes;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
Any SAL_CALL OControlModel::queryAggregation(const Type& _rType) throw (RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
// base class 1
|
2003-03-25 17:05:07 +00:00
|
|
|
Any aReturn(OComponentHelper::queryAggregation(_rType));
|
2000-09-18 15:33:13 +00:00
|
|
|
|
|
|
|
// base class 2
|
|
|
|
if (!aReturn.hasValue())
|
2000-11-23 07:48:15 +00:00
|
|
|
{
|
2003-03-25 17:05:07 +00:00
|
|
|
aReturn = OControlModel_BASE::queryInterface(_rType);
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2000-11-23 07:48:15 +00:00
|
|
|
// our own interfaces
|
|
|
|
if (!aReturn.hasValue())
|
|
|
|
{
|
2003-03-25 17:05:07 +00:00
|
|
|
aReturn = OPropertySetAggregationHelper::queryInterface(_rType);
|
2000-11-23 07:48:15 +00:00
|
|
|
// our aggregate
|
2002-08-01 13:57:01 +00:00
|
|
|
if (!aReturn.hasValue() && m_xAggregate.is() && !_rType.equals(::getCppuType(static_cast< Reference< XCloneable>* >(NULL))))
|
2000-11-23 07:48:15 +00:00
|
|
|
aReturn = m_xAggregate->queryAggregation(_rType);
|
|
|
|
}
|
|
|
|
}
|
2000-09-18 15:33:13 +00:00
|
|
|
return aReturn;
|
|
|
|
}
|
|
|
|
|
2001-04-02 09:28:06 +00:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void OControlModel::readHelpTextCompatibly(const staruno::Reference< stario::XObjectInputStream >& _rxInStream)
|
|
|
|
{
|
|
|
|
::rtl::OUString sHelpText;
|
2001-04-04 11:56:34 +00:00
|
|
|
::comphelper::operator>>( _rxInStream, sHelpText);
|
2001-04-02 09:28:06 +00:00
|
|
|
try
|
|
|
|
{
|
|
|
|
if (m_xAggregateSet.is())
|
|
|
|
m_xAggregateSet->setPropertyValue(PROPERTY_HELPTEXT, makeAny(sHelpText));
|
|
|
|
}
|
|
|
|
catch(const Exception&)
|
|
|
|
{
|
|
|
|
OSL_ENSURE(sal_False, "OControlModel::readHelpTextCompatibly: could not forward the property value to the aggregate!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void OControlModel::writeHelpTextCompatibly(const staruno::Reference< stario::XObjectOutputStream >& _rxOutStream)
|
|
|
|
{
|
|
|
|
::rtl::OUString sHelpText;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
if (m_xAggregateSet.is())
|
|
|
|
m_xAggregateSet->getPropertyValue(PROPERTY_HELPTEXT) >>= sHelpText;
|
|
|
|
}
|
|
|
|
catch(const Exception&)
|
|
|
|
{
|
|
|
|
OSL_ENSURE(sal_False, "OControlModel::writeHelpTextCompatibly: could not retrieve the property value from the aggregate!");
|
|
|
|
}
|
2001-04-04 11:56:34 +00:00
|
|
|
::comphelper::operator<<( _rxOutStream, sHelpText);
|
2001-04-02 09:28:06 +00:00
|
|
|
}
|
|
|
|
|
2000-09-18 15:33:13 +00:00
|
|
|
//------------------------------------------------------------------
|
|
|
|
OControlModel::OControlModel(
|
2000-11-23 07:48:15 +00:00
|
|
|
const Reference<com::sun::star::lang::XMultiServiceFactory>& _rxFactory,
|
2000-09-18 15:33:13 +00:00
|
|
|
const ::rtl::OUString& _rUnoControlModelTypeName,
|
2001-05-31 13:04:53 +00:00
|
|
|
const ::rtl::OUString& rDefault, const sal_Bool _bSetDelegator)
|
2000-09-18 15:33:13 +00:00
|
|
|
:OComponentHelper(m_aMutex)
|
|
|
|
,OPropertySetAggregationHelper(OComponentHelper::rBHelper)
|
|
|
|
,m_nTabIndex(FRM_DEFAULT_TABINDEX)
|
2000-11-23 07:48:15 +00:00
|
|
|
,m_nClassId(FormComponentType::CONTROL)
|
2000-09-18 15:33:13 +00:00
|
|
|
,m_xServiceFactory(_rxFactory)
|
|
|
|
{
|
|
|
|
DBG_CTOR(OControlModel, NULL);
|
|
|
|
if (_rUnoControlModelTypeName.getLength()) // the is a model we have to aggregate
|
|
|
|
{
|
|
|
|
increment(m_refCount);
|
|
|
|
|
|
|
|
{
|
2001-04-10 07:49:26 +00:00
|
|
|
m_xAggregate = Reference<XAggregation>(_rxFactory->createInstance(_rUnoControlModelTypeName), UNO_QUERY);
|
2000-09-18 15:33:13 +00:00
|
|
|
setAggregation(m_xAggregate);
|
|
|
|
|
2001-05-14 08:08:00 +00:00
|
|
|
if (m_xAggregateSet.is() && rDefault.getLength())
|
2001-04-10 07:49:26 +00:00
|
|
|
m_xAggregateSet->setPropertyValue(PROPERTY_DEFAULTCONTROL, makeAny(rDefault));
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
2001-05-31 13:04:53 +00:00
|
|
|
if (_bSetDelegator)
|
|
|
|
doSetDelegator();
|
2000-09-18 15:33:13 +00:00
|
|
|
|
|
|
|
// Refcount wieder bei NULL
|
2001-05-31 13:04:53 +00:00
|
|
|
decrement(m_refCount);
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-12-02 08:56:36 +00:00
|
|
|
//------------------------------------------------------------------
|
2004-05-07 15:07:05 +00:00
|
|
|
OControlModel::OControlModel( const OControlModel* _pOriginal, const Reference< XMultiServiceFactory>& _rxFactory, const sal_Bool _bCloneAggregate, const sal_Bool _bSetDelegator )
|
2002-12-02 08:56:36 +00:00
|
|
|
:OComponentHelper( m_aMutex )
|
|
|
|
,OPropertySetAggregationHelper( OComponentHelper::rBHelper )
|
|
|
|
,m_nTabIndex( FRM_DEFAULT_TABINDEX )
|
|
|
|
,m_nClassId( FormComponentType::CONTROL )
|
|
|
|
,m_xServiceFactory( _rxFactory )
|
|
|
|
{
|
|
|
|
DBG_CTOR( OControlModel, NULL );
|
|
|
|
DBG_ASSERT( _pOriginal, "OControlModel::OControlModel: invalid original!" );
|
|
|
|
|
|
|
|
// copy members
|
2002-12-12 15:13:48 +00:00
|
|
|
m_aName = _pOriginal->m_aName;
|
|
|
|
m_aTag = _pOriginal->m_aTag;
|
2002-12-02 08:56:36 +00:00
|
|
|
m_nTabIndex = _pOriginal->m_nTabIndex;
|
|
|
|
m_nClassId = _pOriginal->m_nClassId;
|
|
|
|
|
2004-05-07 15:07:05 +00:00
|
|
|
if ( _bCloneAggregate )
|
2002-12-02 08:56:36 +00:00
|
|
|
{
|
2004-05-07 15:07:05 +00:00
|
|
|
// temporarily increment refcount because of temporary references to ourself in the following
|
|
|
|
increment( m_refCount );
|
2002-12-02 08:56:36 +00:00
|
|
|
|
2004-05-07 15:07:05 +00:00
|
|
|
{
|
|
|
|
// transfer the (only, at the very moment!) ref count
|
|
|
|
m_xAggregate = createAggregateClone( _pOriginal );
|
|
|
|
|
|
|
|
// set aggregation (retrieve other direct interfaces of the aggregate)
|
|
|
|
setAggregation( m_xAggregate );
|
|
|
|
}
|
2002-12-02 08:56:36 +00:00
|
|
|
|
2004-05-07 15:07:05 +00:00
|
|
|
// set the delegator, if allowed by our derived class
|
|
|
|
if ( _bSetDelegator )
|
|
|
|
doSetDelegator();
|
2002-12-02 08:56:36 +00:00
|
|
|
|
2004-05-07 15:07:05 +00:00
|
|
|
// decrement ref count
|
|
|
|
decrement( m_refCount );
|
|
|
|
}
|
2002-12-02 08:56:36 +00:00
|
|
|
}
|
|
|
|
|
2000-09-18 15:33:13 +00:00
|
|
|
//------------------------------------------------------------------
|
|
|
|
OControlModel::~OControlModel()
|
|
|
|
{
|
|
|
|
// release the aggregate
|
2003-10-21 07:57:42 +00:00
|
|
|
doResetDelegator( );
|
|
|
|
|
|
|
|
DBG_DTOR(OControlModel, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
void OControlModel::clonedFrom( const OControlModel* _pOriginal )
|
|
|
|
{
|
|
|
|
// nothing to do in this base class
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
2001-05-31 13:04:53 +00:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void OControlModel::doResetDelegator()
|
|
|
|
{
|
|
|
|
if (m_xAggregate.is())
|
|
|
|
m_xAggregate->setDelegator(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void OControlModel::doSetDelegator()
|
|
|
|
{
|
|
|
|
increment(m_refCount);
|
|
|
|
if (m_xAggregate.is())
|
|
|
|
{
|
|
|
|
m_xAggregate->setDelegator(static_cast<XWeak*>(this));
|
|
|
|
}
|
|
|
|
decrement(m_refCount);
|
|
|
|
}
|
|
|
|
|
2004-04-13 10:13:27 +00:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void OControlModel::ensureAlive() SAL_THROW( ( DisposedException ) )
|
|
|
|
{
|
|
|
|
if ( OComponentHelper::rBHelper.bDisposed || OComponentHelper::rBHelper.bInDispose )
|
|
|
|
throw DisposedException();
|
|
|
|
}
|
|
|
|
|
2000-09-18 15:33:13 +00:00
|
|
|
// XChild
|
2002-03-04 12:59:21 +00:00
|
|
|
//------------------------------------------------------------------------------
|
2003-05-19 12:08:37 +00:00
|
|
|
InterfaceRef SAL_CALL OControlModel::getParent() throw(RuntimeException)
|
2002-03-04 12:59:21 +00:00
|
|
|
{
|
|
|
|
return m_xParent;
|
|
|
|
}
|
|
|
|
|
2000-09-18 15:33:13 +00:00
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
void SAL_CALL OControlModel::setParent(const InterfaceRef& _rxParent) throw(com::sun::star::lang::NoSupportException, RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
osl::MutexGuard aGuard(m_aMutex);
|
|
|
|
|
2002-10-02 13:46:57 +00:00
|
|
|
Reference<XComponent> xComp(m_xParent, UNO_QUERY);
|
2000-09-18 15:33:13 +00:00
|
|
|
if (xComp.is())
|
2001-05-31 13:04:53 +00:00
|
|
|
xComp->removeEventListener(static_cast<XPropertiesChangeListener*>(this));
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2002-10-02 13:46:57 +00:00
|
|
|
{
|
|
|
|
xComp = xComp.query( _rxParent );
|
2004-05-07 15:07:05 +00:00
|
|
|
RTL_LOGFILE_CONTEXT( aLogger, "OControlModel::setParent::logOnEventListener" );
|
2002-10-02 13:46:57 +00:00
|
|
|
if ( xComp.is() )
|
|
|
|
xComp->addEventListener(static_cast<XPropertiesChangeListener*>(this));
|
|
|
|
}
|
|
|
|
|
2000-09-18 15:33:13 +00:00
|
|
|
m_xParent = _rxParent;
|
|
|
|
}
|
|
|
|
|
|
|
|
// XNamed
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
::rtl::OUString SAL_CALL OControlModel::getName() throw(RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
::rtl::OUString aReturn;
|
|
|
|
OPropertySetHelper::getFastPropertyValue(PROPERTY_ID_NAME) >>= aReturn;
|
|
|
|
return aReturn;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
void SAL_CALL OControlModel::setName(const ::rtl::OUString& _rName) throw(RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2000-11-23 07:48:15 +00:00
|
|
|
setFastPropertyValue(PROPERTY_ID_NAME, makeAny(_rName));
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// XServiceInfo
|
|
|
|
//------------------------------------------------------------------------------
|
2003-05-19 12:08:37 +00:00
|
|
|
sal_Bool SAL_CALL OControlModel::supportsService(const rtl::OUString& _rServiceName) throw ( RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2000-11-23 07:48:15 +00:00
|
|
|
Sequence<rtl::OUString> aSupported = getSupportedServiceNames();
|
2000-09-18 15:33:13 +00:00
|
|
|
const rtl::OUString* pSupported = aSupported.getConstArray();
|
|
|
|
for (sal_Int32 i=0; i<aSupported.getLength(); ++i, ++pSupported)
|
|
|
|
if (pSupported->equals(_rServiceName))
|
|
|
|
return sal_True;
|
|
|
|
return sal_False;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2003-12-11 11:28:53 +00:00
|
|
|
Sequence< ::rtl::OUString > OControlModel::getAggregateServiceNames()
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2003-12-11 11:28:53 +00:00
|
|
|
Sequence< ::rtl::OUString > aAggServices;
|
|
|
|
Reference< XServiceInfo > xInfo;
|
|
|
|
if ( query_aggregation( m_xAggregate, xInfo ) )
|
|
|
|
aAggServices = xInfo->getSupportedServiceNames();
|
|
|
|
return aAggServices;
|
|
|
|
}
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2003-12-11 11:28:53 +00:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
Sequence<rtl::OUString> SAL_CALL OControlModel::getSupportedServiceNames() throw(RuntimeException)
|
|
|
|
{
|
|
|
|
return ::comphelper::concatSequences(
|
|
|
|
getAggregateServiceNames(),
|
|
|
|
getSupportedServiceNames_Static()
|
|
|
|
);
|
|
|
|
}
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2003-12-11 11:28:53 +00:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
Sequence< ::rtl::OUString > SAL_CALL OControlModel::getSupportedServiceNames_Static() throw( RuntimeException )
|
|
|
|
{
|
|
|
|
Sequence< ::rtl::OUString > aServiceNames( 2 );
|
|
|
|
aServiceNames[ 0 ] = FRM_SUN_FORMCOMPONENT;
|
|
|
|
aServiceNames[ 1 ] = ::rtl::OUString::createFromAscii( "com.sun.star.form.FormControlModel" );
|
|
|
|
return aServiceNames;
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// XEventListener
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
void SAL_CALL OControlModel::disposing(const com::sun::star::lang::EventObject& _rSource) throw (RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
// release the parent
|
|
|
|
if (_rSource.Source == m_xParent)
|
|
|
|
{
|
|
|
|
osl::MutexGuard aGuard(m_aMutex);
|
|
|
|
m_xParent = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2001-05-31 13:04:53 +00:00
|
|
|
Reference<com::sun::star::lang::XEventListener> xEvtLst;
|
2000-09-18 15:33:13 +00:00
|
|
|
if (query_aggregation(m_xAggregate, xEvtLst))
|
|
|
|
{
|
|
|
|
osl::MutexGuard aGuard(m_aMutex);
|
|
|
|
xEvtLst->disposing(_rSource);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// OComponentHelper
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void OControlModel::disposing()
|
|
|
|
{
|
|
|
|
OPropertySetAggregationHelper::disposing();
|
|
|
|
|
2001-05-31 13:04:53 +00:00
|
|
|
Reference<com::sun::star::lang::XComponent> xComp;
|
2000-09-18 15:33:13 +00:00
|
|
|
if (query_aggregation(m_xAggregate, xComp))
|
|
|
|
xComp->dispose();
|
|
|
|
|
2001-05-31 13:04:53 +00:00
|
|
|
setParent(Reference<XFormComponent>());
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
2004-05-07 15:07:05 +00:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void OControlModel::writeAggregate( const Reference< XObjectOutputStream >& _rxOutStream ) const
|
|
|
|
{
|
|
|
|
Reference< XPersistObject > xPersist;
|
|
|
|
if ( query_aggregation( m_xAggregate, xPersist ) )
|
|
|
|
xPersist->write( _rxOutStream );
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void OControlModel::readAggregate( const Reference< XObjectInputStream >& _rxInStream )
|
|
|
|
{
|
|
|
|
Reference< XPersistObject > xPersist;
|
|
|
|
if ( query_aggregation( m_xAggregate, xPersist ) )
|
|
|
|
xPersist->read( _rxInStream );
|
|
|
|
}
|
|
|
|
|
2000-09-18 15:33:13 +00:00
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
void SAL_CALL OControlModel::write(const Reference<stario::XObjectOutputStream>& _rxOutStream)
|
|
|
|
throw(stario::IOException, RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
osl::MutexGuard aGuard(m_aMutex);
|
|
|
|
|
|
|
|
// 1. Schreiben des UnoControls
|
2001-12-20 15:16:37 +00:00
|
|
|
Reference<stario::XMarkableStream> xMark(_rxOutStream, UNO_QUERY);
|
|
|
|
if ( !xMark.is() )
|
|
|
|
{
|
|
|
|
throw IOException(
|
|
|
|
FRM_RES_STRING( RID_STR_INVALIDSTREAM ),
|
|
|
|
static_cast< ::cppu::OWeakObject* >( this )
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2000-09-18 15:33:13 +00:00
|
|
|
sal_Int32 nMark = xMark->createMark();
|
|
|
|
sal_Int32 nLen = 0;
|
|
|
|
|
|
|
|
_rxOutStream->writeLong(nLen);
|
|
|
|
|
2004-05-07 15:07:05 +00:00
|
|
|
writeAggregate( _rxOutStream );
|
2000-09-18 15:33:13 +00:00
|
|
|
|
|
|
|
// feststellen der Laenge
|
|
|
|
nLen = xMark->offsetToMark(nMark) - 4;
|
|
|
|
xMark->jumpToMark(nMark);
|
|
|
|
_rxOutStream->writeLong(nLen);
|
|
|
|
xMark->jumpToFurthest();
|
|
|
|
xMark->deleteMark(nMark);
|
|
|
|
|
|
|
|
// 2. Schreiben einer VersionsNummer
|
|
|
|
_rxOutStream->writeShort(0x0003);
|
|
|
|
|
|
|
|
// 3. Schreiben der allgemeinen Properties
|
2001-04-04 11:56:34 +00:00
|
|
|
::comphelper::operator<<( _rxOutStream, m_aName);
|
2000-09-18 15:33:13 +00:00
|
|
|
_rxOutStream->writeShort(m_nTabIndex);
|
2001-04-04 11:56:34 +00:00
|
|
|
::comphelper::operator<<( _rxOutStream, m_aTag); // 3. version
|
2000-09-18 15:33:13 +00:00
|
|
|
|
|
|
|
// !!! IMPORTANT NOTE !!!
|
|
|
|
// don't write any new members here : this wouldn't be compatible with older versions, as OControlModel
|
|
|
|
// is a base class which is called in derived classes "read" method. So if you increment the version
|
|
|
|
// and write new stuff, older office versions will read this in the _derived_ classes, which may result
|
|
|
|
// in anything from data loss to crash.
|
|
|
|
// !!! EOIN !!!
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
void OControlModel::read(const Reference<stario::XObjectInputStream>& InStream) throw (::com::sun::star::io::IOException, RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
osl::MutexGuard aGuard(m_aMutex);
|
|
|
|
|
2001-12-20 15:16:37 +00:00
|
|
|
Reference<stario::XMarkableStream> xMark(InStream, UNO_QUERY);
|
|
|
|
if ( !xMark.is() )
|
|
|
|
{
|
|
|
|
throw IOException(
|
|
|
|
FRM_RES_STRING( RID_STR_INVALIDSTREAM ),
|
|
|
|
static_cast< ::cppu::OWeakObject* >( this )
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2000-09-18 15:33:13 +00:00
|
|
|
// 1. Lesen des UnoControls
|
|
|
|
sal_Int32 nLen = InStream->readLong();
|
|
|
|
if (nLen)
|
|
|
|
{
|
|
|
|
sal_Int32 nMark = xMark->createMark();
|
|
|
|
|
2004-05-07 15:07:05 +00:00
|
|
|
readAggregate( InStream );
|
2000-09-18 15:33:13 +00:00
|
|
|
|
|
|
|
xMark->jumpToMark(nMark);
|
|
|
|
InStream->skipBytes(nLen);
|
|
|
|
xMark->deleteMark(nMark);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 2. Lesen des Versionsnummer
|
|
|
|
UINT16 nVersion = InStream->readShort();
|
|
|
|
|
|
|
|
// 3. Lesen der allgemeinen Properties
|
2001-04-04 11:56:34 +00:00
|
|
|
::comphelper::operator>>( InStream, m_aName);
|
2000-09-18 15:33:13 +00:00
|
|
|
m_nTabIndex = InStream->readShort();
|
|
|
|
|
|
|
|
if (nVersion > 0x0002)
|
2001-04-04 11:56:34 +00:00
|
|
|
::comphelper::operator>>( InStream, m_aTag);
|
2000-09-18 15:33:13 +00:00
|
|
|
|
|
|
|
// we had a version where we wrote the help text
|
|
|
|
if (nVersion == 0x0004)
|
2001-04-02 09:28:06 +00:00
|
|
|
readHelpTextCompatibly(InStream);
|
2000-09-18 15:33:13 +00:00
|
|
|
|
|
|
|
DBG_ASSERT(nVersion < 5, "OControlModel::read : suspicious version number !");
|
|
|
|
// 4 was the version where we wrote the help text
|
|
|
|
// later versions shouldn't exist (see write for a detailed comment)
|
|
|
|
}
|
|
|
|
|
2001-08-24 07:53:48 +00:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
PropertyState OControlModel::getPropertyStateByHandle( sal_Int32 _nHandle )
|
|
|
|
{
|
|
|
|
Any aDefault = getPropertyDefaultByHandle( _nHandle );
|
|
|
|
Any aCurrent;
|
|
|
|
getFastPropertyValue( aCurrent, _nHandle );
|
|
|
|
|
|
|
|
if ( ::comphelper::compare( aDefault, aCurrent ) )
|
|
|
|
return PropertyState_DEFAULT_VALUE;
|
|
|
|
|
|
|
|
return PropertyState_DIRECT_VALUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void OControlModel::setPropertyToDefaultByHandle( sal_Int32 _nHandle)
|
|
|
|
{
|
|
|
|
Any aDefault = getPropertyDefaultByHandle( _nHandle );
|
|
|
|
|
|
|
|
Any aConvertedValue, aOldValue;
|
|
|
|
if ( convertFastPropertyValue( aConvertedValue, aOldValue, _nHandle, aDefault ) )
|
|
|
|
{
|
|
|
|
setFastPropertyValue_NoBroadcast( _nHandle, aConvertedValue );
|
|
|
|
// TODO: fire the property change
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
Any OControlModel::getPropertyDefaultByHandle( sal_Int32 _nHandle ) const
|
|
|
|
{
|
|
|
|
Any aReturn;
|
|
|
|
switch ( _nHandle )
|
|
|
|
{
|
|
|
|
case PROPERTY_ID_NAME:
|
|
|
|
case PROPERTY_ID_TAG:
|
|
|
|
aReturn <<= ::rtl::OUString();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PROPERTY_ID_CLASSID:
|
|
|
|
aReturn <<= (sal_Int16)FormComponentType::CONTROL;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PROPERTY_ID_TABINDEX:
|
|
|
|
aReturn <<= (sal_Int16)FRM_DEFAULT_TABINDEX;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return aReturn;
|
|
|
|
}
|
|
|
|
|
2000-09-18 15:33:13 +00:00
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
void OControlModel::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
switch (nHandle)
|
|
|
|
{
|
|
|
|
case PROPERTY_ID_NAME:
|
|
|
|
rValue <<= m_aName;
|
|
|
|
break;
|
|
|
|
case PROPERTY_ID_TAG:
|
|
|
|
rValue <<= m_aTag;
|
|
|
|
break;
|
|
|
|
case PROPERTY_ID_CLASSID:
|
|
|
|
rValue <<= m_nClassId;
|
|
|
|
break;
|
|
|
|
case PROPERTY_ID_TABINDEX:
|
|
|
|
rValue <<= m_nTabIndex;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
OPropertySetAggregationHelper::getFastPropertyValue(rValue, nHandle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
sal_Bool OControlModel::convertFastPropertyValue(
|
2000-11-23 07:48:15 +00:00
|
|
|
Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue)
|
2000-10-24 12:07:20 +00:00
|
|
|
throw (com::sun::star::lang::IllegalArgumentException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
sal_Bool bModified(sal_False);
|
|
|
|
switch (_nHandle)
|
|
|
|
{
|
|
|
|
case PROPERTY_ID_NAME:
|
|
|
|
bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_aName);
|
|
|
|
break;
|
|
|
|
case PROPERTY_ID_TAG:
|
|
|
|
bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_aTag);
|
|
|
|
break;
|
|
|
|
case PROPERTY_ID_TABINDEX:
|
|
|
|
bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_nTabIndex);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return bModified;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
void OControlModel::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle, const Any& _rValue)
|
|
|
|
throw (Exception)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
switch (_nHandle)
|
|
|
|
{
|
|
|
|
case PROPERTY_ID_NAME:
|
|
|
|
DBG_ASSERT(_rValue.getValueType() == getCppuType((const ::rtl::OUString*)NULL),
|
|
|
|
"OControlModel::setFastPropertyValue_NoBroadcast : invalid type" );
|
|
|
|
_rValue >>= m_aName;
|
|
|
|
break;
|
|
|
|
case PROPERTY_ID_TAG:
|
|
|
|
DBG_ASSERT(_rValue.getValueType() == getCppuType((const ::rtl::OUString*)NULL),
|
|
|
|
"OControlModel::setFastPropertyValue_NoBroadcast : invalid type" );
|
|
|
|
_rValue >>= m_aTag;
|
|
|
|
break;
|
|
|
|
case PROPERTY_ID_TABINDEX:
|
|
|
|
DBG_ASSERT(_rValue.getValueType() == getCppuType((const sal_Int16*)NULL),
|
|
|
|
"OControlModel::setFastPropertyValue_NoBroadcast : invalid type" );
|
|
|
|
_rValue >>= m_nTabIndex;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-04-02 09:52:14 +00:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void OControlModel::fillProperties( Sequence< Property >& /* [out] */ _rProps, Sequence< Property >& /* [out] */ _rAggregateProps ) const
|
|
|
|
{
|
|
|
|
BEGIN_DESCRIBE_AGGREGATION_PROPERTIES( 3, m_xAggregateSet )
|
|
|
|
DECL_PROP2(CLASSID, sal_Int16, READONLY, TRANSIENT);
|
|
|
|
DECL_PROP1(NAME, ::rtl::OUString, BOUND);
|
|
|
|
DECL_PROP1(TAG, ::rtl::OUString, BOUND);
|
|
|
|
END_DESCRIBE_PROPERTIES()
|
|
|
|
}
|
|
|
|
|
2000-09-18 15:33:13 +00:00
|
|
|
//==================================================================
|
|
|
|
//= OBoundControlModel
|
|
|
|
//==================================================================
|
|
|
|
DBG_NAME(frm_OBoundControlModel);
|
|
|
|
//------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
Any SAL_CALL OBoundControlModel::queryAggregation( const Type& _rType ) throw (RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2003-03-25 17:05:07 +00:00
|
|
|
Any aReturn( OControlModel::queryAggregation(_rType) );
|
2000-09-18 15:33:13 +00:00
|
|
|
if (!aReturn.hasValue())
|
2000-11-23 07:48:15 +00:00
|
|
|
{
|
|
|
|
aReturn = OBoundControlModel_BASE1::queryInterface(_rType);
|
2003-10-21 07:57:42 +00:00
|
|
|
|
|
|
|
if ( !aReturn.hasValue() && m_bCommitable )
|
2004-04-02 09:52:14 +00:00
|
|
|
aReturn = OBoundControlModel_COMMITTING::queryInterface( _rType );
|
2003-10-21 07:57:42 +00:00
|
|
|
|
|
|
|
if ( !aReturn.hasValue() && m_bSupportsExternalBinding )
|
2004-04-02 09:52:14 +00:00
|
|
|
aReturn = OBoundControlModel_BINDING::queryInterface( _rType );
|
|
|
|
|
|
|
|
if ( !aReturn.hasValue() && m_bSupportsValidation )
|
|
|
|
aReturn = OBoundControlModel_VALIDATION::queryInterface( _rType );
|
2000-11-23 07:48:15 +00:00
|
|
|
}
|
2000-09-18 15:33:13 +00:00
|
|
|
|
|
|
|
return aReturn;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
OBoundControlModel::OBoundControlModel(
|
2004-04-02 09:52:14 +00:00
|
|
|
const Reference< XMultiServiceFactory>& _rxFactory,
|
|
|
|
const ::rtl::OUString& _rUnoControlModelTypeName, const ::rtl::OUString& _rDefault,
|
|
|
|
const sal_Bool _bCommitable, const sal_Bool _bSupportExternalBinding, const sal_Bool _bSupportsValidation )
|
2003-10-21 07:57:42 +00:00
|
|
|
:OControlModel( _rxFactory, _rUnoControlModelTypeName, _rDefault, sal_False )
|
|
|
|
,OPropertyChangeListener( m_aMutex )
|
2002-12-02 08:56:36 +00:00
|
|
|
,m_aUpdateListeners(m_aMutex)
|
|
|
|
,m_aResetListeners(m_aMutex)
|
2004-04-02 09:52:14 +00:00
|
|
|
,m_pFormComponentListeners( new OFormComponentListeners( m_aMutex ) )
|
2002-12-02 08:56:36 +00:00
|
|
|
,m_bLoaded(sal_False)
|
|
|
|
,m_bRequired(sal_False)
|
|
|
|
,m_bCommitable(_bCommitable)
|
2003-10-21 07:57:42 +00:00
|
|
|
,m_bSupportsExternalBinding( _bSupportExternalBinding )
|
2004-04-02 09:52:14 +00:00
|
|
|
,m_bSupportsValidation( _bSupportsValidation )
|
2002-12-02 08:56:36 +00:00
|
|
|
,m_aLabelServiceName(FRM_SUN_COMPONENT_FIXEDTEXT)
|
|
|
|
,m_bForwardValueChanges(sal_True)
|
2003-10-21 07:57:42 +00:00
|
|
|
,m_bLoadListening( sal_False )
|
|
|
|
,m_nValuePropertyAggregateHandle( -1 )
|
|
|
|
,m_pAggPropMultiplexer( NULL )
|
|
|
|
,m_bSettingAggregateState( sal_False )
|
2004-04-02 09:52:14 +00:00
|
|
|
,m_bIsCurrentValueValid( sal_True )
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
DBG_CTOR(frm_OBoundControlModel, NULL);
|
2003-10-21 07:57:42 +00:00
|
|
|
|
|
|
|
// start property listening at the aggregate
|
|
|
|
implInitAggMultiplexer( );
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
2002-12-02 08:56:36 +00:00
|
|
|
//------------------------------------------------------------------
|
|
|
|
OBoundControlModel::OBoundControlModel(
|
2003-10-21 07:57:42 +00:00
|
|
|
const OBoundControlModel* _pOriginal, const Reference< XMultiServiceFactory>& _rxFactory )
|
2004-05-07 15:07:05 +00:00
|
|
|
:OControlModel( _pOriginal, _rxFactory, sal_True, sal_False )
|
2003-10-21 07:57:42 +00:00
|
|
|
,OPropertyChangeListener( m_aMutex )
|
2002-12-02 08:56:36 +00:00
|
|
|
,m_aUpdateListeners( m_aMutex )
|
|
|
|
,m_aResetListeners( m_aMutex )
|
2004-04-02 09:52:14 +00:00
|
|
|
,m_pFormComponentListeners( new OFormComponentListeners( m_aMutex ) )
|
2002-12-02 08:56:36 +00:00
|
|
|
,m_bLoaded( sal_False )
|
|
|
|
,m_bRequired( sal_False )
|
2003-10-21 07:57:42 +00:00
|
|
|
,m_bCommitable( _pOriginal->m_bCommitable )
|
|
|
|
,m_bSupportsExternalBinding( _pOriginal->m_bSupportsExternalBinding )
|
2004-04-02 09:52:14 +00:00
|
|
|
,m_bSupportsValidation( _pOriginal->m_bSupportsValidation )
|
2002-12-02 08:56:36 +00:00
|
|
|
,m_bForwardValueChanges( sal_True )
|
2003-10-21 07:57:42 +00:00
|
|
|
,m_bLoadListening( sal_False )
|
|
|
|
,m_nValuePropertyAggregateHandle( _pOriginal->m_nValuePropertyAggregateHandle )
|
|
|
|
,m_pAggPropMultiplexer( NULL )
|
|
|
|
,m_bSettingAggregateState( sal_False )
|
2004-04-02 09:52:14 +00:00
|
|
|
,m_xValidator( _pOriginal->m_xValidator )
|
|
|
|
,m_bIsCurrentValueValid( _pOriginal->m_bIsCurrentValueValid )
|
2002-12-02 08:56:36 +00:00
|
|
|
{
|
|
|
|
DBG_CTOR(frm_OBoundControlModel, NULL);
|
|
|
|
|
2003-10-21 07:57:42 +00:00
|
|
|
// start property listening at the aggregate
|
|
|
|
implInitAggMultiplexer( );
|
|
|
|
|
2002-12-02 08:56:36 +00:00
|
|
|
m_aLabelServiceName = _pOriginal->m_aLabelServiceName;
|
2003-10-21 07:57:42 +00:00
|
|
|
m_sValuePropertyName = _pOriginal->m_sValuePropertyName;
|
|
|
|
m_nValuePropertyAggregateHandle = _pOriginal->m_nValuePropertyAggregateHandle;
|
2002-12-02 08:56:36 +00:00
|
|
|
m_aControlSource = _pOriginal->m_aControlSource;
|
2003-10-21 07:57:42 +00:00
|
|
|
// m_xLabelControl, though being a property, is not to be cloned, not even the reference will be transfered.
|
2002-12-02 08:56:36 +00:00
|
|
|
// (the former should be clear - a clone of the object we're only referencing does not make sense)
|
|
|
|
// (the second would violate the restriction for label controls that they're part of the
|
|
|
|
// same form component hierarchy - we ourself are no part, yet, so we can't have a label control)
|
2003-10-21 07:57:42 +00:00
|
|
|
|
|
|
|
// start listening for changes at the value property
|
|
|
|
implInitValuePropertyListening( );
|
2002-12-02 08:56:36 +00:00
|
|
|
}
|
|
|
|
|
2000-09-18 15:33:13 +00:00
|
|
|
//------------------------------------------------------------------
|
|
|
|
OBoundControlModel::~OBoundControlModel()
|
|
|
|
{
|
2003-10-21 07:57:42 +00:00
|
|
|
if ( !OComponentHelper::rBHelper.bDisposed )
|
|
|
|
{
|
|
|
|
acquire();
|
|
|
|
dispose();
|
|
|
|
}
|
|
|
|
|
|
|
|
doResetDelegator( );
|
|
|
|
|
|
|
|
OSL_ENSURE( m_pAggPropMultiplexer, "OBoundControlModel::~OBoundControlModel: what about my property multiplexer?" );
|
|
|
|
if ( m_pAggPropMultiplexer )
|
|
|
|
{
|
|
|
|
m_pAggPropMultiplexer->dispose();
|
|
|
|
m_pAggPropMultiplexer->release();
|
|
|
|
m_pAggPropMultiplexer = NULL;
|
|
|
|
}
|
|
|
|
|
2000-09-18 15:33:13 +00:00
|
|
|
DBG_DTOR(frm_OBoundControlModel, NULL);
|
|
|
|
}
|
|
|
|
|
2003-10-21 07:57:42 +00:00
|
|
|
//------------------------------------------------------------------
|
|
|
|
void OBoundControlModel::clonedFrom( const OControlModel* _pOriginal )
|
|
|
|
{
|
|
|
|
const OBoundControlModel* pBoundOriginal = static_cast< const OBoundControlModel* >( _pOriginal );
|
|
|
|
// the value binding can be handled as if somebody called setValueBinding here
|
|
|
|
// By definition, bindings can be share between bindables
|
|
|
|
if ( pBoundOriginal && pBoundOriginal->m_xExternalBinding.is() )
|
|
|
|
setValueBinding( pBoundOriginal->m_xExternalBinding );
|
|
|
|
}
|
|
|
|
|
2000-09-18 15:33:13 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
2003-10-21 07:57:42 +00:00
|
|
|
void OBoundControlModel::implInitAggMultiplexer( )
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2003-10-21 07:57:42 +00:00
|
|
|
increment( m_refCount );
|
|
|
|
if ( m_xAggregateSet.is() )
|
|
|
|
{
|
|
|
|
m_pAggPropMultiplexer = new OPropertyChangeMultiplexer( this, m_xAggregateSet, sal_False );
|
|
|
|
m_pAggPropMultiplexer->acquire();
|
|
|
|
}
|
|
|
|
decrement( m_refCount );
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2003-10-21 07:57:42 +00:00
|
|
|
doSetDelegator();
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void OBoundControlModel::implInitValuePropertyListening( ) const
|
|
|
|
{
|
|
|
|
// start listening for changes at the value property
|
2004-04-02 09:52:14 +00:00
|
|
|
// There are three pre-requisites for this to be done:
|
2003-10-21 07:57:42 +00:00
|
|
|
// 1. We support external value bindings. In this case, the changes in the control value need to
|
|
|
|
// be propagated to the external binding immediately when they happen
|
2004-04-02 09:52:14 +00:00
|
|
|
// 2. We support external validation. In this case, we need to listen for changes in the value
|
|
|
|
// property, since we need to revalidate then.
|
|
|
|
// 3. We are not committable. In this case, changes in the control value need to be propagated
|
2003-10-21 07:57:42 +00:00
|
|
|
// to the database column immediately when they happen.
|
2004-04-02 09:52:14 +00:00
|
|
|
if ( m_bSupportsExternalBinding || m_bSupportsValidation || !m_bCommitable )
|
2003-10-21 07:57:42 +00:00
|
|
|
{
|
|
|
|
OSL_ENSURE( m_pAggPropMultiplexer, "OBoundControlModel::implInitValuePropertyListening: no multiplexer!" );
|
|
|
|
if ( m_pAggPropMultiplexer && m_sValuePropertyName.getLength() )
|
|
|
|
m_pAggPropMultiplexer->addProperty( m_sValuePropertyName );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void OBoundControlModel::initValueProperty( const ::rtl::OUString& _rValuePropertyName, sal_Int32 _nValuePropertyExternalHandle )
|
|
|
|
{
|
|
|
|
OSL_PRECOND( !m_sValuePropertyName.getLength() && -1 == m_nValuePropertyAggregateHandle,
|
|
|
|
"OBoundControlModel::initValueProperty: already called before!" );
|
|
|
|
OSL_ENSURE( _rValuePropertyName.getLength(), "OBoundControlModel::initValueProperty: invalid property name!" );
|
|
|
|
OSL_ENSURE( _nValuePropertyExternalHandle != -1, "OBoundControlModel::initValueProperty: invalid property handle!" );
|
|
|
|
|
|
|
|
m_sValuePropertyName = _rValuePropertyName;
|
|
|
|
m_nValuePropertyAggregateHandle = getOriginalHandle( _nValuePropertyExternalHandle );
|
|
|
|
OSL_ENSURE( m_nValuePropertyAggregateHandle != -1, "OBoundControlModel::initValueProperty: unable to find the original handle!" );
|
|
|
|
|
|
|
|
// start listening for changes at the value property
|
|
|
|
implInitValuePropertyListening( );
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void OBoundControlModel::suspendValueListening( )
|
|
|
|
{
|
|
|
|
OSL_PRECOND( m_sValuePropertyName.getLength(), "OBoundControlModel::suspendValueListening: don't have a value property!" );
|
|
|
|
OSL_PRECOND( m_pAggPropMultiplexer, "OBoundControlModel::suspendValueListening: I *am* not listening!" );
|
|
|
|
|
|
|
|
if ( m_pAggPropMultiplexer )
|
|
|
|
m_pAggPropMultiplexer->lock();
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void OBoundControlModel::resumeValueListening( )
|
|
|
|
{
|
|
|
|
OSL_PRECOND( m_sValuePropertyName.getLength(), "OBoundControlModel::resumeValueListening: don't have a value property!" );
|
|
|
|
OSL_PRECOND( m_pAggPropMultiplexer, "OBoundControlModel::resumeValueListening: I *am* not listening at all!" );
|
|
|
|
OSL_PRECOND( !m_pAggPropMultiplexer || m_pAggPropMultiplexer->locked(), "OBoundControlModel::resumeValueListening: listening not suspended currently!" );
|
|
|
|
|
|
|
|
if ( m_pAggPropMultiplexer )
|
|
|
|
m_pAggPropMultiplexer->unlock();
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
template< class T >
|
|
|
|
void appendSequence( Sequence< T >& _rInOut, const Sequence< T >& _rAppend )
|
|
|
|
{
|
|
|
|
sal_Int32 nLengthBefore = _rInOut.getLength();
|
|
|
|
sal_Int32 nLengthAppend = _rAppend.getLength();
|
|
|
|
_rInOut.realloc( nLengthBefore + nLengthAppend );
|
|
|
|
::std::copy(
|
|
|
|
_rAppend.getConstArray(),
|
|
|
|
_rAppend.getConstArray() + nLengthAppend,
|
|
|
|
_rInOut.getArray() + nLengthBefore
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
Sequence< Type > OBoundControlModel::_getTypes()
|
|
|
|
{
|
|
|
|
Sequence< Type > aTypes( concatSequences(
|
|
|
|
OControlModel::_getTypes(),
|
|
|
|
OBoundControlModel_BASE1::getTypes()
|
|
|
|
) );
|
|
|
|
|
|
|
|
if ( m_bCommitable )
|
2004-04-02 09:52:14 +00:00
|
|
|
appendSequence( aTypes, OBoundControlModel_COMMITTING::getTypes() );
|
2003-10-21 07:57:42 +00:00
|
|
|
|
|
|
|
if ( m_bSupportsExternalBinding )
|
2004-04-02 09:52:14 +00:00
|
|
|
appendSequence( aTypes, OBoundControlModel_BINDING::getTypes() );
|
|
|
|
|
|
|
|
if ( m_bSupportsValidation )
|
|
|
|
appendSequence( aTypes, OBoundControlModel_VALIDATION::getTypes() );
|
2003-10-21 07:57:42 +00:00
|
|
|
|
|
|
|
return aTypes;
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// OComponentHelper
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void OBoundControlModel::disposing()
|
|
|
|
{
|
|
|
|
OControlModel::disposing();
|
|
|
|
|
2004-04-02 09:52:14 +00:00
|
|
|
::osl::ClearableMutexGuard aGuard(m_aMutex);
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2003-10-21 07:57:42 +00:00
|
|
|
if ( m_pAggPropMultiplexer )
|
|
|
|
m_pAggPropMultiplexer->dispose();
|
|
|
|
|
|
|
|
// notify all our listeners
|
|
|
|
com::sun::star::lang::EventObject aEvt( static_cast< XWeak* >( this ) );
|
|
|
|
m_aResetListeners.disposeAndClear( aEvt );
|
|
|
|
m_aUpdateListeners.disposeAndClear( aEvt );
|
|
|
|
|
|
|
|
// disconnect from our database column
|
|
|
|
// TODO: could we replace the following 5 lines with a call to disconnectDatabaseColumn?
|
|
|
|
// The only more thing which it does is calling onDisconnectedDbColumn - could this
|
|
|
|
// cause trouble? At least when we continue to call OControlModel::disposing before, it *may*.
|
|
|
|
if ( m_xField.is() )
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2003-10-21 07:57:42 +00:00
|
|
|
m_xField->removePropertyChangeListener( PROPERTY_VALUE, this );
|
2000-09-18 15:33:13 +00:00
|
|
|
resetField();
|
|
|
|
}
|
|
|
|
m_xCursor = NULL;
|
|
|
|
|
2004-04-02 09:52:14 +00:00
|
|
|
Reference< XComponent > xComp( m_xLabelControl, UNO_QUERY );
|
|
|
|
if ( xComp.is() )
|
|
|
|
xComp->removeEventListener(static_cast< XEventListener* >( static_cast< XPropertyChangeListener* >( this ) ) );
|
|
|
|
|
2003-10-21 07:57:42 +00:00
|
|
|
// disconnect from our external value binding
|
|
|
|
if ( hasExternalValueBinding() )
|
|
|
|
disconnectExternalValueBinding();
|
|
|
|
|
2004-04-02 09:52:14 +00:00
|
|
|
// dito for the validator
|
|
|
|
if ( hasValidator() )
|
|
|
|
disconnectValidator( );
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2003-10-21 07:57:42 +00:00
|
|
|
void OBoundControlModel::_propertyChanged( const PropertyChangeEvent& _rEvt ) throw ( RuntimeException )
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2004-04-02 09:52:14 +00:00
|
|
|
::osl::ClearableMutexGuard aGuard( m_aMutex );
|
2003-10-21 07:57:42 +00:00
|
|
|
|
|
|
|
OSL_ENSURE( _rEvt.PropertyName == m_sValuePropertyName,
|
|
|
|
"OBoundControlModel::_propertyChanged: where did this come from (1)?" );
|
|
|
|
OSL_ENSURE( m_pAggPropMultiplexer && !m_pAggPropMultiplexer->locked(),
|
|
|
|
"OBoundControlModel::_propertyChanged: where did this come from (2)?" );
|
|
|
|
|
|
|
|
if ( _rEvt.PropertyName == m_sValuePropertyName )
|
2004-04-02 09:52:14 +00:00
|
|
|
{ // our control value changed
|
|
|
|
|
|
|
|
if ( !m_bSettingAggregateState )
|
|
|
|
{ // not caused by ourself
|
|
|
|
if ( hasExternalValueBinding() )
|
|
|
|
{ // the control value changed, while we have an external value binding
|
|
|
|
// -> forward the value to it
|
|
|
|
transferControlValueToExternal( );
|
|
|
|
}
|
|
|
|
else if ( !m_bCommitable && m_xColumnUpdate.is() )
|
|
|
|
{ // the control value changed, while we have are bound to a database column,
|
|
|
|
// but not committable (which means changes in the control have to be reflected to
|
|
|
|
// the underlying database column immediately)
|
|
|
|
// -> forward the value to the database column
|
|
|
|
commitControlValueToDbColumn( false );
|
|
|
|
}
|
2003-10-21 07:57:42 +00:00
|
|
|
}
|
2004-04-02 09:52:14 +00:00
|
|
|
|
|
|
|
// validate the new value
|
|
|
|
if ( m_bSupportsValidation )
|
|
|
|
recheckValidity( true );
|
2003-10-21 07:57:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void OBoundControlModel::startAggregatePropertyListening( const ::rtl::OUString& _rPropertyName )
|
|
|
|
{
|
|
|
|
OSL_PRECOND( m_pAggPropMultiplexer, "OBoundControlModel::startAggregatePropertyListening: no multiplexer!" );
|
|
|
|
OSL_ENSURE( _rPropertyName.getLength(), "OBoundControlModel::startAggregatePropertyListening: invalid property name!" );
|
|
|
|
|
|
|
|
if ( m_pAggPropMultiplexer && _rPropertyName.getLength() )
|
|
|
|
{
|
|
|
|
m_pAggPropMultiplexer->addProperty( _rPropertyName );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void OBoundControlModel::startLoadListening( )
|
|
|
|
{
|
|
|
|
OSL_PRECOND( !isLoadListening(), "OBoundControlModel::startLoadListening: already listening!" );
|
|
|
|
OSL_PRECOND( m_xParent.is(), "OBoundControlModel::startLoadListening: no parent to listen at!" );
|
|
|
|
OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::startLoadListening: external value binding should overrule the database binding!" );
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2002-10-02 13:46:57 +00:00
|
|
|
Reference< XLoadable > xLoadable( m_xParent, UNO_QUERY );
|
|
|
|
if ( xLoadable.is() )
|
2003-10-21 07:57:42 +00:00
|
|
|
{
|
|
|
|
RTL_LOGFILE_CONTEXT( aLogger, "forms::OBoundControlModel::startLoadListening" );
|
|
|
|
xLoadable->addLoadListener( this );
|
|
|
|
m_bLoadListening = sal_True;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void OBoundControlModel::stopLoadListening( )
|
|
|
|
{
|
|
|
|
OSL_PRECOND( isLoadListening(), "OBoundControlModel::stopLoadListening: not listening!" );
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2003-10-21 07:57:42 +00:00
|
|
|
Reference< XLoadable > xLoadable( m_xParent, UNO_QUERY );
|
|
|
|
if ( xLoadable.is() && isLoadListening() )
|
2002-10-02 13:46:57 +00:00
|
|
|
{
|
2003-10-21 07:57:42 +00:00
|
|
|
xLoadable->removeLoadListener( this );
|
|
|
|
m_bLoadListening = sal_False;
|
2002-10-02 13:46:57 +00:00
|
|
|
}
|
2003-10-21 07:57:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// XChild
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void SAL_CALL OBoundControlModel::setParent(const Reference<XInterface>& _rxParent) throw(com::sun::star::lang::NoSupportException, RuntimeException)
|
|
|
|
{
|
|
|
|
::osl::MutexGuard aGuard( m_aMutex );
|
|
|
|
|
|
|
|
// log off old listeners
|
|
|
|
if ( isLoadListening() )
|
|
|
|
stopLoadListening( );
|
2000-09-18 15:33:13 +00:00
|
|
|
|
|
|
|
OControlModel::setParent(_rxParent);
|
2003-10-21 07:57:42 +00:00
|
|
|
|
|
|
|
// log on new listeners - only in case we do not have an external value binding
|
|
|
|
if ( m_xParent.is() && !hasExternalValueBinding() )
|
|
|
|
startLoadListening( );
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// XEventListener
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
void SAL_CALL OBoundControlModel::disposing(const com::sun::star::lang::EventObject& _rEvent) throw (RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2004-04-02 09:52:14 +00:00
|
|
|
::osl::ClearableMutexGuard aGuard( m_aMutex );
|
2003-10-21 07:57:42 +00:00
|
|
|
if ( _rEvent.Source == m_xField )
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
resetField();
|
|
|
|
}
|
2003-10-21 07:57:42 +00:00
|
|
|
else if ( _rEvent.Source == m_xLabelControl )
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2003-03-25 17:05:07 +00:00
|
|
|
Reference<XPropertySet> xOldValue = m_xLabelControl;
|
2000-09-18 15:33:13 +00:00
|
|
|
m_xLabelControl = NULL;
|
|
|
|
|
|
|
|
// fire a property change event
|
2003-10-21 07:57:42 +00:00
|
|
|
Any aOldValue; aOldValue <<= xOldValue;
|
|
|
|
Any aNewValue; aNewValue <<= m_xLabelControl;
|
2000-09-18 15:33:13 +00:00
|
|
|
sal_Int32 nHandle = PROPERTY_ID_CONTROLLABEL;
|
2003-10-21 07:57:42 +00:00
|
|
|
OPropertySetHelper::fire( &nHandle, &aNewValue, &aOldValue, 1, sal_False );
|
|
|
|
}
|
|
|
|
else if ( _rEvent.Source == m_xExternalBinding )
|
2004-04-02 09:52:14 +00:00
|
|
|
{ // *first* check for the external binding
|
2003-10-21 07:57:42 +00:00
|
|
|
disconnectExternalValueBinding( );
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
2004-04-02 09:52:14 +00:00
|
|
|
else if ( _rEvent.Source == m_xValidator )
|
|
|
|
{ // *then* check for the validator. Reason is that bindings may also act as validator at the same
|
|
|
|
// time, in this case, the validator is automatically revoked when the binding is revoked
|
|
|
|
disconnectValidator( );
|
|
|
|
}
|
2000-09-18 15:33:13 +00:00
|
|
|
else
|
|
|
|
OControlModel::disposing(_rEvent);
|
|
|
|
}
|
|
|
|
|
|
|
|
// XServiceInfo
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
StringSequence SAL_CALL OBoundControlModel::getSupportedServiceNames() throw(RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2003-12-11 11:28:53 +00:00
|
|
|
return ::comphelper::concatSequences(
|
|
|
|
getAggregateServiceNames(),
|
|
|
|
getSupportedServiceNames_Static()
|
|
|
|
);
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
2003-12-11 11:28:53 +00:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
Sequence< ::rtl::OUString > SAL_CALL OBoundControlModel::getSupportedServiceNames_Static() throw( RuntimeException )
|
|
|
|
{
|
|
|
|
Sequence< ::rtl::OUString > aOwnServiceNames( 1 );
|
|
|
|
aOwnServiceNames[ 0 ] = ::rtl::OUString::createFromAscii( "com.sun.star.form.DataAwareControlModel" );
|
|
|
|
|
|
|
|
return ::comphelper::concatSequences(
|
|
|
|
OControlModel::getSupportedServiceNames_Static(),
|
|
|
|
aOwnServiceNames
|
|
|
|
);
|
|
|
|
}
|
2000-09-18 15:33:13 +00:00
|
|
|
|
|
|
|
// XPersist
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
void SAL_CALL OBoundControlModel::write( const Reference<stario::XObjectOutputStream>& _rxOutStream ) throw(stario::IOException, RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
OControlModel::write(_rxOutStream);
|
|
|
|
|
|
|
|
osl::MutexGuard aGuard(m_aMutex);
|
|
|
|
|
|
|
|
// Version
|
|
|
|
_rxOutStream->writeShort(0x0002);
|
|
|
|
|
|
|
|
// Controlsource
|
2001-04-04 11:56:34 +00:00
|
|
|
::comphelper::operator<<( _rxOutStream, m_aControlSource);
|
2000-09-18 15:33:13 +00:00
|
|
|
|
|
|
|
// !!! IMPORTANT NOTE !!!
|
|
|
|
// don't write any new members here : this wouldn't be compatible with older versions, as OBoundControlModel
|
|
|
|
// is a base class which is called in derived classes "read" method. So if you increment the version
|
|
|
|
// and write new stuff, older office versions will read this in the _derived_ classes, which may result
|
|
|
|
// in anything from data loss to crash.
|
|
|
|
// (use writeCommonProperties instead, this is called in derived classes write-method)
|
|
|
|
// !!! EOIN !!!
|
|
|
|
// FS - 68876 - 28.09.1999
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void OBoundControlModel::defaultCommonProperties()
|
|
|
|
{
|
2000-11-23 07:48:15 +00:00
|
|
|
Reference<com::sun::star::lang::XComponent> xComp(m_xLabelControl, UNO_QUERY);
|
2000-09-18 15:33:13 +00:00
|
|
|
if (xComp.is())
|
2000-11-23 07:48:15 +00:00
|
|
|
xComp->removeEventListener(static_cast<com::sun::star::lang::XEventListener*>(static_cast<XPropertyChangeListener*>(this)));
|
2000-09-18 15:33:13 +00:00
|
|
|
m_xLabelControl = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
void OBoundControlModel::readCommonProperties(const Reference<stario::XObjectInputStream>& _rxInStream)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
sal_Int32 nLen = _rxInStream->readLong();
|
|
|
|
|
2000-11-23 07:48:15 +00:00
|
|
|
Reference<stario::XMarkableStream> xMark(_rxInStream, UNO_QUERY);
|
2000-09-18 15:33:13 +00:00
|
|
|
DBG_ASSERT(xMark.is(), "OBoundControlModel::readCommonProperties : can only work with markable streams !");
|
|
|
|
sal_Int32 nMark = xMark->createMark();
|
|
|
|
|
|
|
|
// read the reference to the label control
|
2000-11-23 07:48:15 +00:00
|
|
|
Reference<stario::XPersistObject> xPersist;
|
2000-09-18 15:33:13 +00:00
|
|
|
sal_Int32 nUsedFlag;
|
|
|
|
nUsedFlag = _rxInStream->readLong();
|
|
|
|
if (nUsedFlag)
|
|
|
|
xPersist = _rxInStream->readObject();
|
2004-04-02 09:52:14 +00:00
|
|
|
m_xLabelControl = m_xLabelControl.query( xPersist );
|
|
|
|
Reference< XComponent > xComp( m_xLabelControl, UNO_QUERY );
|
2000-09-18 15:33:13 +00:00
|
|
|
if (xComp.is())
|
2004-04-02 09:52:14 +00:00
|
|
|
xComp->addEventListener(static_cast<com::sun::star::lang::XEventListener*>(static_cast<XPropertyChangeListener*>(this)));
|
2000-09-18 15:33:13 +00:00
|
|
|
|
|
|
|
// read any other new common properties here
|
|
|
|
|
|
|
|
// skip the remaining bytes
|
|
|
|
xMark->jumpToMark(nMark);
|
|
|
|
_rxInStream->skipBytes(nLen);
|
|
|
|
xMark->deleteMark(nMark);
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
void OBoundControlModel::writeCommonProperties(const Reference<stario::XObjectOutputStream>& _rxOutStream)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2000-11-23 07:48:15 +00:00
|
|
|
Reference<stario::XMarkableStream> xMark(_rxOutStream, UNO_QUERY);
|
2000-09-18 15:33:13 +00:00
|
|
|
DBG_ASSERT(xMark.is(), "OBoundControlModel::writeCommonProperties : can only work with markable streams !");
|
|
|
|
sal_Int32 nMark = xMark->createMark();
|
|
|
|
|
|
|
|
// a placeholder where we will write the overall length (later in this method)
|
|
|
|
sal_Int32 nLen = 0;
|
|
|
|
_rxOutStream->writeLong(nLen);
|
|
|
|
|
|
|
|
// write the reference to the label control
|
2000-11-23 07:48:15 +00:00
|
|
|
Reference<stario::XPersistObject> xPersist(m_xLabelControl, UNO_QUERY);
|
2000-09-18 15:33:13 +00:00
|
|
|
sal_Int32 nUsedFlag = 0;
|
|
|
|
if (xPersist.is())
|
|
|
|
nUsedFlag = 1;
|
|
|
|
_rxOutStream->writeLong(nUsedFlag);
|
|
|
|
if (xPersist.is())
|
|
|
|
_rxOutStream->writeObject(xPersist);
|
|
|
|
|
|
|
|
// write any other new common properties here
|
|
|
|
|
|
|
|
// write the correct length at the beginning of the block
|
|
|
|
nLen = xMark->offsetToMark(nMark) - sizeof(nLen);
|
|
|
|
xMark->jumpToMark(nMark);
|
|
|
|
_rxOutStream->writeLong(nLen);
|
|
|
|
xMark->jumpToFurthest();
|
|
|
|
xMark->deleteMark(nMark);
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
void SAL_CALL OBoundControlModel::read( const Reference< stario::XObjectInputStream >& _rxInStream ) throw(stario::IOException, RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
OControlModel::read(_rxInStream);
|
|
|
|
|
|
|
|
osl::MutexGuard aGuard(m_aMutex);
|
|
|
|
UINT16 nVersion = _rxInStream->readShort();
|
2001-04-04 11:56:34 +00:00
|
|
|
::comphelper::operator>>( _rxInStream, m_aControlSource);
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
void OBoundControlModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle) const
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
switch (nHandle)
|
|
|
|
{
|
|
|
|
case PROPERTY_ID_CONTROLSOURCEPROPERTY:
|
2003-10-21 07:57:42 +00:00
|
|
|
rValue <<= m_sValuePropertyName;
|
2000-09-18 15:33:13 +00:00
|
|
|
break;
|
|
|
|
case PROPERTY_ID_CONTROLSOURCE:
|
|
|
|
rValue <<= m_aControlSource;
|
|
|
|
break;
|
|
|
|
case PROPERTY_ID_BOUNDFIELD:
|
|
|
|
rValue <<= m_xField;
|
|
|
|
break;
|
|
|
|
case PROPERTY_ID_CONTROLLABEL:
|
|
|
|
if (!m_xLabelControl.is())
|
|
|
|
rValue.clear();
|
|
|
|
else
|
|
|
|
rValue <<= m_xLabelControl;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
OControlModel::getFastPropertyValue(rValue, nHandle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
sal_Bool OBoundControlModel::convertFastPropertyValue(
|
2000-11-23 07:48:15 +00:00
|
|
|
Any& _rConvertedValue, Any& _rOldValue,
|
2000-09-18 15:33:13 +00:00
|
|
|
sal_Int32 _nHandle,
|
2000-11-23 07:48:15 +00:00
|
|
|
const Any& _rValue)
|
2000-10-24 12:07:20 +00:00
|
|
|
throw (com::sun::star::lang::IllegalArgumentException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
sal_Bool bModified(sal_False);
|
|
|
|
switch (_nHandle)
|
|
|
|
{
|
|
|
|
case PROPERTY_ID_CONTROLSOURCE:
|
|
|
|
bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_aControlSource);
|
|
|
|
break;
|
|
|
|
case PROPERTY_ID_BOUNDFIELD:
|
|
|
|
bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_xField);
|
|
|
|
break;
|
|
|
|
case PROPERTY_ID_CONTROLLABEL:
|
|
|
|
if (!_rValue.hasValue())
|
|
|
|
{ // property set to void
|
2000-11-23 07:48:15 +00:00
|
|
|
_rConvertedValue = Any();
|
2000-09-18 15:33:13 +00:00
|
|
|
getFastPropertyValue(_rOldValue, _nHandle);
|
|
|
|
bModified = m_xLabelControl.is();
|
|
|
|
}
|
|
|
|
else
|
2001-03-13 09:34:43 +00:00
|
|
|
{
|
2000-09-18 15:33:13 +00:00
|
|
|
bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_xLabelControl);
|
2001-03-13 09:34:43 +00:00
|
|
|
if (!m_xLabelControl.is())
|
|
|
|
// an empty interface is interpreted as VOID
|
|
|
|
_rOldValue.clear();
|
|
|
|
}
|
2000-09-18 15:33:13 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
bModified = OControlModel::convertFastPropertyValue(_rConvertedValue, _rOldValue, _nHandle, _rValue);
|
|
|
|
}
|
|
|
|
return bModified;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
void OBoundControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw (Exception)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
switch (nHandle)
|
|
|
|
{
|
|
|
|
case PROPERTY_ID_CONTROLSOURCE:
|
2000-11-23 07:48:15 +00:00
|
|
|
DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_STRING, "invalid type" );
|
2000-09-18 15:33:13 +00:00
|
|
|
rValue >>= m_aControlSource;
|
|
|
|
break;
|
|
|
|
case PROPERTY_ID_BOUNDFIELD:
|
|
|
|
DBG_ERROR("OBoundControlModel::setFastPropertyValue_NoBroadcast : BoundField should be a read-only property !");
|
2000-11-23 07:48:15 +00:00
|
|
|
throw com::sun::star::lang::IllegalArgumentException();
|
2000-09-18 15:33:13 +00:00
|
|
|
break;
|
|
|
|
case PROPERTY_ID_CONTROLLABEL:
|
|
|
|
{
|
2000-11-23 07:48:15 +00:00
|
|
|
DBG_ASSERT(!rValue.hasValue() || (rValue.getValueType().getTypeClass() == TypeClass_INTERFACE),
|
2000-09-18 15:33:13 +00:00
|
|
|
"OBoundControlModel::setFastPropertyValue_NoBroadcast : invalid argument !");
|
|
|
|
if (!rValue.hasValue())
|
|
|
|
{ // set property to "void"
|
2000-11-23 07:48:15 +00:00
|
|
|
Reference<com::sun::star::lang::XComponent> xComp(m_xLabelControl, UNO_QUERY);
|
2000-09-18 15:33:13 +00:00
|
|
|
if (xComp.is())
|
2000-11-23 07:48:15 +00:00
|
|
|
xComp->removeEventListener(static_cast<com::sun::star::lang::XEventListener*>(static_cast<XPropertyChangeListener*>(this)));
|
2000-09-18 15:33:13 +00:00
|
|
|
m_xLabelControl = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2000-11-23 07:48:15 +00:00
|
|
|
InterfaceRef xNewValue;
|
|
|
|
rValue >>= xNewValue;
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2000-12-06 09:14:22 +00:00
|
|
|
Reference<XControlModel> xAsModel(xNewValue, UNO_QUERY);
|
2000-11-23 07:48:15 +00:00
|
|
|
Reference<com::sun::star::lang::XServiceInfo> xAsServiceInfo(xNewValue, UNO_QUERY);
|
|
|
|
Reference<XPropertySet> xAsPropSet(xNewValue, UNO_QUERY);
|
|
|
|
Reference<XChild> xAsChild(xNewValue, UNO_QUERY);
|
2000-09-18 15:33:13 +00:00
|
|
|
if (!xAsModel.is() || !xAsServiceInfo.is() || !xAsPropSet.is() || !xAsChild.is())
|
|
|
|
{
|
2000-11-23 07:48:15 +00:00
|
|
|
throw com::sun::star::lang::IllegalArgumentException();
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!xAsServiceInfo->supportsService(m_aLabelServiceName))
|
|
|
|
{
|
2000-11-23 07:48:15 +00:00
|
|
|
throw com::sun::star::lang::IllegalArgumentException();
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// check if weself and the given model have a common anchestor (up to the forms collection)
|
2000-11-23 07:48:15 +00:00
|
|
|
Reference<XChild> xCont;
|
|
|
|
query_interface(static_cast<XWeak*>(this), xCont);
|
2000-09-18 15:33:13 +00:00
|
|
|
InterfaceRef xMyTopLevel = xCont->getParent();
|
|
|
|
while (xMyTopLevel.is())
|
|
|
|
{
|
2000-11-23 07:48:15 +00:00
|
|
|
Reference<XForm> xAsForm(xMyTopLevel, UNO_QUERY);
|
2000-09-18 15:33:13 +00:00
|
|
|
if (!xAsForm.is())
|
|
|
|
// found my root
|
|
|
|
break;
|
|
|
|
|
2000-11-23 07:48:15 +00:00
|
|
|
Reference<XChild> xAsChild(xMyTopLevel, UNO_QUERY);
|
2000-09-18 15:33:13 +00:00
|
|
|
xMyTopLevel = xAsChild.is() ? xAsChild->getParent() : InterfaceRef();
|
|
|
|
}
|
|
|
|
InterfaceRef xNewTopLevel = xAsChild->getParent();
|
|
|
|
while (xNewTopLevel.is())
|
|
|
|
{
|
2000-11-23 07:48:15 +00:00
|
|
|
Reference<XForm> xAsForm(xNewTopLevel, UNO_QUERY);
|
2000-09-18 15:33:13 +00:00
|
|
|
if (!xAsForm.is())
|
|
|
|
break;
|
|
|
|
|
2000-11-23 07:48:15 +00:00
|
|
|
Reference<XChild> xAsChild(xNewTopLevel, UNO_QUERY);
|
2000-09-18 15:33:13 +00:00
|
|
|
xNewTopLevel = xAsChild.is() ? xAsChild->getParent() : InterfaceRef();
|
|
|
|
}
|
|
|
|
if (xNewTopLevel != xMyTopLevel)
|
|
|
|
{
|
|
|
|
// the both objects don't belong to the same forms collection -> not acceptable
|
2000-11-23 07:48:15 +00:00
|
|
|
throw com::sun::star::lang::IllegalArgumentException();
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
m_xLabelControl = xAsPropSet;
|
2000-11-23 07:48:15 +00:00
|
|
|
Reference<com::sun::star::lang::XComponent> xComp(m_xLabelControl, UNO_QUERY);
|
2000-09-18 15:33:13 +00:00
|
|
|
if (xComp.is())
|
2000-11-23 07:48:15 +00:00
|
|
|
xComp->addEventListener(static_cast<com::sun::star::lang::XEventListener*>(static_cast<XPropertyChangeListener*>(this)));
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
OControlModel::setFastPropertyValue_NoBroadcast(nHandle, rValue );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// XPropertyChangeListener
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
void SAL_CALL OBoundControlModel::propertyChange( const PropertyChangeEvent& evt ) throw(RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2003-10-21 07:57:42 +00:00
|
|
|
// TODO: check how this works with external bindings
|
|
|
|
OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::propertyChange: Hey, I have an external binding, so how this?" );
|
|
|
|
// if we have an external value binding, then we should *not* be a property change
|
|
|
|
// listener at an sdb::Column
|
|
|
|
|
2000-09-18 15:33:13 +00:00
|
|
|
// Bei Wertaenderung neu initialisieren
|
2003-10-21 07:57:42 +00:00
|
|
|
if ( evt.PropertyName.equals( PROPERTY_VALUE ) )
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
osl::MutexGuard aGuard(m_aMutex);
|
2003-10-21 07:57:42 +00:00
|
|
|
if ( m_bForwardValueChanges && m_xColumn.is() )
|
|
|
|
transferDbValueToControl();
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// XBoundComponent
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
void SAL_CALL OBoundControlModel::addUpdateListener(const Reference<XUpdateListener>& _rxListener) throw(RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
m_aUpdateListeners.addInterface(_rxListener);
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
void SAL_CALL OBoundControlModel::removeUpdateListener(const Reference< XUpdateListener>& _rxListener) throw(RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
m_aUpdateListeners.removeInterface(_rxListener);
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
sal_Bool SAL_CALL OBoundControlModel::commit() throw(RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2003-10-21 07:57:42 +00:00
|
|
|
OSL_PRECOND( m_bCommitable, "OBoundControlModel::commit: invalid call (I'm not commitable !) " );
|
|
|
|
if ( hasExternalValueBinding() )
|
|
|
|
{
|
|
|
|
// in most cases, no action is required: For most derivees, we know the value property of
|
|
|
|
// our control (see initValueProperty), and when an external binding is active, we
|
|
|
|
// instantly forward all changes in this property to the external binding.
|
|
|
|
if ( !m_sValuePropertyName.getLength() )
|
|
|
|
// but for those derivees which did not use this feature, we need an
|
|
|
|
// explicit transfer
|
|
|
|
transferControlValueToExternal( );
|
|
|
|
return sal_True;
|
|
|
|
}
|
|
|
|
|
|
|
|
OSL_ENSURE( !hasExternalValueBinding(), "OBoundControlModel::commit: control flow broken!" );
|
|
|
|
// we reach this only if we're not working with an external binding
|
|
|
|
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
osl::MutexGuard aGuard(m_aMutex);
|
2003-10-21 07:57:42 +00:00
|
|
|
if ( !m_xField.is() )
|
2000-09-18 15:33:13 +00:00
|
|
|
return sal_True;
|
|
|
|
}
|
|
|
|
|
2003-10-21 07:57:42 +00:00
|
|
|
::cppu::OInterfaceIteratorHelper aIter( m_aUpdateListeners );
|
|
|
|
EventObject aEvt;
|
|
|
|
aEvt.Source = static_cast< XWeak* >( this );
|
2000-09-18 15:33:13 +00:00
|
|
|
sal_Bool bSucceed = sal_True;
|
|
|
|
while (aIter.hasMoreElements() && bSucceed)
|
2003-10-21 07:57:42 +00:00
|
|
|
bSucceed = static_cast< XUpdateListener* >( aIter.next() )->approveUpdate( aEvt );
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2003-10-21 07:57:42 +00:00
|
|
|
if ( bSucceed )
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
osl::MutexGuard aGuard(m_aMutex);
|
|
|
|
try
|
|
|
|
{
|
2003-10-21 07:57:42 +00:00
|
|
|
if ( m_xColumnUpdate.is() )
|
|
|
|
bSucceed = commitControlValueToDbColumn( sal_False );
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
2000-11-23 07:48:15 +00:00
|
|
|
catch(Exception&)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
bSucceed = sal_False;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-10-21 07:57:42 +00:00
|
|
|
if ( bSucceed )
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2003-10-21 07:57:42 +00:00
|
|
|
cppu::OInterfaceIteratorHelper aIter( m_aUpdateListeners );
|
|
|
|
while ( aIter.hasMoreElements() )
|
|
|
|
static_cast< XUpdateListener* >( aIter.next() )->updated( aEvt );
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return bSucceed;
|
|
|
|
}
|
|
|
|
|
2003-10-21 07:57:42 +00:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void OBoundControlModel::resetField()
|
|
|
|
{
|
|
|
|
m_xColumnUpdate.clear();
|
|
|
|
m_xColumn.clear();
|
|
|
|
m_xField.clear();
|
|
|
|
}
|
|
|
|
|
2000-09-18 15:33:13 +00:00
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
sal_Bool OBoundControlModel::connectToField(const Reference<XRowSet>& rForm)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2003-10-21 07:57:42 +00:00
|
|
|
OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::connectToField: invalid call (have an external binding)!" );
|
|
|
|
|
2000-09-18 15:33:13 +00:00
|
|
|
// wenn eine Verbindung zur Datenbank existiert
|
|
|
|
if (rForm.is() && getConnection(rForm).is())
|
|
|
|
{
|
|
|
|
// Feld bestimmen und PropertyChangeListener
|
|
|
|
m_xCursor = rForm;
|
2000-11-23 07:48:15 +00:00
|
|
|
Reference<XPropertySet> xFieldCandidate;
|
2000-09-18 15:33:13 +00:00
|
|
|
|
|
|
|
if (m_xCursor.is())
|
|
|
|
{
|
2000-11-23 07:48:15 +00:00
|
|
|
Reference<XColumnsSupplier> xColumnsSupplier(m_xCursor, UNO_QUERY);
|
2000-09-18 15:33:13 +00:00
|
|
|
DBG_ASSERT(xColumnsSupplier.is(), "OBoundControlModel::connectToField : the row set should support the com::sun::star::sdb::ResultSet service !");
|
|
|
|
if (xColumnsSupplier.is())
|
|
|
|
{
|
2000-11-23 07:48:15 +00:00
|
|
|
Reference<XNameAccess> xColumns(xColumnsSupplier->getColumns(), UNO_QUERY);
|
2000-09-18 15:33:13 +00:00
|
|
|
if (xColumns.is() && xColumns->hasByName(m_aControlSource))
|
|
|
|
{
|
2000-11-23 07:48:15 +00:00
|
|
|
Any aElement(xColumns->getByName(m_aControlSource));
|
|
|
|
DBG_ASSERT(xColumns->getElementType().equals(::getCppuType(reinterpret_cast<Reference<XPropertySet>*>(NULL))),
|
2000-09-18 15:33:13 +00:00
|
|
|
"OBoundControlModel::connectToField : the columns container should contain XPropertySets !");
|
|
|
|
// if this assertion fails we probably should do a queryInterface ....
|
|
|
|
aElement >>= xFieldCandidate;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// darf ich mich ueberhaupt an dieses Feld binden (Typ-Check)
|
|
|
|
if (xFieldCandidate.is())
|
|
|
|
{
|
|
|
|
sal_Int32 nFieldType;
|
|
|
|
xFieldCandidate->getPropertyValue(PROPERTY_FIELDTYPE) >>= nFieldType;
|
2003-10-21 07:57:42 +00:00
|
|
|
if (approveDbColumnType(nFieldType))
|
2003-05-19 12:08:37 +00:00
|
|
|
setField(xFieldCandidate,sal_False);
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
else
|
2003-05-19 12:08:37 +00:00
|
|
|
setField(NULL,sal_False);
|
2000-09-18 15:33:13 +00:00
|
|
|
|
|
|
|
if (m_xField.is())
|
|
|
|
{
|
|
|
|
if(m_xField->getPropertySetInfo()->hasPropertyByName(PROPERTY_VALUE))
|
|
|
|
{
|
|
|
|
// an wertaenderungen horchen
|
2003-10-21 07:57:42 +00:00
|
|
|
m_xField->addPropertyChangeListener( PROPERTY_VALUE, this );
|
|
|
|
m_xColumnUpdate = Reference< XColumnUpdate >( m_xField, UNO_QUERY );
|
|
|
|
m_xColumn = Reference< XColumn >( m_xField, UNO_QUERY );
|
|
|
|
|
|
|
|
INT32 nNullableFlag = ColumnValue::NO_NULLS;
|
|
|
|
m_xField->getPropertyValue(PROPERTY_ISNULLABLE) >>= nNullableFlag;
|
2000-11-23 07:48:15 +00:00
|
|
|
m_bRequired = (ColumnValue::NO_NULLS == nNullableFlag);
|
2000-09-18 15:33:13 +00:00
|
|
|
// we're optimistic : in case of ColumnValue_NULLABLE_UNKNOWN we assume nullability ....
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2001-06-12 05:02:47 +00:00
|
|
|
OSL_ENSURE(sal_False, "OBoundControlModel::connectToField: property NAME not supported!");
|
2003-05-19 12:08:37 +00:00
|
|
|
setField(NULL,sal_False);
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return m_xField.is();
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2003-10-21 07:57:42 +00:00
|
|
|
sal_Bool OBoundControlModel::approveDbColumnType(sal_Int32 _nColumnType)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2003-10-21 07:57:42 +00:00
|
|
|
OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::approveDbColumnType: invalid call (have an external binding)!" );
|
|
|
|
|
2000-11-23 07:48:15 +00:00
|
|
|
if ((_nColumnType == DataType::BINARY) || (_nColumnType == DataType::VARBINARY)
|
|
|
|
|| (_nColumnType == DataType::LONGVARBINARY) || (_nColumnType == DataType::OTHER)
|
|
|
|
|| (_nColumnType == DataType::OBJECT) || (_nColumnType == DataType::DISTINCT)
|
|
|
|
|| (_nColumnType == DataType::STRUCT) || (_nColumnType == DataType::ARRAY)
|
|
|
|
|| (_nColumnType == DataType::BLOB) || (_nColumnType == DataType::CLOB)
|
|
|
|
|| (_nColumnType == DataType::REF) || (_nColumnType == DataType::SQLNULL))
|
2000-09-18 15:33:13 +00:00
|
|
|
return sal_False;
|
|
|
|
|
|
|
|
return sal_True;
|
|
|
|
}
|
|
|
|
|
2003-10-21 07:57:42 +00:00
|
|
|
//==============================================================================
|
|
|
|
// value binding handling
|
|
|
|
|
2000-09-18 15:33:13 +00:00
|
|
|
//------------------------------------------------------------------------------
|
2003-10-21 07:57:42 +00:00
|
|
|
void OBoundControlModel::connectDatabaseColumn( const Reference< XRowSet >& _rxRowSet, bool _bFromReload )
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2003-10-21 07:57:42 +00:00
|
|
|
OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::connectDatabaseColumn: not to be called with an external value binding!" );
|
|
|
|
::osl::MutexGuard aGuard( m_aMutex );
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2003-10-21 07:57:42 +00:00
|
|
|
// consistency checks
|
|
|
|
DBG_ASSERT( !( m_xField.is() && !_bFromReload ),
|
|
|
|
"OBoundControlModel::connectDatabaseColumn: the form is just *loaded*, but we already have a field!" );
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2003-10-21 07:57:42 +00:00
|
|
|
Reference< XPropertySet > xOldField = m_xField;
|
|
|
|
if ( !m_xField.is() )
|
2001-08-07 13:58:08 +00:00
|
|
|
{
|
2003-10-21 07:57:42 +00:00
|
|
|
// connect to the column
|
|
|
|
connectToField( _rxRowSet );
|
|
|
|
}
|
|
|
|
|
|
|
|
// now that we're connected (more or less, even if we did not find a column),
|
|
|
|
// we definately want to forward any potentially occuring value changes
|
|
|
|
m_bForwardValueChanges = sal_True;
|
|
|
|
|
|
|
|
// let derived classes react on this new connection
|
|
|
|
m_bLoaded = sal_True;
|
|
|
|
onConnectedDbColumn( _rxRowSet );
|
|
|
|
|
|
|
|
// did we successfully connect to a database column?
|
|
|
|
if ( m_xField.is() )
|
|
|
|
{ // initially transfer the db column value to the control
|
2001-08-07 13:58:08 +00:00
|
|
|
// but only if the rowset if posisitioned on a valid record
|
2003-10-21 07:57:42 +00:00
|
|
|
if ( _rxRowSet.is() )
|
2001-08-07 13:58:08 +00:00
|
|
|
{
|
2003-10-21 07:57:42 +00:00
|
|
|
if ( !_rxRowSet->isBeforeFirst() && !_rxRowSet->isAfterLast() )
|
|
|
|
transferDbValueToControl();
|
2001-08-07 13:58:08 +00:00
|
|
|
}
|
|
|
|
}
|
2003-05-19 12:08:37 +00:00
|
|
|
|
|
|
|
if ( xOldField != m_xField )
|
|
|
|
{
|
|
|
|
Any aNewValue; aNewValue <<= m_xField;
|
|
|
|
Any aOldValue; aOldValue <<= xOldField;
|
|
|
|
sal_Int32 nHandle = PROPERTY_ID_BOUNDFIELD;
|
|
|
|
OPropertySetHelper::fire(&nHandle, &aNewValue, &aOldValue, 1, sal_False);
|
|
|
|
}
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
2003-10-21 07:57:42 +00:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void OBoundControlModel::disconnectDatabaseColumn( )
|
|
|
|
{
|
|
|
|
OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::disconnectDatabaseColumn: not to be called with an external value binding!" );
|
|
|
|
::osl::MutexGuard aGuard( m_aMutex );
|
|
|
|
|
|
|
|
// let derived classes react on this
|
|
|
|
onDisconnectedDbColumn();
|
|
|
|
|
|
|
|
if ( m_xField.is() )
|
|
|
|
{
|
|
|
|
m_xField->removePropertyChangeListener( PROPERTY_VALUE, this );
|
|
|
|
resetField();
|
|
|
|
}
|
|
|
|
|
|
|
|
m_xCursor = NULL;
|
|
|
|
m_bLoaded = sal_False;
|
|
|
|
}
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
// XLoadListener
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void SAL_CALL OBoundControlModel::loaded( const EventObject& _rEvent ) throw(RuntimeException)
|
|
|
|
{
|
|
|
|
OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::loaded: we should never reach this with an external value binding!" );
|
|
|
|
if ( hasExternalValueBinding() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
// connect to the database column described by our SQL-binding-related properties
|
|
|
|
Reference< XRowSet > xRowSet( _rEvent.Source, UNO_QUERY );
|
|
|
|
DBG_ASSERT( xRowSet.is(), "OBoundControlModel::loaded: event source is no RowSet?!" );
|
|
|
|
connectDatabaseColumn( xRowSet, false );
|
|
|
|
}
|
|
|
|
|
2000-09-18 15:33:13 +00:00
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
void SAL_CALL OBoundControlModel::unloaded( const com::sun::star::lang::EventObject& aEvent ) throw(RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2003-10-21 07:57:42 +00:00
|
|
|
OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::unloaded: we should never reach this with an external value binding!" );
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
void SAL_CALL OBoundControlModel::reloading( const com::sun::star::lang::EventObject& aEvent ) throw(RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2003-10-21 07:57:42 +00:00
|
|
|
OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::reloading: we should never reach this with an external value binding!" );
|
|
|
|
if ( hasExternalValueBinding() )
|
|
|
|
return;
|
|
|
|
|
2000-09-18 15:33:13 +00:00
|
|
|
osl::MutexGuard aGuard(m_aMutex);
|
|
|
|
m_bForwardValueChanges = sal_False;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
void SAL_CALL OBoundControlModel::unloading(const com::sun::star::lang::EventObject& aEvent) throw(RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2003-10-21 07:57:42 +00:00
|
|
|
OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::unloading: we should never reach this with an external value binding!" );
|
|
|
|
if ( hasExternalValueBinding() )
|
|
|
|
return;
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2003-10-21 07:57:42 +00:00
|
|
|
// disconnect from the database column described by our SQL-binding-related properties
|
|
|
|
disconnectDatabaseColumn();
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2003-10-21 07:57:42 +00:00
|
|
|
void SAL_CALL OBoundControlModel::reloaded( const EventObject& _rEvent ) throw(RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2003-10-21 07:57:42 +00:00
|
|
|
OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::reloaded: we should never reach this with an external value binding!" );
|
|
|
|
if ( hasExternalValueBinding() )
|
|
|
|
return;
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2003-10-21 07:57:42 +00:00
|
|
|
Reference< XRowSet > xRowSet( _rEvent.Source, UNO_QUERY );
|
|
|
|
DBG_ASSERT( xRowSet.is(), "OBoundControlModel::reloaded: event source is no RowSet?!" );
|
|
|
|
connectDatabaseColumn( xRowSet, true );
|
|
|
|
}
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2003-10-21 07:57:42 +00:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void OBoundControlModel::setControlValue( const Any& _rValue )
|
|
|
|
{
|
|
|
|
OSL_PRECOND( m_xAggregateFastSet.is() && m_xAggregateSet.is(),
|
|
|
|
"OBoundControlModel::setControlValue: invalid aggregate !" );
|
|
|
|
OSL_PRECOND( m_sValuePropertyName.getLength() || ( m_nValuePropertyAggregateHandle != -1 ),
|
|
|
|
"OBoundControlModel::setControlValue: please override if you have own value property handling!" );
|
2003-05-19 12:08:37 +00:00
|
|
|
|
2003-10-21 07:57:42 +00:00
|
|
|
m_bSettingAggregateState = sal_True;
|
2003-05-19 12:08:37 +00:00
|
|
|
{
|
2003-10-21 07:57:42 +00:00
|
|
|
// release our mutex once (it's acquired in the calling method !), as setting aggregate properties
|
|
|
|
// may cause any uno controls belonging to us to lock the solar mutex, which is potentially dangerous with
|
|
|
|
// our own mutex locked
|
|
|
|
// FS - 72451 - 31.01.00
|
|
|
|
MutexRelease aRelease( m_aMutex );
|
|
|
|
if ( ( m_nValuePropertyAggregateHandle != -1 ) && m_xAggregateFastSet.is() )
|
|
|
|
{
|
|
|
|
m_xAggregateFastSet->setFastPropertyValue( m_nValuePropertyAggregateHandle, _rValue );
|
|
|
|
}
|
|
|
|
else if ( m_sValuePropertyName.getLength() && m_xAggregateSet.is() )
|
|
|
|
{
|
|
|
|
m_xAggregateSet->setPropertyValue( m_sValuePropertyName, _rValue );
|
|
|
|
}
|
2003-05-19 12:08:37 +00:00
|
|
|
}
|
2003-10-21 07:57:42 +00:00
|
|
|
m_bSettingAggregateState = sal_False;
|
|
|
|
}
|
|
|
|
|
2004-04-02 09:52:14 +00:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void OBoundControlModel::onConnectedValidator( )
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
// if we have an external validator, we do not want the control to force invalid
|
|
|
|
// inputs to the default value. Instead, invalid inputs should be translated
|
|
|
|
// to NaN (not a number)
|
|
|
|
Reference< XPropertySetInfo > xAggregatePropertyInfo;
|
|
|
|
if ( m_xAggregateSet.is() )
|
|
|
|
xAggregatePropertyInfo = m_xAggregateSet->getPropertySetInfo();
|
|
|
|
if ( xAggregatePropertyInfo.is() && xAggregatePropertyInfo->hasPropertyByName( PROPERTY_ENFORCE_FORMAT ) )
|
|
|
|
m_xAggregateSet->setPropertyValue( PROPERTY_ENFORCE_FORMAT, makeAny( (sal_Bool)sal_False ) );
|
|
|
|
}
|
|
|
|
catch( const Exception& )
|
|
|
|
{
|
|
|
|
OSL_ENSURE( sal_False, "OBoundControlModel::onConnectedValidator: caught an exception!" );
|
|
|
|
}
|
|
|
|
recheckValidity( false );
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void OBoundControlModel::onDisconnectedValidator( )
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
Reference< XPropertySetInfo > xAggregatePropertyInfo;
|
|
|
|
if ( m_xAggregateSet.is() )
|
|
|
|
xAggregatePropertyInfo = m_xAggregateSet->getPropertySetInfo();
|
|
|
|
if ( xAggregatePropertyInfo.is() && xAggregatePropertyInfo->hasPropertyByName( PROPERTY_ENFORCE_FORMAT ) )
|
|
|
|
m_xAggregateSet->setPropertyValue( PROPERTY_ENFORCE_FORMAT, makeAny( (sal_Bool)sal_True ) );
|
|
|
|
}
|
|
|
|
catch( const Exception& )
|
|
|
|
{
|
|
|
|
OSL_ENSURE( sal_False, "OBoundControlModel::onDisconnectedValidator: caught an exception!" );
|
|
|
|
}
|
|
|
|
recheckValidity( false );
|
|
|
|
}
|
|
|
|
|
2003-10-21 07:57:42 +00:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void OBoundControlModel::onConnectedExternalValue( )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void OBoundControlModel::onDisconnectedExternalValue( )
|
|
|
|
{
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2003-10-21 07:57:42 +00:00
|
|
|
void OBoundControlModel::onConnectedDbColumn( const Reference< XInterface >& _rxForm )
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2003-10-21 07:57:42 +00:00
|
|
|
OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::onConnectedDbColumn: how this? There's an external value binding!" );
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2003-10-21 07:57:42 +00:00
|
|
|
void OBoundControlModel::onDisconnectedDbColumn()
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2003-10-21 07:57:42 +00:00
|
|
|
OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::onDisconnectedDbColumn: how this? There's an external value binding!" );
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// XReset
|
|
|
|
//-----------------------------------------------------------------------------
|
2003-10-21 07:57:42 +00:00
|
|
|
Any OBoundControlModel::getDefaultForReset() const
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2003-10-21 07:57:42 +00:00
|
|
|
return Any();
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void OBoundControlModel::resetNoBroadcast()
|
|
|
|
{
|
|
|
|
setControlValue( getDefaultForReset() );
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
void OBoundControlModel::addResetListener(const Reference<XResetListener>& l) throw (RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
m_aResetListeners.addInterface(l);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
void OBoundControlModel::removeResetListener(const Reference<XResetListener>& l) throw (RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
m_aResetListeners.removeInterface(l);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2000-11-23 07:48:15 +00:00
|
|
|
void OBoundControlModel::reset() throw (RuntimeException)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
cppu::OInterfaceIteratorHelper aIter(m_aResetListeners);
|
2003-10-21 07:57:42 +00:00
|
|
|
EventObject aResetEvent(static_cast<XWeak*>(this));
|
2000-09-18 15:33:13 +00:00
|
|
|
sal_Bool bContinue = sal_True;
|
2003-10-21 07:57:42 +00:00
|
|
|
while ( aIter.hasMoreElements() && bContinue )
|
|
|
|
bContinue = static_cast< XResetListener* >( aIter.next() )->approveReset( aResetEvent );
|
2000-09-18 15:33:13 +00:00
|
|
|
|
|
|
|
if (!bContinue)
|
|
|
|
return;
|
|
|
|
|
2004-04-02 09:52:14 +00:00
|
|
|
::osl::ClearableMutexGuard aGuard( m_aMutex );
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2003-10-21 07:57:42 +00:00
|
|
|
sal_Bool bSimpleReset =
|
|
|
|
( !m_xColumn.is() // no connection to a database column
|
2003-03-25 17:05:07 +00:00
|
|
|
|| ( m_xCursor.is() // OR we have an improperly positioned cursor
|
|
|
|
&& ( m_xCursor->isAfterLast()
|
|
|
|
|| m_xCursor->isBeforeFirst()
|
|
|
|
)
|
2003-10-21 07:57:42 +00:00
|
|
|
)
|
|
|
|
|| hasExternalValueBinding() // OR we have an external value binding
|
|
|
|
);
|
2003-03-25 17:05:07 +00:00
|
|
|
|
|
|
|
if ( !bSimpleReset )
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2003-03-25 17:05:07 +00:00
|
|
|
// The default values will be set if and only if the current value of the field which we're bound
|
|
|
|
// to is NULL.
|
|
|
|
// Else, the current field value should be refreshed
|
|
|
|
// This behaviour is not completely ... "matured": What should happen if the field as well as the
|
|
|
|
// control have a default value?
|
2000-09-18 15:33:13 +00:00
|
|
|
|
|
|
|
sal_Bool bIsNull = sal_True;
|
|
|
|
// we have to access the field content at least once to get a reliable result by XColumn::wasNull
|
|
|
|
try
|
|
|
|
{
|
2004-03-19 10:52:54 +00:00
|
|
|
// normally, we'd do a getString here. However, this is extremely expensive in the case
|
|
|
|
// of binary fields. Unfortunately, getString is the only method which is guaranteed
|
|
|
|
// to *always* succeed, all other getXXX methods may fail if the column is asked for a
|
|
|
|
// non-convertible type
|
|
|
|
sal_Int32 nFieldType = DataType::OBJECT;
|
|
|
|
getField()->getPropertyValue( PROPERTY_FIELDTYPE ) >>= nFieldType;
|
|
|
|
if ( ( nFieldType == DataType::BINARY )
|
|
|
|
|| ( nFieldType == DataType::VARBINARY )
|
|
|
|
|| ( nFieldType == DataType::LONGVARBINARY )
|
|
|
|
|| ( nFieldType == DataType::OBJECT )
|
|
|
|
|| ( nFieldType == DataType::BLOB )
|
|
|
|
|| ( nFieldType == DataType::CLOB )
|
|
|
|
)
|
|
|
|
m_xColumn->getBinaryStream();
|
|
|
|
else
|
|
|
|
m_xColumn->getString();
|
|
|
|
|
2003-03-25 17:05:07 +00:00
|
|
|
bIsNull = m_xColumn->wasNull();
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
2000-11-23 07:48:15 +00:00
|
|
|
catch(Exception&)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2004-03-19 10:52:54 +00:00
|
|
|
DBG_ERROR("OBoundControlModel::reset: this should have succeeded in all cases!");
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
2003-10-21 07:57:42 +00:00
|
|
|
sal_Bool bNeedValueTransfer = sal_True;
|
|
|
|
|
|
|
|
if ( bIsNull )
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
sal_Bool bIsNewRecord = sal_False;
|
2003-10-21 07:57:42 +00:00
|
|
|
Reference<XPropertySet> xSet( m_xCursor, UNO_QUERY );
|
|
|
|
if ( xSet.is() )
|
|
|
|
xSet->getPropertyValue( PROPERTY_ISNEW ) >>= bIsNewRecord;
|
|
|
|
|
|
|
|
if ( bIsNewRecord )
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2003-10-21 07:57:42 +00:00
|
|
|
// reset the control to it's default
|
|
|
|
resetNoBroadcast();
|
|
|
|
// and immediately commit the changes to the DB column, to keep consistency
|
|
|
|
commitControlValueToDbColumn( sal_True );
|
|
|
|
|
|
|
|
bNeedValueTransfer = sal_False;
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
}
|
2003-10-21 07:57:42 +00:00
|
|
|
|
|
|
|
if ( bNeedValueTransfer )
|
|
|
|
transferDbValueToControl();
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
else
|
2003-10-21 07:57:42 +00:00
|
|
|
{
|
|
|
|
resetNoBroadcast();
|
2004-04-02 09:52:14 +00:00
|
|
|
|
|
|
|
// transfer to the external binding, if necessary
|
2003-10-21 07:57:42 +00:00
|
|
|
if ( hasExternalValueBinding() )
|
|
|
|
transferControlValueToExternal();
|
|
|
|
}
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2004-04-02 09:52:14 +00:00
|
|
|
// revalidate, if necessary
|
|
|
|
if ( hasValidator() )
|
|
|
|
recheckValidity( true );
|
|
|
|
|
2000-09-18 15:33:13 +00:00
|
|
|
aGuard.clear();
|
|
|
|
|
|
|
|
cppu::OInterfaceIteratorHelper aIterDone(m_aResetListeners);
|
|
|
|
while (aIterDone.hasMoreElements())
|
2000-11-23 07:48:15 +00:00
|
|
|
reinterpret_cast<XResetListener*>(aIterDone.next())->resetted(aResetEvent);
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
2003-05-19 12:08:37 +00:00
|
|
|
// -----------------------------------------------------------------------------
|
2003-10-21 07:57:42 +00:00
|
|
|
void OBoundControlModel::setField( const Reference< XPropertySet>& _rxField,sal_Bool _bFire )
|
2003-05-19 12:08:37 +00:00
|
|
|
{
|
2003-10-21 07:57:42 +00:00
|
|
|
DBG_ASSERT( !hasExternalValueBinding(), "OBoundControlModel::setField: We have an external value binding!" );
|
|
|
|
|
2003-05-19 12:08:37 +00:00
|
|
|
// fire a property change event
|
|
|
|
if ( m_xField != _rxField )
|
|
|
|
{
|
|
|
|
Any aOldValue; aOldValue <<= m_xField;
|
|
|
|
m_xField = _rxField;
|
|
|
|
if ( _bFire )
|
|
|
|
{
|
|
|
|
Any aNewValue; aNewValue <<= _rxField;
|
|
|
|
sal_Int32 nHandle = PROPERTY_ID_BOUNDFIELD;
|
|
|
|
OPropertySetHelper::fire(&nHandle, &aNewValue, &aOldValue, 1, sal_False);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-10-21 07:57:42 +00:00
|
|
|
//--------------------------------------------------------------------
|
|
|
|
sal_Bool OBoundControlModel::approveValueBinding( const Reference< XValueBinding >& _rxBinding )
|
|
|
|
{
|
|
|
|
// reject everything. Derived classes need to override this if they want to
|
|
|
|
// benefit from this data binding functionality
|
|
|
|
return sal_False;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
void OBoundControlModel::connectExternalValueBinding( const Reference< XValueBinding >& _rxBinding )
|
|
|
|
{
|
|
|
|
OSL_PRECOND( _rxBinding.is(), "OBoundControlModel::connectExternalValueBinding: invalid binding instance!" );
|
|
|
|
OSL_PRECOND( approveValueBinding( _rxBinding ), "OBoundControlModel::connectExternalValueBinding: binding is not approved!" );
|
|
|
|
OSL_PRECOND( !hasExternalValueBinding( ), "OBoundControlModel::connectExternalValueBinding: precond not met (currently have a binding)!" );
|
|
|
|
|
|
|
|
// Suspend being a load listener at our parent form. This is because
|
|
|
|
// an external value binding overrules a possible database binding
|
|
|
|
if ( isLoadListening() )
|
|
|
|
stopLoadListening( );
|
|
|
|
|
|
|
|
// TODO: if we're already connected to a db column, we should disconnect from it here,
|
|
|
|
// shouldn't we?
|
|
|
|
|
|
|
|
// remember this new binding
|
|
|
|
m_xExternalBinding = _rxBinding;
|
|
|
|
|
|
|
|
// add as value listener so we get notified when the value changes
|
|
|
|
Reference< XModifyBroadcaster > xModifiable( m_xExternalBinding, UNO_QUERY );
|
|
|
|
if ( xModifiable.is() )
|
|
|
|
xModifiable->addModifyListener( this );
|
|
|
|
|
|
|
|
// tell the derivee
|
|
|
|
onConnectedExternalValue();
|
|
|
|
|
|
|
|
// propagate our new value
|
|
|
|
transferExternalValueToControl( );
|
2004-04-02 09:52:14 +00:00
|
|
|
|
|
|
|
// if the binding is also a validator, use it, too. This is a constraint of the
|
|
|
|
// com.sun.star.form.binding.ValidatableBindableFormComponent service
|
|
|
|
try
|
|
|
|
{
|
|
|
|
Reference< XValidator > xAsValidator( _rxBinding, UNO_QUERY );
|
|
|
|
if ( xAsValidator.is() )
|
|
|
|
setValidator( xAsValidator );
|
|
|
|
}
|
|
|
|
catch( const Exception& )
|
|
|
|
{
|
|
|
|
OSL_ENSURE( sal_False, "OBoundControlModel::connectExternalValueBinding: caught an exception while establishing the binding as validator!" );
|
|
|
|
}
|
2003-10-21 07:57:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
void OBoundControlModel::disconnectExternalValueBinding( )
|
|
|
|
{
|
|
|
|
// not listening at the binding anymore
|
|
|
|
Reference< XModifyBroadcaster > xModifiable( m_xExternalBinding, UNO_QUERY );
|
|
|
|
if ( xModifiable.is() )
|
|
|
|
xModifiable->removeModifyListener( this );
|
|
|
|
|
2004-04-02 09:52:14 +00:00
|
|
|
// if the binding also acts as our validator, disconnect the validator, too
|
|
|
|
if ( ( m_xExternalBinding == m_xValidator ) && m_xValidator.is() )
|
|
|
|
disconnectValidator( );
|
|
|
|
|
2003-10-21 07:57:42 +00:00
|
|
|
// no binding anymore
|
|
|
|
m_xExternalBinding.clear();
|
|
|
|
|
|
|
|
// be a load listener at our parent, again. This was suspended while we had
|
|
|
|
// an external value binding in place.
|
|
|
|
if ( m_xParent.is() )
|
|
|
|
startLoadListening( );
|
|
|
|
|
|
|
|
// TODO: anything to care for here? Changing values? Falling back to a
|
|
|
|
// database binding if appropriate?
|
|
|
|
|
|
|
|
// tell the derivee
|
|
|
|
onDisconnectedExternalValue();
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
void SAL_CALL OBoundControlModel::setValueBinding( const Reference< XValueBinding >& _rxBinding ) throw (IncompatibleTypesException, RuntimeException)
|
|
|
|
{
|
|
|
|
::osl::MutexGuard aGuard( m_aMutex );
|
|
|
|
|
|
|
|
OSL_PRECOND( m_bSupportsExternalBinding, "OBoundControlModel::setValueBinding: How did you reach this method?" );
|
|
|
|
// the interface for this method should not have been exposed if we do not
|
|
|
|
// support binding to external data
|
|
|
|
|
|
|
|
if ( _rxBinding.is() && !approveValueBinding( _rxBinding ) )
|
|
|
|
{
|
|
|
|
throw IncompatibleTypesException(
|
2004-04-02 09:52:14 +00:00
|
|
|
FRM_RES_STRING( RID_STR_INCOMPATIBLE_TYPES ),
|
2003-10-21 07:57:42 +00:00
|
|
|
*this
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
// disconnect from the old binding
|
|
|
|
if ( hasExternalValueBinding() )
|
|
|
|
disconnectExternalValueBinding( );
|
|
|
|
|
|
|
|
// connect to the new binding
|
|
|
|
if ( _rxBinding.is() )
|
|
|
|
connectExternalValueBinding( _rxBinding );
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
Reference< XValueBinding > SAL_CALL OBoundControlModel::getValueBinding( ) throw (RuntimeException)
|
|
|
|
{
|
|
|
|
::osl::MutexGuard aGuard( m_aMutex );
|
|
|
|
OSL_PRECOND( m_bSupportsExternalBinding, "OBoundControlModel::getValueBinding: How did you reach this method?" );
|
|
|
|
// the interface for this method should not have been exposed if we do not
|
|
|
|
// support binding to external data
|
|
|
|
|
|
|
|
return m_xExternalBinding;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
void SAL_CALL OBoundControlModel::modified( const EventObject& _rEvent ) throw ( RuntimeException )
|
|
|
|
{
|
|
|
|
::osl::MutexGuard aGuard( m_aMutex );
|
|
|
|
|
|
|
|
OSL_PRECOND( hasExternalValueBinding(), "OBoundControlModel::modified: Where did this come from?" );
|
|
|
|
if ( hasExternalValueBinding() && ( m_xExternalBinding == _rEvent.Source ) )
|
|
|
|
{
|
|
|
|
transferExternalValueToControl( );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
void OBoundControlModel::transferDbValueToControl( )
|
|
|
|
{
|
|
|
|
setControlValue( translateDbColumnToControlValue() );
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void OBoundControlModel::transferExternalValueToControl( )
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
setControlValue( translateExternalValueToControlValue( ) );
|
|
|
|
}
|
|
|
|
catch( const Exception& )
|
|
|
|
{
|
|
|
|
OSL_ENSURE( sal_False, "OBoundControlModel::transferExternalValueToControl: caught an exception!" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void OBoundControlModel::transferControlValueToExternal( )
|
|
|
|
{
|
|
|
|
OSL_PRECOND( m_bSupportsExternalBinding && hasExternalValueBinding(),
|
|
|
|
"OBoundControlModel::transferControlValueToExternal: precondition not met!" );
|
|
|
|
|
|
|
|
if ( m_xExternalBinding.is() )
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
m_xExternalBinding->setValue( translateControlValueToExternalValue( ) );
|
|
|
|
}
|
|
|
|
catch( const IncompatibleTypesException& )
|
|
|
|
{
|
|
|
|
OSL_ENSURE( sal_False, "OBoundControlModel::transferControlValueToExternal: could not commit the value (incomptible types)!" );
|
|
|
|
}
|
|
|
|
catch( const NoSupportException& )
|
|
|
|
{
|
|
|
|
OSL_ENSURE( sal_False, "OBoundControlModel::transferControlValueToExternal: could not commit the value (no support)!" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
Any OBoundControlModel::translateExternalValueToControlValue( )
|
|
|
|
{
|
|
|
|
OSL_PRECOND( m_bSupportsExternalBinding && hasExternalValueBinding(),
|
|
|
|
"OBoundControlModel::translateExternalValueToControlValue: precondition not met!" );
|
|
|
|
|
|
|
|
// determine the type of our value property
|
|
|
|
if ( m_sValuePropertyName.getLength() && m_xAggregateSet.is() )
|
|
|
|
{
|
|
|
|
Reference< XPropertySetInfo > xPropInfo( m_xAggregateSet->getPropertySetInfo( ) );
|
|
|
|
if ( xPropInfo.is() )
|
|
|
|
{
|
|
|
|
Type aValuePropType = xPropInfo->getPropertyByName( m_sValuePropertyName ).Type;
|
|
|
|
if ( m_xExternalBinding.is() && m_xExternalBinding->supportsType( aValuePropType ) )
|
|
|
|
return m_xExternalBinding->getValue( aValuePropType );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
OSL_ENSURE( sal_False, "OBoundControlModel::translateExternalValueToControlValue: no default implementation available!" );
|
|
|
|
return Any();
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
Any OBoundControlModel::translateControlValueToExternalValue( )
|
2004-04-02 09:52:14 +00:00
|
|
|
{
|
|
|
|
return getControlValue( );
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
Any OBoundControlModel::translateControlValueToValidatableValue( ) const
|
|
|
|
{
|
|
|
|
return getControlValue();
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
Any OBoundControlModel::getControlValue( ) const
|
2003-10-21 07:57:42 +00:00
|
|
|
{
|
|
|
|
OSL_PRECOND( m_xAggregateFastSet.is() && m_xAggregateSet.is(),
|
2004-04-02 09:52:14 +00:00
|
|
|
"OBoundControlModel::getControlValue: invalid aggregate !" );
|
2003-10-21 07:57:42 +00:00
|
|
|
OSL_PRECOND( m_sValuePropertyName.getLength() || ( m_nValuePropertyAggregateHandle != -1 ),
|
2004-04-02 09:52:14 +00:00
|
|
|
"OBoundControlModel::getControlValue: please override if you have own value property handling!" );
|
2003-10-21 07:57:42 +00:00
|
|
|
|
|
|
|
// determine the current control value
|
|
|
|
Any aControlValue;
|
|
|
|
if ( ( m_nValuePropertyAggregateHandle != -1 ) && m_xAggregateFastSet.is() )
|
|
|
|
{
|
|
|
|
aControlValue = m_xAggregateFastSet->getFastPropertyValue( m_nValuePropertyAggregateHandle );
|
|
|
|
}
|
|
|
|
else if ( m_sValuePropertyName.getLength() && m_xAggregateSet.is() )
|
|
|
|
{
|
|
|
|
aControlValue = m_xAggregateSet->getPropertyValue( m_sValuePropertyName );
|
|
|
|
}
|
|
|
|
|
|
|
|
return aControlValue;
|
|
|
|
}
|
|
|
|
|
2004-04-02 09:52:14 +00:00
|
|
|
//--------------------------------------------------------------------
|
|
|
|
void OBoundControlModel::connectValidator( const Reference< XValidator >& _rxValidator )
|
|
|
|
{
|
|
|
|
OSL_PRECOND( _rxValidator.is(), "OBoundControlModel::connectValidator: invalid validator instance!" );
|
|
|
|
OSL_PRECOND( !hasValidator( ), "OBoundControlModel::connectValidator: precond not met (have a validator currently)!" );
|
|
|
|
|
|
|
|
m_xValidator = _rxValidator;
|
|
|
|
|
|
|
|
// add as value listener so we get notified when the value changes
|
|
|
|
if ( m_xValidator.is() )
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
m_xValidator->addValidityConstraintListener( this );
|
|
|
|
}
|
|
|
|
catch( const RuntimeException& )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
onConnectedValidator( );
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
void OBoundControlModel::disconnectValidator( )
|
|
|
|
{
|
|
|
|
OSL_PRECOND( hasValidator( ), "OBoundControlModel::connectValidator: precond not met (don't have a validator currently)!" );
|
|
|
|
|
|
|
|
// add as value listener so we get notified when the value changes
|
|
|
|
if ( m_xValidator.is() )
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
m_xValidator->removeValidityConstraintListener( this );
|
|
|
|
}
|
|
|
|
catch( const RuntimeException& )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m_xValidator.clear();
|
|
|
|
|
|
|
|
onDisconnectedValidator( );
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
void SAL_CALL OBoundControlModel::setValidator( const Reference< XValidator >& _rxValidator ) throw (VetoException,RuntimeException)
|
|
|
|
{
|
|
|
|
::osl::ClearableMutexGuard aGuard( m_aMutex );
|
|
|
|
OSL_PRECOND( m_bSupportsValidation, "OBoundControlModel::setValidator: How did you reach this method?" );
|
|
|
|
// the interface for this method should not have been exposed if we do not
|
|
|
|
// support validation
|
|
|
|
|
|
|
|
if ( m_xValidator.is() && ( m_xValidator == m_xExternalBinding ) )
|
|
|
|
throw VetoException(
|
|
|
|
FRM_RES_STRING( RID_STR_INVALID_VALIDATOR ),
|
|
|
|
*this
|
|
|
|
);
|
|
|
|
|
|
|
|
// disconnect from the old validator
|
|
|
|
if ( hasValidator() )
|
|
|
|
disconnectValidator( );
|
|
|
|
|
|
|
|
// connect to the new validator
|
|
|
|
if ( _rxValidator.is() )
|
|
|
|
connectValidator( _rxValidator );
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
Reference< XValidator > SAL_CALL OBoundControlModel::getValidator( ) throw (RuntimeException)
|
|
|
|
{
|
|
|
|
::osl::MutexGuard aGuard( m_aMutex );
|
|
|
|
OSL_PRECOND( m_bSupportsValidation, "OBoundControlModel::getValidator: How did you reach this method?" );
|
|
|
|
// the interface for this method should not have been exposed if we do not
|
|
|
|
// support validation
|
|
|
|
|
|
|
|
return m_xValidator;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
void SAL_CALL OBoundControlModel::validityConstraintChanged( const EventObject& Source ) throw (RuntimeException)
|
|
|
|
{
|
|
|
|
::osl::ClearableMutexGuard aGuard( m_aMutex );
|
|
|
|
OSL_PRECOND( m_bSupportsValidation, "OBoundControlModel::validityConstraintChanged: How did you reach this method?" );
|
|
|
|
// the interface for this method should not have been exposed if we do not
|
|
|
|
// support validation
|
|
|
|
|
|
|
|
recheckValidity( false );
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
sal_Bool SAL_CALL OBoundControlModel::isValid( ) throw (RuntimeException)
|
|
|
|
{
|
|
|
|
return m_bIsCurrentValueValid;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
Any SAL_CALL OBoundControlModel::getCurrentValue( ) throw (RuntimeException)
|
|
|
|
{
|
|
|
|
return translateControlValueToValidatableValue();
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
void SAL_CALL OBoundControlModel::addFormComponentValidityListener( const Reference< validation::XFormComponentValidityListener >& Listener ) throw (NullPointerException, RuntimeException)
|
|
|
|
{
|
|
|
|
if ( !Listener.is() )
|
|
|
|
throw NullPointerException();
|
|
|
|
m_pFormComponentListeners->addListener( Listener );
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
void SAL_CALL OBoundControlModel::removeFormComponentValidityListener( const Reference< validation::XFormComponentValidityListener >& Listener ) throw (NullPointerException, RuntimeException)
|
|
|
|
{
|
|
|
|
if ( !Listener.is() )
|
|
|
|
throw NullPointerException();
|
|
|
|
m_pFormComponentListeners->removeListener( Listener );
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
void OBoundControlModel::recheckValidity( bool _bForceNotification )
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
sal_Bool bIsCurrentlyValid = sal_True;
|
|
|
|
if ( hasValidator() )
|
|
|
|
bIsCurrentlyValid = m_xValidator->isValid( translateControlValueToValidatableValue() );
|
|
|
|
|
|
|
|
if ( ( bIsCurrentlyValid != m_bIsCurrentValueValid ) || _bForceNotification )
|
|
|
|
{
|
|
|
|
m_bIsCurrentValueValid = bIsCurrentlyValid;
|
|
|
|
|
|
|
|
// release our mutex for the notifications
|
|
|
|
MutexRelease aRelease( m_aMutex );
|
|
|
|
m_pFormComponentListeners->notify( EventObject( *this ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch( const Exception& )
|
|
|
|
{
|
|
|
|
OSL_ENSURE( sal_False, "OBoundControlModel::recheckValidity: caught an exception!" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void OBoundControlModel::fillProperties( Sequence< Property >& /* [out] */ _rProps, Sequence< Property >& /* [out] */ _rAggregateProps ) const
|
|
|
|
{
|
|
|
|
BEGIN_DESCRIBE_PROPERTIES( 4, OControlModel )
|
|
|
|
DECL_PROP1 ( CONTROLSOURCE, ::rtl::OUString, BOUND );
|
|
|
|
DECL_IFACE_PROP3( BOUNDFIELD, XPropertySet, BOUND, READONLY, TRANSIENT );
|
|
|
|
DECL_IFACE_PROP2( CONTROLLABEL, XPropertySet, BOUND, MAYBEVOID );
|
|
|
|
DECL_PROP2 ( CONTROLSOURCEPROPERTY, ::rtl::OUString, READONLY, TRANSIENT );
|
|
|
|
END_DESCRIBE_PROPERTIES()
|
|
|
|
}
|
|
|
|
|
2003-05-19 12:08:37 +00:00
|
|
|
// -----------------------------------------------------------------------------
|
2000-09-18 15:33:13 +00:00
|
|
|
|
|
|
|
//.........................................................................
|
|
|
|
}
|
|
|
|
//... namespace frm .......................................................
|
|
|
|
|