Files
libreoffice/forms/source/component/FormComponent.cxx

1567 lines
55 KiB
C++
Raw Normal View History

2000-09-18 15:33:13 +00:00
/*************************************************************************
*
* $RCSfile: FormComponent.cxx,v $
*
* $Revision: 1.18 $
2000-09-18 15:33:13 +00:00
*
* last change: $Author: fs $ $Date: 2002-03-04 13:59:21 $
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
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
#ifndef _COMPHELPER_BASIC_IO_HXX_
2001-04-04 11:56:34 +00:00
#include <comphelper/basicio.hxx>
#endif
#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
{
//.........................................................................
2000-11-23 07:48:15 +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 ::dbtools;
using namespace ::comphelper;
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
2000-11-23 07:48:15 +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
//------------------------------------------------------------------------------
2001-09-12 14:59:39 +00:00
sal_Bool SAL_CALL OControl::supportsService(const rtl::OUString& _rsServiceName) throw ( ::com::sun::star::uno::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;
}
//------------------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
Sequence<rtl::OUString> SAL_CALL OControl::getSupportedServiceNames() throw(RuntimeException)
2000-09-18 15:33:13 +00:00
{
Sequence< rtl::OUString > aSupported;
2000-09-18 15:33:13 +00:00
// ask our aggregate
Reference< com::sun::star::lang::XServiceInfo > xInfo;
if ( query_aggregation( m_xAggregate, xInfo ) )
2000-09-18 15:33:13 +00:00
aSupported = xInfo->getSupportedServiceNames();
return aSupported;
}
// 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();
}
//------------------------------------------------------------------------------
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);
}
//------------------------------------------------------------------------------
2001-09-12 14:59:39 +00:00
Reference<XWindowPeer> SAL_CALL OControl::getPeer() throw ( ::com::sun::star::uno::RuntimeException)
2000-09-18 15:33:13 +00:00
{
return m_xControl.is() ? m_xControl->getPeer() : Reference<XWindowPeer>();
2000-09-18 15:33:13 +00:00
}
//------------------------------------------------------------------------------
2001-09-12 14:59:39 +00:00
sal_Bool SAL_CALL OControl::setModel(const Reference<XControlModel>& Model) throw ( ::com::sun::star::uno::RuntimeException)
2000-09-18 15:33:13 +00:00
{
return m_xControl.is() ? m_xControl->setModel( Model ) : sal_False;
}
//------------------------------------------------------------------------------
2001-09-12 14:59:39 +00:00
Reference<XControlModel> SAL_CALL OControl::getModel() throw ( ::com::sun::star::uno::RuntimeException)
2000-09-18 15:33:13 +00:00
{
return m_xControl.is() ? m_xControl->getModel() : Reference<XControlModel>();
2000-09-18 15:33:13 +00:00
}
//------------------------------------------------------------------------------
2001-09-12 14:59:39 +00:00
Reference<XView> SAL_CALL OControl::getView() throw ( ::com::sun::star::uno::RuntimeException)
2000-09-18 15:33:13 +00:00
{
return m_xControl.is() ? m_xControl->getView() : Reference<XView>();
2000-09-18 15:33:13 +00:00
}
//------------------------------------------------------------------------------
2001-09-12 14:59:39 +00:00
void SAL_CALL OControl::setDesignMode(sal_Bool bOn) throw ( ::com::sun::star::uno::RuntimeException)
2000-09-18 15:33:13 +00:00
{
if (m_xControl.is())
m_xControl->setDesignMode(bOn);
}
//------------------------------------------------------------------------------
2001-09-12 14:59:39 +00:00
sal_Bool SAL_CALL OControl::isDesignMode() throw ( ::com::sun::star::uno::RuntimeException)
2000-09-18 15:33:13 +00:00
{
return m_xControl.is() ? m_xControl->isDesignMode() : sal_True;
}
//------------------------------------------------------------------------------
2001-09-12 14:59:39 +00:00
sal_Bool SAL_CALL OControl::isTransparent() throw ( ::com::sun::star::uno::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)
{
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 the base class
2000-11-23 07:48:15 +00:00
Any aReturn = OControl::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 = OBoundControl_BASE::queryInterface(_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
Reference<XWindowPeer> xPeer = getPeer();
2000-11-23 07:48:15 +00:00
Reference<com::sun::star::awt::XTextComponent> xText(xPeer, UNO_QUERY);
2000-09-18 15:33:13 +00:00
if (xText.is())
xText->setEditable(!_bLock);
else
{
// disable the window
Reference<XWindow> xComp(xPeer, UNO_QUERY);
2000-09-18 15:33:13 +00:00
if (xComp.is())
xComp->setEnable(!_bLock);
}
}
//==================================================================
//= 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
2000-11-23 07:48:15 +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
{
2000-09-18 15:33:13 +00:00
aReturn = OPropertySetAggregationHelper::queryInterface(_rType);
2000-11-23 07:48:15 +00:00
// our own interfaces
if (!aReturn.hasValue())
{
aReturn = OControlModel_BASE::queryInterface(_rType);
// our aggregate
if (!aReturn.hasValue() && m_xAggregate.is())
aReturn = m_xAggregate->queryAggregation(_rType);
}
}
2000-09-18 15:33:13 +00:00
return aReturn;
}
//------------------------------------------------------------------------------
void OControlModel::readHelpTextCompatibly(const staruno::Reference< stario::XObjectInputStream >& _rxInStream)
{
::rtl::OUString sHelpText;
2001-04-04 11:56:34 +00:00
::comphelper::operator>>( _rxInStream, sHelpText);
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);
}
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,
const ::rtl::OUString& rDefault, const sal_Bool _bSetDelegator)
2000-09-18 15:33:13 +00:00
:OComponentHelper(m_aMutex)
,OPropertySetAggregationHelper(OComponentHelper::rBHelper)
,m_aUnoControlModelTypeName(_rUnoControlModelTypeName)
,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);
// Muss im eigenen Block,
// da xAgg vor dem delegator setzen wieder freigesetzt sein mu<6D>!
{
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
}
if (_bSetDelegator)
doSetDelegator();
2000-09-18 15:33:13 +00:00
// Refcount wieder bei NULL
decrement(m_refCount);
2000-09-18 15:33:13 +00:00
}
}
//------------------------------------------------------------------
OControlModel::~OControlModel()
{
DBG_DTOR(OControlModel, NULL);
// release the aggregate
if (m_xAggregate.is())
m_xAggregate->setDelegator(InterfaceRef());
}
//------------------------------------------------------------------------------
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);
}
2000-09-18 15:33:13 +00:00
// XChild
//------------------------------------------------------------------------------
InterfaceRef SAL_CALL OControlModel::getParent() throw(::com::sun::star::uno::RuntimeException)
{
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);
Reference<com::sun::star::lang::XComponent> xComp(m_xParent, UNO_QUERY);
2000-09-18 15:33:13 +00:00
if (xComp.is())
xComp->removeEventListener(static_cast<XPropertiesChangeListener*>(this));
2000-09-18 15:33:13 +00:00
xComp = Reference<com::sun::star::lang::XComponent>(_rxParent, UNO_QUERY);
2000-09-18 15:33:13 +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
//------------------------------------------------------------------------------
2001-09-12 14:59:39 +00:00
sal_Bool SAL_CALL OControlModel::supportsService(const rtl::OUString& _rServiceName) throw ( ::com::sun::star::uno::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;
}
//------------------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
Sequence<rtl::OUString> SAL_CALL OControlModel::getSupportedServiceNames() throw(RuntimeException)
2000-09-18 15:33:13 +00:00
{
2000-11-23 07:48:15 +00:00
Sequence<rtl::OUString> aSupported;
2000-09-18 15:33:13 +00:00
// ask our aggregate
2000-11-23 07:48:15 +00:00
Reference<com::sun::star::lang::XServiceInfo> xInfo;
2000-09-18 15:33:13 +00:00
if (query_aggregation(m_xAggregate, xInfo))
aSupported = xInfo->getSupportedServiceNames();
aSupported.realloc(aSupported.getLength() + 2);
::rtl::OUString* pArray = aSupported.getArray();
pArray[aSupported.getLength()-2] = ::rtl::OUString::createFromAscii("com.sun.star.form.FormComponent");
pArray[aSupported.getLength()-1] = ::rtl::OUString::createFromAscii("com.sun.star.form.FormControlModel");
return aSupported;
}
// 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
{
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();
Reference<com::sun::star::lang::XComponent> xComp;
2000-09-18 15:33:13 +00:00
if (query_aggregation(m_xAggregate, xComp))
xComp->dispose();
setParent(Reference<XFormComponent>());
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
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);
Reference<stario::XPersistObject> xPersist;
2000-09-18 15:33:13 +00:00
if (query_aggregation(m_xAggregate, xPersist))
xPersist->write(_rxOutStream);
// 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);
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();
Reference<stario::XPersistObject> xPersist;
2000-09-18 15:33:13 +00:00
if (query_aggregation(m_xAggregate, xPersist))
xPersist->read(InStream);
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)
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)
}
//------------------------------------------------------------------------------
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)
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;
}
}
//==================================================================
//= 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
{
2001-06-12 05:02:47 +00:00
Any aReturn;
2000-09-18 15:33:13 +00:00
aReturn = OControlModel::queryAggregation(_rType);
if (!aReturn.hasValue())
2000-11-23 07:48:15 +00:00
{
aReturn = OBoundControlModel_BASE1::queryInterface(_rType);
if (!aReturn.hasValue() && m_bCommitable)
aReturn = OBoundControlModel_BASE2::queryInterface(_rType);
}
2000-09-18 15:33:13 +00:00
return aReturn;
}
//------------------------------------------------------------------
OBoundControlModel::OBoundControlModel(
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,
const ::rtl::OUString& _rDefault,
const sal_Bool _bCommitable,
const sal_Bool _bSetDelegator)
:OControlModel(_rxFactory, _rUnoControlModelTypeName, _rDefault, _bSetDelegator)
2000-09-18 15:33:13 +00:00
,m_aUpdateListeners(m_aMutex)
,m_aResetListeners(m_aMutex)
,m_bLoaded(sal_False)
,m_bRequired(sal_False)
,m_bCommitable(_bCommitable)
,m_aLabelServiceName(FRM_SUN_COMPONENT_FIXEDTEXT)
,m_bResetting(sal_False)
,m_bForwardValueChanges(sal_True)
{
DBG_CTOR(frm_OBoundControlModel, NULL);
}
//------------------------------------------------------------------
OBoundControlModel::~OBoundControlModel()
{
DBG_DTOR(frm_OBoundControlModel, NULL);
}
//-----------------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
Sequence<Type> OBoundControlModel::_getTypes()
2000-09-18 15:33:13 +00:00
{
if (m_bCommitable)
2000-11-23 07:48:15 +00:00
return concatSequences(OControlModel::_getTypes(),OBoundControlModel_BASE1::getTypes(),OBoundControlModel_BASE2::getTypes());
2000-09-18 15:33:13 +00:00
2000-11-23 07:48:15 +00:00
return concatSequences(OControlModel::_getTypes(),OBoundControlModel_BASE1::getTypes());
2000-09-18 15:33:13 +00:00
}
// OComponentHelper
//-----------------------------------------------------------------------------
void OBoundControlModel::disposing()
{
OControlModel::disposing();
osl::MutexGuard aGuard(m_aMutex);
2000-11-23 07:48:15 +00:00
com::sun::star::lang::EventObject aEvt(static_cast<XWeak*>(this));
2000-09-18 15:33:13 +00:00
m_aResetListeners.disposeAndClear(aEvt);
m_aUpdateListeners.disposeAndClear(aEvt);
if (m_xField.is())
{
m_xField->removePropertyChangeListener(PROPERTY_VALUE, this);
resetField();
}
m_xCursor = NULL;
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
}
// XChild
//------------------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
void SAL_CALL OBoundControlModel::setParent(const Reference<XInterface>& _rxParent) throw(com::sun::star::lang::NoSupportException, RuntimeException)
2000-09-18 15:33:13 +00:00
{
osl::MutexGuard aGuard(m_aMutex);
// log off old listeners
2000-11-23 07:48:15 +00:00
Reference<XLoadable> xLoadable(m_xParent, UNO_QUERY);
2000-09-18 15:33:13 +00:00
if (xLoadable.is())
xLoadable->removeLoadListener(this);
// log on new listeners
2000-11-23 07:48:15 +00:00
xLoadable = Reference<XLoadable>(_rxParent, UNO_QUERY);
2000-09-18 15:33:13 +00:00
if (xLoadable.is())
xLoadable->addLoadListener(this);
OControlModel::setParent(_rxParent);
}
// 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
{
osl::MutexGuard aGuard(m_aMutex);
if (m_xField == _rEvent.Source)
{
resetField();
}
else if (m_xLabelControl == _rEvent.Source)
{
2000-11-23 07:48:15 +00:00
Reference<XPropertySet> xOldValue = m_xLabelControl;
2000-09-18 15:33:13 +00:00
m_xLabelControl = NULL;
// fire a property change event
2000-11-23 07:48:15 +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;
OPropertySetHelper::fire(&nHandle, &aNewValue, &aOldValue, 1, sal_False);
}
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
{
StringSequence aSupported = OControlModel::getSupportedServiceNames();
aSupported.realloc(aSupported.getLength() + 1);
::rtl::OUString* pArray = aSupported.getArray();
pArray[aSupported.getLength()-1] = ::rtl::OUString::createFromAscii("com.sun.star.form.DataAwareControlModel");
return aSupported;
}
// 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();
2000-11-23 07:48:15 +00:00
m_xLabelControl = Reference<XPropertySet>(xPersist, UNO_QUERY);
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
// 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:
rValue <<= m_sDataFieldConnectivityProperty;
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)
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
{
2000-09-18 15:33:13 +00:00
bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_xLabelControl);
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
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
{
// Bei Wertaenderung neu initialisieren
if (evt.PropertyName.equals(PROPERTY_VALUE))
{
osl::MutexGuard aGuard(m_aMutex);
if (m_bForwardValueChanges && m_xColumn.is())
_onValueChanged();
}
}
// 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
{
DBG_ASSERT(m_bCommitable, "OBoundControlModel::commit : invalid call (I'm not commitable !) ");
{
osl::MutexGuard aGuard(m_aMutex);
if (!m_xField.is())
return sal_True;
}
cppu::OInterfaceIteratorHelper aIter(m_aUpdateListeners);
2000-11-23 07:48:15 +00:00
com::sun::star::lang::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)
2000-11-23 07:48:15 +00:00
bSucceed = ((XUpdateListener*)aIter.next())->approveUpdate(aEvt);
2000-09-18 15:33:13 +00:00
if (bSucceed)
{
osl::MutexGuard aGuard(m_aMutex);
try
{
bSucceed = _commit();
}
2000-11-23 07:48:15 +00:00
catch(Exception&)
2000-09-18 15:33:13 +00:00
{
bSucceed = sal_False;
}
}
if (bSucceed)
{
cppu::OInterfaceIteratorHelper aIter(m_aUpdateListeners);
while (aIter.hasMoreElements())
2000-11-23 07:48:15 +00:00
((XUpdateListener*)aIter.next())->updated(aEvt);
2000-09-18 15:33:13 +00:00
}
return bSucceed;
}
//------------------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
sal_Bool OBoundControlModel::connectToField(const Reference<XRowSet>& rForm)
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;
if (_approve(nFieldType))
m_xField = xFieldCandidate;
}
else
m_xField = NULL;
if (m_xField.is())
{
if(m_xField->getPropertySetInfo()->hasPropertyByName(PROPERTY_VALUE))
{
// an wertaenderungen horchen
m_xField->addPropertyChangeListener(PROPERTY_VALUE, this);
2000-11-23 07:48:15 +00:00
m_xColumnUpdate = Reference<XColumnUpdate>(m_xField, UNO_QUERY);
m_xColumn = Reference<XColumn>(m_xField, UNO_QUERY);
2000-09-18 15:33:13 +00:00
INT32 nNullableFlag; 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!");
2000-09-18 15:33:13 +00:00
m_xField = NULL;
}
}
}
return m_xField.is();
}
//------------------------------------------------------------------------------
sal_Bool OBoundControlModel::_approve(sal_Int32 _nColumnType)
{
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;
}
// XLoadListener
//------------------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
void SAL_CALL OBoundControlModel::loaded(const com::sun::star::lang::EventObject& _rEvent) throw(RuntimeException)
2000-09-18 15:33:13 +00:00
{
osl::MutexGuard aGuard(m_aMutex);
Reference<XRowSet> xForm(_rEvent.Source, UNO_QUERY);
2000-09-18 15:33:13 +00:00
connectToField(xForm);
m_bLoaded = sal_True;
_loaded(_rEvent);
if (m_xField.is())
{
// initially call _onValueChanged
// but only if the rowset if posisitioned on a valid record
Reference< XRowSet > xRowset( _rEvent.Source, UNO_QUERY );
OSL_ENSURE( xRowset.is(), "OBoundControlModel::loaded: invalid event source (no rowset)!" );
if ( xRowset.is() )
{
if ( !xRowset->isBeforeFirst() && !xRowset->isAfterLast() )
_onValueChanged();
}
}
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
{
}
//------------------------------------------------------------------------------
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
{
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
{
osl::MutexGuard aGuard(m_aMutex);
_unloaded();
if (m_xField.is())
{
m_xField->removePropertyChangeListener(PROPERTY_VALUE, this);
resetField();
}
m_xCursor = NULL;
m_bLoaded = sal_False;
}
//------------------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
void SAL_CALL OBoundControlModel::reloaded(const com::sun::star::lang::EventObject& aEvent) throw(RuntimeException)
2000-09-18 15:33:13 +00:00
{
osl::MutexGuard aGuard(m_aMutex);
// did we lost the connection to the field because there was a new created?
if (!m_xField.is())
{
2000-11-23 07:48:15 +00:00
Reference<XRowSet> xForm(aEvent.Source, UNO_QUERY);
2000-09-18 15:33:13 +00:00
connectToField(xForm);
}
m_bForwardValueChanges = sal_True;
_loaded(aEvent);
2000-09-18 15:33:13 +00:00
// do we have a field, than get the new value
if (m_xField.is())
_onValueChanged();
}
//------------------------------------------------------------------------------
void OBoundControlModel::_loaded(const com::sun::star::lang::EventObject& rEvent)
2000-09-18 15:33:13 +00:00
{
}
//------------------------------------------------------------------------------
void OBoundControlModel::_unloaded()
{
}
// XReset
//-----------------------------------------------------------------------------
void OBoundControlModel::_reset()
{
}
//-----------------------------------------------------------------------------
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);
2000-11-23 07:48:15 +00:00
com::sun::star::lang::EventObject aResetEvent(static_cast<XWeak*>(this));
2000-09-18 15:33:13 +00:00
sal_Bool bContinue = sal_True;
while (aIter.hasMoreElements() && bContinue)
2000-11-23 07:48:15 +00:00
bContinue = reinterpret_cast<XResetListener*>(aIter.next())->approveReset(aResetEvent);
2000-09-18 15:33:13 +00:00
if (!bContinue)
return;
osl::ClearableMutexGuard aGuard(m_aMutex);
m_bResetting = sal_True;
// gesondertes Verhalten bei Datenbankverbindung
if (m_xField.is())
{
// nur wenn der derzeitige Wert des Feldes auf NULL steht
// werden die Defaultwerte gesetzt
// ansonsten soll der aktuelle Werte nochmals aus dem Feld gesetzt werden
// dieses Verhalten ist noch nicht ganz ausgereift, was passiert wenn das Feld einen Defaultwert besitzt
// und das Control auch?
sal_Bool bIsNull = sal_True;
// we have to access the field content at least once to get a reliable result by XColumn::wasNull
try
{
m_xColumn->getString();
}
2000-11-23 07:48:15 +00:00
catch(Exception&)
2000-09-18 15:33:13 +00:00
{
DBG_ERROR("OBoundControlModel::reset : XColumn::getString is expected to always succeed !");
}
bIsNull = m_xColumn->wasNull();
if (bIsNull)
{
2000-11-23 07:48:15 +00:00
Reference<XPropertySet> xSet(m_xCursor, UNO_QUERY);
2000-09-18 15:33:13 +00:00
sal_Bool bIsNewRecord = sal_False;
if (xSet.is())
xSet->getPropertyValue(PROPERTY_ISNEW) >>= bIsNewRecord;
if (bIsNewRecord)
{
_reset(); // setzen der Werte,
_commit(); // uebertragen der Werte ins Feld
// fuer das zuruecksetzen des modifyflags ist das Formular zust<73>ndig
}
else
_onValueChanged();
}
else
_onValueChanged();
}
else
_reset();
m_bResetting = sal_False;
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
}
//.........................................................................
}
//... namespace frm .......................................................