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

1247 lines
49 KiB
C++
Raw Normal View History

2000-09-18 15:33:13 +00:00
/*************************************************************************
*
* $RCSfile: FormattedField.cxx,v $
*
* $Revision: 1.15 $
2000-09-18 15:33:13 +00:00
*
* last change: $Author: fs $ $Date: 2001-06-25 10:30:09 $
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_FORMATTEDFIELD_HXX_
#include "FormattedField.hxx"
#endif
#ifndef _FRM_SERVICES_HXX_
#include "services.hxx"
#endif
#ifndef _FRM_PROPERTY_HRC_
#include "property.hrc"
#endif
#ifndef _FRM_PROPERTY_HXX_
#include "property.hxx"
#endif
2000-10-19 10:52:20 +00:00
#ifndef _COMPHELPER_SEQUENCE_HXX_
#include <comphelper/sequence.hxx>
2000-09-18 15:33:13 +00:00
#endif
2000-10-19 10:52:20 +00:00
#ifndef _COMPHELPER_NUMBERS_HXX_
#include <comphelper/numbers.hxx>
2000-09-18 15:33:13 +00:00
#endif
2000-10-19 10:52:20 +00:00
#ifndef _COMPHELPER_DATETIME_HXX_
#include <comphelper/datetime.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
2000-10-19 10:52:20 +00:00
#ifndef _DBHELPER_DBCONVERSION_HXX_
#include <connectivity/dbconversion.hxx>
2000-09-18 15:33:13 +00:00
#endif
#ifndef _ZFORLIST_HXX //autogen
#include <svtools/zforlist.hxx>
#endif
#ifndef _NUMUNO_HXX
#include <svtools/numuno.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _TOOLS_VCLRSC_HXX
#include <tools/vclrsc.hxx>
#endif
#ifndef _ISOLANG_HXX
#include <tools/isolang.hxx>
#endif
#ifndef _RTL_TEXTENC_H
#include <rtl/textenc.h>
#endif
#ifndef _COM_SUN_STAR_SDBC_DATATYPE_HPP_
#include <com/sun/star/sdbc/DataType.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_NUMBERFORMAT_HPP_
#include <com/sun/star/util/NumberFormat.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_MOUSEEVENT_HPP_
#include <com/sun/star/awt/MouseEvent.hpp>
#endif
#ifndef _COM_SUN_STAR_FORM_XSUBMIT_HPP_
#include <com/sun/star/form/XSubmit.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XWINDOW_HPP_
#include <com/sun/star/awt/XWindow.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XKEYLISTENER_HPP_
#include <com/sun/star/awt/XKeyListener.hpp>
#endif
#ifndef _COM_SUN_STAR_FORM_FORMCOMPONENTTYPE_HPP_
#include <com/sun/star/form/FormComponentType.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATSSUPPLIER_HPP_
#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATTYPES_HPP_
#include <com/sun/star/util/XNumberFormatTypes.hpp>
#endif
#ifndef _COM_SUN_STAR_FORM_XFORM_HPP_
#include <com/sun/star/form/XForm.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XINDEXACCESS_HPP_
#include <com/sun/star/container/XIndexAccess.hpp>
#endif
#ifndef _VOS_MUTEX_HXX_
#include <vos/mutex.hxx>
#endif
// needed as long as we use the SolarMutex
2000-11-23 07:48:15 +00:00
using namespace dbtools;
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;
2000-09-18 15:33:13 +00:00
//namespace stario = ::com::sun::star::io;
2000-10-19 10:52:20 +00:00
2000-09-18 15:33:13 +00:00
/** implements handling for compatibly reading/writing data from/into an input/output stream.
data written in a block secured by this class should be readable by older versions which
use the same mechanism.
*/
/*************************************************************************/
class OMarkableStreamBlock
{
2001-05-18 13:44:30 +00:00
Reference< XMarkableStream > m_xMarkStream;
Reference< XDataInputStream > m_xInStream;
Reference< XDataOutputStream > m_xOutStream;
2000-09-18 15:33:13 +00:00
sal_Int32 m_nBlockStart;
sal_Int32 m_nBlockLen;
public:
/** starts reading of a "skippable" block of data within the given input stream<BR>
The object given by _rxInput must support the XMarkableStream interface.
*/
2001-05-18 13:44:30 +00:00
OMarkableStreamBlock(const Reference< XDataInputStream >& _rxInput);
2000-09-18 15:33:13 +00:00
/** starts writing of a "skippable" block of data into the given output stream
The object given by _rxOutput must support the XMarkableStream interface.
*/
2001-05-18 13:44:30 +00:00
OMarkableStreamBlock(const Reference< XDataOutputStream >& _rxOutput);
2000-09-18 15:33:13 +00:00
~OMarkableStreamBlock();
};
//-------------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
OMarkableStreamBlock::OMarkableStreamBlock(const Reference< XDataInputStream >& _rxInput)
2000-09-18 15:33:13 +00:00
:m_xInStream(_rxInput)
2000-11-23 07:48:15 +00:00
,m_xMarkStream(_rxInput, UNO_QUERY)
2000-09-18 15:33:13 +00:00
,m_nBlockStart(-1)
,m_nBlockLen(-1)
{
DBG_ASSERT(m_xInStream.is() && m_xMarkStream.is(), "OMarkableStreamBlock::OMarkableStreamBlock : invaid argument !");
if (m_xInStream.is() && m_xMarkStream.is())
{
m_nBlockLen = _rxInput->readLong();
m_nBlockStart = m_xMarkStream->createMark();
}
}
//-------------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
OMarkableStreamBlock::OMarkableStreamBlock(const Reference< XDataOutputStream >& _rxOutput)
2000-09-18 15:33:13 +00:00
:m_xOutStream(_rxOutput)
2000-11-23 07:48:15 +00:00
,m_xMarkStream(_rxOutput, UNO_QUERY)
2000-09-18 15:33:13 +00:00
,m_nBlockStart(-1)
,m_nBlockLen(-1)
{
DBG_ASSERT(m_xOutStream.is() && m_xMarkStream.is(), "OMarkableStreamBlock::OMarkableStreamBlock : invaid argument !");
if (m_xOutStream.is() && m_xMarkStream.is())
{
m_nBlockStart = m_xMarkStream->createMark();
// a placeholder where we will write the overall length (within the destructor)
m_nBlockLen = 0;
m_xOutStream->writeLong(m_nBlockLen);
}
}
//-------------------------------------------------------------------------
OMarkableStreamBlock::~OMarkableStreamBlock()
{
if (m_xInStream.is() && m_xMarkStream.is())
{ // we're working on an input stream
m_xMarkStream->jumpToMark(m_nBlockStart);
m_xInStream->skipBytes(m_nBlockLen);
m_xMarkStream->deleteMark(m_nBlockStart);
}
else if (m_xOutStream.is() && m_xMarkStream.is())
{
m_nBlockLen = m_xMarkStream->offsetToMark(m_nBlockStart) - sizeof(m_nBlockLen);
m_xMarkStream->jumpToMark(m_nBlockStart);
m_xOutStream->writeLong(m_nBlockLen);
m_xMarkStream->jumpToFurthest();
m_xMarkStream->deleteMark(m_nBlockStart);
}
}
//.........................................................................
namespace frm
{
/*************************************************************************/
class StandardFormatsSupplier : protected SvNumberFormatsSupplierObj
{
protected:
SvNumberFormatter* m_pMyPrivateFormatter;
public:
StandardFormatsSupplier(const Reference<XMultiServiceFactory>& _rxFactory);
2000-09-18 15:33:13 +00:00
2000-11-23 07:48:15 +00:00
operator Reference<XNumberFormatsSupplier> ();
2000-09-18 15:33:13 +00:00
SvNumberFormatsSupplierObj::operator new;
SvNumberFormatsSupplierObj::operator delete;
protected:
~StandardFormatsSupplier() { if (m_pMyPrivateFormatter) delete m_pMyPrivateFormatter; }
};
//------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
StandardFormatsSupplier::StandardFormatsSupplier(const Reference< XMultiServiceFactory > & _rxFactory)
2000-09-18 15:33:13 +00:00
:SvNumberFormatsSupplierObj()
,m_pMyPrivateFormatter(new SvNumberFormatter(_rxFactory, Application::GetAppInternational().GetLanguage()))
2000-09-18 15:33:13 +00:00
{
SetNumberFormatter(m_pMyPrivateFormatter);
}
//------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
StandardFormatsSupplier::operator Reference<XNumberFormatsSupplier> ()
2000-09-18 15:33:13 +00:00
{
2000-11-23 07:48:15 +00:00
return static_cast<XNumberFormatsSupplier*>(static_cast<SvNumberFormatsSupplierObj*>(this));
2000-09-18 15:33:13 +00:00
}
//------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
Reference<XNumberFormatsSupplier> OFormattedModel::s_xDefaultFormatter;
2000-09-18 15:33:13 +00:00
sal_Int32 OFormattedModel::nValueHandle = -1;
/*************************************************************************/
//------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
InterfaceRef SAL_CALL OFormattedControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
2000-09-18 15:33:13 +00:00
{
return *(new OFormattedControl(_rxFactory));
}
//------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
Sequence<Type> OFormattedControl::_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(OFormattedControl_BASE::getTypes(), OBoundControl::_getTypes());
2000-09-18 15:33:13 +00:00
return aTypes;
}
//------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
Any SAL_CALL OFormattedControl::queryAggregation(const Type& _rType) throw (RuntimeException)
2000-09-18 15:33:13 +00:00
{
2000-11-23 07:48:15 +00:00
Any aReturn = OBoundControl::queryAggregation(_rType);
2000-09-18 15:33:13 +00:00
if (!aReturn.hasValue())
2000-11-23 07:48:15 +00:00
aReturn = OFormattedControl_BASE::queryInterface(_rType);
2000-09-18 15:33:13 +00:00
return aReturn;
}
DBG_NAME(OFormattedControl);
//------------------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
OFormattedControl::OFormattedControl(const Reference<XMultiServiceFactory>& _rxFactory)
2000-09-18 15:33:13 +00:00
:OBoundControl(_rxFactory, VCL_CONTROL_FORMATTEDFIELD)
,m_nKeyEvent(0)
{
DBG_CTOR(OFormattedControl,NULL);
increment(m_refCount);
{ // als FocusListener anmelden
2001-05-18 13:44:30 +00:00
Reference<XWindow> xComp;
2000-09-18 15:33:13 +00:00
if (query_aggregation(m_xAggregate, xComp))
{
xComp->addKeyListener(this);
}
}
// Refcount wieder bei 1 fuer den Listener
sal_Int32 n = decrement(m_refCount);
}
//------------------------------------------------------------------------------
OFormattedControl::~OFormattedControl()
{
if( m_nKeyEvent )
Application::RemoveUserEvent( m_nKeyEvent );
if (!OComponentHelper::rBHelper.bDisposed)
{
acquire();
dispose();
}
DBG_DTOR(OFormattedControl,NULL);
}
2000-11-23 07:48:15 +00:00
// XKeyListener
2000-09-18 15:33:13 +00:00
//------------------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
void OFormattedControl::disposing(const EventObject& _rSource) throw(RuntimeException)
2000-09-18 15:33:13 +00:00
{
OBoundControl::disposing(_rSource);
}
//------------------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
void OFormattedControl::keyPressed(const KeyEvent& e)
2000-09-18 15:33:13 +00:00
{
if( e.KeyCode != KEY_RETURN || e.Modifiers != 0 )
return;
// Steht das Control in einem Formular mit einer Submit-URL?
2000-11-23 07:48:15 +00:00
Reference<com::sun::star::beans::XPropertySet> xSet(getModel(), UNO_QUERY);
2000-09-18 15:33:13 +00:00
if( !xSet.is() )
return;
2000-11-23 07:48:15 +00:00
Reference<XFormComponent> xFComp(xSet, UNO_QUERY);
2000-09-18 15:33:13 +00:00
InterfaceRef xParent = xFComp->getParent();
if( !xParent.is() )
return;
2000-11-23 07:48:15 +00:00
Reference<com::sun::star::beans::XPropertySet> xFormSet(xParent, UNO_QUERY);
2000-09-18 15:33:13 +00:00
if( !xFormSet.is() )
return;
2000-11-23 07:48:15 +00:00
Any aTmp(xFormSet->getPropertyValue( PROPERTY_TARGET_URL ));
2000-09-18 15:33:13 +00:00
if (!isA(aTmp, static_cast< ::rtl::OUString* >(NULL)) ||
!getString(aTmp).getLength() )
return;
2000-11-23 07:48:15 +00:00
Reference<XIndexAccess> xElements(xParent, UNO_QUERY);
2000-09-18 15:33:13 +00:00
sal_Int32 nCount = xElements->getCount();
if( nCount > 1 )
{
2000-11-23 07:48:15 +00:00
Reference<com::sun::star::beans::XPropertySet> xFCSet;
2000-09-18 15:33:13 +00:00
for( sal_Int32 nIndex=0; nIndex < nCount; nIndex++ )
{
2000-11-23 07:48:15 +00:00
// Any aElement(xElements->getByIndex(nIndex));
xElements->getByIndex(nIndex) >>= xFCSet;
2000-09-18 15:33:13 +00:00
if (hasProperty(PROPERTY_CLASSID, xFCSet) &&
2000-11-23 07:48:15 +00:00
getINT16(xFCSet->getPropertyValue(PROPERTY_CLASSID)) == FormComponentType::TEXTFIELD)
2000-09-18 15:33:13 +00:00
{
// Noch ein weiteres Edit gefunden ==> dann nicht submitten
if (xFCSet != xSet)
return;
}
}
}
// Da wir noch im Haender stehen, submit asynchron ausloesen
if( m_nKeyEvent )
Application::RemoveUserEvent( m_nKeyEvent );
m_nKeyEvent = Application::PostUserEvent( LINK(this, OFormattedControl,
OnKeyPressed) );
}
//------------------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
void OFormattedControl::keyReleased(const KeyEvent& e)
2000-09-18 15:33:13 +00:00
{
}
//------------------------------------------------------------------------------
IMPL_LINK(OFormattedControl, OnKeyPressed, void*, EMPTYARG)
{
m_nKeyEvent = 0;
2001-04-26 11:36:28 +00:00
Reference<XFormComponent> xFComp(getModel(), UNO_QUERY);
2000-09-18 15:33:13 +00:00
InterfaceRef xParent = xFComp->getParent();
2001-04-26 11:36:28 +00:00
Reference<XSubmit> xSubmit(xParent, UNO_QUERY);
2000-09-18 15:33:13 +00:00
if (xSubmit.is())
2001-04-26 11:36:28 +00:00
xSubmit->submit( Reference<XControl> (), MouseEvent() );
2000-09-18 15:33:13 +00:00
return 0L;
}
//------------------------------------------------------------------------------
StringSequence OFormattedControl::getSupportedServiceNames() throw()
{
StringSequence aSupported = OBoundControl::getSupportedServiceNames();
aSupported.realloc(aSupported.getLength() + 1);
::rtl::OUString*pArray = aSupported.getArray();
pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_FORMATTEDFIELD;
return aSupported;
}
//------------------------------------------------------------------------------
void OFormattedControl::setDesignMode(sal_Bool bOn)
{
OBoundControl::setDesignMode(bOn);
}
/*************************************************************************/
DBG_NAME(OFormattedModel)
2000-09-18 15:33:13 +00:00
//------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
InterfaceRef SAL_CALL OFormattedModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
2000-09-18 15:33:13 +00:00
{
return *(new OFormattedModel(_rxFactory));
}
//------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
OFormattedModel::OFormattedModel(const Reference<XMultiServiceFactory>& _rxFactory)
:OEditBaseModel(_rxFactory, VCL_CONTROLMODEL_FORMATTEDFIELD, FRM_CONTROL_FORMATTEDFIELD, sal_False )
2000-09-18 15:33:13 +00:00
// use the old control name for compytibility reasons
,OPropertyChangeListener(m_aMutex)
,m_bOriginalNumeric(sal_False)
,m_bNumeric(sal_False)
,m_xOriginalFormatter(NULL)
2000-11-23 07:48:15 +00:00
,m_nKeyType(NumberFormat::UNDEFINED)
2000-12-06 09:24:23 +00:00
,m_aNullDate(DBTypeConversion::getStandardDate())
,m_bAggregateListening(sal_False)
,m_pPropertyMultiplexer(NULL)
2000-09-18 15:33:13 +00:00
{
DBG_CTOR(OFormattedModel, NULL);
2000-11-23 07:48:15 +00:00
m_nClassId = FormComponentType::TEXTFIELD;
2000-09-18 15:33:13 +00:00
increment(m_refCount);
setPropertyToDefaultByHandle(PROPERTY_ID_FORMATSSUPPLIER);
decrement(m_refCount);
m_sDataFieldConnectivityProperty = PROPERTY_EFFECTIVE_VALUE;
if (OFormattedModel::nValueHandle == -1)
OFormattedModel::nValueHandle = getOriginalHandle(PROPERTY_ID_EFFECTIVE_VALUE);
startAggregateListening();
doSetDelegator();
}
//------------------------------------------------------------------------------
OFormattedModel::~OFormattedModel()
{
doResetDelegator();
releaseAggregateListener();
DBG_DTOR(OFormattedModel, NULL);
}
//------------------------------------------------------------------------------
void OFormattedModel::startAggregateListening()
{
DBG_ASSERT(!m_bAggregateListening, "OFormattedModel::startAggregateListening: already listening!");
if (m_bAggregateListening)
return;
DBG_ASSERT(NULL == m_pPropertyMultiplexer, "OFormattedModel::startAggregateListening: previous listener not released!");
if (m_pPropertyMultiplexer)
releaseAggregateListener();
m_pPropertyMultiplexer = new OPropertyChangeMultiplexer(this, m_xAggregateSet, sal_False);
m_pPropertyMultiplexer->addProperty(PROPERTY_FORMATKEY);
m_pPropertyMultiplexer->acquire();
m_bAggregateListening = sal_True;
}
//------------------------------------------------------------------------------
void OFormattedModel::stopAggregateListening()
{
DBG_ASSERT(m_bAggregateListening, "OFormattedModel::stopAggregateListening: not listening!");
if (!m_bAggregateListening)
return;
if (m_pPropertyMultiplexer)
m_pPropertyMultiplexer->dispose();
m_bAggregateListening = sal_False;
}
//------------------------------------------------------------------------------
void OFormattedModel::releaseAggregateListener()
{
DBG_ASSERT(!m_bAggregateListening, "OFormattedModel::releaseAggregateListener: still listening!");
if (m_bAggregateListening)
stopAggregateListening();
if (m_pPropertyMultiplexer)
2000-09-18 15:33:13 +00:00
{
m_pPropertyMultiplexer->release();
m_pPropertyMultiplexer = NULL;
2000-09-18 15:33:13 +00:00
}
}
//------------------------------------------------------------------------------
void SAL_CALL OFormattedModel::disposing()
{
stopAggregateListening();
OEditBaseModel::disposing();
2000-09-18 15:33:13 +00:00
}
2000-11-23 07:48:15 +00:00
// XServiceInfo
2000-09-18 15:33:13 +00:00
//------------------------------------------------------------------------------
StringSequence OFormattedModel::getSupportedServiceNames() throw()
{
StringSequence aSupported = OEditBaseModel::getSupportedServiceNames();
aSupported.realloc(aSupported.getLength() + 2);
::rtl::OUString*pArray = aSupported.getArray();
pArray[aSupported.getLength()-2] = ::rtl::OUString::createFromAscii("com.sun.star.form.component.DatabaseFormattedField");
pArray[aSupported.getLength()-1] = FRM_SUN_COMPONENT_FORMATTEDFIELD;
return aSupported;
}
2000-11-23 07:48:15 +00:00
// XPersistObject
2000-09-18 15:33:13 +00:00
//------------------------------------------------------------------------------
::rtl::OUString SAL_CALL OFormattedModel::getServiceName()
{
return ::rtl::OUString(FRM_COMPONENT_EDIT);
// return ::rtl::OUString(FRM_COMPONENT_FORMATTEDFIELD); // old (non-sun) name for compatibility !
}
2000-11-23 07:48:15 +00:00
// XPropertySet
2000-09-18 15:33:13 +00:00
//------------------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
Reference<com::sun::star::beans::XPropertySetInfo> SAL_CALL OFormattedModel::getPropertySetInfo() throw(RuntimeException)
2000-09-18 15:33:13 +00:00
{
2001-05-18 13:44:30 +00:00
Reference<com::sun::star::beans::XPropertySetInfo> xInfo( createPropertySetInfo( getInfoHelper() ) );
2000-09-18 15:33:13 +00:00
return xInfo;
}
//------------------------------------------------------------------------------
::cppu::IPropertyArrayHelper& OFormattedModel::getInfoHelper()
{
return *const_cast<OFormattedModel*>(this)->getArrayHelper();
}
//------------------------------------------------------------------------------
void OFormattedModel::fillProperties(
2000-11-23 07:48:15 +00:00
Sequence< com::sun::star::beans::Property >& _rProps,
Sequence< com::sun::star::beans::Property >& _rAggregateProps ) const
2000-09-18 15:33:13 +00:00
{
FRM_BEGIN_PROP_HELPER(10)
2000-09-18 15:33:13 +00:00
DECL_PROP1(NAME, ::rtl::OUString, BOUND);
DECL_PROP2(CLASSID, sal_Int16, READONLY, TRANSIENT);
DECL_BOOL_PROP1(EMPTY_IS_NULL, BOUND);
DECL_PROP1(TAG, ::rtl::OUString, BOUND);
DECL_PROP1(TABINDEX, sal_Int16, BOUND);
DECL_PROP1(CONTROLSOURCE, ::rtl::OUString, BOUND);
2000-11-23 07:48:15 +00:00
DECL_IFACE_PROP2(BOUNDFIELD, com::sun::star::beans::XPropertySet,READONLY, TRANSIENT);
2000-09-18 15:33:13 +00:00
DECL_BOOL_PROP2(FILTERPROPOSAL, BOUND, MAYBEDEFAULT);
2000-11-23 07:48:15 +00:00
DECL_IFACE_PROP2(CONTROLLABEL, com::sun::star::beans::XPropertySet,BOUND, MAYBEVOID);
2000-09-18 15:33:13 +00:00
DECL_PROP2(CONTROLSOURCEPROPERTY, rtl::OUString, READONLY, TRANSIENT);
// der Supplier ist fuer uns nur read-only
2000-11-23 07:48:15 +00:00
ModifyPropertyAttributes(_rAggregateProps, PROPERTY_FORMATSSUPPLIER, com::sun::star::beans::PropertyAttribute::READONLY, 0);
2000-09-18 15:33:13 +00:00
// TreatAsNumeric nicht transient : wir wollen es an der UI anbinden (ist noetig, um dem EffectiveDefault
// - der kann Text oder Zahl sein - einen Sinn zu geben)
ModifyPropertyAttributes(_rAggregateProps, PROPERTY_TREATASNUMERIC, 0, com::sun::star::beans::PropertyAttribute::TRANSIENT);
// same for FormatKey
// (though the paragraph above for the TreatAsNumeric does not hold anymore - we do not have an UI for this.
// But we have for the format key ...)
// 25.06.2001 - 87862 - frank.schoenheit@sun.com
ModifyPropertyAttributes(_rAggregateProps, PROPERTY_FORMATKEY, 0, com::sun::star::beans::PropertyAttribute::TRANSIENT);
RemoveProperty(_rAggregateProps, PROPERTY_STRICTFORMAT);
// no strict format property for formatted fields: it does not make sense, 'cause
// there is no general way to decide which characters/sub strings are allowed during the input of an
// arbitraryly formatted control
// 81441 - 12/07/00 - FS
2000-09-18 15:33:13 +00:00
FRM_END_PROP_HELPER();
}
//------------------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
void OFormattedModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle) const
2000-09-18 15:33:13 +00:00
{
OEditBaseModel::getFastPropertyValue(rValue, nHandle);
}
//------------------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
void OFormattedModel::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const Any& rValue)
2000-09-18 15:33:13 +00:00
{
OEditBaseModel::setFastPropertyValue_NoBroadcast(nHandle, rValue);
}
//------------------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
sal_Bool OFormattedModel::convertFastPropertyValue(Any& rConvertedValue, Any& rOldValue, sal_Int32 nHandle, const Any& rValue)
throw( IllegalArgumentException )
2000-09-18 15:33:13 +00:00
{
return OEditBaseModel::convertFastPropertyValue(rConvertedValue, rOldValue, nHandle, rValue);
}
//------------------------------------------------------------------------------
void OFormattedModel::setPropertyToDefaultByHandle(sal_Int32 nHandle)
{
if (nHandle == PROPERTY_ID_FORMATSSUPPLIER)
{ // das aggregierte Model koennte auf die Idee kommen
2001-05-18 13:44:30 +00:00
Reference<XNumberFormatsSupplier> xSupplier = calcDefaultFormatsSupplier();
2000-09-18 15:33:13 +00:00
DBG_ASSERT(m_xAggregateSet.is(), "OFormattedModel::setPropertyToDefaultByHandle(FORMATSSUPPLIER) : have no aggregate !");
if (m_xAggregateSet.is())
2000-11-23 07:48:15 +00:00
m_xAggregateSet->setPropertyValue(PROPERTY_FORMATSSUPPLIER, makeAny(xSupplier));
2000-09-18 15:33:13 +00:00
}
else
OEditBaseModel::setPropertyToDefaultByHandle(nHandle);
}
//------------------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
void OFormattedModel::setPropertyToDefault(const ::rtl::OUString& aPropertyName) throw( com::sun::star::beans::UnknownPropertyException, RuntimeException )
2000-09-18 15:33:13 +00:00
{
OPropertyArrayAggregationHelper& rPH = (OPropertyArrayAggregationHelper&)getInfoHelper();
sal_Int32 nHandle = rPH.getHandleByName( aPropertyName );
if (nHandle == PROPERTY_ID_FORMATSSUPPLIER)
setPropertyToDefaultByHandle(PROPERTY_ID_FORMATSSUPPLIER);
else
OEditBaseModel::setPropertyToDefault(aPropertyName);
}
//------------------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
Any OFormattedModel::getPropertyDefaultByHandle( sal_Int32 nHandle ) const
2000-09-18 15:33:13 +00:00
{
if (nHandle == PROPERTY_ID_FORMATSSUPPLIER)
{
2000-11-23 07:48:15 +00:00
Reference<XNumberFormatsSupplier> xSupplier = calcFormFormatsSupplier();
return makeAny(xSupplier);
2000-09-18 15:33:13 +00:00
}
else
return OEditBaseModel::getPropertyDefaultByHandle(nHandle);
}
//------------------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
Any SAL_CALL OFormattedModel::getPropertyDefault( const ::rtl::OUString& aPropertyName ) throw( com::sun::star::beans::UnknownPropertyException, RuntimeException )
2000-09-18 15:33:13 +00:00
{
OPropertyArrayAggregationHelper& rPH = (OPropertyArrayAggregationHelper&)getInfoHelper();
sal_Int32 nHandle = rPH.getHandleByName( aPropertyName );
if (nHandle == PROPERTY_ID_FORMATSSUPPLIER)
return getPropertyDefaultByHandle(PROPERTY_ID_FORMATSSUPPLIER);
else
return OEditBaseModel::getPropertyDefault(aPropertyName);
}
//------------------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
void OFormattedModel::_propertyChanged( const com::sun::star::beans::PropertyChangeEvent& evt ) throw(RuntimeException)
2000-09-18 15:33:13 +00:00
{
Reference< XPropertySet > xSourceSet(evt.Source, UNO_QUERY);
if (xSourceSet.get() == m_xAggregateSet.get())
2000-09-18 15:33:13 +00:00
{
if (evt.PropertyName.equals(PROPERTY_FORMATKEY))
{
2000-11-23 07:48:15 +00:00
if (evt.NewValue.getValueType().getTypeClass() == TypeClass_LONG)
2000-09-18 15:33:13 +00:00
{
try
{
2000-11-23 07:48:15 +00:00
Reference<XNumberFormatsSupplier> xSupplier(calcFormatsSupplier());
2000-09-18 15:33:13 +00:00
m_nKeyType = getNumberFormatType(xSupplier->getNumberFormats(), getINT32(evt.NewValue));
// as m_aSaveValue (which is used by _commit) is format dependent we have
// to recalc it, which is done by _onValueChanged
if (m_xColumn.is() && m_xAggregateFastSet.is())
{
::osl::MutexGuard aGuard(m_aMutex); // _onValueChanged expects that ...
_onValueChanged();
}
}
2000-11-23 07:48:15 +00:00
catch(Exception&)
2000-09-18 15:33:13 +00:00
{
}
}
}
// our base class does not listen at the aggregate at the moment ... and it does not expect
// to get events from objects other than the field we're bound to. So do not call the
// base class method here.
return;
}
}
//------------------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
Reference<XNumberFormatsSupplier> OFormattedModel::calcFormatsSupplier() const
2000-09-18 15:33:13 +00:00
{
2000-11-23 07:48:15 +00:00
Reference<XNumberFormatsSupplier> xSupplier;
2000-09-18 15:33:13 +00:00
DBG_ASSERT(m_xAggregateSet.is(), "OFormattedModel::calcFormatsSupplier : have no aggregate !");
// hat mein aggregiertes Model einen FormatSupplier ?
2000-11-23 07:48:15 +00:00
if( m_xAggregateSet.is() )
2000-09-18 15:33:13 +00:00
2000-11-23 07:48:15 +00:00
m_xAggregateSet->getPropertyValue(PROPERTY_FORMATSSUPPLIER) >>= xSupplier;
2000-09-18 15:33:13 +00:00
if (!xSupplier.is())
// testen, ob meine Parent-starform einen Formatter hat
xSupplier = calcFormFormatsSupplier();
if (!xSupplier.is())
xSupplier = calcDefaultFormatsSupplier();
DBG_ASSERT(xSupplier.is(), "OFormattedModel::calcFormatsSupplier : no supplier !");
// jetzt sollte aber einer da sein
return xSupplier;
}
//------------------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
Reference<XNumberFormatsSupplier> OFormattedModel::calcFormFormatsSupplier() const
2000-09-18 15:33:13 +00:00
{
2000-11-23 07:48:15 +00:00
Reference<XChild> xMe;
query_interface(static_cast<XWeak*>(const_cast<OFormattedModel*>(this)), xMe);
2000-09-18 15:33:13 +00:00
// damit stellen wir sicher, dass wir auch fuer den Fall der Aggregation das richtige
// Objekt bekommen
DBG_ASSERT(xMe.is(), "OFormattedModel::calcFormFormatsSupplier : I should have a content interface !");
// jetzt durchhangeln nach oben, bis wir auf eine starform treffen (angefangen mit meinem eigenen Parent)
2000-11-23 07:48:15 +00:00
Reference<XChild> xParent(xMe->getParent(), UNO_QUERY);
Reference<XForm> xNextParentForm(xParent, UNO_QUERY);
2000-09-18 15:33:13 +00:00
while (!xNextParentForm.is() && xParent.is())
{
2000-11-23 07:48:15 +00:00
xParent = Reference<XChild> (xParent->getParent(), UNO_QUERY);
xNextParentForm = Reference<XForm> (xParent, UNO_QUERY);
2000-09-18 15:33:13 +00:00
}
if (!xNextParentForm.is())
{
DBG_ERROR("OFormattedModel::calcFormFormatsSupplier : have no ancestor which is a form !");
return NULL;
}
// den FormatSupplier von meinem Vorfahren (falls der einen hat)
2000-11-23 07:48:15 +00:00
Reference<XRowSet> xRowSet(xNextParentForm, UNO_QUERY);
Reference<XNumberFormatsSupplier> xSupplier;
2000-09-18 15:33:13 +00:00
if (xRowSet.is())
xSupplier = getNumberFormats(getConnection(xRowSet), sal_True, m_xServiceFactory);
return xSupplier;
}
//------------------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
Reference<XNumberFormatsSupplier> OFormattedModel::calcDefaultFormatsSupplier() const
2000-09-18 15:33:13 +00:00
{
if (!s_xDefaultFormatter.is())
s_xDefaultFormatter = *new StandardFormatsSupplier(m_xServiceFactory);
2000-09-18 15:33:13 +00:00
return s_xDefaultFormatter;
}
//------------------------------------------------------------------------------
sal_Int32 OFormattedModel::calcFormatKey() const
{
DBG_ASSERT(m_xAggregateSet.is(), "OFormattedModel::calcFormatKey : have no aggregate !");
// hat mein aggregiertes Model einen FormatSupplier ?
Any aFormatKey = m_xAggregateSet.is() ? m_xAggregateSet->getPropertyValue(PROPERTY_FORMATKEY): Any();
2000-09-18 15:33:13 +00:00
if (aFormatKey.hasValue())
return getINT32(aFormatKey);
if (m_xField.is())
return getINT32(m_xField->getPropertyValue(PROPERTY_FORMATKEY));
return 0;
}
//------------------------------------------------------------------------------
void OFormattedModel::getFormatDescription(::rtl::OUString& sFormat, LanguageType& eLanguage)
{
}
2000-11-23 07:48:15 +00:00
// XBoundComponent
2000-09-18 15:33:13 +00:00
//------------------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
void OFormattedModel::loaded(const EventObject& rEvent)
2000-09-18 15:33:13 +00:00
{
// HACK : our _loaded accesses our NumberFormatter which locks the solar mutex (as it doesn't have
// an own one). To prevent deadlocks with other threads which may request a property from us in an
// UI-triggered action (e.g. an tooltip) we lock the solar mutex _here_ before our base class locks
// it's own muext (which is used for property requests)
// alternative a): we use two mutexes, one which is passed to the OPropertysetHelper and used for
// property requests and one for our own code. This would need a lot of code rewriting
// alternative b): The NumberFormatter has to be really threadsafe (with an own mutex), which is
// the only "clean" solution for me.
// FS - 69603 - 02.11.99
::vos::OGuard aGuard(Application::GetSolarMutex());
OEditBaseModel::loaded(rEvent);
}
//------------------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
void OFormattedModel::_loaded(const EventObject& rEvent)
2000-09-18 15:33:13 +00:00
{
static const ::rtl::OUString s_aNullDataProp = ::rtl::OUString::createFromAscii("NullDate");
m_xOriginalFormatter = NULL;
DBG_ASSERT(m_xAggregateSet.is(), "OFormattedModel::_loaded : have no aggregate !");
if (m_xAggregateSet.is())
{ // all the following doesn't make any sense if we have no aggregate ...
2000-11-23 07:48:15 +00:00
Any aSupplier = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATSSUPPLIER);
DBG_ASSERT(((Reference<XNumberFormatsSupplier> *)aSupplier.getValue())->is(), "OFormattedModel::_loaded : invalid property value !");
// das sollte im Constructor oder im read auf was richtiges gesetzt worden sein
2000-09-18 15:33:13 +00:00
2000-11-23 07:48:15 +00:00
Any aFmtKey = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATKEY);
2000-09-18 15:33:13 +00:00
if (!aFmtKey.hasValue())
{ // unser aggregiertes Model hat noch keine Format-Informationen, also geben wir die von dem Feld, an das
// wir gebunden sind, weiter
2000-11-23 07:48:15 +00:00
sal_Int32 nType = DataType::VARCHAR;
2000-09-18 15:33:13 +00:00
if (m_xField.is())
{
aFmtKey = m_xField->getPropertyValue(PROPERTY_FORMATKEY);
m_xField->getPropertyValue(PROPERTY_FIELDTYPE) >>= nType ;
}
2000-11-23 07:48:15 +00:00
Reference<XNumberFormatsSupplier> xSupplier = calcFormFormatsSupplier();
2000-09-18 15:33:13 +00:00
DBG_ASSERT(xSupplier.is(), "OFormattedModel::_loaded : bound to a field but no parent with a formatter ? how this ?");
if (xSupplier.is())
{
m_bOriginalNumeric = getBOOL(getPropertyValue(PROPERTY_TREATASNUMERIC));
2000-09-18 15:33:13 +00:00
if (!aFmtKey.hasValue())
{ // we aren't bound to a field (or this field's format is invalid)
// -> determine the standard text (or numeric) format of the supplier
Reference<XNumberFormatTypes> xTypes(xSupplier->getNumberFormats(), UNO_QUERY);
2000-09-18 15:33:13 +00:00
if (xTypes.is())
{
UniString sLanguage, sCountry;
ConvertLanguageToIsoNames(Application::GetAppInternational().GetLanguage(), sLanguage, sCountry);
Locale aApplicationLocale(sLanguage, sCountry, ::rtl::OUString());
sal_Int32 nNewKey = 0;
if (m_bOriginalNumeric)
aFmtKey <<= (sal_Int32)xTypes->getStandardFormat(NumberFormat::NUMBER, aApplicationLocale);
else
aFmtKey <<= (sal_Int32)xTypes->getStandardFormat(NumberFormat::TEXT, aApplicationLocale);
2000-09-18 15:33:13 +00:00
}
}
aSupplier >>= m_xOriginalFormatter;
m_xAggregateSet->setPropertyValue(PROPERTY_FORMATSSUPPLIER, makeAny(xSupplier));
2000-09-18 15:33:13 +00:00
m_xAggregateSet->setPropertyValue(PROPERTY_FORMATKEY, aFmtKey);
// das Numeric-Flag an mein gebundenes Feld anpassen
if (m_xField.is())
2000-09-18 15:33:13 +00:00
{
m_bNumeric = sal_False;
switch (nType)
{
case DataType::BIT:
case DataType::TINYINT:
case DataType::SMALLINT:
case DataType::INTEGER:
case DataType::BIGINT:
case DataType::FLOAT:
case DataType::REAL:
case DataType::DOUBLE:
case DataType::NUMERIC:
case DataType::DECIMAL:
case DataType::DATE:
case DataType::TIME:
case DataType::TIMESTAMP:
m_bNumeric = sal_True;
break;
}
2000-09-18 15:33:13 +00:00
}
else
m_bNumeric = m_bOriginalNumeric;
2000-11-23 07:48:15 +00:00
setPropertyValue(PROPERTY_TREATASNUMERIC, makeAny((sal_Bool)m_bNumeric));
2000-09-18 15:33:13 +00:00
m_nKeyType = getNumberFormatType(xSupplier->getNumberFormats(), getINT32(aFmtKey));
xSupplier->getNumberFormatSettings()->getPropertyValue(s_aNullDataProp) >>= m_aNullDate;
2000-09-18 15:33:13 +00:00
}
}
else
{
Reference<XNumberFormatsSupplier> xSupplier = calcFormatsSupplier();
2000-09-18 15:33:13 +00:00
m_bNumeric = getBOOL(getPropertyValue(PROPERTY_TREATASNUMERIC));
m_nKeyType = getNumberFormatType(xSupplier->getNumberFormats(), getINT32(aFmtKey));
xSupplier->getNumberFormatSettings()->getPropertyValue(s_aNullDataProp) >>= m_aNullDate;
2000-09-18 15:33:13 +00:00
}
}
else
{ // try to get some defaults ...
Reference<XNumberFormatsSupplier> xSupplier = calcFormatsSupplier();
2000-09-18 15:33:13 +00:00
m_bNumeric = getBOOL(getPropertyValue(PROPERTY_TREATASNUMERIC));
m_nKeyType = getNumberFormatType(xSupplier->getNumberFormats(), 0);
xSupplier->getNumberFormatSettings()->getPropertyValue(s_aNullDataProp) >>= m_aNullDate;
2000-09-18 15:33:13 +00:00
}
OEditBaseModel::_loaded(rEvent);
}
//------------------------------------------------------------------------------
void OFormattedModel::_unloaded()
{
OEditBaseModel::_unloaded();
if (m_xOriginalFormatter.is())
{ // unser aggregiertes Model hatte keinerlei Format-Informationen
m_xAggregateSet->setPropertyValue(PROPERTY_FORMATSSUPPLIER, makeAny(m_xOriginalFormatter));
m_xAggregateSet->setPropertyValue(PROPERTY_FORMATKEY, Any());
setPropertyValue(PROPERTY_TREATASNUMERIC, makeAny((sal_Bool)m_bOriginalNumeric));
2000-09-18 15:33:13 +00:00
m_xOriginalFormatter = NULL;
}
2000-11-23 07:48:15 +00:00
m_nKeyType = NumberFormat::UNDEFINED;
2000-12-06 09:24:23 +00:00
m_aNullDate = DBTypeConversion::getStandardDate();
2000-09-18 15:33:13 +00:00
}
//------------------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
void OFormattedModel::write(const Reference<XObjectOutputStream>& _rxOutStream)
2000-09-18 15:33:13 +00:00
{
OEditBaseModel::write(_rxOutStream);
_rxOutStream->writeShort(0x0003);
DBG_ASSERT(m_xAggregateSet.is(), "OFormattedModel::write : have no aggregate !");
// mein Format (evtl. void) in ein persistentes Format bringen (der Supplier zusammen mit dem Key ist es zwar auch,
// aber deswegen muessen wir ja nicht gleich den ganzen Supplier speichern, das waere ein klein wenig Overhead ;)
2000-11-23 07:48:15 +00:00
Reference<XNumberFormatsSupplier> xSupplier;
Any aFmtKey;
2000-09-18 15:33:13 +00:00
sal_Bool bVoidKey = sal_True;
if (m_xAggregateSet.is())
{
2000-11-23 07:48:15 +00:00
Any aSupplier = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATSSUPPLIER);
if (aSupplier.getValueType().getTypeClass() != TypeClass_VOID)
2000-09-18 15:33:13 +00:00
{
2000-11-23 07:48:15 +00:00
DBG_ASSERT(isAReference(aSupplier, static_cast<XNumberFormatsSupplier*>(NULL)),
2000-09-18 15:33:13 +00:00
"OFormattedModel::write : invalid formats supplier !");
2000-11-23 07:48:15 +00:00
xSupplier = *(Reference<XNumberFormatsSupplier> *)aSupplier.getValue();
2000-09-18 15:33:13 +00:00
}
aFmtKey = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATKEY);
bVoidKey = (!xSupplier.is() || !aFmtKey.hasValue()) || (m_bLoaded && m_xOriginalFormatter.is());
// (kein Fomatter und/oder Key) oder (loaded und faked Formatter)
}
_rxOutStream->writeBoolean(!bVoidKey);
if (!bVoidKey)
{
// aus dem FormatKey und dem Formatter persistente Angaben basteln
2001-05-18 13:44:30 +00:00
Any aKey = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATKEY);
2000-09-18 15:33:13 +00:00
sal_Int32 nKey = aKey.hasValue() ? getINT32(aKey) : 0;
2001-05-18 13:44:30 +00:00
Reference<XNumberFormats> xFormats = xSupplier->getNumberFormats();
2000-09-18 15:33:13 +00:00
::rtl::OUString sFormatDescription;
LanguageType eFormatLanguage = LANGUAGE_DONTKNOW;
static const ::rtl::OUString s_aLocaleProp = ::rtl::OUString::createFromAscii("Locale");
2001-05-18 13:44:30 +00:00
Reference<com::sun::star::beans::XPropertySet> xFormat = xFormats->getByKey(nKey);
2000-09-18 15:33:13 +00:00
if (hasProperty(s_aLocaleProp, xFormat))
{
2001-05-18 13:44:30 +00:00
Any aLocale = xFormat->getPropertyValue(s_aLocaleProp);
DBG_ASSERT(isA(aLocale, static_cast<Locale*>(NULL)), "OFormattedModel::write : invalid language property !");
if (isA(aLocale, static_cast<Locale*>(NULL)))
2000-09-18 15:33:13 +00:00
{
2001-05-18 13:44:30 +00:00
Locale* pLocale = (Locale*)aLocale.getValue();
2000-09-18 15:33:13 +00:00
eFormatLanguage = ConvertIsoNamesToLanguage(
::rtl::OUStringToOString(pLocale->Language, RTL_TEXTENCODING_ASCII_US).getStr(),
::rtl::OUStringToOString(pLocale->Country, RTL_TEXTENCODING_ASCII_US).getStr()
);
}
}
static const ::rtl::OUString s_aFormatStringProp = ::rtl::OUString::createFromAscii("FormatString");
if (hasProperty(s_aFormatStringProp, xFormat))
xFormat->getPropertyValue(s_aFormatStringProp) >>= sFormatDescription;
_rxOutStream->writeUTF(sFormatDescription);
_rxOutStream->writeLong((sal_Int32)eFormatLanguage);
}
// version 2 : write the properties common to all OEditBaseModels
writeCommonEditProperties(_rxOutStream);
// version 3 : write the effective value property of the aggregate
// Due to a bug within the UnoControlFormattedFieldModel implementation (our default aggregate) this props value isn't correctly read
// and this can't be corrected without being incompatible.
// so we have our own handling.
// and to be a little bit more compatible we make the following section skippable
{
2001-05-18 13:44:30 +00:00
Reference< XDataOutputStream > xOut(_rxOutStream, UNO_QUERY);
2000-09-18 15:33:13 +00:00
OMarkableStreamBlock aDownCompat(xOut);
// a sub version within the skippable block
_rxOutStream->writeShort(0x0000);
// version 0: the effective value of the aggregate
2000-11-23 07:48:15 +00:00
Any aEffectiveValue;
2000-09-18 15:33:13 +00:00
if (m_xAggregateSet.is())
{
2000-11-23 07:48:15 +00:00
try { aEffectiveValue = m_xAggregateSet->getPropertyValue(PROPERTY_EFFECTIVE_VALUE); } catch(Exception&) { }
2000-09-18 15:33:13 +00:00
}
{
OMarkableStreamBlock aDownCompat2(xOut);
switch (aEffectiveValue.getValueType().getTypeClass())
{
2000-11-23 07:48:15 +00:00
case TypeClass_STRING:
2000-09-18 15:33:13 +00:00
_rxOutStream->writeShort(0x0000);
2000-10-19 10:52:20 +00:00
_rxOutStream->writeUTF(::comphelper::getString(aEffectiveValue));
2000-09-18 15:33:13 +00:00
break;
2000-11-23 07:48:15 +00:00
case TypeClass_DOUBLE:
2000-09-18 15:33:13 +00:00
_rxOutStream->writeShort(0x0001);
2000-10-19 10:52:20 +00:00
_rxOutStream->writeDouble(::comphelper::getDouble(aEffectiveValue));
2000-09-18 15:33:13 +00:00
break;
default: // void and all unknown states
DBG_ASSERT(!aEffectiveValue.hasValue(), "FmXFormattedModel::write : unknown property value type !");
_rxOutStream->writeShort(0x0002);
break;
}
}
}
}
//------------------------------------------------------------------------------
2000-11-23 07:48:15 +00:00
void OFormattedModel::read(const Reference<XObjectInputStream>& _rxInStream)
2000-09-18 15:33:13 +00:00
{
OEditBaseModel::read(_rxInStream);
sal_uInt16 nVersion = _rxInStream->readShort();
2001-05-18 13:44:30 +00:00
Reference<XNumberFormatsSupplier> xSupplier;
2000-09-18 15:33:13 +00:00
sal_Int32 nKey = -1;
switch (nVersion)
{
case 0x0001 :
case 0x0002 :
case 0x0003 :
{
sal_Bool bNonVoidKey = _rxInStream->readBoolean();
if (bNonVoidKey)
{
2000-11-23 07:48:15 +00:00
// den String und die Language lesen ....
2000-09-18 15:33:13 +00:00
::rtl::OUString sFormatDescription = _rxInStream->readUTF();
LanguageType eDescriptionLanguage = (LanguageType)_rxInStream->readLong();
// und daraus von einem Formatter zu einem Key zusammenwuerfeln lassen ...
xSupplier = calcFormatsSupplier();
// calcFormatsSupplier nimmt erst den vom Model, dann einen von der starform, dann einen ganz neuen ....
2001-05-18 13:44:30 +00:00
Reference<XNumberFormats> xFormats = xSupplier->getNumberFormats();
2000-09-18 15:33:13 +00:00
if (xFormats.is())
{
UniString sLanguage, sCountry;
ConvertLanguageToIsoNames(eDescriptionLanguage, sLanguage, sCountry);
2001-05-18 13:44:30 +00:00
Locale aDescriptionLanguage(
2000-09-18 15:33:13 +00:00
sLanguage,
sCountry,
2001-05-18 13:44:30 +00:00
::rtl::OUString()
);
2000-09-18 15:33:13 +00:00
nKey = xFormats->queryKey(sFormatDescription, aDescriptionLanguage, sal_False);
if (nKey == (sal_Int32)-1)
{ // noch nicht vorhanden in meinem Formatter ...
nKey = xFormats->addNew(sFormatDescription, aDescriptionLanguage);
}
}
}
if ((nVersion == 0x0002) || (nVersion == 0x0003))
readCommonEditProperties(_rxInStream);
if (nVersion == 0x0003)
{ // since version 3 there is a "skippable" block at this position
2001-05-18 13:44:30 +00:00
Reference< XDataInputStream > xIn(_rxInStream, UNO_QUERY);
2000-09-18 15:33:13 +00:00
OMarkableStreamBlock aDownCompat(xIn);
sal_Int16 nSubVersion = _rxInStream->readShort();
// version 0 and higher : the "effective value" property
2000-11-23 07:48:15 +00:00
Any aEffectiveValue;
2000-09-18 15:33:13 +00:00
{
OMarkableStreamBlock aDownCompat2(xIn);
switch (_rxInStream->readShort())
{
case 0: // String
aEffectiveValue <<= _rxInStream->readUTF();
break;
case 1: // double
aEffectiveValue <<= (double)_rxInStream->readDouble();
break;
case 2:
break;
case 3:
DBG_ERROR("FmXFormattedModel::read : unknown effective value type !");
}
}
// this property is only to be set if we have no control source : in all other cases the base class did a
// reset after it's read and this set the effective value to a default value
if (m_xAggregateSet.is() && (m_aControlSource.getLength() == 0))
{
try
{
m_xAggregateSet->setPropertyValue(PROPERTY_EFFECTIVE_VALUE, aEffectiveValue);
}
2000-11-23 07:48:15 +00:00
catch(Exception&)
2000-09-18 15:33:13 +00:00
{
}
}
}
}
break;
default :
DBG_ERROR("OFormattedModel::read : unknown version !");
// dann bleibt das Format des aggregierten Sets, wie es bei der Erzeugung ist : void
defaultCommonEditProperties();
break;
}
if ((nKey != -1) && m_xAggregateSet.is())
{
2000-11-23 07:48:15 +00:00
m_xAggregateSet->setPropertyValue(PROPERTY_FORMATSSUPPLIER, makeAny(xSupplier));
m_xAggregateSet->setPropertyValue(PROPERTY_FORMATKEY, makeAny((sal_Int32)nKey));
2000-09-18 15:33:13 +00:00
}
else
{
setPropertyToDefault(PROPERTY_FORMATSSUPPLIER);
setPropertyToDefault(PROPERTY_FORMATKEY);
}
}
//------------------------------------------------------------------------------
sal_Int16 OFormattedModel::getPersistenceFlags() const
{
return (OEditBaseModel::getPersistenceFlags() & ~PF_HANDLE_COMMON_PROPS);
// a) we do our own call to writeCommonEditProperties
}
//------------------------------------------------------------------------------
sal_Bool OFormattedModel::_commit()
{
2000-11-23 07:48:15 +00:00
Any aNewValue = m_xAggregateFastSet->getFastPropertyValue( OFormattedModel::nValueHandle );
2000-09-18 15:33:13 +00:00
if (!compare(aNewValue, m_aSaveValue))
{
// Leerstring + EmptyIsNull = void
2001-02-21 10:10:53 +00:00
if ( !aNewValue.hasValue()
|| ( (aNewValue.getValueType().getTypeClass() == TypeClass_STRING)
&& (getString(aNewValue).getLength() == 0)
&& m_bEmptyIsNull
)
)
2000-09-18 15:33:13 +00:00
m_xColumnUpdate->updateNull();
else
{
// als Value koennen nur double, string oder void auftreten
try
{
2001-02-21 10:10:53 +00:00
if (aNewValue.getValueType().getTypeClass() == TypeClass_DOUBLE)
2000-09-18 15:33:13 +00:00
{
DBTypeConversion::setValue(m_xColumnUpdate, m_aNullDate, getDouble(aNewValue), m_nKeyType);
}
else
{
2001-02-21 10:10:53 +00:00
DBG_ASSERT(aNewValue.getValueType().getTypeClass() == TypeClass_STRING, "OFormattedModel::_commit : invalud value type !");
2000-09-18 15:33:13 +00:00
m_xColumnUpdate->updateString(getString(aNewValue));
}
}
2000-11-23 07:48:15 +00:00
catch(Exception&)
2000-09-18 15:33:13 +00:00
{
return sal_False;
}
m_aSaveValue = aNewValue;
}
}
return sal_True;
}
2000-11-23 07:48:15 +00:00
// XPropertyChangeListener
2000-09-18 15:33:13 +00:00
//------------------------------------------------------------------------------
void OFormattedModel::_onValueChanged()
{
if (m_bNumeric)
m_aSaveValue <<= m_xColumn->getDouble();
else
m_aSaveValue <<= m_xColumn->getString();
if (m_xColumn->wasNull())
m_aSaveValue.clear();
{ // 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);
m_xAggregateFastSet->setFastPropertyValue(OFormattedModel::nValueHandle, m_aSaveValue);
}
}
2000-11-23 07:48:15 +00:00
// XReset
2000-09-18 15:33:13 +00:00
//------------------------------------------------------------------------------
void OFormattedModel::_reset( void )
{
if (!m_xAggregateSet.is())
{
DBG_ERROR("OFormattedModel::_reset : no aggregate !");
return;
}
2000-11-23 07:48:15 +00:00
Any aValue = m_xAggregateSet->getPropertyValue(PROPERTY_EFFECTIVE_DEFAULT);
2000-09-18 15:33:13 +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);
m_xAggregateFastSet->setFastPropertyValue(OFormattedModel::nValueHandle, aValue);
}
}
//.........................................................................
}
//.........................................................................
2000-11-23 07:48:15 +00:00