summaryrefslogtreecommitdiff
path: root/forms/source/component
diff options
context:
space:
mode:
Diffstat (limited to 'forms/source/component')
-rw-r--r--forms/source/component/BaseListBox.hxx45
-rw-r--r--forms/source/component/Button.cxx781
-rw-r--r--forms/source/component/Button.hxx212
-rw-r--r--forms/source/component/CheckBox.cxx275
-rw-r--r--forms/source/component/CheckBox.hxx93
-rw-r--r--forms/source/component/Columns.cxx600
-rw-r--r--forms/source/component/Columns.hxx223
-rw-r--r--forms/source/component/ComboBox.cxx916
-rw-r--r--forms/source/component/ComboBox.hxx180
-rw-r--r--forms/source/component/Currency.cxx270
-rw-r--r--forms/source/component/Currency.hxx103
-rw-r--r--forms/source/component/DatabaseForm.cxx4159
-rw-r--r--forms/source/component/DatabaseForm.hxx569
-rw-r--r--forms/source/component/Date.cxx365
-rw-r--r--forms/source/component/Date.hxx135
-rw-r--r--forms/source/component/Edit.cxx767
-rw-r--r--forms/source/component/Edit.hxx190
-rw-r--r--forms/source/component/EditBase.cxx361
-rw-r--r--forms/source/component/EditBase.hxx115
-rw-r--r--forms/source/component/EventThread.cxx242
-rw-r--r--forms/source/component/EventThread.hxx128
-rw-r--r--forms/source/component/File.cxx306
-rw-r--r--forms/source/component/File.hxx105
-rw-r--r--forms/source/component/Filter.cxx913
-rw-r--r--forms/source/component/Filter.hxx161
-rw-r--r--forms/source/component/FixedText.cxx138
-rw-r--r--forms/source/component/FixedText.hxx73
-rw-r--r--forms/source/component/FormComponent.cxx3070
-rw-r--r--forms/source/component/FormattedField.cxx1257
-rw-r--r--forms/source/component/FormattedField.hxx200
-rw-r--r--forms/source/component/FormattedFieldWrapper.cxx400
-rw-r--r--forms/source/component/FormattedFieldWrapper.hxx101
-rw-r--r--forms/source/component/FormsCollection.cxx188
-rw-r--r--forms/source/component/FormsCollection.hxx102
-rw-r--r--forms/source/component/Grid.cxx1165
-rw-r--r--forms/source/component/Grid.hxx221
-rw-r--r--forms/source/component/GroupBox.cxx175
-rw-r--r--forms/source/component/GroupBox.hxx86
-rw-r--r--forms/source/component/GroupManager.cxx533
-rw-r--r--forms/source/component/GroupManager.hxx234
-rw-r--r--forms/source/component/Hidden.cxx190
-rw-r--r--forms/source/component/Hidden.hxx86
-rw-r--r--forms/source/component/ImageButton.cxx275
-rw-r--r--forms/source/component/ImageButton.hxx109
-rw-r--r--forms/source/component/ImageControl.cxx1021
-rw-r--r--forms/source/component/ImageControl.hxx212
-rw-r--r--forms/source/component/ListBox.cxx1862
-rw-r--r--forms/source/component/ListBox.hxx288
-rw-r--r--forms/source/component/Numeric.cxx224
-rw-r--r--forms/source/component/Numeric.hxx101
-rw-r--r--forms/source/component/Pattern.cxx264
-rw-r--r--forms/source/component/Pattern.hxx110
-rw-r--r--forms/source/component/RadioButton.cxx438
-rw-r--r--forms/source/component/RadioButton.hxx115
-rw-r--r--forms/source/component/Time.cxx367
-rw-r--r--forms/source/component/Time.hxx135
-rw-r--r--forms/source/component/cachedrowset.cxx205
-rw-r--r--forms/source/component/cachedrowset.hxx100
-rw-r--r--forms/source/component/clickableimage.cxx927
-rw-r--r--forms/source/component/clickableimage.hxx297
-rw-r--r--forms/source/component/cloneable.cxx70
-rw-r--r--forms/source/component/entrylisthelper.cxx324
-rw-r--r--forms/source/component/entrylisthelper.hxx201
-rw-r--r--forms/source/component/errorbroadcaster.cxx115
-rw-r--r--forms/source/component/errorbroadcaster.hxx76
-rw-r--r--forms/source/component/findpos.cxx60
-rw-r--r--forms/source/component/findpos.hxx48
-rw-r--r--forms/source/component/formcontrolfont.cxx552
-rw-r--r--forms/source/component/imgprod.cxx582
-rw-r--r--forms/source/component/imgprod.hxx113
-rw-r--r--forms/source/component/makefile.mk95
-rw-r--r--forms/source/component/navigationbar.cxx512
-rw-r--r--forms/source/component/navigationbar.hxx140
-rw-r--r--forms/source/component/propertybaghelper.cxx360
-rw-r--r--forms/source/component/refvaluecomponent.cxx303
-rw-r--r--forms/source/component/refvaluecomponent.hxx111
-rw-r--r--forms/source/component/scrollbar.cxx322
-rw-r--r--forms/source/component/scrollbar.hxx104
-rw-r--r--forms/source/component/spinbutton.cxx278
-rw-r--r--forms/source/component/spinbutton.hxx104
80 files changed, 31953 insertions, 0 deletions
diff --git a/forms/source/component/BaseListBox.hxx b/forms/source/component/BaseListBox.hxx
new file mode 100644
index 000000000000..01d63db5659f
--- /dev/null
+++ b/forms/source/component/BaseListBox.hxx
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FORMS_BASELISTBOX_HXX_
+#define _FORMS_BASELISTBOX_HXX_
+
+//.........................................................................
+namespace frm
+{
+
+const sal_uInt16 ENTRY_NOT_FOUND = 0xFFFF;
+const sal_uInt16 BOUNDCOLUMN = 0x0001;
+
+//.........................................................................
+}
+//.........................................................................
+
+#endif // _FORMS_BASELISTBOX_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/Button.cxx b/forms/source/component/Button.cxx
new file mode 100644
index 000000000000..33d1e9d3a553
--- /dev/null
+++ b/forms/source/component/Button.cxx
@@ -0,0 +1,781 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+
+#include "Button.hxx"
+
+#include <com/sun/star/awt/XVclWindowPeer.hpp>
+
+#include <comphelper/streamsection.hxx>
+#include <comphelper/basicio.hxx>
+#include <tools/diagnose_ex.h>
+#include <tools/debug.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/svapp.hxx>
+#include <osl/mutex.hxx>
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+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 ::com::sun::star::frame::XDispatchProviderInterceptor;
+
+//==================================================================
+//= OButtonModel
+//==================================================================
+DBG_NAME(OButtonModel)
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL OButtonModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
+{
+ return *(new OButtonModel(_rxFactory));
+}
+
+//------------------------------------------------------------------
+OButtonModel::OButtonModel(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OClickableImageBaseModel( _rxFactory, VCL_CONTROLMODEL_COMMANDBUTTON, FRM_SUN_CONTROL_COMMANDBUTTON )
+ // use the old control name for compatibility reasons
+ ,m_aResetHelper( *this, m_aMutex )
+ ,m_eDefaultState( STATE_NOCHECK )
+{
+ DBG_CTOR( OButtonModel, NULL );
+ m_nClassId = FormComponentType::COMMANDBUTTON;
+}
+
+//------------------------------------------------------------------
+Any SAL_CALL OButtonModel::queryAggregation( const Type& _type ) throw(RuntimeException)
+{
+ Any aReturn = OClickableImageBaseModel::queryAggregation( _type );
+ if ( !aReturn.hasValue() )
+ aReturn = OButtonModel_Base::queryInterface( _type );
+ return aReturn;
+}
+
+//------------------------------------------------------------------
+Sequence< Type > OButtonModel::_getTypes()
+{
+ return ::comphelper::concatSequences(
+ OClickableImageBaseModel::_getTypes(),
+ OButtonModel_Base::getTypes()
+ );
+}
+
+//------------------------------------------------------------------
+OButtonModel::OButtonModel( const OButtonModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
+ :OClickableImageBaseModel( _pOriginal, _rxFactory )
+ ,m_aResetHelper( *this, m_aMutex )
+ ,m_eDefaultState( _pOriginal->m_eDefaultState )
+{
+ DBG_CTOR( OButtonModel, NULL );
+ m_nClassId = FormComponentType::COMMANDBUTTON;
+
+ implInitializeImageURL();
+}
+
+//------------------------------------------------------------------------------
+OButtonModel::~OButtonModel()
+{
+ DBG_DTOR(OButtonModel, NULL);
+}
+
+//------------------------------------------------------------------------------
+void OButtonModel::describeFixedProperties( Sequence< Property >& _rProps ) const
+{
+ BEGIN_DESCRIBE_PROPERTIES( 6, OClickableImageBaseModel )
+ DECL_PROP1( BUTTONTYPE, FormButtonType, BOUND );
+ DECL_PROP1( DEFAULT_STATE, sal_Int16, BOUND );
+ DECL_PROP1( DISPATCHURLINTERNAL, sal_Bool, BOUND );
+ DECL_PROP1( TARGET_URL, ::rtl::OUString, BOUND );
+ DECL_PROP1( TARGET_FRAME, ::rtl::OUString, BOUND );
+ DECL_PROP1( TABINDEX, sal_Int16, BOUND );
+ END_DESCRIBE_PROPERTIES();
+}
+
+//------------------------------------------------------------------------------
+IMPLEMENT_DEFAULT_CLONING( OButtonModel )
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+StringSequence OButtonModel::getSupportedServiceNames() throw()
+{
+ StringSequence aSupported = OClickableImageBaseModel::getSupportedServiceNames();
+ aSupported.realloc( aSupported.getLength() + 1 );
+
+ ::rtl::OUString* pArray = aSupported.getArray();
+ pArray[ aSupported.getLength() - 1 ] = FRM_SUN_COMPONENT_COMMANDBUTTON;
+
+ return aSupported;
+}
+
+//------------------------------------------------------------------------------
+::rtl::OUString OButtonModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException)
+{
+ return FRM_COMPONENT_COMMANDBUTTON; // old (non-sun) name for compatibility !
+}
+
+//------------------------------------------------------------------------------
+void OButtonModel::write(const Reference<XObjectOutputStream>& _rxOutStream) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
+{
+ OClickableImageBaseModel::write(_rxOutStream);
+
+ _rxOutStream->writeShort(0x0003); // Version
+
+ {
+ OStreamSection aSection( _rxOutStream.get() );
+ // this will allow readers to skip unknown bytes in their dtor
+
+ _rxOutStream->writeShort( (sal_uInt16)m_eButtonType );
+
+ ::rtl::OUString sTmp = INetURLObject::decode( m_sTargetURL, '%', INetURLObject::DECODE_UNAMBIGUOUS);
+ _rxOutStream << sTmp;
+ _rxOutStream << m_sTargetFrame;
+ writeHelpTextCompatibly(_rxOutStream);
+ _rxOutStream << isDispatchUrlInternal();
+ }
+}
+
+//------------------------------------------------------------------------------
+void OButtonModel::read(const Reference<XObjectInputStream>& _rxInStream) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
+{
+ OClickableImageBaseModel::read(_rxInStream);
+
+ sal_uInt16 nVersion = _rxInStream->readShort(); // Version
+ switch (nVersion)
+ {
+ case 0x0001:
+ {
+ m_eButtonType = (FormButtonType)_rxInStream->readShort();
+
+ _rxInStream >> m_sTargetURL;
+ _rxInStream >> m_sTargetFrame;
+ }
+ break;
+
+ case 0x0002:
+ {
+ m_eButtonType = (FormButtonType)_rxInStream->readShort();
+
+ _rxInStream >> m_sTargetURL;
+ _rxInStream >> m_sTargetFrame;
+ readHelpTextCompatibly(_rxInStream);
+ }
+ break;
+
+ case 0x0003:
+ {
+ OStreamSection aSection( _rxInStream.get() );
+ // this will skip any unknown bytes in it's dtor
+
+ // button type
+ m_eButtonType = (FormButtonType)_rxInStream->readShort();
+
+ // URL
+ _rxInStream >> m_sTargetURL;
+
+ // target frame
+ _rxInStream >> m_sTargetFrame;
+
+ // help text
+ readHelpTextCompatibly(_rxInStream);
+
+ // DispatchInternal
+ sal_Bool bDispath;
+ _rxInStream >> bDispath;
+ setDispatchUrlInternal(bDispath);
+ }
+ break;
+
+ default:
+ OSL_FAIL("OButtonModel::read : unknown version !");
+ m_eButtonType = FormButtonType_PUSH;
+ m_sTargetURL = ::rtl::OUString();
+ m_sTargetFrame = ::rtl::OUString();
+ break;
+ }
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL OButtonModel::disposing()
+{
+ m_aResetHelper.disposing();
+ OClickableImageBaseModel::disposing();
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL OButtonModel::reset() throw (RuntimeException)
+{
+ if ( !m_aResetHelper.approveReset() )
+ return;
+
+ impl_resetNoBroadcast_nothrow();
+
+ m_aResetHelper.notifyResetted();
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL OButtonModel::addResetListener( const Reference< XResetListener >& _listener ) throw (RuntimeException)
+{
+ m_aResetHelper.addResetListener( _listener );
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL OButtonModel::removeResetListener( const Reference< XResetListener >& _listener ) throw (RuntimeException)
+{
+ m_aResetHelper.removeResetListener( _listener );
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL OButtonModel::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const
+{
+ switch ( _nHandle )
+ {
+ case PROPERTY_ID_DEFAULT_STATE:
+ _rValue <<= (sal_Int16)m_eDefaultState;
+ break;
+
+ default:
+ OClickableImageBaseModel::getFastPropertyValue( _rValue, _nHandle );
+ break;
+ }
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL OButtonModel::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const Any& _rValue ) throw (Exception)
+{
+ switch ( _nHandle )
+ {
+ case PROPERTY_ID_DEFAULT_STATE:
+ {
+ sal_Int16 nDefaultState( (sal_Int16)STATE_NOCHECK );
+ OSL_VERIFY( _rValue >>= nDefaultState );
+ m_eDefaultState = (ToggleState)nDefaultState;
+ impl_resetNoBroadcast_nothrow();
+ }
+ break;
+
+ default:
+ OClickableImageBaseModel::setFastPropertyValue_NoBroadcast( _nHandle, _rValue );
+ break;
+ }
+}
+
+//--------------------------------------------------------------------
+sal_Bool SAL_CALL OButtonModel::convertFastPropertyValue( Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue ) throw (IllegalArgumentException)
+{
+ sal_Bool bModified = sal_False;
+ switch ( _nHandle )
+ {
+ case PROPERTY_ID_DEFAULT_STATE:
+ bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, (sal_Int16)m_eDefaultState );
+ break;
+
+ default:
+ bModified = OClickableImageBaseModel::convertFastPropertyValue( _rConvertedValue, _rOldValue, _nHandle, _rValue );
+ break;
+ }
+ return bModified;
+}
+
+//--------------------------------------------------------------------
+Any OButtonModel::getPropertyDefaultByHandle( sal_Int32 _nHandle ) const
+{
+ Any aDefault;
+ switch ( _nHandle )
+ {
+ case PROPERTY_ID_DEFAULT_STATE:
+ aDefault <<= (sal_Int16)STATE_NOCHECK;
+ break;
+
+ default:
+ aDefault = OClickableImageBaseModel::getPropertyDefaultByHandle( _nHandle );
+ break;
+ }
+ return aDefault;
+}
+
+//--------------------------------------------------------------------
+void OButtonModel::impl_resetNoBroadcast_nothrow()
+{
+ try
+ {
+ setPropertyValue( PROPERTY_STATE, getPropertyValue( PROPERTY_DEFAULT_STATE ) );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+
+//==================================================================
+// OButtonControl
+//==================================================================
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL OButtonControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
+{
+ return *(new OButtonControl(_rxFactory));
+}
+
+//------------------------------------------------------------------------------
+Sequence<Type> OButtonControl::_getTypes()
+{
+ return ::comphelper::concatSequences(
+ OButtonControl_BASE::getTypes(),
+ OClickableImageBaseControl::_getTypes(),
+ OFormNavigationHelper::getTypes()
+ );
+}
+
+//------------------------------------------------------------------------------
+StringSequence OButtonControl::getSupportedServiceNames() throw()
+{
+ StringSequence aSupported = OClickableImageBaseControl::getSupportedServiceNames();
+ aSupported.realloc(aSupported.getLength() + 1);
+
+ ::rtl::OUString*pArray = aSupported.getArray();
+ pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_COMMANDBUTTON;
+ return aSupported;
+}
+
+//------------------------------------------------------------------------------
+OButtonControl::OButtonControl(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OClickableImageBaseControl(_rxFactory, VCL_CONTROL_COMMANDBUTTON)
+ ,OFormNavigationHelper( _rxFactory )
+ ,m_nClickEvent( 0 )
+ ,m_nTargetUrlFeatureId( -1 )
+ ,m_bEnabledByPropertyValue( sal_False )
+{
+ increment(m_refCount);
+ {
+ // als ActionListener anmelden
+ Reference<XButton> xButton;
+ query_aggregation( m_xAggregate, xButton);
+ if (xButton.is())
+ xButton->addActionListener(this);
+ }
+ // Refcount bei 1 fuer Listener
+ decrement(m_refCount);
+}
+
+//------------------------------------------------------------------------------
+OButtonControl::~OButtonControl()
+{
+ if (m_nClickEvent)
+ Application::RemoveUserEvent(m_nClickEvent);
+}
+
+// UNO Anbindung
+//------------------------------------------------------------------------------
+Any SAL_CALL OButtonControl::queryAggregation(const Type& _rType) throw (RuntimeException)
+{
+ // if asked for the XTypeProvider, don't let OButtonControl_BASE do this
+ Any aReturn;
+ if ( !_rType.equals( ::getCppuType( static_cast< Reference< XTypeProvider >* >( NULL ) ) ) )
+ aReturn = OButtonControl_BASE::queryInterface( _rType );
+
+ if ( !aReturn.hasValue() )
+ aReturn = OClickableImageBaseControl::queryAggregation( _rType );
+
+ if ( !aReturn.hasValue() )
+ aReturn = OFormNavigationHelper::queryInterface( _rType );
+
+ return aReturn;
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OButtonControl::disposing()
+{
+ startOrStopModelPropertyListening( false );
+
+ OClickableImageBaseControl::disposing();
+ OFormNavigationHelper::dispose();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OButtonControl::disposing( const EventObject& _rSource ) throw( RuntimeException )
+{
+ OControl::disposing( _rSource );
+ OFormNavigationHelper::disposing( _rSource );
+}
+
+// ActionListener
+//------------------------------------------------------------------------------
+void OButtonControl::actionPerformed(const ActionEvent& /*rEvent*/) throw ( ::com::sun::star::uno::RuntimeException)
+{
+ // Asynchron fuer starutil::URL-Button
+ sal_uLong n = Application::PostUserEvent( LINK(this, OButtonControl,OnClick) );
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ m_nClickEvent = n;
+ }
+}
+
+//------------------------------------------------------------------------------
+IMPL_LINK( OButtonControl, OnClick, void*, EMPTYARG )
+{
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+ m_nClickEvent = 0;
+
+ if (m_aApproveActionListeners.getLength())
+ {
+ // if there are listeners, start the action in an own thread, to not allow
+ // them to block us here (we're in the application's main thread)
+ getImageProducerThread()->addEvent();
+ }
+ else
+ {
+ // Sonst nicht. Dann darf man aber auf keinen Fal die Listener
+ // benachrichtigen, auch dann nicht, wenn er spaeter hinzukommt.
+ aGuard.clear();
+
+ // recognize the button type
+ Reference<XPropertySet> xSet(getModel(), UNO_QUERY);
+ if (!xSet.is())
+ return 0L;
+
+ if (FormButtonType_PUSH == *(FormButtonType*)xSet->getPropertyValue(PROPERTY_BUTTONTYPE).getValue())
+ {
+ // notify the action listeners for a push button
+ ::cppu::OInterfaceIteratorHelper aIter(m_aActionListeners);
+ ActionEvent aEvt(static_cast<XWeak*>(this), m_aActionCommand);
+ while(aIter.hasMoreElements() )
+ {
+ // catch exceptions
+ // and catch them on a per-listener basis - if one listener fails, the others still need
+ // to get notified
+ try
+ {
+ static_cast< XActionListener* >( aIter.next() )->actionPerformed(aEvt);
+ }
+#ifdef DBG_UTIL
+ catch( const RuntimeException& )
+ {
+ // silent this
+ }
+#endif
+ catch( const Exception& )
+ {
+ OSL_FAIL( "OButtonControl::OnClick: caught a exception other than RuntimeException!" );
+ }
+ }
+ }
+ else
+ actionPerformed_Impl( sal_False, ::com::sun::star::awt::MouseEvent() );
+ }
+ return 0L;
+}
+
+//------------------------------------------------------------------------------
+void OButtonControl::actionPerformed_Impl( sal_Bool _bNotifyListener, const ::com::sun::star::awt::MouseEvent& _rEvt )
+{
+ {
+ sal_Int16 nFeatureId = -1;
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ nFeatureId = m_nTargetUrlFeatureId;
+ }
+
+ if ( nFeatureId != -1 )
+ {
+ if ( !approveAction() )
+ return;
+
+ SolarMutexGuard aGuard;
+ dispatch( nFeatureId );
+ return;
+ }
+ }
+
+ OClickableImageBaseControl::actionPerformed_Impl( _bNotifyListener, _rEvt );
+}
+
+// XButton
+//------------------------------------------------------------------------------
+void OButtonControl::setLabel(const ::rtl::OUString& Label) throw( RuntimeException )
+{
+ Reference<XButton> xButton;
+ query_aggregation( m_xAggregate, xButton );
+ if (xButton.is())
+ xButton->setLabel(Label);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OButtonControl::setActionCommand(const ::rtl::OUString& _rCommand) throw( RuntimeException )
+{
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ m_aActionCommand = _rCommand;
+ }
+
+ Reference<XButton> xButton;
+ query_aggregation( m_xAggregate, xButton);
+ if (xButton.is())
+ xButton->setActionCommand(_rCommand);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OButtonControl::addActionListener(const Reference<XActionListener>& _rxListener) throw( RuntimeException )
+{
+ m_aActionListeners.addInterface(_rxListener);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OButtonControl::removeActionListener(const Reference<XActionListener>& _rxListener) throw( RuntimeException )
+{
+ m_aActionListeners.removeInterface(_rxListener);
+}
+
+//------------------------------------------------------------------------------
+class DoPropertyListening
+{
+private:
+ Reference< XPropertySet > m_xProps;
+ Reference< XPropertyChangeListener > m_xListener;
+ bool m_bStartListening;
+
+public:
+ DoPropertyListening(
+ const Reference< XInterface >& _rxComponent,
+ const Reference< XPropertyChangeListener >& _rxListener,
+ bool _bStart
+ );
+
+ void handleListening( const ::rtl::OUString& _rPropertyName );
+};
+
+//..............................................................................
+DoPropertyListening::DoPropertyListening(
+ const Reference< XInterface >& _rxComponent, const Reference< XPropertyChangeListener >& _rxListener,
+ bool _bStart )
+ :m_xProps( _rxComponent, UNO_QUERY )
+ ,m_xListener( _rxListener )
+ ,m_bStartListening( _bStart )
+{
+ DBG_ASSERT( m_xProps.is() || !_rxComponent.is(), "DoPropertyListening::DoPropertyListening: valid component, but no property set!" );
+ DBG_ASSERT( m_xListener.is(), "DoPropertyListening::DoPropertyListening: invalid listener!" );
+}
+
+//..............................................................................
+void DoPropertyListening::handleListening( const ::rtl::OUString& _rPropertyName )
+{
+ if ( m_xProps.is() )
+ {
+ if ( m_bStartListening )
+ m_xProps->addPropertyChangeListener( _rPropertyName, m_xListener );
+ else
+ m_xProps->removePropertyChangeListener( _rPropertyName, m_xListener );
+ }
+}
+
+//------------------------------------------------------------------------------
+void OButtonControl::startOrStopModelPropertyListening( bool _bStart )
+{
+ DoPropertyListening aListeningHandler( getModel(), this, _bStart );
+ aListeningHandler.handleListening( PROPERTY_TARGET_URL );
+ aListeningHandler.handleListening( PROPERTY_BUTTONTYPE );
+ aListeningHandler.handleListening( PROPERTY_ENABLED );
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL OButtonControl::setModel( const Reference< XControlModel >& _rxModel ) throw ( RuntimeException )
+{
+ startOrStopModelPropertyListening( false );
+ sal_Bool bResult = OClickableImageBaseControl::setModel( _rxModel );
+ startOrStopModelPropertyListening( true );
+
+ m_bEnabledByPropertyValue = sal_True;
+ Reference< XPropertySet > xModelProps( _rxModel, UNO_QUERY );
+ if ( xModelProps.is() )
+ xModelProps->getPropertyValue( PROPERTY_ENABLED ) >>= m_bEnabledByPropertyValue;
+
+ modelFeatureUrlPotentiallyChanged( );
+
+ return bResult;
+}
+
+//------------------------------------------------------------------------------
+void OButtonControl::modelFeatureUrlPotentiallyChanged( )
+{
+ sal_Int16 nOldUrlFeatureId = m_nTargetUrlFeatureId;
+
+ // doe we have another TargetURL now? If so, we need to update our dispatches
+ m_nTargetUrlFeatureId = getModelUrlFeatureId( );
+ if ( nOldUrlFeatureId != m_nTargetUrlFeatureId )
+ {
+ invalidateSupportedFeaturesSet();
+ if ( !isDesignMode() )
+ updateDispatches( );
+ }
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OButtonControl::propertyChange( const PropertyChangeEvent& _rEvent ) throw ( RuntimeException )
+{
+ if ( _rEvent.PropertyName.equals( PROPERTY_TARGET_URL )
+ || _rEvent.PropertyName.equals( PROPERTY_BUTTONTYPE )
+ )
+ {
+ modelFeatureUrlPotentiallyChanged( );
+ }
+ else if ( _rEvent.PropertyName.equals( PROPERTY_ENABLED ) )
+ {
+ _rEvent.NewValue >>= m_bEnabledByPropertyValue;
+ }
+}
+
+//------------------------------------------------------------------------------
+namespace
+{
+ bool isFormControllerURL( const ::rtl::OUString& _rURL )
+ {
+ const sal_Int32 nPrefixLen = URL_CONTROLLER_PREFIX.length;
+ return ( _rURL.getLength() > nPrefixLen )
+ && ( _rURL.compareToAscii( URL_CONTROLLER_PREFIX, nPrefixLen ) == 0 );
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Int16 OButtonControl::getModelUrlFeatureId( ) const
+{
+ sal_Int16 nFeatureId = -1;
+
+ // some URL related properties of the model
+ ::rtl::OUString sUrl;
+ FormButtonType eButtonType = FormButtonType_PUSH;
+
+ Reference< XPropertySet > xModelProps( const_cast< OButtonControl* >( this )->getModel(), UNO_QUERY );
+ if ( xModelProps.is() )
+ {
+ xModelProps->getPropertyValue( PROPERTY_TARGET_URL ) >>= sUrl;
+ xModelProps->getPropertyValue( PROPERTY_BUTTONTYPE ) >>= eButtonType;
+ }
+
+ // are we an URL button?
+ if ( eButtonType == FormButtonType_URL )
+ {
+ // is it a feature URL?
+ if ( isFormControllerURL( sUrl ) )
+ {
+ OFormNavigationMapper aMapper( m_aContext.getLegacyServiceFactory() );
+ nFeatureId = aMapper.getFeatureId( sUrl );
+ }
+ }
+
+ return nFeatureId;
+}
+
+//------------------------------------------------------------------
+void SAL_CALL OButtonControl::setDesignMode( sal_Bool _bOn ) throw( RuntimeException )
+{
+ OClickableImageBaseControl::setDesignMode( _bOn );
+
+ if ( _bOn )
+ disconnectDispatchers();
+ else
+ connectDispatchers();
+ // this will connect if not already connected and just update else
+}
+
+//------------------------------------------------------------------------------
+void OButtonControl::getSupportedFeatures( ::std::vector< sal_Int16 >& /* [out] */ _rFeatureIds )
+{
+ if ( -1 != m_nTargetUrlFeatureId )
+ _rFeatureIds.push_back( m_nTargetUrlFeatureId );
+}
+
+//------------------------------------------------------------------
+void OButtonControl::featureStateChanged( sal_Int16 _nFeatureId, sal_Bool _bEnabled )
+{
+ if ( _nFeatureId == m_nTargetUrlFeatureId )
+ {
+ // enable or disable our peer, according to the new state
+ Reference< XVclWindowPeer > xPeer( getPeer(), UNO_QUERY );
+ if ( xPeer.is() )
+ xPeer->setProperty( PROPERTY_ENABLED, makeAny( m_bEnabledByPropertyValue ? _bEnabled : sal_False ) );
+ // if we're disabled according to our model's property, then
+ // we don't care for the feature state, but *are* disabled.
+ // If the model's property states that we're enabled, then we *do*
+ // care for the feature state
+ }
+
+ // base class
+ OFormNavigationHelper::featureStateChanged( _nFeatureId, _bEnabled );
+}
+
+//------------------------------------------------------------------
+void OButtonControl::allFeatureStatesChanged( )
+{
+ if ( -1 != m_nTargetUrlFeatureId )
+ // we have only one supported feature, so simulate it has changed ...
+ featureStateChanged( m_nTargetUrlFeatureId, isEnabled( m_nTargetUrlFeatureId ) );
+
+ // base class
+ OFormNavigationHelper::allFeatureStatesChanged( );
+}
+
+//------------------------------------------------------------------
+bool OButtonControl::isEnabled( sal_Int16 _nFeatureId ) const
+{
+ if ( const_cast< OButtonControl* >( this )->isDesignMode() )
+ // TODO: the model property?
+ return true;
+
+ return OFormNavigationHelper::isEnabled( _nFeatureId );
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL OButtonControl::registerDispatchProviderInterceptor( const Reference< XDispatchProviderInterceptor >& _rxInterceptor ) throw (RuntimeException)
+{
+ OClickableImageBaseControl::registerDispatchProviderInterceptor( _rxInterceptor );
+ OFormNavigationHelper::registerDispatchProviderInterceptor( _rxInterceptor );
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL OButtonControl::releaseDispatchProviderInterceptor( const Reference< XDispatchProviderInterceptor >& _rxInterceptor ) throw (RuntimeException)
+{
+ OClickableImageBaseControl::releaseDispatchProviderInterceptor( _rxInterceptor );
+ OFormNavigationHelper::releaseDispatchProviderInterceptor( _rxInterceptor );
+}
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/Button.hxx b/forms/source/component/Button.hxx
new file mode 100644
index 000000000000..1c6b168a877c
--- /dev/null
+++ b/forms/source/component/Button.hxx
@@ -0,0 +1,212 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FRM_BUTTON_HXX_
+#define _FRM_BUTTON_HXX_
+
+#include "clickableimage.hxx"
+#include "togglestate.hxx"
+#include "formnavigation.hxx"
+#include "resettable.hxx"
+
+#include <com/sun/star/awt/MouseEvent.hpp>
+#include <com/sun/star/lang/EventObject.hpp>
+#include <com/sun/star/awt/ActionEvent.hpp>
+#include <com/sun/star/awt/XActionListener.hpp>
+#include <com/sun/star/awt/XButton.hpp>
+#include <com/sun/star/form/XReset.hpp>
+#include <com/sun/star/beans/PropertyChangeEvent.hpp>
+
+#include <cppuhelper/implbase1.hxx>
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+//==================================================================
+// OButtonModel
+//==================================================================
+typedef ::cppu::ImplHelper1 < ::com::sun::star::form::XReset
+ > OButtonModel_Base;
+class OButtonModel :public OClickableImageBaseModel
+ ,public OButtonModel_Base
+{
+public:
+ DECLARE_DEFAULT_LEAF_XTOR( OButtonModel );
+
+ // UNO
+ DECLARE_UNO3_AGG_DEFAULTS( OButtonModel, OClickableImageBaseModel );
+ virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw(::com::sun::star::uno::RuntimeException);
+
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();
+
+// ::com::sun::star::lang::XServiceInfo
+ IMPLEMENTATION_NAME(OButtonModel);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw();
+
+// ::com::sun::star::io::XPersistObject
+ virtual ::rtl::OUString SAL_CALL getServiceName() throw ( ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ // XReset
+ virtual void SAL_CALL reset( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addResetListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XResetListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeResetListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XResetListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // OControlModel's property handling
+ virtual void describeFixedProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps
+ ) const;
+
+ // XPropertySet and friends
+ virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const;
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
+ throw (::com::sun::star::uno::Exception);
+ virtual sal_Bool SAL_CALL convertFastPropertyValue(
+ ::com::sun::star::uno::Any& _rConvertedValue, ::com::sun::star::uno::Any& _rOldValue, sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue )
+ throw (::com::sun::star::lang::IllegalArgumentException);
+ virtual ::com::sun::star::uno::Any getPropertyDefaultByHandle( sal_Int32 nHandle ) const;
+
+ // OComponentHelper
+ virtual void SAL_CALL disposing();
+
+protected:
+ DECLARE_XCLONEABLE();
+
+private:
+ void impl_resetNoBroadcast_nothrow();
+
+ using ::cppu::OPropertySetHelper::getFastPropertyValue;
+
+private:
+ ResetHelper m_aResetHelper;
+
+ // <properties>
+ ToggleState m_eDefaultState; // the default check state
+ // </properties>
+protected:
+ using OClickableImageBaseModel::disposing;
+};
+
+//==================================================================
+// OButtonControl
+//==================================================================
+typedef ::cppu::ImplHelper3 < ::com::sun::star::awt::XButton
+ , ::com::sun::star::awt::XActionListener
+ , ::com::sun::star::beans::XPropertyChangeListener
+ > OButtonControl_BASE;
+
+class OButtonControl :public OButtonControl_BASE
+ ,public OClickableImageBaseControl
+ ,public OFormNavigationHelper
+{
+private:
+ sal_uLong m_nClickEvent;
+ sal_Int16 m_nTargetUrlFeatureId;
+ /// caches the value of the "Enabled" property of our model
+ sal_Bool m_bEnabledByPropertyValue;
+
+protected:
+
+ // UNO Anbindung
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();
+
+public:
+ OButtonControl(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);
+ virtual ~OButtonControl();
+
+ // XServiceInfo
+ IMPLEMENTATION_NAME(OButtonControl);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw();
+
+ // UNO Anbindung
+ DECLARE_UNO3_AGG_DEFAULTS(OButtonControl, OClickableImageBaseControl);
+ virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation(const ::com::sun::star::uno::Type& _rType) throw(::com::sun::star::uno::RuntimeException);
+
+ // XActionListener
+ virtual void SAL_CALL actionPerformed(const ::com::sun::star::awt::ActionEvent& rEvent) throw ( ::com::sun::star::uno::RuntimeException);
+
+ // XButton
+ virtual void SAL_CALL addActionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XActionListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeActionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XActionListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setLabel(const ::rtl::OUString& Label) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setActionCommand(const ::rtl::OUString& _rCommand) throw(::com::sun::star::uno::RuntimeException);
+
+ // OComponentHelper
+ virtual void SAL_CALL disposing();
+
+ // XPropertyChangeListener
+ virtual void SAL_CALL propertyChange( const ::com::sun::star::beans::PropertyChangeEvent& evt ) throw(::com::sun::star::uno::RuntimeException);
+
+ // XEventListener
+ virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& _rSource) throw(::com::sun::star::uno::RuntimeException);
+
+ // XControl
+ virtual sal_Bool SAL_CALL setModel( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >& _rxModel ) throw ( ::com::sun::star::uno::RuntimeException );
+ void SAL_CALL setDesignMode(sal_Bool bOn) throw (::com::sun::star::uno::RuntimeException);
+
+protected:
+ // OFormNavigationHelper overriables
+ virtual void getSupportedFeatures( ::std::vector< sal_Int16 >& /* [out] */ _rFeatureIds );
+ virtual void featureStateChanged( sal_Int16 _nFeatureId, sal_Bool _bEnabled );
+ virtual void allFeatureStatesChanged( );
+ virtual bool isEnabled( sal_Int16 _nFeatureId ) const;
+
+ // XDispatchProviderInterception disambiguaiton
+ virtual void SAL_CALL registerDispatchProviderInterceptor( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProviderInterceptor >& Interceptor ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL releaseDispatchProviderInterceptor( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProviderInterceptor >& Interceptor ) throw (::com::sun::star::uno::RuntimeException);
+
+ // OImageControl overridables
+ virtual void actionPerformed_Impl( sal_Bool bNotifyListener, const ::com::sun::star::awt::MouseEvent& _rEvt );
+
+private:
+ DECL_LINK( OnClick, void* );
+
+ /** to be called whenever the feature URL represented by our model has potentially changed
+ */
+ void modelFeatureUrlPotentiallyChanged( );
+
+ /** retrieves the feature id (see OFormNavigationHelper) of the TargetURL of
+ the model.
+ */
+ sal_Int16 getModelUrlFeatureId( ) const;
+
+ /** starts or stops listening for changes in model properties we're interested in
+ */
+ void startOrStopModelPropertyListening( bool _bStart );
+};
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+#endif // _FRM_BUTTON_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/CheckBox.cxx b/forms/source/component/CheckBox.cxx
new file mode 100644
index 000000000000..5fbf0a8d1086
--- /dev/null
+++ b/forms/source/component/CheckBox.cxx
@@ -0,0 +1,275 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+#include "CheckBox.hxx"
+#include "property.hxx"
+#include "property.hrc"
+#include "services.hxx"
+#include <tools/debug.hxx>
+#include <comphelper/basicio.hxx>
+
+//.........................................................................
+namespace frm
+{
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::form;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::form::binding;
+
+//==================================================================
+//= OCheckBoxControl
+//==================================================================
+
+//------------------------------------------------------------------
+OCheckBoxControl::OCheckBoxControl(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OBoundControl(_rxFactory, VCL_CONTROL_CHECKBOX)
+{
+}
+
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL OCheckBoxControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory) throw (RuntimeException)
+{
+ return *(new OCheckBoxControl(_rxFactory));
+}
+
+//------------------------------------------------------------------------------
+StringSequence SAL_CALL OCheckBoxControl::getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException)
+{
+ StringSequence aSupported = OBoundControl::getSupportedServiceNames();
+ aSupported.realloc(aSupported.getLength() + 1);
+
+ ::rtl::OUString* pArray = aSupported.getArray();
+ pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_CHECKBOX;
+ return aSupported;
+}
+
+//==================================================================
+//= OCheckBoxModel
+//==================================================================
+
+//==================================================================
+InterfaceRef SAL_CALL OCheckBoxModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory) throw (RuntimeException)
+{
+ return *(new OCheckBoxModel(_rxFactory));
+}
+
+//------------------------------------------------------------------
+DBG_NAME( OCheckBoxModel )
+//------------------------------------------------------------------
+OCheckBoxModel::OCheckBoxModel(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OReferenceValueComponent( _rxFactory, VCL_CONTROLMODEL_CHECKBOX, FRM_SUN_CONTROL_CHECKBOX, sal_True )
+ // use the old control name for compytibility reasons
+{
+ DBG_CTOR( OCheckBoxModel, NULL );
+
+ m_nClassId = FormComponentType::CHECKBOX;
+ initValueProperty( PROPERTY_STATE, PROPERTY_ID_STATE );
+}
+
+//------------------------------------------------------------------
+OCheckBoxModel::OCheckBoxModel( const OCheckBoxModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
+ :OReferenceValueComponent( _pOriginal, _rxFactory )
+{
+ DBG_CTOR( OCheckBoxModel, NULL );
+}
+
+//------------------------------------------------------------------------------
+OCheckBoxModel::~OCheckBoxModel()
+{
+ DBG_DTOR( OCheckBoxModel, NULL );
+}
+
+//------------------------------------------------------------------------------
+IMPLEMENT_DEFAULT_CLONING( OCheckBoxModel )
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+StringSequence SAL_CALL OCheckBoxModel::getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException)
+{
+ StringSequence aSupported = OReferenceValueComponent::getSupportedServiceNames();
+
+ sal_Int32 nOldLen = aSupported.getLength();
+ aSupported.realloc( nOldLen + 8 );
+ ::rtl::OUString* pStoreTo = aSupported.getArray() + nOldLen;
+
+ *pStoreTo++ = BINDABLE_CONTROL_MODEL;
+ *pStoreTo++ = DATA_AWARE_CONTROL_MODEL;
+ *pStoreTo++ = VALIDATABLE_CONTROL_MODEL;
+
+ *pStoreTo++ = BINDABLE_DATA_AWARE_CONTROL_MODEL;
+ *pStoreTo++ = VALIDATABLE_BINDABLE_CONTROL_MODEL;
+
+ *pStoreTo++ = FRM_SUN_COMPONENT_CHECKBOX;
+ *pStoreTo++ = FRM_SUN_COMPONENT_DATABASE_CHECKBOX;
+ *pStoreTo++ = BINDABLE_DATABASE_CHECK_BOX;
+
+ return aSupported;
+}
+
+//------------------------------------------------------------------------------
+void OCheckBoxModel::describeFixedProperties( Sequence< Property >& _rProps ) const
+{
+ BEGIN_DESCRIBE_PROPERTIES( 1, OReferenceValueComponent )
+ DECL_PROP1(TABINDEX, sal_Int16, BOUND);
+ END_DESCRIBE_PROPERTIES();
+}
+
+//------------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OCheckBoxModel::getServiceName() throw(RuntimeException)
+{
+ return FRM_COMPONENT_CHECKBOX; // old (non-sun) name for compatibility !
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OCheckBoxModel::write(const Reference<stario::XObjectOutputStream>& _rxOutStream)
+ throw(stario::IOException, RuntimeException)
+{
+ OReferenceValueComponent::write(_rxOutStream);
+
+ // Version
+ _rxOutStream->writeShort(0x0003);
+ // Properties
+ _rxOutStream << getReferenceValue();
+ _rxOutStream << (sal_Int16)getDefaultChecked();
+ writeHelpTextCompatibly(_rxOutStream);
+ // from version 0x0003 : common properties
+ writeCommonProperties(_rxOutStream);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OCheckBoxModel::read(const Reference<stario::XObjectInputStream>& _rxInStream) throw(stario::IOException, RuntimeException)
+{
+ OReferenceValueComponent::read(_rxInStream);
+ osl::MutexGuard aGuard(m_aMutex);
+
+ // Version
+ sal_uInt16 nVersion = _rxInStream->readShort();
+
+ ::rtl::OUString sReferenceValue;
+ sal_Int16 nDefaultChecked( 0 );
+ switch ( nVersion )
+ {
+ case 0x0001:
+ _rxInStream >> sReferenceValue;
+ nDefaultChecked = _rxInStream->readShort();
+ break;
+ case 0x0002:
+ _rxInStream >> sReferenceValue;
+ _rxInStream >> nDefaultChecked;
+ readHelpTextCompatibly( _rxInStream );
+ break;
+ case 0x0003:
+ _rxInStream >> sReferenceValue;
+ _rxInStream >> nDefaultChecked;
+ readHelpTextCompatibly(_rxInStream);
+ readCommonProperties(_rxInStream);
+ break;
+ default:
+ OSL_FAIL("OCheckBoxModel::read : unknown version !");
+ defaultCommonProperties();
+ break;
+ }
+ setReferenceValue( sReferenceValue );
+ setDefaultChecked( static_cast< ToggleState >( nDefaultChecked ) );
+
+ // Nach dem Lesen die Defaultwerte anzeigen
+ if ( getControlSource().getLength() )
+ // (not if we don't have a control source - the "State" property acts like it is persistent, then
+ resetNoBroadcast();
+}
+
+//------------------------------------------------------------------------------
+Any OCheckBoxModel::translateDbColumnToControlValue()
+{
+ Any aValue;
+
+ //////////////////////////////////////////////////////////////////
+ // Wert an ControlModel setzen
+ sal_Bool bValue = m_xColumn->getBoolean();
+ if ( m_xColumn->wasNull() )
+ {
+ sal_Bool bTriState = sal_True;
+ if ( m_xAggregateSet.is() )
+ m_xAggregateSet->getPropertyValue( PROPERTY_TRISTATE ) >>= bTriState;
+ aValue <<= (sal_Int16)( bTriState ? STATE_DONTKNOW : getDefaultChecked() );
+ }
+ else
+ aValue <<= (sal_Int16)( bValue ? STATE_CHECK : STATE_NOCHECK );
+
+ return aValue;
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool OCheckBoxModel::commitControlValueToDbColumn( bool /*_bPostReset*/ )
+{
+ OSL_PRECOND( m_xColumnUpdate.is(), "OCheckBoxModel::commitControlValueToDbColumn: not bound!" );
+ if ( m_xColumnUpdate.is() )
+ {
+ Any aControlValue( m_xAggregateSet->getPropertyValue( PROPERTY_STATE ) );
+ try
+ {
+ sal_Int16 nValue = STATE_DONTKNOW;
+ aControlValue >>= nValue;
+ switch (nValue)
+ {
+ case STATE_DONTKNOW:
+ m_xColumnUpdate->updateNull();
+ break;
+ case STATE_CHECK:
+ m_xColumnUpdate->updateBoolean( sal_True );
+ break;
+ case STATE_NOCHECK:
+ m_xColumnUpdate->updateBoolean( sal_False );
+ break;
+ default:
+ OSL_FAIL("OCheckBoxModel::commitControlValueToDbColumn: invalid value !");
+ }
+ }
+ catch(Exception&)
+ {
+ OSL_FAIL("OCheckBoxModel::commitControlValueToDbColumn: could not commit !");
+ }
+ }
+ return sal_True;
+}
+
+//.........................................................................
+}
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/CheckBox.hxx b/forms/source/component/CheckBox.hxx
new file mode 100644
index 000000000000..f5620b310947
--- /dev/null
+++ b/forms/source/component/CheckBox.hxx
@@ -0,0 +1,93 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FORMS_CHECKBOX_HXX_
+#define _FORMS_CHECKBOX_HXX_
+
+#include "refvaluecomponent.hxx"
+
+//.........................................................................
+namespace frm
+{
+
+//==================================================================
+//= OCheckBoxModel
+//==================================================================
+class OCheckBoxModel :public OReferenceValueComponent
+{
+protected:
+ sal_Int16 getState(const ::com::sun::star::uno::Any& rValue);
+
+public:
+ DECLARE_DEFAULT_LEAF_XTOR( OCheckBoxModel );
+
+ // XServiceInfo
+ IMPLEMENTATION_NAME(OCheckBoxModel);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
+
+ // XPersistObject
+ virtual ::rtl::OUString SAL_CALL getServiceName() throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL
+ write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL
+ read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ // OControlModel's property handling
+ virtual void describeFixedProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps
+ ) const;
+
+protected:
+ DECLARE_XCLONEABLE();
+
+ // OBoundControlModel overridables
+ virtual ::com::sun::star::uno::Any
+ translateDbColumnToControlValue( );
+ virtual sal_Bool commitControlValueToDbColumn( bool _bPostReset );
+};
+
+//==================================================================
+//= OCheckBoxControl
+//==================================================================
+class OCheckBoxControl : public OBoundControl
+{
+public:
+ OCheckBoxControl(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);
+
+ // XServiceInfo
+ IMPLEMENTATION_NAME(OCheckBoxControl);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
+};
+
+//.........................................................................
+}
+//.........................................................................
+
+#endif // _FORMS_CHECKBOX_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/Columns.cxx b/forms/source/component/Columns.cxx
new file mode 100644
index 000000000000..9bc330360e56
--- /dev/null
+++ b/forms/source/component/Columns.cxx
@@ -0,0 +1,600 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+#include "Columns.hxx"
+#include "property.hrc"
+#include "property.hxx"
+#include "componenttools.hxx"
+#include "ids.hxx"
+#include "findpos.hxx"
+#include <com/sun/star/io/XPersistObject.hpp>
+#include <com/sun/star/io/XObjectOutputStream.hpp>
+#include <com/sun/star/io/XObjectInputStream.hpp>
+#include <com/sun/star/io/XMarkableStream.hpp>
+#include <com/sun/star/form/XFormComponent.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/form/binding/XBindableValue.hpp>
+#include <com/sun/star/beans/XPropertyContainer.hpp>
+#include <comphelper/sequence.hxx>
+#include <comphelper/property.hxx>
+#include <comphelper/basicio.hxx>
+#include "services.hxx"
+#include "frm_resource.hrc"
+#include <tools/debug.hxx>
+#include <rtl/uuid.h>
+#include <rtl/memory.h>
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::form;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::form::binding;
+
+const sal_uInt16 WIDTH = 0x0001;
+const sal_uInt16 ALIGN = 0x0002;
+const sal_uInt16 OLD_HIDDEN = 0x0004;
+const sal_uInt16 COMPATIBLE_HIDDEN = 0x0008;
+
+//------------------------------------------------------------------------------
+const StringSequence& getColumnTypes()
+{
+ static StringSequence aColumnTypes(10);
+ if (!aColumnTypes.getConstArray()[0].getLength())
+ {
+ ::rtl::OUString* pNames = aColumnTypes.getArray();
+ pNames[TYPE_CHECKBOX] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CheckBox" ) );
+ pNames[TYPE_COMBOBOX] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ComboBox" ) );
+ pNames[TYPE_CURRENCYFIELD] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CurrencyField" ) );
+ pNames[TYPE_DATEFIELD] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DateField" ) );
+ pNames[TYPE_FORMATTEDFIELD] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FormattedField" ) );
+ pNames[TYPE_LISTBOX] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ListBox" ) );
+ pNames[TYPE_NUMERICFIELD] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NumericField" ) );
+ pNames[TYPE_PATTERNFIELD] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PatternField" ) );
+ pNames[TYPE_TEXTFIELD] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TextField" ) );
+ pNames[TYPE_TIMEFIELD] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TimeField" ) );
+ }
+ return aColumnTypes;
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 getColumnTypeByModelName(const ::rtl::OUString& aModelName)
+{
+ const ::rtl::OUString aModelPrefix (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.form.component.") );
+ const ::rtl::OUString aCompatibleModelPrefix (RTL_CONSTASCII_USTRINGPARAM("stardiv.one.form.component.") );
+
+ sal_Int32 nTypeId = -1;
+ if (aModelName == FRM_COMPONENT_EDIT)
+ nTypeId = TYPE_TEXTFIELD;
+ else
+ {
+ sal_Int32 nPrefixPos = aModelName.indexOf(aModelPrefix);
+#ifdef DBG_UTIL
+ sal_Int32 nCompatiblePrefixPos = aModelName.indexOf(aCompatibleModelPrefix);
+#endif
+ DBG_ASSERT( (nPrefixPos != -1) || (nCompatiblePrefixPos != -1),
+ "::getColumnTypeByModelName() : wrong servivce !");
+
+ ::rtl::OUString aColumnType = (nPrefixPos != -1)
+ ? aModelName.copy(aModelPrefix.getLength())
+ : aModelName.copy(aCompatibleModelPrefix.getLength());
+
+ const StringSequence& rColumnTypes = getColumnTypes();
+ nTypeId = ::detail::findPos(aColumnType, rColumnTypes);
+ }
+ return nTypeId;
+}
+
+/*************************************************************************/
+
+//------------------------------------------------------------------
+const Sequence<sal_Int8>& OGridColumn::getUnoTunnelImplementationId()
+{
+ static Sequence< sal_Int8 > * pSeq = 0;
+ if( !pSeq )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+//------------------------------------------------------------------
+sal_Int64 SAL_CALL OGridColumn::getSomething( const Sequence<sal_Int8>& _rIdentifier) throw(RuntimeException)
+{
+ sal_Int64 nReturn(0);
+
+ if ( (_rIdentifier.getLength() == 16)
+ && (0 == rtl_compareMemory( getUnoTunnelImplementationId().getConstArray(), _rIdentifier.getConstArray(), 16 ))
+ )
+ {
+ nReturn = reinterpret_cast<sal_Int64>(this);
+ }
+ else
+ {
+ Reference< XUnoTunnel > xAggTunnel;
+ if ( query_aggregation( m_xAggregate, xAggTunnel ) )
+ return xAggTunnel->getSomething( _rIdentifier );
+ }
+ return nReturn;
+}
+
+//------------------------------------------------------------------
+Sequence<sal_Int8> SAL_CALL OGridColumn::getImplementationId() throw(RuntimeException)
+{
+ return OImplementationIds::getImplementationId(getTypes());
+}
+
+//------------------------------------------------------------------
+Sequence<Type> SAL_CALL OGridColumn::getTypes() throw(RuntimeException)
+{
+ TypeBag aTypes( OGridColumn_BASE::getTypes() );
+ // erase the types which we do not support
+ aTypes.removeType( XFormComponent::static_type() );
+ aTypes.removeType( XServiceInfo::static_type() );
+ aTypes.removeType( XBindableValue::static_type() );
+ aTypes.removeType( XPropertyContainer::static_type() );
+ // but re-add their base class(es)
+ aTypes.addType( XChild::static_type() );
+
+ Reference< XTypeProvider > xProv;
+ if ( query_aggregation( m_xAggregate, xProv ))
+ aTypes.addTypes( xProv->getTypes() );
+
+ return aTypes.getTypes();
+}
+
+//------------------------------------------------------------------
+Any SAL_CALL OGridColumn::queryAggregation( const Type& _rType ) throw (RuntimeException)
+{
+ Any aReturn;
+ // some functionality at our aggregate cannot be reasonably fullfilled here.
+ if ( _rType.equals(::getCppuType(static_cast< Reference< XFormComponent >* >(NULL)))
+ || _rType.equals(::getCppuType(static_cast< Reference< XServiceInfo >* >(NULL)))
+ || _rType.equals(::getCppuType(static_cast< Reference< XBindableValue >* >(NULL)))
+ || _rType.equals(::getCppuType(static_cast< Reference< XPropertyContainer >* >(NULL)))
+ )
+ return aReturn;
+
+ aReturn = OGridColumn_BASE::queryAggregation(_rType);
+ if (!aReturn.hasValue())
+ {
+ aReturn = OPropertySetAggregationHelper::queryInterface(_rType);
+ if (!aReturn.hasValue() && m_xAggregate.is())
+ aReturn = m_xAggregate->queryAggregation(_rType);
+ }
+
+ return aReturn;
+}
+
+DBG_NAME(OGridColumn);
+//------------------------------------------------------------------------------
+OGridColumn::OGridColumn( const comphelper::ComponentContext& _rContext, const ::rtl::OUString& _sModelName )
+ :OGridColumn_BASE(m_aMutex)
+ ,OPropertySetAggregationHelper(OGridColumn_BASE::rBHelper)
+ ,m_aHidden( makeAny( sal_False ) )
+ ,m_aContext( _rContext )
+ ,m_aModelName(_sModelName)
+{
+ DBG_CTOR(OGridColumn,NULL);
+
+ // Anlegen des UnoControlModels
+ if ( m_aModelName.getLength() ) // is there a to-be-aggregated model?
+ {
+ increment( m_refCount );
+
+ {
+ m_xAggregate.set( m_aContext.createComponent( m_aModelName ), UNO_QUERY );
+ setAggregation( m_xAggregate );
+ }
+
+ if ( m_xAggregate.is() )
+ { // don't omit those brackets - they ensure that the following temporary is properly deleted
+ m_xAggregate->setDelegator( static_cast< ::cppu::OWeakObject* >( this ) );
+ }
+
+ // Refcount wieder bei NULL
+ decrement( m_refCount );
+ }
+}
+
+//------------------------------------------------------------------------------
+OGridColumn::OGridColumn( const OGridColumn* _pOriginal )
+ :OGridColumn_BASE( m_aMutex )
+ ,OPropertySetAggregationHelper( OGridColumn_BASE::rBHelper )
+ ,m_aContext( _pOriginal->m_aContext )
+{
+ DBG_CTOR(OGridColumn,NULL);
+
+ m_aWidth = _pOriginal->m_aWidth;
+ m_aAlign = _pOriginal->m_aAlign;
+ m_aHidden = _pOriginal->m_aHidden;
+ m_aModelName = _pOriginal->m_aModelName;
+ m_aLabel = _pOriginal->m_aLabel;
+
+ increment( m_refCount );
+ {
+ {
+ m_xAggregate = createAggregateClone( _pOriginal );
+ setAggregation( m_xAggregate );
+ }
+
+ if ( m_xAggregate.is() )
+ { // don't omit this brackets - they ensure that the following temporary is properly deleted
+ m_xAggregate->setDelegator( static_cast< ::cppu::OWeakObject* >( this ) );
+ }
+ }
+ decrement( m_refCount );
+}
+
+//------------------------------------------------------------------------------
+OGridColumn::~OGridColumn()
+{
+ if (!OGridColumn_BASE::rBHelper.bDisposed)
+ {
+ acquire();
+ dispose();
+ }
+
+ // freigeben der Agg
+ if (m_xAggregate.is())
+ {
+ InterfaceRef xIface;
+ m_xAggregate->setDelegator(xIface);
+ }
+
+ DBG_DTOR(OGridColumn,NULL);
+}
+
+// XEventListener
+//------------------------------------------------------------------------------
+void SAL_CALL OGridColumn::disposing(const EventObject& _rSource) throw(RuntimeException)
+{
+ OPropertySetAggregationHelper::disposing(_rSource);
+
+ Reference<XEventListener> xEvtLstner;
+ if (query_aggregation(m_xAggregate, xEvtLstner))
+ xEvtLstner->disposing(_rSource);
+}
+
+// OGridColumn_BASE
+//-----------------------------------------------------------------------------
+void OGridColumn::disposing()
+{
+ OGridColumn_BASE::disposing();
+ OPropertySetAggregationHelper::disposing();
+
+ Reference<XComponent> xComp;
+ if (query_aggregation(m_xAggregate, xComp))
+ xComp->dispose();
+}
+
+//------------------------------------------------------------------------------
+void OGridColumn::clearAggregateProperties( Sequence< Property >& _rProps, sal_Bool bAllowDropDown )
+{
+ // some properties are not to be exposed to the outer world
+ ::std::set< ::rtl::OUString > aForbiddenProperties;
+ aForbiddenProperties.insert( PROPERTY_ALIGN );
+ aForbiddenProperties.insert( PROPERTY_AUTOCOMPLETE );
+ aForbiddenProperties.insert( PROPERTY_BACKGROUNDCOLOR );
+ aForbiddenProperties.insert( PROPERTY_BORDER );
+ aForbiddenProperties.insert( PROPERTY_BORDERCOLOR );
+ aForbiddenProperties.insert( PROPERTY_ECHO_CHAR );
+ aForbiddenProperties.insert( PROPERTY_FILLCOLOR );
+ aForbiddenProperties.insert( PROPERTY_FONT );
+ aForbiddenProperties.insert( PROPERTY_FONT_NAME );
+ aForbiddenProperties.insert( PROPERTY_FONT_STYLENAME );
+ aForbiddenProperties.insert( PROPERTY_FONT_FAMILY );
+ aForbiddenProperties.insert( PROPERTY_FONT_CHARSET );
+ aForbiddenProperties.insert( PROPERTY_FONT_HEIGHT );
+ aForbiddenProperties.insert( PROPERTY_FONT_WEIGHT );
+ aForbiddenProperties.insert( PROPERTY_FONT_SLANT );
+ aForbiddenProperties.insert( PROPERTY_FONT_UNDERLINE );
+ aForbiddenProperties.insert( PROPERTY_FONT_STRIKEOUT );
+ aForbiddenProperties.insert( PROPERTY_FONT_WORDLINEMODE );
+ aForbiddenProperties.insert( PROPERTY_TEXTLINECOLOR );
+ aForbiddenProperties.insert( PROPERTY_FONTEMPHASISMARK );
+ aForbiddenProperties.insert( PROPERTY_FONTRELIEF );
+ aForbiddenProperties.insert( PROPERTY_HARDLINEBREAKS );
+ aForbiddenProperties.insert( PROPERTY_HSCROLL );
+ aForbiddenProperties.insert( PROPERTY_LABEL );
+ aForbiddenProperties.insert( PROPERTY_LINECOLOR );
+ aForbiddenProperties.insert( PROPERTY_MULTISELECTION );
+ aForbiddenProperties.insert( PROPERTY_PRINTABLE );
+ aForbiddenProperties.insert( PROPERTY_TABINDEX );
+ aForbiddenProperties.insert( PROPERTY_TABSTOP );
+ aForbiddenProperties.insert( PROPERTY_TEXTCOLOR );
+ aForbiddenProperties.insert( PROPERTY_VSCROLL );
+ aForbiddenProperties.insert( PROPERTY_CONTROLLABEL );
+ aForbiddenProperties.insert( PROPERTY_RICH_TEXT );
+ aForbiddenProperties.insert( PROPERTY_VERTICAL_ALIGN );
+ aForbiddenProperties.insert( PROPERTY_IMAGE_URL );
+ aForbiddenProperties.insert( PROPERTY_IMAGE_POSITION );
+ aForbiddenProperties.insert( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EnableVisible" ) ) );
+ if ( !bAllowDropDown )
+ aForbiddenProperties.insert( PROPERTY_DROPDOWN );
+
+ Sequence< Property > aNewProps( _rProps.getLength() );
+ Property* pNewProps = aNewProps.getArray();
+
+ const Property* pProps = _rProps.getConstArray();
+ const Property* pPropsEnd = pProps + _rProps.getLength();
+ for ( ; pProps != pPropsEnd; ++pProps )
+ {
+ if ( aForbiddenProperties.find( pProps->Name ) == aForbiddenProperties.end() )
+ *pNewProps++ = *pProps;
+ }
+
+ aNewProps.realloc( pNewProps - aNewProps.getArray() );
+ _rProps = aNewProps;
+}
+
+//------------------------------------------------------------------------------
+void OGridColumn::setOwnProperties(Sequence<Property>& aDescriptor)
+{
+ aDescriptor.realloc(5);
+ Property* pProperties = aDescriptor.getArray();
+ DECL_PROP1(LABEL, ::rtl::OUString, BOUND);
+ DECL_PROP3(WIDTH, sal_Int32, BOUND, MAYBEVOID, MAYBEDEFAULT);
+ DECL_PROP3(ALIGN, sal_Int16, BOUND, MAYBEVOID, MAYBEDEFAULT);
+ DECL_BOOL_PROP2(HIDDEN, BOUND, MAYBEDEFAULT);
+ DECL_PROP1(COLUMNSERVICENAME, ::rtl::OUString, READONLY);
+}
+
+// Reference<XPropertySet>
+//------------------------------------------------------------------------------
+void OGridColumn::getFastPropertyValue(Any& rValue, sal_Int32 nHandle ) const
+{
+ switch (nHandle)
+ {
+ case PROPERTY_ID_COLUMNSERVICENAME:
+ rValue <<= m_aModelName;
+ break;
+ case PROPERTY_ID_LABEL:
+ rValue <<= m_aLabel;
+ break;
+ case PROPERTY_ID_WIDTH:
+ rValue = m_aWidth;
+ break;
+ case PROPERTY_ID_ALIGN:
+ rValue = m_aAlign;
+ break;
+ case PROPERTY_ID_HIDDEN:
+ rValue = m_aHidden;
+ break;
+ default:
+ OPropertySetAggregationHelper::getFastPropertyValue(rValue, nHandle);
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OGridColumn::convertFastPropertyValue( Any& rConvertedValue, Any& rOldValue,
+ sal_Int32 nHandle, const Any& rValue )throw( IllegalArgumentException )
+{
+ sal_Bool bModified(sal_False);
+ switch (nHandle)
+ {
+ case PROPERTY_ID_LABEL:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aLabel);
+ break;
+ case PROPERTY_ID_WIDTH:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aWidth, ::getCppuType((const sal_Int32*)NULL));
+ break;
+ case PROPERTY_ID_ALIGN:
+ bModified = tryPropertyValue( rConvertedValue, rOldValue, rValue, m_aAlign, ::getCppuType( (const sal_Int32*)NULL ) );
+ // strange enough, css.awt.TextAlign is a 32-bit integer, while the Align property (both here for grid controls
+ // and for ordinary toolkit controls) is a 16-bit integer. So, allow for 32 bit, but normalize it to 16 bit
+ if ( bModified )
+ {
+ sal_Int32 nAlign( 0 );
+ if ( rConvertedValue >>= nAlign )
+ rConvertedValue <<= (sal_Int16)nAlign;
+ }
+ break;
+ case PROPERTY_ID_HIDDEN:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, getBOOL(m_aHidden));
+ break;
+ }
+ return bModified;
+}
+
+//------------------------------------------------------------------------------
+void OGridColumn::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw (::com::sun::star::uno::Exception)
+{
+ switch (nHandle)
+ {
+ case PROPERTY_ID_LABEL:
+ DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_STRING, "invalid type" );
+ rValue >>= m_aLabel;
+ break;
+ case PROPERTY_ID_WIDTH:
+ m_aWidth = rValue;
+ break;
+ case PROPERTY_ID_ALIGN:
+ m_aAlign = rValue;
+ break;
+ case PROPERTY_ID_HIDDEN:
+ m_aHidden = rValue;
+ break;
+ }
+}
+
+
+// XPropertyState
+//------------------------------------------------------------------------------
+Any OGridColumn::getPropertyDefaultByHandle( sal_Int32 nHandle ) const
+{
+ switch (nHandle)
+ {
+ case PROPERTY_ID_WIDTH:
+ case PROPERTY_ID_ALIGN:
+ return Any();
+ case PROPERTY_ID_HIDDEN:
+ return makeAny((sal_Bool)sal_False);
+ default:
+ return OPropertySetAggregationHelper::getPropertyDefaultByHandle(nHandle);
+ }
+}
+
+// XCloneable
+//------------------------------------------------------------------------------
+Reference< XCloneable > SAL_CALL OGridColumn::createClone( ) throw (RuntimeException)
+{
+ OGridColumn* pNewColumn = createCloneColumn();
+ return pNewColumn;
+}
+
+//XPersistObject
+//------------------------------------------------------------------------------
+void SAL_CALL OGridColumn::write(const Reference<XObjectOutputStream>& _rxOutStream)
+{
+ // 1. Schreiben des UnoControls
+ Reference<XMarkableStream> xMark(_rxOutStream, UNO_QUERY);
+ sal_Int32 nMark = xMark->createMark();
+
+ sal_Int32 nLen = 0;
+ _rxOutStream->writeLong(nLen);
+
+ Reference<XPersistObject> xPersist;
+ 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(0x0002);
+
+ sal_uInt16 nAnyMask = 0;
+ if (m_aWidth.getValueType().getTypeClass() == TypeClass_LONG)
+ nAnyMask |= WIDTH;
+
+ if (m_aAlign.getValueTypeClass() == TypeClass_SHORT)
+ nAnyMask |= ALIGN;
+
+ nAnyMask |= COMPATIBLE_HIDDEN;
+
+ _rxOutStream->writeShort(nAnyMask);
+
+ if (nAnyMask & WIDTH)
+ _rxOutStream->writeLong(getINT32(m_aWidth));
+ if (nAnyMask & ALIGN)
+ _rxOutStream->writeShort(getINT16(m_aAlign));
+
+ // Name
+ _rxOutStream << m_aLabel;
+
+ // the new place for the hidden flag : after m_aLabel, so older office version read the correct label, too
+ if (nAnyMask & COMPATIBLE_HIDDEN)
+ _rxOutStream->writeBoolean(getBOOL(m_aHidden));
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OGridColumn::read(const Reference<XObjectInputStream>& _rxInStream)
+{
+ // 1. Lesen des UnoControls
+ sal_Int32 nLen = _rxInStream->readLong();
+ if (nLen)
+ {
+ Reference<XMarkableStream> xMark(_rxInStream, UNO_QUERY);
+ sal_Int32 nMark = xMark->createMark();
+ Reference<XPersistObject> xPersist;
+ if (query_aggregation(m_xAggregate, xPersist))
+ xPersist->read(_rxInStream);
+
+ xMark->jumpToMark(nMark);
+ _rxInStream->skipBytes(nLen);
+ xMark->deleteMark(nMark);
+ }
+
+ // 2. Lesen des Versionsnummer
+ sal_uInt16 nVersion = _rxInStream->readShort(); (void)nVersion;
+ sal_uInt16 nAnyMask = _rxInStream->readShort();
+
+ if (nAnyMask & WIDTH)
+ {
+ sal_Int32 nValue = _rxInStream->readLong();
+ m_aWidth <<= (sal_Int32)nValue;
+ }
+
+ if (nAnyMask & ALIGN)
+ {
+ sal_Int16 nValue = _rxInStream->readShort();
+ m_aAlign <<= nValue;
+ }
+ if (nAnyMask & OLD_HIDDEN)
+ {
+ sal_Bool bValue = _rxInStream->readBoolean();
+ m_aHidden <<= (sal_Bool)bValue;
+ }
+
+ // Name
+ _rxInStream >> m_aLabel;
+
+ if (nAnyMask & COMPATIBLE_HIDDEN)
+ {
+ sal_Bool bValue = _rxInStream->readBoolean();
+ m_aHidden <<= (sal_Bool)bValue;
+ }
+}
+
+//------------------------------------------------------------------------------
+IMPL_COLUMN(TextFieldColumn, FRM_SUN_COMPONENT_TEXTFIELD, sal_False);
+IMPL_COLUMN(PatternFieldColumn, FRM_SUN_COMPONENT_PATTERNFIELD, sal_False);
+IMPL_COLUMN(DateFieldColumn, FRM_SUN_COMPONENT_DATEFIELD, sal_True);
+IMPL_COLUMN(TimeFieldColumn, FRM_SUN_COMPONENT_TIMEFIELD, sal_False);
+IMPL_COLUMN(NumericFieldColumn, FRM_SUN_COMPONENT_NUMERICFIELD, sal_False);
+IMPL_COLUMN(CurrencyFieldColumn, FRM_SUN_COMPONENT_CURRENCYFIELD, sal_False);
+IMPL_COLUMN(CheckBoxColumn, FRM_SUN_COMPONENT_CHECKBOX, sal_False);
+IMPL_COLUMN(ComboBoxColumn, FRM_SUN_COMPONENT_COMBOBOX, sal_False);
+IMPL_COLUMN(ListBoxColumn, FRM_SUN_COMPONENT_LISTBOX, sal_False);
+IMPL_COLUMN(FormattedFieldColumn, FRM_SUN_COMPONENT_FORMATTEDFIELD, sal_False);
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/Columns.hxx b/forms/source/component/Columns.hxx
new file mode 100644
index 000000000000..4068a7b88590
--- /dev/null
+++ b/forms/source/component/Columns.hxx
@@ -0,0 +1,223 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FRM_COLUMNS_HXX
+#define _FRM_COLUMNS_HXX
+
+#include "cloneable.hxx"
+#include "frm_strings.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/io/XObjectInputStream.hpp>
+#include <com/sun/star/io/XObjectOutputStream.hpp>
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+#include <com/sun/star/util/XCloneable.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/broadcasthelper.hxx>
+#include <comphelper/componentcontext.hxx>
+#include <comphelper/propagg.hxx>
+#include <comphelper/proparrhlp.hxx>
+#include <comphelper/uno3.hxx>
+#include <cppuhelper/compbase2.hxx>
+#include <cppuhelper/component.hxx>
+
+using namespace comphelper;
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+//==================================================================
+// OGridColumn
+//==================================================================
+typedef ::cppu::WeakAggComponentImplHelper2 < ::com::sun::star::lang::XUnoTunnel
+ , ::com::sun::star::util::XCloneable > OGridColumn_BASE;
+class OGridColumn :public ::comphelper::OBaseMutex
+ ,public OGridColumn_BASE
+ ,public OPropertySetAggregationHelper
+ ,public OCloneableAggregation
+{
+protected:
+// [properties]
+ ::com::sun::star::uno::Any m_aWidth; // column width
+ ::com::sun::star::uno::Any m_aAlign; // column alignment
+ ::com::sun::star::uno::Any m_aHidden; // column hidden?
+// [properties]
+
+ ::comphelper::ComponentContext m_aContext;
+ ::rtl::OUString m_aModelName;
+
+// [properties]
+ ::rtl::OUString m_aLabel; // Name der Spalte
+// [properties]
+
+public:
+ OGridColumn(const ::comphelper::ComponentContext& _rContext, const ::rtl::OUString& _sModelName = ::rtl::OUString());
+ OGridColumn(const OGridColumn* _pOriginal );
+ virtual ~OGridColumn();
+
+ // UNO Anbindung
+ DECLARE_UNO3_AGG_DEFAULTS(OGridControlModel, OGridColumn_BASE);
+ virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException);
+
+ static const ::com::sun::star::uno::Sequence<sal_Int8>& getUnoTunnelImplementationId();
+ // XUnoTunnel
+ virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence<sal_Int8>& _rIdentifier) throw(::com::sun::star::uno::RuntimeException);
+
+ // XTypeProvider
+ virtual ::com::sun::star::uno::Sequence<sal_Int8> SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> SAL_CALL getTypes() throw(::com::sun::star::uno::RuntimeException);
+
+ // OComponentHelper
+ virtual void SAL_CALL disposing();
+
+ // XEventListener
+ virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& _rSource) throw(::com::sun::star::uno::RuntimeException);
+
+ // XPersistObject
+ virtual void SAL_CALL write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream);
+ virtual void SAL_CALL read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream);
+
+ // XPropertySet
+ virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() = 0;
+ virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle ) const;
+ virtual sal_Bool SAL_CALL convertFastPropertyValue(::com::sun::star::uno::Any& rConvertedValue, ::com::sun::star::uno::Any& rOldValue,
+ sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
+ throw(::com::sun::star::lang::IllegalArgumentException);
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue) throw (::com::sun::star::uno::Exception);
+
+ using OPropertySetAggregationHelper::getFastPropertyValue;
+
+ // ::com::sun::star::beans::XPropertyState
+ virtual ::com::sun::star::uno::Any getPropertyDefaultByHandle( sal_Int32 nHandle ) const;
+
+ // XCloneable
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL createClone( ) throw (::com::sun::star::uno::RuntimeException);
+
+ const ::rtl::OUString& getModelName() const { return m_aModelName; }
+
+protected:
+ static void clearAggregateProperties(::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property>& seqProps, sal_Bool bAllowDropDown);
+ static void setOwnProperties(::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property>& seqProps);
+
+ virtual OGridColumn* createCloneColumn() const = 0;
+};
+
+#define DECL_COLUMN(ClassName) \
+class ClassName \
+ :public OGridColumn \
+ ,public OAggregationArrayUsageHelper< ClassName > \
+{ \
+public: \
+ ClassName(const ::comphelper::ComponentContext& _rContext ); \
+ ClassName(const ClassName* _pCloneFrom); \
+ \
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() throw(::com::sun::star::uno::RuntimeException); \
+ virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper(); \
+ \
+ virtual void fillProperties( \
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps, \
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rAggregateProps \
+ ) const; \
+ \
+ virtual OGridColumn* createCloneColumn() const; \
+};
+
+
+#define IMPL_COLUMN(ClassName, Model, bAllowDropDown) \
+ ClassName::ClassName( const ::comphelper::ComponentContext& _rContext ) \
+ :OGridColumn(_rContext, Model) \
+{ \
+} \
+ClassName::ClassName( const ClassName* _pCloneFrom ) \
+ :OGridColumn( _pCloneFrom ) \
+{ \
+} \
+::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo> ClassName::getPropertySetInfo() throw(::com::sun::star::uno::RuntimeException) \
+{ \
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo> xInfo( createPropertySetInfo( getInfoHelper() ) ); \
+ return xInfo; \
+} \
+::cppu::IPropertyArrayHelper& ClassName::getInfoHelper() \
+{ \
+ return *const_cast<ClassName*>(this)->getArrayHelper(); \
+} \
+void ClassName::fillProperties( \
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps, \
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rAggregateProps \
+ ) const \
+{ \
+ if (m_xAggregateSet.is()) \
+ { \
+ _rAggregateProps = m_xAggregateSet->getPropertySetInfo()->getProperties(); \
+ clearAggregateProperties(_rAggregateProps, bAllowDropDown); \
+ setOwnProperties(_rProps); \
+ } \
+} \
+OGridColumn* ClassName::createCloneColumn() const \
+{ \
+ return new ClassName( this ); \
+} \
+ \
+// column type ids
+#define TYPE_CHECKBOX 0
+#define TYPE_COMBOBOX 1
+#define TYPE_CURRENCYFIELD 2
+#define TYPE_DATEFIELD 3
+#define TYPE_FORMATTEDFIELD 4
+#define TYPE_LISTBOX 5
+#define TYPE_NUMERICFIELD 6
+#define TYPE_PATTERNFIELD 7
+#define TYPE_TEXTFIELD 8
+#define TYPE_TIMEFIELD 9
+
+// liste aller bekannten columns
+const StringSequence& getColumnTypes();
+sal_Int32 getColumnTypeByModelName(const ::rtl::OUString& aModelName);
+
+// Columns
+DECL_COLUMN(TextFieldColumn)
+DECL_COLUMN(PatternFieldColumn)
+DECL_COLUMN(DateFieldColumn)
+DECL_COLUMN(TimeFieldColumn)
+DECL_COLUMN(NumericFieldColumn)
+DECL_COLUMN(CurrencyFieldColumn)
+DECL_COLUMN(CheckBoxColumn)
+DECL_COLUMN(ComboBoxColumn)
+DECL_COLUMN(ListBoxColumn)
+DECL_COLUMN(FormattedFieldColumn)
+
+#endif // _FRM_COLUMNS_HXX
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/ComboBox.cxx b/forms/source/component/ComboBox.cxx
new file mode 100644
index 000000000000..9b893f5d708a
--- /dev/null
+++ b/forms/source/component/ComboBox.cxx
@@ -0,0 +1,916 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+
+#include "ComboBox.hxx"
+#include "property.hxx"
+#include "property.hrc"
+#include "services.hxx"
+
+#include "frm_resource.hxx"
+#include "frm_resource.hrc"
+#include "BaseListBox.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/sdb/SQLErrorEvent.hpp>
+#include <com/sun/star/sdbc/XRowSet.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/sdb/XSQLQueryComposerFactory.hpp>
+#include <com/sun/star/sdb/XQueriesSupplier.hpp>
+#include <com/sun/star/util/NumberFormat.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/sdb/SQLContext.hpp>
+#include <com/sun/star/sdb/CommandType.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/numbers.hxx>
+#include <comphelper/basicio.hxx>
+#include <connectivity/dbtools.hxx>
+#include <connectivity/dbconversion.hxx>
+#include <cppuhelper/queryinterface.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <unotools/sharedunocomponent.hxx>
+
+#include <limits.h>
+
+using namespace dbtools;
+
+//.........................................................................
+namespace frm
+{
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::form;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::form::binding;
+
+//========================================================================
+// class OComboBoxModel
+//========================================================================
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL OComboBoxModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory) throw (RuntimeException)
+{
+ return (*new OComboBoxModel(_rxFactory));
+}
+
+//------------------------------------------------------------------------------
+Sequence<Type> OComboBoxModel::_getTypes()
+{
+ return ::comphelper::concatSequences(
+ OBoundControlModel::_getTypes(),
+ OEntryListHelper::getTypes(),
+ OErrorBroadcaster::getTypes()
+ );
+}
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+StringSequence SAL_CALL OComboBoxModel::getSupportedServiceNames() throw(RuntimeException)
+{
+ StringSequence aSupported = OBoundControlModel::getSupportedServiceNames();
+
+ sal_Int32 nOldLen = aSupported.getLength();
+ aSupported.realloc( nOldLen + 8 );
+ ::rtl::OUString* pStoreTo = aSupported.getArray() + nOldLen;
+
+ *pStoreTo++ = BINDABLE_CONTROL_MODEL;
+ *pStoreTo++ = DATA_AWARE_CONTROL_MODEL;
+ *pStoreTo++ = VALIDATABLE_CONTROL_MODEL;
+
+ *pStoreTo++ = BINDABLE_DATA_AWARE_CONTROL_MODEL;
+ *pStoreTo++ = VALIDATABLE_BINDABLE_CONTROL_MODEL;
+
+ *pStoreTo++ = FRM_SUN_COMPONENT_COMBOBOX;
+ *pStoreTo++ = FRM_SUN_COMPONENT_DATABASE_COMBOBOX;
+ *pStoreTo++ = BINDABLE_DATABASE_COMBO_BOX;
+
+ return aSupported;
+}
+
+//------------------------------------------------------------------------------
+Any SAL_CALL OComboBoxModel::queryAggregation(const Type& _rType) throw (RuntimeException)
+{
+ Any aReturn = OBoundControlModel::queryAggregation( _rType );
+ if ( !aReturn.hasValue() )
+ aReturn = OEntryListHelper::queryInterface( _rType );
+ if ( !aReturn.hasValue() )
+ aReturn = OErrorBroadcaster::queryInterface( _rType );
+ return aReturn;
+}
+
+//------------------------------------------------------------------
+DBG_NAME( OComboBoxModel )
+//------------------------------------------------------------------
+OComboBoxModel::OComboBoxModel(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OBoundControlModel( _rxFactory, VCL_CONTROLMODEL_COMBOBOX, FRM_SUN_CONTROL_COMBOBOX, sal_True, sal_True, sal_True )
+ // use the old control name for compytibility reasons
+ ,OEntryListHelper( (OControlModel&)*this )
+ ,OErrorBroadcaster( OComponentHelper::rBHelper )
+ ,m_aListRowSet( getContext() )
+ ,m_eListSourceType(ListSourceType_TABLE)
+ ,m_bEmptyIsNull(sal_True)
+{
+ DBG_CTOR( OComboBoxModel, NULL );
+
+ m_nClassId = FormComponentType::COMBOBOX;
+ initValueProperty( PROPERTY_TEXT, PROPERTY_ID_TEXT );
+}
+
+//------------------------------------------------------------------
+OComboBoxModel::OComboBoxModel( const OComboBoxModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
+ :OBoundControlModel( _pOriginal, _rxFactory )
+ ,OEntryListHelper( *_pOriginal, (OControlModel&)*this )
+ ,OErrorBroadcaster( OComponentHelper::rBHelper )
+ ,m_aListRowSet( getContext() )
+ ,m_aListSource( _pOriginal->m_aListSource )
+ ,m_aDefaultText( _pOriginal->m_aDefaultText )
+ ,m_eListSourceType( _pOriginal->m_eListSourceType )
+ ,m_bEmptyIsNull( _pOriginal->m_bEmptyIsNull )
+{
+ DBG_CTOR( OComboBoxModel, NULL );
+}
+
+//------------------------------------------------------------------
+OComboBoxModel::~OComboBoxModel()
+{
+ if (!OComponentHelper::rBHelper.bDisposed)
+ {
+ acquire();
+ dispose();
+ }
+
+ DBG_DTOR( OComboBoxModel, NULL );
+}
+
+// XCloneable
+//------------------------------------------------------------------------------
+IMPLEMENT_DEFAULT_CLONING( OComboBoxModel )
+
+//------------------------------------------------------------------------------
+void OComboBoxModel::disposing()
+{
+ OBoundControlModel::disposing();
+ OEntryListHelper::disposing();
+ OErrorBroadcaster::disposing();
+ m_xFormatter = NULL;
+}
+
+//------------------------------------------------------------------------------
+void OComboBoxModel::getFastPropertyValue(Any& _rValue, sal_Int32 _nHandle) const
+{
+ switch (_nHandle)
+ {
+ case PROPERTY_ID_LISTSOURCETYPE:
+ _rValue <<= m_eListSourceType;
+ break;
+
+ case PROPERTY_ID_LISTSOURCE:
+ _rValue <<= m_aListSource;
+ break;
+
+ case PROPERTY_ID_EMPTY_IS_NULL:
+ _rValue <<= m_bEmptyIsNull;
+ break;
+
+ case PROPERTY_ID_DEFAULT_TEXT:
+ _rValue <<= m_aDefaultText;
+ break;
+
+ case PROPERTY_ID_STRINGITEMLIST:
+ _rValue <<= getStringItemList();
+ break;
+
+ default:
+ OBoundControlModel::getFastPropertyValue(_rValue, _nHandle);
+ }
+}
+
+//------------------------------------------------------------------------------
+void OComboBoxModel::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle, const Any& _rValue)
+ throw (Exception)
+{
+ switch (_nHandle)
+ {
+ case PROPERTY_ID_LISTSOURCETYPE :
+ DBG_ASSERT(_rValue.getValueType().equals(::getCppuType(reinterpret_cast<ListSourceType*>(NULL))),
+ "OComboBoxModel::setFastPropertyValue_NoBroadcast : invalid type !" );
+ _rValue >>= m_eListSourceType;
+ break;
+
+ case PROPERTY_ID_LISTSOURCE :
+ DBG_ASSERT(_rValue.getValueType().getTypeClass() == TypeClass_STRING,
+ "OComboBoxModel::setFastPropertyValue_NoBroadcast : invalid type !" );
+ _rValue >>= m_aListSource;
+ // die ListSource hat sich geaendert -> neu laden
+ if (ListSourceType_VALUELIST != m_eListSourceType)
+ {
+ if ( m_xCursor.is() && !hasField() && !hasExternalListSource() )
+ // combo box is already connected to a database, and no external list source
+ // data source changed -> refresh
+ loadData( false );
+ }
+ break;
+
+ case PROPERTY_ID_EMPTY_IS_NULL :
+ DBG_ASSERT(_rValue.getValueType().getTypeClass() == TypeClass_BOOLEAN,
+ "OComboBoxModel::setFastPropertyValue_NoBroadcast : invalid type !" );
+ _rValue >>= m_bEmptyIsNull;
+ break;
+
+ case PROPERTY_ID_DEFAULT_TEXT :
+ DBG_ASSERT(_rValue.getValueType().getTypeClass() == TypeClass_STRING,
+ "OComboBoxModel::setFastPropertyValue_NoBroadcast : invalid type !" );
+ _rValue >>= m_aDefaultText;
+ resetNoBroadcast();
+ break;
+
+ case PROPERTY_ID_STRINGITEMLIST:
+ {
+ ControlModelLock aLock( *this );
+ setNewStringItemList( _rValue, aLock );
+ // TODO: this is bogus. setNewStringItemList expects a guard which has the *only*
+ // lock to the mutex, but setFastPropertyValue_NoBroadcast is already called with
+ // a lock - so we effectively has two locks here, of which setNewStringItemList can
+ // only control one.
+ }
+ break;
+
+ default:
+ OBoundControlModel::setFastPropertyValue_NoBroadcast(_nHandle, _rValue);
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OComboBoxModel::convertFastPropertyValue(
+ Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue)
+ throw (IllegalArgumentException)
+{
+ sal_Bool bModified(sal_False);
+ switch (_nHandle)
+ {
+ case PROPERTY_ID_LISTSOURCETYPE :
+ bModified = tryPropertyValueEnum(_rConvertedValue, _rOldValue, _rValue, m_eListSourceType);
+ break;
+
+ case PROPERTY_ID_LISTSOURCE :
+ bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_aListSource);
+ break;
+
+ case PROPERTY_ID_EMPTY_IS_NULL :
+ bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_bEmptyIsNull);
+ break;
+
+ case PROPERTY_ID_DEFAULT_TEXT :
+ bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_aDefaultText);
+ break;
+
+ case PROPERTY_ID_STRINGITEMLIST:
+ bModified = convertNewListSourceProperty( _rConvertedValue, _rOldValue, _rValue );
+ break;
+
+ default:
+ bModified = OBoundControlModel::convertFastPropertyValue(_rConvertedValue, _rOldValue, _nHandle, _rValue);
+ break;
+ }
+ return bModified;
+}
+
+//------------------------------------------------------------------------------
+void OComboBoxModel::describeFixedProperties( Sequence< Property >& _rProps ) const
+{
+ BEGIN_DESCRIBE_PROPERTIES( 6, OBoundControlModel )
+ DECL_PROP1(TABINDEX, sal_Int16, BOUND);
+ DECL_PROP1(LISTSOURCETYPE, ListSourceType, BOUND);
+ DECL_PROP1(LISTSOURCE, ::rtl::OUString, BOUND);
+ DECL_BOOL_PROP1(EMPTY_IS_NULL, BOUND);
+ DECL_PROP1(DEFAULT_TEXT, ::rtl::OUString, BOUND);
+ DECL_PROP1(STRINGITEMLIST, Sequence< ::rtl::OUString >,BOUND);
+ END_DESCRIBE_PROPERTIES();
+}
+
+//------------------------------------------------------------------------------
+void OComboBoxModel::describeAggregateProperties( Sequence< Property >& _rAggregateProps ) const
+{
+ OBoundControlModel::describeAggregateProperties( _rAggregateProps );
+
+ // superseded properties:
+ RemoveProperty( _rAggregateProps, PROPERTY_STRINGITEMLIST );
+}
+
+//------------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OComboBoxModel::getServiceName() throw(RuntimeException)
+{
+ return FRM_COMPONENT_COMBOBOX; // old (non-sun) name for compatibility !
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OComboBoxModel::write(const Reference<stario::XObjectOutputStream>& _rxOutStream)
+ throw(stario::IOException, RuntimeException)
+{
+ OBoundControlModel::write(_rxOutStream);
+
+ // Version
+ // Version 0x0002: EmptyIsNull
+ // Version 0x0003: ListSource->Seq
+ // Version 0x0004: DefaultText
+ // Version 0x0005: HelpText
+ _rxOutStream->writeShort(0x0006);
+
+ // Maskierung fuer any
+ sal_uInt16 nAnyMask = 0;
+ if (m_aBoundColumn.getValueType().getTypeClass() == TypeClass_SHORT)
+ nAnyMask |= BOUNDCOLUMN;
+ _rxOutStream << nAnyMask;
+
+ StringSequence aListSourceSeq(&m_aListSource, 1);
+ _rxOutStream << aListSourceSeq;
+ _rxOutStream << (sal_Int16)m_eListSourceType;
+
+ if ((nAnyMask & BOUNDCOLUMN) == BOUNDCOLUMN)
+ {
+ sal_Int16 nBoundColumn = 0;
+ m_aBoundColumn >>= nBoundColumn;
+ _rxOutStream << nBoundColumn;
+ }
+
+ _rxOutStream << (sal_Bool)m_bEmptyIsNull;
+ _rxOutStream << m_aDefaultText;
+ writeHelpTextCompatibly(_rxOutStream);
+
+ // from version 0x0006 : common properties
+ writeCommonProperties(_rxOutStream);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OComboBoxModel::read(const Reference<stario::XObjectInputStream>& _rxInStream) throw(stario::IOException, RuntimeException)
+{
+ OBoundControlModel::read(_rxInStream);
+ ControlModelLock aLock( *this );
+
+ // since we are "overwriting" the StringItemList of our aggregate (means we have
+ // an own place to store the value, instead of relying on our aggregate storing it),
+ // we need to respect what the aggregate just read for the StringItemList property.
+ try
+ {
+ if ( m_xAggregateSet.is() )
+ setNewStringItemList( m_xAggregateSet->getPropertyValue( PROPERTY_STRINGITEMLIST ), aLock );
+ }
+ catch( const Exception& )
+ {
+ OSL_FAIL( "OComboBoxModel::read: caught an exception while examining the aggregate's string item list!" );
+ }
+
+ // Version
+ sal_uInt16 nVersion = _rxInStream->readShort();
+ DBG_ASSERT(nVersion > 0, "OComboBoxModel::read : version 0 ? this should never have been written !");
+
+ if (nVersion > 0x0006)
+ {
+ OSL_FAIL("OComboBoxModel::read : invalid (means unknown) version !");
+ m_aListSource = ::rtl::OUString();
+ m_aBoundColumn <<= (sal_Int16)0;
+ m_aDefaultText = ::rtl::OUString();
+ m_eListSourceType = ListSourceType_TABLE;
+ m_bEmptyIsNull = sal_True;
+ defaultCommonProperties();
+ return;
+ }
+
+ // Maskierung fuer any
+ sal_uInt16 nAnyMask;
+ _rxInStream >> nAnyMask;
+
+ // ListSource
+ if (nVersion < 0x0003)
+ {
+ ::rtl::OUString sListSource;
+ _rxInStream >> m_aListSource;
+ }
+ else // nVersion == 4
+ {
+ m_aListSource = ::rtl::OUString();
+ StringSequence aListSource;
+ _rxInStream >> aListSource;
+ const ::rtl::OUString* pToken = aListSource.getConstArray();
+ sal_Int32 nLen = aListSource.getLength();
+ for (sal_Int32 i = 0; i < nLen; ++i, ++pToken)
+ m_aListSource += *pToken;
+ }
+
+ sal_Int16 nListSourceType;
+ _rxInStream >> nListSourceType;
+ m_eListSourceType = (ListSourceType)nListSourceType;
+
+ if ((nAnyMask & BOUNDCOLUMN) == BOUNDCOLUMN)
+ {
+ sal_Int16 nValue;
+ _rxInStream >> nValue;
+ m_aBoundColumn <<= nValue;
+ }
+
+ if (nVersion > 0x0001)
+ {
+ sal_Bool bNull;
+ _rxInStream >> bNull;
+ m_bEmptyIsNull = bNull;
+ }
+
+ if (nVersion > 0x0003) // nVersion == 4
+ _rxInStream >> m_aDefaultText;
+
+ // Stringliste muss geleert werden, wenn eine Listenquelle gesetzt ist
+ // dieses kann der Fall sein wenn im alive modus gespeichert wird
+ if ( m_aListSource.getLength()
+ && !hasExternalListSource()
+ )
+ {
+ setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, makeAny( StringSequence() ) );
+ }
+
+ if (nVersion > 0x0004)
+ readHelpTextCompatibly(_rxInStream);
+
+ if (nVersion > 0x0005)
+ readCommonProperties(_rxInStream);
+
+ // Nach dem Lesen die Defaultwerte anzeigen
+ if ( getControlSource().getLength() )
+ {
+ // (not if we don't have a control source - the "State" property acts like it is persistent, then
+ resetNoBroadcast();
+ }
+}
+
+//------------------------------------------------------------------------------
+void OComboBoxModel::loadData( bool _bForce )
+{
+ DBG_ASSERT(m_eListSourceType != ListSourceType_VALUELIST, "OComboBoxModel::loadData : do not call for a value list !");
+ DBG_ASSERT( !hasExternalListSource(), "OComboBoxModel::loadData: cannot load from DB when I have an external list source!" );
+
+ if ( hasExternalListSource() )
+ return;
+
+ // Connection holen
+ Reference<XRowSet> xForm(m_xCursor, UNO_QUERY);
+ if (!xForm.is())
+ return;
+ Reference<XConnection> xConnection = getConnection(xForm);
+ if (!xConnection.is())
+ return;
+
+ Reference<XServiceInfo> xServiceInfo(xConnection, UNO_QUERY);
+ if (!xServiceInfo.is() || !xServiceInfo->supportsService(SRV_SDB_CONNECTION))
+ {
+ OSL_FAIL("OComboBoxModel::loadData : invalid connection !");
+ return;
+ }
+
+ if (!m_aListSource.getLength() || m_eListSourceType == ListSourceType_VALUELIST)
+ return;
+
+ ::utl::SharedUNOComponent< XResultSet > xListCursor;
+ try
+ {
+ m_aListRowSet.setConnection( xConnection );
+
+ bool bExecuteRowSet( false );
+ switch (m_eListSourceType)
+ {
+ case ListSourceType_TABLEFIELDS:
+ // don't work with a statement here, the fields will be collected below
+ break;
+ case ListSourceType_TABLE:
+ {
+ // does the bound field belong to the table ?
+ // if we use an alias for the bound field, we won't find it
+ // in that case we use the first field of the table
+
+ Reference<XNameAccess> xFieldsByName = getTableFields(xConnection, m_aListSource);
+ Reference<XIndexAccess> xFieldsByIndex(xFieldsByName, UNO_QUERY);
+
+ ::rtl::OUString aFieldName;
+ if ( xFieldsByName.is() && xFieldsByName->hasByName( getControlSource() ) )
+ {
+ aFieldName = getControlSource();
+ }
+ else
+ {
+ // otherwise look for the alias
+ Reference<XPropertySet> xFormProp(xForm,UNO_QUERY);
+ Reference< XColumnsSupplier > xSupplyFields;
+ xFormProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SingleSelectQueryComposer"))) >>= xSupplyFields;
+
+ // search the field
+ DBG_ASSERT(xSupplyFields.is(), "OComboBoxModel::loadData : invalid query composer !");
+
+ Reference< XNameAccess > xFieldNames = xSupplyFields->getColumns();
+ if ( xFieldNames->hasByName( getControlSource() ) )
+ {
+ Reference< XPropertySet > xComposerFieldAsSet;
+ xFieldNames->getByName( getControlSource() ) >>= xComposerFieldAsSet;
+ if (hasProperty(PROPERTY_FIELDSOURCE, xComposerFieldAsSet))
+ xComposerFieldAsSet->getPropertyValue(PROPERTY_FIELDSOURCE) >>= aFieldName;
+ }
+ }
+
+ if (!aFieldName.getLength())
+ break;
+
+ Reference<XDatabaseMetaData> xMeta = xConnection->getMetaData();
+ OSL_ENSURE(xMeta.is(),"No database meta data!");
+ if ( xMeta.is() )
+ {
+ ::rtl::OUString aQuote = xMeta->getIdentifierQuoteString();
+
+ ::rtl::OUString sCatalog, sSchema, sTable;
+ qualifiedNameComponents( xMeta, m_aListSource, sCatalog, sSchema, sTable, eInDataManipulation );
+
+ ::rtl::OUStringBuffer aStatement;
+ aStatement.appendAscii( "SELECT DISTINCT " );
+ aStatement.append ( quoteName( aQuote, aFieldName ) );
+ aStatement.appendAscii( " FROM " );
+ aStatement.append ( composeTableNameForSelect( xConnection, sCatalog, sSchema, sTable ) );
+
+ m_aListRowSet.setEscapeProcessing( sal_False );
+ m_aListRowSet.setCommand( aStatement.makeStringAndClear() );
+ bExecuteRowSet = true;
+ }
+ } break;
+ case ListSourceType_QUERY:
+ {
+ m_aListRowSet.setCommandFromQuery( m_aListSource );
+ bExecuteRowSet = true;
+ }
+ break;
+
+ default:
+ {
+ m_aListRowSet.setEscapeProcessing( ListSourceType_SQLPASSTHROUGH != m_eListSourceType );
+ m_aListRowSet.setCommand( m_aListSource );
+ bExecuteRowSet = true;
+ }
+ }
+
+ if ( bExecuteRowSet )
+ {
+ if ( !_bForce && !m_aListRowSet.isDirty() )
+ {
+ // if none of the settings of the row set changed, compared to the last
+ // invocation of loadData, then don't re-fill the list. Instead, assume
+ // the list entries are the same.
+ return;
+ }
+ xListCursor.reset( m_aListRowSet.execute() );
+ }
+ }
+ catch(SQLException& eSQL)
+ {
+ onError(eSQL, FRM_RES_STRING(RID_BASELISTBOX_ERROR_FILLLIST));
+ return;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ return;
+ }
+
+ ::std::vector< ::rtl::OUString > aStringList;
+ aStringList.reserve(16);
+ try
+ {
+ OSL_ENSURE( xListCursor.is() || ( ListSourceType_TABLEFIELDS == m_eListSourceType ),
+ "OComboBoxModel::loadData: logic error!" );
+ if ( !xListCursor.is() && ( ListSourceType_TABLEFIELDS != m_eListSourceType ) )
+ return;
+
+ switch (m_eListSourceType)
+ {
+ case ListSourceType_SQL:
+ case ListSourceType_SQLPASSTHROUGH:
+ case ListSourceType_TABLE:
+ case ListSourceType_QUERY:
+ {
+ // die XDatabaseVAriant der ersten Spalte
+ Reference<XColumnsSupplier> xSupplyCols(xListCursor, UNO_QUERY);
+ DBG_ASSERT(xSupplyCols.is(), "OComboBoxModel::loadData : cursor supports the row set service but is no column supplier?!");
+ Reference<XIndexAccess> xColumns;
+ if (xSupplyCols.is())
+ {
+ xColumns = Reference<XIndexAccess>(xSupplyCols->getColumns(), UNO_QUERY);
+ DBG_ASSERT(xColumns.is(), "OComboBoxModel::loadData : no columns supplied by the row set !");
+ }
+ Reference< XPropertySet > xDataField;
+ if ( xColumns.is() )
+ xColumns->getByIndex(0) >>= xDataField;
+ if ( !xDataField.is() )
+ return;
+
+ ::dbtools::FormattedColumnValue aValueFormatter( getContext(), xForm, xDataField );
+
+ // Listen fuellen
+ sal_Int16 i = 0;
+ // per definitionem the list cursor is positioned _before_ the first row at the moment
+ while (xListCursor->next() && (i++<SHRT_MAX)) // max anzahl eintraege
+ {
+ aStringList.push_back( aValueFormatter.getFormattedValue() );
+ }
+ }
+ break;
+ case ListSourceType_TABLEFIELDS:
+ {
+ Reference<XNameAccess> xFieldNames = getTableFields(xConnection, m_aListSource);
+ if (xFieldNames.is())
+ {
+ StringSequence seqNames = xFieldNames->getElementNames();
+ sal_Int32 nFieldsCount = seqNames.getLength();
+ const ::rtl::OUString* pustrNames = seqNames.getConstArray();
+
+ for (sal_Int32 k=0; k<nFieldsCount; ++k)
+ aStringList.push_back(pustrNames[k]);
+ }
+ }
+ break;
+ default:
+ OSL_FAIL( "OComboBoxModel::loadData: unreachable!" );
+ break;
+ }
+ }
+ catch(SQLException& eSQL)
+ {
+ onError(eSQL, FRM_RES_STRING(RID_BASELISTBOX_ERROR_FILLLIST));
+ return;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ return;
+ }
+
+ // String-Sequence fuer ListBox erzeugen
+ StringSequence aStringSeq(aStringList.size());
+ ::rtl::OUString* pStringAry = aStringSeq.getArray();
+ for (sal_Int32 i = 0; i<aStringSeq.getLength(); ++i)
+ pStringAry[i] = aStringList[i];
+
+ // String-Sequence an ListBox setzen
+ setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, makeAny( aStringSeq ) );
+}
+
+//------------------------------------------------------------------------------
+void OComboBoxModel::onConnectedDbColumn( const Reference< XInterface >& _rxForm )
+{
+ Reference<XPropertySet> xField = getField();
+ if ( xField.is() )
+ m_pValueFormatter.reset( new ::dbtools::FormattedColumnValue( getContext(), Reference< XRowSet >( _rxForm, UNO_QUERY ), xField ) );
+ getPropertyValue( PROPERTY_STRINGITEMLIST ) >>= m_aDesignModeStringItems;
+
+ // Daten nur laden, wenn eine Listenquelle angegeben wurde
+ if ( m_aListSource.getLength() && m_xCursor.is() && !hasExternalListSource() )
+ loadData( false );
+}
+
+//------------------------------------------------------------------------------
+void OComboBoxModel::onDisconnectedDbColumn()
+{
+ m_pValueFormatter.reset();
+
+ // reset the string item list
+ if ( !hasExternalListSource() )
+ setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, makeAny( m_aDesignModeStringItems ) );
+
+ m_aListRowSet.dispose();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OComboBoxModel::reloaded( const EventObject& aEvent ) throw(RuntimeException)
+{
+ OBoundControlModel::reloaded(aEvent);
+
+ // reload data if we have a list source
+ if ( m_aListSource.getLength() && m_xCursor.is() && !hasExternalListSource() )
+ loadData( false );
+}
+
+//------------------------------------------------------------------------------
+void OComboBoxModel::resetNoBroadcast()
+{
+ OBoundControlModel::resetNoBroadcast();
+ m_aLastKnownValue.clear();
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool OComboBoxModel::commitControlValueToDbColumn( bool _bPostReset )
+{
+ Any aNewValue( m_xAggregateFastSet->getFastPropertyValue( getValuePropertyAggHandle() ) );
+
+ ::rtl::OUString sNewValue;
+ aNewValue >>= sNewValue;
+
+ bool bModified = ( aNewValue != m_aLastKnownValue );
+ if ( bModified )
+ {
+ if ( !aNewValue.hasValue()
+ || ( !sNewValue.getLength() // an empty string
+ && m_bEmptyIsNull // which should be interpreted as NULL
+ )
+ )
+ {
+ m_xColumnUpdate->updateNull();
+ }
+ else
+ {
+ try
+ {
+ OSL_PRECOND( m_pValueFormatter.get(), "OComboBoxModel::commitControlValueToDbColumn: no value formatter!" );
+ if ( m_pValueFormatter.get() )
+ {
+ if ( !m_pValueFormatter->setFormattedValue( sNewValue ) )
+ return sal_False;
+ }
+ else
+ m_xColumnUpdate->updateString( sNewValue );
+ }
+ catch ( const Exception& )
+ {
+ return sal_False;
+ }
+ }
+
+ m_aLastKnownValue = aNewValue;
+ }
+
+ // add the new value to the list
+ sal_Bool bAddToList = bModified && !_bPostReset;
+ // (only if this is not the "commit" triggered by a "reset")
+
+ if ( bAddToList )
+ {
+ StringSequence aStringItemList;
+ if ( getPropertyValue( PROPERTY_STRINGITEMLIST ) >>= aStringItemList )
+ {
+ const ::rtl::OUString* pStringItems = aStringItemList.getConstArray();
+ sal_Int32 i;
+ for (i=0; i<aStringItemList.getLength(); ++i, ++pStringItems)
+ {
+ if ( pStringItems->equals( sNewValue ) )
+ break;
+ }
+
+ // not found -> add
+ if (i >= aStringItemList.getLength())
+ {
+ sal_Int32 nOldLen = aStringItemList.getLength();
+ aStringItemList.realloc( nOldLen + 1 );
+ aStringItemList.getArray()[ nOldLen ] = sNewValue;
+
+ setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, makeAny( aStringItemList ) );
+ }
+ }
+ }
+
+ return sal_True;
+}
+
+// XPropertiesChangeListener
+//------------------------------------------------------------------------------
+Any OComboBoxModel::translateDbColumnToControlValue()
+{
+ OSL_PRECOND( m_pValueFormatter.get(), "OComboBoxModel::translateDbColumnToControlValue: no value formatter!" );
+ if ( m_pValueFormatter.get() )
+ {
+ ::rtl::OUString sValue( m_pValueFormatter->getFormattedValue() );
+ if ( !sValue.getLength()
+ && m_pValueFormatter->getColumn().is()
+ && m_pValueFormatter->getColumn()->wasNull()
+ )
+ {
+ m_aLastKnownValue.clear();
+ }
+ else
+ {
+
+ m_aLastKnownValue <<= sValue;
+ }
+ }
+ else
+ m_aLastKnownValue.clear();
+
+ return m_aLastKnownValue.hasValue() ? m_aLastKnownValue : makeAny( ::rtl::OUString() );
+ // (m_aLastKnownValue is alllowed to be VOID, the control value isn't)
+}
+
+//------------------------------------------------------------------------------
+Any OComboBoxModel::getDefaultForReset() const
+{
+ return makeAny( m_aDefaultText );
+}
+
+//--------------------------------------------------------------------
+void OComboBoxModel::stringItemListChanged( ControlModelLock& /*_rInstanceLock*/ )
+{
+ if ( m_xAggregateSet.is() )
+ m_xAggregateSet->setPropertyValue( PROPERTY_STRINGITEMLIST, makeAny( getStringItemList() ) );
+}
+
+//--------------------------------------------------------------------
+void OComboBoxModel::connectedExternalListSource( )
+{
+ // TODO?
+}
+
+//--------------------------------------------------------------------
+void OComboBoxModel::disconnectedExternalListSource( )
+{
+ // TODO?
+}
+
+//--------------------------------------------------------------------
+void OComboBoxModel::refreshInternalEntryList()
+{
+ DBG_ASSERT( !hasExternalListSource(), "OComboBoxModel::refreshInternalEntryList: invalid call!" );
+
+ if ( !hasExternalListSource( )
+ && ( m_eListSourceType != ListSourceType_VALUELIST )
+ && ( m_xCursor.is() )
+ )
+ {
+ loadData( true );
+ }
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL OComboBoxModel::disposing( const EventObject& _rSource ) throw ( RuntimeException )
+{
+ if ( !OEntryListHelper::handleDisposing( _rSource ) )
+ OBoundControlModel::disposing( _rSource );
+}
+
+//========================================================================
+//= OComboBoxControl
+//========================================================================
+
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL OComboBoxControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory) throw (RuntimeException)
+{
+ return *(new OComboBoxControl(_rxFactory));
+}
+
+//------------------------------------------------------------------------------
+OComboBoxControl::OComboBoxControl(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OBoundControl(_rxFactory, VCL_CONTROL_COMBOBOX)
+{
+}
+
+//------------------------------------------------------------------------------
+StringSequence SAL_CALL OComboBoxControl::getSupportedServiceNames() throw(RuntimeException)
+{
+ StringSequence aSupported = OBoundControl::getSupportedServiceNames();
+ aSupported.realloc(aSupported.getLength() + 1);
+
+ ::rtl::OUString* pArray = aSupported.getArray();
+ pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_COMBOBOX;
+ return aSupported;
+}
+
+//.........................................................................
+}
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/ComboBox.hxx b/forms/source/component/ComboBox.hxx
new file mode 100644
index 000000000000..0a45a2fa78d9
--- /dev/null
+++ b/forms/source/component/ComboBox.hxx
@@ -0,0 +1,180 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FORMS_COMBOBOX_HXX_
+#define _FORMS_COMBOBOX_HXX_
+
+#include "FormComponent.hxx"
+#include "errorbroadcaster.hxx"
+#include "entrylisthelper.hxx"
+#include "cachedrowset.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/util/XNumberFormatter.hpp>
+#include <com/sun/star/sdb/XSQLErrorBroadcaster.hpp>
+#include <com/sun/star/form/ListSourceType.hpp>
+#include <com/sun/star/awt/XItemListener.hpp>
+#include <com/sun/star/awt/XFocusListener.hpp>
+/** === end UNO includes === **/
+
+#include <connectivity/formattedcolumnvalue.hxx>
+
+#include <cppuhelper/interfacecontainer.hxx>
+
+#include <vcl/timer.hxx>
+
+#include <tools/date.hxx>
+
+//.........................................................................
+namespace frm
+{
+
+//==================================================================
+// OComboBoxModel
+//==================================================================
+class OComboBoxModel
+ :public OBoundControlModel
+ ,public OEntryListHelper
+ ,public OErrorBroadcaster
+{
+ CachedRowSet m_aListRowSet; // the row set to fill the list
+ ::com::sun::star::uno::Any m_aBoundColumn; // obsolet
+ ::rtl::OUString m_aListSource; //
+ ::rtl::OUString m_aDefaultText; // DefaultText
+ ::com::sun::star::uno::Any m_aLastKnownValue;
+
+ StringSequence m_aDesignModeStringItems;
+ // upon loading, in some cases we reset fill our string item list ourself. We don't want
+ // to lose the user's items then, so we remember them here.
+
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter> m_xFormatter;
+
+ ::com::sun::star::form::ListSourceType m_eListSourceType; // type der list source
+ sal_Bool m_bEmptyIsNull; // LeerString wird als NULL interpretiert
+
+ ::std::auto_ptr< ::dbtools::FormattedColumnValue >
+ m_pValueFormatter;
+
+
+
+protected:
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();
+
+public:
+ DECLARE_DEFAULT_LEAF_XTOR( OComboBoxModel );
+
+ virtual void SAL_CALL disposing();
+
+ // OPropertySetHelper
+ virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const;
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
+ throw (::com::sun::star::uno::Exception);
+ virtual sal_Bool SAL_CALL convertFastPropertyValue(
+ ::com::sun::star::uno::Any& _rConvertedValue, ::com::sun::star::uno::Any& _rOldValue, sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue )
+ throw (::com::sun::star::lang::IllegalArgumentException);
+
+ // XLoadListener
+ virtual void SAL_CALL reloaded( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ IMPLEMENTATION_NAME(OComboBoxModel);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
+
+ // UNO
+ DECLARE_UNO3_AGG_DEFAULTS(OComboBoxModel, OBoundControlModel);
+ virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XPersistObject
+ virtual ::rtl::OUString SAL_CALL getServiceName() throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL
+ write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL
+ read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ // OControlModel's property handling
+ virtual void describeFixedProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps
+ ) const;
+ virtual void describeAggregateProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rAggregateProps
+ ) const;
+
+ // XEventListener
+ virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException);
+
+ // prevent method hiding
+ using OBoundControlModel::getFastPropertyValue;
+
+protected:
+ // OBoundControlModel overridables
+ virtual ::com::sun::star::uno::Any
+ translateDbColumnToControlValue( );
+ virtual sal_Bool commitControlValueToDbColumn( bool _bPostReset );
+
+ virtual void onConnectedDbColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxForm );
+ virtual void onDisconnectedDbColumn();
+
+ virtual ::com::sun::star::uno::Any
+ getDefaultForReset() const;
+
+ virtual void resetNoBroadcast();
+
+ // OEntryListHelper overriables
+ virtual void stringItemListChanged( ControlModelLock& _rInstanceLock );
+ virtual void connectedExternalListSource( );
+ virtual void disconnectedExternalListSource( );
+ virtual void refreshInternalEntryList();
+
+protected:
+ void loadData( bool _bForce );
+
+ DECLARE_XCLONEABLE();
+};
+
+//==================================================================
+// OComboBoxControl
+//==================================================================
+
+class OComboBoxControl : public OBoundControl
+{
+public:
+ OComboBoxControl(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);
+
+ // XServiceInfo
+ IMPLEMENTATION_NAME(OComboBoxControl);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
+};
+
+//.........................................................................
+}
+//.........................................................................
+
+#endif // _FORMS_COMBOBOX_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/Currency.cxx b/forms/source/component/Currency.cxx
new file mode 100644
index 000000000000..9ae25ed9b4b8
--- /dev/null
+++ b/forms/source/component/Currency.cxx
@@ -0,0 +1,270 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+#include "Currency.hxx"
+#include <tools/debug.hxx>
+#include <unotools/localedatawrapper.hxx>
+#include <vcl/svapp.hxx>
+#include <unotools/syslocale.hxx>
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+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;
+
+//==================================================================
+// OCurrencyControl
+//==================================================================
+//------------------------------------------------------------------
+OCurrencyControl::OCurrencyControl(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OBoundControl(_rxFactory, VCL_CONTROL_CURRENCYFIELD)
+{
+}
+
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL OCurrencyControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
+{
+ return *(new OCurrencyControl(_rxFactory));
+}
+
+//------------------------------------------------------------------------------
+Sequence<Type> OCurrencyControl::_getTypes()
+{
+ return OBoundControl::_getTypes();
+}
+
+//------------------------------------------------------------------------------
+StringSequence SAL_CALL OCurrencyControl::getSupportedServiceNames() throw()
+{
+ StringSequence aSupported = OBoundControl::getSupportedServiceNames();
+ aSupported.realloc(aSupported.getLength() + 1);
+
+ ::rtl::OUString*pArray = aSupported.getArray();
+ pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_CURRENCYFIELD;
+ return aSupported;
+}
+
+//==================================================================
+// OCurrencyModel
+//==================================================================
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL OCurrencyModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
+{
+ return *(new OCurrencyModel(_rxFactory));
+}
+
+//------------------------------------------------------------------------------
+Sequence<Type> OCurrencyModel::_getTypes()
+{
+ return OEditBaseModel::_getTypes();
+}
+
+//------------------------------------------------------------------
+void OCurrencyModel::implConstruct()
+{
+ if (m_xAggregateSet.is())
+ {
+ try
+ {
+ // get the system international informations
+ const SvtSysLocale aSysLocale;
+ const LocaleDataWrapper& aLocaleInfo = aSysLocale.GetLocaleData();
+
+ ::rtl::OUString sCurrencySymbol;
+ sal_Bool bPrependCurrencySymbol;
+ switch ( aLocaleInfo.getCurrPositiveFormat() )
+ {
+ case 0: // $1
+ sCurrencySymbol = String(aLocaleInfo.getCurrSymbol());
+ bPrependCurrencySymbol = sal_True;
+ break;
+ case 1: // 1$
+ sCurrencySymbol = String(aLocaleInfo.getCurrSymbol());
+ bPrependCurrencySymbol = sal_False;
+ break;
+ case 2: // $ 1
+ sCurrencySymbol = ::rtl::OUString(String(aLocaleInfo.getCurrSymbol())) + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" ") );
+ bPrependCurrencySymbol = sal_True;
+ break;
+ case 3: // 1 $
+ sCurrencySymbol = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" ") ) + ::rtl::OUString(String(aLocaleInfo.getCurrSymbol()));
+ bPrependCurrencySymbol = sal_False;
+ break;
+ }
+ if (sCurrencySymbol.getLength())
+ {
+ m_xAggregateSet->setPropertyValue(PROPERTY_CURRENCYSYMBOL, makeAny(sCurrencySymbol));
+ m_xAggregateSet->setPropertyValue(PROPERTY_CURRSYM_POSITION, makeAny(bPrependCurrencySymbol));
+ }
+ }
+ catch(Exception&)
+ {
+ OSL_FAIL( "OCurrencyModel::implConstruct: caught an exception while initializing the aggregate!" );
+ }
+ }
+}
+
+//------------------------------------------------------------------
+DBG_NAME( OCurrencyModel )
+//------------------------------------------------------------------
+OCurrencyModel::OCurrencyModel(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OEditBaseModel( _rxFactory, VCL_CONTROLMODEL_CURRENCYFIELD, FRM_SUN_CONTROL_CURRENCYFIELD, sal_False, sal_True )
+ // use the old control name for compytibility reasons
+{
+ DBG_CTOR( OCurrencyModel, NULL );
+
+ m_nClassId = FormComponentType::CURRENCYFIELD;
+ initValueProperty( PROPERTY_VALUE, PROPERTY_ID_VALUE );
+
+ implConstruct();
+}
+
+//------------------------------------------------------------------
+OCurrencyModel::OCurrencyModel( const OCurrencyModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
+ :OEditBaseModel( _pOriginal, _rxFactory )
+{
+ DBG_CTOR( OCurrencyModel, NULL );
+ implConstruct();
+}
+
+//------------------------------------------------------------------
+OCurrencyModel::~OCurrencyModel()
+{
+ DBG_DTOR( OCurrencyModel, NULL );
+}
+
+// XCloneable
+//------------------------------------------------------------------------------
+IMPLEMENT_DEFAULT_CLONING( OCurrencyModel )
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+StringSequence SAL_CALL OCurrencyModel::getSupportedServiceNames() throw()
+{
+ StringSequence aSupported = OBoundControlModel::getSupportedServiceNames();
+
+ sal_Int32 nOldLen = aSupported.getLength();
+ aSupported.realloc( nOldLen + 4 );
+ ::rtl::OUString* pStoreTo = aSupported.getArray() + nOldLen;
+
+ *pStoreTo++ = DATA_AWARE_CONTROL_MODEL;
+ *pStoreTo++ = VALIDATABLE_CONTROL_MODEL;
+
+ *pStoreTo++ = FRM_SUN_COMPONENT_CURRENCYFIELD;
+ *pStoreTo++ = FRM_SUN_COMPONENT_DATABASE_CURRENCYFIELD;
+
+ return aSupported;
+}
+
+//------------------------------------------------------------------------------
+void OCurrencyModel::describeFixedProperties( Sequence< Property >& _rProps ) const
+{
+ BEGIN_DESCRIBE_PROPERTIES( 2, OEditBaseModel )
+ // Value auf transient setzen
+// ModifyPropertyAttributes(_rAggregateProps, PROPERTY_VALUE, PropertyAttribute::TRANSIENT, 0);
+
+ DECL_PROP3(DEFAULT_VALUE, double, BOUND, MAYBEDEFAULT, MAYBEVOID);
+ DECL_PROP1(TABINDEX, sal_Int16, BOUND);
+ END_DESCRIBE_PROPERTIES();
+}
+
+//------------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OCurrencyModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException)
+{
+ return FRM_COMPONENT_CURRENCYFIELD; // old (non-sun) name for compatibility !
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OCurrencyModel::commitControlValueToDbColumn( bool /*_bPostReset*/ )
+{
+ Any aControlValue( m_xAggregateFastSet->getFastPropertyValue( getValuePropertyAggHandle() ) );
+ if ( !compare( aControlValue, m_aSaveValue ) )
+ {
+ if ( aControlValue.getValueType().getTypeClass() == TypeClass_VOID )
+ m_xColumnUpdate->updateNull();
+ else
+ {
+ try
+ {
+ m_xColumnUpdate->updateDouble( getDouble( aControlValue ) );
+ }
+ catch(Exception&)
+ {
+ return sal_False;
+ }
+ }
+ m_aSaveValue = aControlValue;
+ }
+ return sal_True;
+}
+
+//------------------------------------------------------------------------------
+Any OCurrencyModel::translateDbColumnToControlValue()
+{
+ m_aSaveValue <<= m_xColumn->getDouble();
+ if ( m_xColumn->wasNull() )
+ m_aSaveValue.clear();
+ return m_aSaveValue;
+}
+
+// XReset
+//------------------------------------------------------------------------------
+Any OCurrencyModel::getDefaultForReset() const
+{
+ Any aValue;
+ if ( m_aDefault.getValueType().getTypeClass() == TypeClass_DOUBLE )
+ aValue = m_aDefault;
+
+ return aValue;
+}
+
+//------------------------------------------------------------------------------
+void OCurrencyModel::resetNoBroadcast()
+{
+ OEditBaseModel::resetNoBroadcast();
+ m_aSaveValue.clear();
+}
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/Currency.hxx b/forms/source/component/Currency.hxx
new file mode 100644
index 000000000000..b36585e52e39
--- /dev/null
+++ b/forms/source/component/Currency.hxx
@@ -0,0 +1,103 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FORMS_CURRENCY_HXX_
+#define _FORMS_CURRENCY_HXX_
+
+#include "EditBase.hxx"
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+//==================================================================
+//= OCurrencyModel
+//==================================================================
+class OCurrencyModel
+ :public OEditBaseModel
+{
+ ::com::sun::star::uno::Any m_aSaveValue;
+
+protected:
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();
+
+public:
+ DECLARE_DEFAULT_LEAF_XTOR( OCurrencyModel );
+
+ // ::com::sun::star::lang::XServiceInfo
+ IMPLEMENTATION_NAME(OCurrencyModel);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw();
+
+ // ::com::sun::star::io::XPersistObject
+ virtual ::rtl::OUString SAL_CALL getServiceName() throw ( ::com::sun ::star::uno::RuntimeException);
+
+ // OControlModel's property handling
+ virtual void describeFixedProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps
+ ) const;
+
+protected:
+ // OBoundControlModel overridables
+ virtual ::com::sun::star::uno::Any
+ translateDbColumnToControlValue( );
+ virtual sal_Bool commitControlValueToDbColumn( bool _bPostReset );
+
+ virtual ::com::sun::star::uno::Any
+ getDefaultForReset() const;
+
+ virtual void resetNoBroadcast();
+
+protected:
+ DECLARE_XCLONEABLE();
+
+ void implConstruct();
+};
+
+//==================================================================
+//= OCurrencyControl
+//==================================================================
+class OCurrencyControl: public OBoundControl
+{
+protected:
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();
+
+public:
+ OCurrencyControl(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);
+ // ::com::sun::star::lang::XServiceInfo
+ IMPLEMENTATION_NAME(OCurrencyControl);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw();
+};
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+#endif // _FORMS_CURRENCY_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/DatabaseForm.cxx b/forms/source/component/DatabaseForm.cxx
new file mode 100644
index 000000000000..a6a14e652f62
--- /dev/null
+++ b/forms/source/component/DatabaseForm.cxx
@@ -0,0 +1,4159 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+
+#include "componenttools.hxx"
+#include "DatabaseForm.hxx"
+#include "EventThread.hxx"
+#include "frm_module.hxx"
+#include "frm_resource.hrc"
+#include "frm_resource.hxx"
+#include "GroupManager.hxx"
+#include "property.hrc"
+#include "property.hxx"
+#include "services.hxx"
+
+#include <com/sun/star/awt/XControlContainer.hpp>
+#include <com/sun/star/awt/XTextComponent.hpp>
+#include <com/sun/star/form/DataSelectionType.hpp>
+#include <com/sun/star/form/FormComponentType.hpp>
+#include <com/sun/star/form/TabulatorCycle.hpp>
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/io/XObjectInputStream.hpp>
+#include <com/sun/star/io/XObjectOutputStream.hpp>
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/sdb/RowSetVetoException.hpp>
+#include <com/sun/star/sdb/SQLContext.hpp>
+#include <com/sun/star/sdb/XColumnUpdate.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
+#include <com/sun/star/sdbc/ResultSetType.hpp>
+#include <com/sun/star/sdbc/XRowSet.hpp>
+#include <com/sun/star/sdbcx/Privilege.hpp>
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include <com/sun/star/util/XCancellable.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/util/XModifiable2.hpp>
+
+#include <comphelper/basicio.hxx>
+#include <comphelper/container.hxx>
+#include <comphelper/enumhelper.hxx>
+#include <comphelper/extract.hxx>
+#include <comphelper/seqstream.hxx>
+#include <comphelper/sequence.hxx>
+#include <comphelper/stl_types.hxx>
+#include <comphelper/uno3.hxx>
+#include <connectivity/dbtools.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <cppuhelper/implbase2.hxx>
+#include <rtl/math.hxx>
+#include <rtl/tencinfo.h>
+#include <svl/inetstrm.hxx>
+#include <svl/inettype.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <tools/fsys.hxx>
+#include <tools/inetmsg.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/ucblockbytes.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/timer.hxx>
+#include <osl/mutex.hxx>
+
+#include <ctype.h>
+#include <boost/unordered_map.hpp>
+
+// compatiblity: DatabaseCursorType is dead, but for compatiblity reasons we still have to write it ...
+namespace com {
+namespace sun {
+namespace star {
+namespace data {
+
+enum DatabaseCursorType
+{
+ DatabaseCursorType_FORWARD = 0,
+ DatabaseCursorType_SNAPSHOT = 1,
+ DatabaseCursorType_KEYSET = 2,
+ DatabaseCursorType_DYNAMIC = 3,
+ DatabaseCursorType_MAKE_FIXED_SIZE = SAL_MAX_ENUM
+};
+
+} } } }
+
+using namespace ::dbtools;
+using namespace ::comphelper;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::task;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::form;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::data;
+using namespace ::com::sun::star::util;
+
+//--------------------------------------------------------------------------
+extern "C" void SAL_CALL createRegistryInfo_ODatabaseForm()
+{
+ static ::frm::OMultiInstanceAutoRegistration< ::frm::ODatabaseForm > aAutoRegistration;
+}
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+//==================================================================
+//= DocumentModifyGuard
+//==================================================================
+class DocumentModifyGuard
+{
+public:
+ DocumentModifyGuard( const Reference< XInterface >& _rxFormComponent )
+ :m_xDocumentModify( getXModel( _rxFormComponent ), UNO_QUERY )
+ {
+ impl_changeModifiableFlag_nothrow( false );
+ }
+ ~DocumentModifyGuard()
+ {
+ impl_changeModifiableFlag_nothrow( true );
+ }
+
+private:
+ void impl_changeModifiableFlag_nothrow( const bool _enable )
+ {
+ try
+ {
+ if ( m_xDocumentModify.is() )
+ _enable ? m_xDocumentModify->enableSetModified() : m_xDocumentModify->disableSetModified();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+private:
+ Reference< XModifiable2 > m_xDocumentModify;
+};
+
+//==================================================================
+//= OFormSubmitResetThread
+//=-----------------------------------------------------------------
+//= submitting and resetting html-forms asynchronously
+//==================================================================
+
+//------------------------------------------------------------------
+class OFormSubmitResetThread: public OComponentEventThread
+{
+protected:
+
+ // duplicate an event with respect to it's type
+ virtual EventObject *cloneEvent( const EventObject *pEvt ) const;
+
+ // process an event. while processing the mutex isn't locked, and pCompImpl
+ // is made sure to remain valid
+ virtual void processEvent( ::cppu::OComponentHelper* _pCompImpl,
+ const EventObject* _pEvt,
+ const Reference<XControl>& _rControl,
+ sal_Bool _bSubmit);
+
+public:
+
+ OFormSubmitResetThread(ODatabaseForm* pControl) : OComponentEventThread(pControl) { }
+};
+
+//------------------------------------------------------------------
+EventObject* OFormSubmitResetThread::cloneEvent(
+ const EventObject *pEvt ) const
+{
+ return new ::com::sun::star::awt::MouseEvent( *(::com::sun::star::awt::MouseEvent *)pEvt );
+}
+
+//------------------------------------------------------------------
+void OFormSubmitResetThread::processEvent(
+ ::cppu::OComponentHelper* pCompImpl,
+ const EventObject *_pEvt,
+ const Reference<XControl>& _rControl,
+ sal_Bool _bSubmit)
+{
+ if (_bSubmit)
+ ((ODatabaseForm *)pCompImpl)->submit_impl(_rControl, *static_cast<const ::com::sun::star::awt::MouseEvent*>(_pEvt), true);
+ else
+ ((ODatabaseForm *)pCompImpl)->reset_impl(true);
+}
+
+//==================================================================
+//= ODatabaseForm
+//==================================================================
+
+//------------------------------------------------------------------
+Reference< XInterface > SAL_CALL ODatabaseForm::Create( const Reference< XMultiServiceFactory >& _rxFactory )
+{
+ return *( new ODatabaseForm( _rxFactory ) );
+}
+
+//------------------------------------------------------------------------------
+Sequence<sal_Int8> SAL_CALL ODatabaseForm::getImplementationId() throw(RuntimeException)
+{
+ return OImplementationIds::getImplementationId(getTypes());
+}
+
+//------------------------------------------------------------------
+Sequence<Type> SAL_CALL ODatabaseForm::getTypes() throw(RuntimeException)
+{
+ // ask the aggregate
+ Sequence<Type> aAggregateTypes;
+ Reference<XTypeProvider> xAggregateTypes;
+ if (query_aggregation(m_xAggregate, xAggregateTypes))
+ aAggregateTypes = xAggregateTypes->getTypes();
+
+ Sequence< Type > aRet = concatSequences(
+ aAggregateTypes, ODatabaseForm_BASE1::getTypes(), OFormComponents::getTypes()
+ );
+ aRet = concatSequences( aRet, ODatabaseForm_BASE2::getTypes(), ODatabaseForm_BASE3::getTypes() );
+ return concatSequences( aRet, OPropertySetAggregationHelper::getTypes() );
+}
+
+//------------------------------------------------------------------
+Any SAL_CALL ODatabaseForm::queryAggregation(const Type& _rType) throw(RuntimeException)
+{
+ Any aReturn = ODatabaseForm_BASE1::queryInterface(_rType);
+ // our own interfaces
+ if (!aReturn.hasValue())
+ {
+ aReturn = ODatabaseForm_BASE2::queryInterface(_rType);
+ // property set related interfaces
+ if (!aReturn.hasValue())
+ {
+ aReturn = OPropertySetAggregationHelper::queryInterface(_rType);
+
+ // form component collection related interfaces
+ if (!aReturn.hasValue())
+ {
+ aReturn = OFormComponents::queryAggregation(_rType);
+
+ // interfaces already present in the aggregate which we want to reroute
+ // only available if we could create the aggregate
+ if (!aReturn.hasValue() && m_xAggregateAsRowSet.is())
+ aReturn = ODatabaseForm_BASE3::queryInterface(_rType);
+
+ // aggregate interfaces
+ // (ask the aggregated object _after_ the OComponentHelper (base of OFormComponents),
+ // so calls to the XComponent interface reach us and not the aggreagtion)
+ if (!aReturn.hasValue() && m_xAggregate.is())
+ aReturn = m_xAggregate->queryAggregation(_rType);
+ }
+ }
+ }
+
+ return aReturn;
+}
+
+DBG_NAME(ODatabaseForm);
+//------------------------------------------------------------------
+ODatabaseForm::ODatabaseForm(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OFormComponents(_rxFactory)
+ ,OPropertySetAggregationHelper(OComponentHelper::rBHelper)
+ ,OPropertyChangeListener(m_aMutex)
+ ,m_aLoadListeners(m_aMutex)
+ ,m_aRowSetApproveListeners(m_aMutex)
+ ,m_aRowSetListeners(m_aMutex)
+ ,m_aSubmitListeners(m_aMutex)
+ ,m_aErrorListeners(m_aMutex)
+ ,m_aResetListeners( *this, m_aMutex )
+ ,m_aPropertyBagHelper( *this )
+ ,m_pAggregatePropertyMultiplexer(NULL)
+ ,m_pGroupManager( NULL )
+ ,m_aParameterManager( m_aMutex, _rxFactory )
+ ,m_aFilterManager( _rxFactory )
+ ,m_pLoadTimer(NULL)
+ ,m_pThread(NULL)
+ ,m_nResetsPending(0)
+ ,m_nPrivileges(0)
+ ,m_bInsertOnly( sal_False )
+ ,m_eSubmitMethod(FormSubmitMethod_GET)
+ ,m_eSubmitEncoding(FormSubmitEncoding_URL)
+ ,m_eNavigation(NavigationBarMode_CURRENT)
+ ,m_bAllowInsert(sal_True)
+ ,m_bAllowUpdate(sal_True)
+ ,m_bAllowDelete(sal_True)
+ ,m_bLoaded(sal_False)
+ ,m_bSubForm(sal_False)
+ ,m_bForwardingConnection(sal_False)
+ ,m_bSharingConnection( sal_False )
+{
+ DBG_CTOR( ODatabaseForm, NULL );
+ impl_construct();
+}
+
+//------------------------------------------------------------------
+ODatabaseForm::ODatabaseForm( const ODatabaseForm& _cloneSource )
+ :OFormComponents( _cloneSource )
+ ,OPropertySetAggregationHelper( OComponentHelper::rBHelper )
+ ,OPropertyChangeListener( m_aMutex )
+ ,ODatabaseForm_BASE1()
+ ,ODatabaseForm_BASE2()
+ ,ODatabaseForm_BASE3()
+ ,IPropertyBagHelperContext()
+ ,m_aLoadListeners( m_aMutex )
+ ,m_aRowSetApproveListeners( m_aMutex )
+ ,m_aRowSetListeners( m_aMutex )
+ ,m_aSubmitListeners( m_aMutex )
+ ,m_aErrorListeners( m_aMutex )
+ ,m_aResetListeners( *this, m_aMutex )
+ ,m_aPropertyBagHelper( *this )
+ ,m_pAggregatePropertyMultiplexer( NULL )
+ ,m_pGroupManager( NULL )
+ ,m_aParameterManager( m_aMutex, _cloneSource.m_xServiceFactory )
+ ,m_aFilterManager( _cloneSource.m_xServiceFactory )
+ ,m_pLoadTimer( NULL )
+ ,m_pThread( NULL )
+ ,m_nResetsPending( 0 )
+ ,m_nPrivileges( 0 )
+ ,m_bInsertOnly( _cloneSource.m_bInsertOnly )
+ ,m_aControlBorderColorFocus( _cloneSource.m_aControlBorderColorFocus )
+ ,m_aControlBorderColorMouse( _cloneSource.m_aControlBorderColorMouse )
+ ,m_aControlBorderColorInvalid( _cloneSource.m_aControlBorderColorInvalid )
+ ,m_aDynamicControlBorder( _cloneSource.m_aDynamicControlBorder )
+ ,m_sName( _cloneSource.m_sName )
+ ,m_aTargetURL( _cloneSource.m_aTargetURL )
+ ,m_aTargetFrame( _cloneSource.m_aTargetFrame )
+ ,m_eSubmitMethod( _cloneSource.m_eSubmitMethod )
+ ,m_eSubmitEncoding( _cloneSource.m_eSubmitEncoding )
+ ,m_eNavigation( _cloneSource.m_eNavigation )
+ ,m_bAllowInsert( _cloneSource.m_bAllowInsert )
+ ,m_bAllowUpdate( _cloneSource.m_bAllowUpdate )
+ ,m_bAllowDelete( _cloneSource.m_bAllowDelete )
+ ,m_bLoaded( sal_False )
+ ,m_bSubForm( sal_False )
+ ,m_bForwardingConnection( sal_False )
+ ,m_bSharingConnection( sal_False )
+{
+ DBG_CTOR( ODatabaseForm, NULL );
+
+ impl_construct();
+
+ osl_incrementInterlockedCount( &m_refCount );
+ {
+ // our aggregated rowset itself is not cloneable, so simply copy the properties
+ ::comphelper::copyProperties( _cloneSource.m_xAggregateSet, m_xAggregateSet );
+
+ // also care for the dynamic properties: If the clone source has properties which we do not have,
+ // then add them
+ try
+ {
+ Reference< XPropertySet > xSourceProps( const_cast< ODatabaseForm& >( _cloneSource ).queryAggregation(
+ XPropertySet::static_type() ), UNO_QUERY_THROW );
+ Reference< XPropertySetInfo > xSourcePSI( xSourceProps->getPropertySetInfo(), UNO_SET_THROW );
+ Reference< XPropertyState > xSourcePropState( xSourceProps, UNO_QUERY );
+
+ Reference< XPropertySetInfo > xDestPSI( getPropertySetInfo(), UNO_QUERY_THROW );
+
+ Sequence< Property > aSourceProperties( xSourcePSI->getProperties() );
+ for ( const Property* pSourceProperty = aSourceProperties.getConstArray();
+ pSourceProperty != aSourceProperties.getConstArray() + aSourceProperties.getLength();
+ ++pSourceProperty
+ )
+ {
+ if ( xDestPSI->hasPropertyByName( pSourceProperty->Name ) )
+ continue;
+
+ // the initial value passed to XPropertyContainer is also used as default, usually. So, try
+ // to retrieve the default of the source property
+ Any aInitialValue;
+ if ( xSourcePropState.is() )
+ {
+ aInitialValue = xSourcePropState->getPropertyDefault( pSourceProperty->Name );
+ }
+ else
+ {
+ aInitialValue = xSourceProps->getPropertyValue( pSourceProperty->Name );
+ }
+ addProperty( pSourceProperty->Name, pSourceProperty->Attributes, aInitialValue );
+ setPropertyValue( pSourceProperty->Name, xSourceProps->getPropertyValue( pSourceProperty->Name ) );
+ }
+ }
+ catch( const Exception& )
+ {
+ throw WrappedTargetException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Could not clone the given database form." ) ),
+ *const_cast< ODatabaseForm* >( &_cloneSource ),
+ ::cppu::getCaughtException()
+ );
+ }
+ }
+ osl_decrementInterlockedCount( &m_refCount );
+}
+
+//------------------------------------------------------------------
+void ODatabaseForm::impl_construct()
+{
+ // aggregate a row set
+ increment(m_refCount);
+ {
+ m_xAggregate = Reference< XAggregation >( m_xServiceFactory->createInstance( SRV_SDB_ROWSET ), UNO_QUERY_THROW );
+ m_xAggregateAsRowSet.set( m_xAggregate, UNO_QUERY_THROW );
+ setAggregation( m_xAggregate );
+ }
+
+ // listen for the properties, important for Parameters
+ if ( m_xAggregateSet.is() )
+ {
+ m_pAggregatePropertyMultiplexer = new OPropertyChangeMultiplexer(this, m_xAggregateSet, sal_False);
+ m_pAggregatePropertyMultiplexer->acquire();
+ m_pAggregatePropertyMultiplexer->addProperty(PROPERTY_COMMAND);
+ m_pAggregatePropertyMultiplexer->addProperty(PROPERTY_ACTIVE_CONNECTION);
+ }
+
+ {
+ Reference< XWarningsSupplier > xRowSetWarnings( m_xAggregate, UNO_QUERY );
+ m_aWarnings.setExternalWarnings( xRowSetWarnings );
+ }
+
+ if ( m_xAggregate.is() )
+ {
+ m_xAggregate->setDelegator( static_cast< XWeak* >( this ) );
+ }
+
+ {
+ m_aFilterManager.initialize( m_xAggregateSet );
+ m_aParameterManager.initialize( this, m_xAggregate );
+
+ declareForwardedProperty( PROPERTY_ID_ACTIVE_CONNECTION );
+ }
+ decrement( m_refCount );
+
+ m_pGroupManager = new OGroupManager( this );
+ m_pGroupManager->acquire();
+}
+
+//------------------------------------------------------------------
+ODatabaseForm::~ODatabaseForm()
+{
+ DBG_DTOR(ODatabaseForm,NULL);
+
+ m_pGroupManager->release();
+ m_pGroupManager = NULL;
+
+ if (m_xAggregate.is())
+ m_xAggregate->setDelegator( NULL );
+
+ m_aWarnings.setExternalWarnings( NULL );
+
+ if (m_pAggregatePropertyMultiplexer)
+ {
+ m_pAggregatePropertyMultiplexer->dispose();
+ m_pAggregatePropertyMultiplexer->release();
+ m_pAggregatePropertyMultiplexer = NULL;
+ }
+}
+
+//==============================================================================
+// html tools
+//------------------------------------------------------------------------
+::rtl::OUString ODatabaseForm::GetDataURLEncoded(const Reference<XControl>& SubmitButton, const ::com::sun::star::awt::MouseEvent& MouseEvt)
+{
+ return GetDataEncoded(true,SubmitButton,MouseEvt);
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString ODatabaseForm::GetDataEncoded(bool _bURLEncoded,const Reference<XControl>& SubmitButton, const ::com::sun::star::awt::MouseEvent& MouseEvt)
+{
+ // Liste von successful Controls fuellen
+ HtmlSuccessfulObjList aSuccObjList;
+ FillSuccessfulList( aSuccObjList, SubmitButton, MouseEvt );
+
+
+ // Liste zu ::rtl::OUString zusammensetzen
+ ::rtl::OUStringBuffer aResult;
+ ::rtl::OUString aName;
+ ::rtl::OUString aValue;
+
+ for ( HtmlSuccessfulObjListIterator pSuccObj = aSuccObjList.begin();
+ pSuccObj < aSuccObjList.end();
+ ++pSuccObj
+ )
+ {
+ aName = pSuccObj->aName;
+ aValue = pSuccObj->aValue;
+ if( pSuccObj->nRepresentation == SUCCESSFUL_REPRESENT_FILE && aValue.getLength() )
+ {
+ // Bei File-URLs wird der Dateiname und keine URL uebertragen,
+ // weil Netscape dies so macht.
+ INetURLObject aURL;
+ aURL.SetSmartProtocol(INET_PROT_FILE);
+ aURL.SetSmartURL(aValue);
+ if( INET_PROT_FILE == aURL.GetProtocol() )
+ aValue = INetURLObject::decode(aURL.PathToFileName(), '%', INetURLObject::DECODE_UNAMBIGUOUS);
+ }
+ Encode( aName );
+ Encode( aValue );
+
+ aResult.append(aName);
+ aResult.append(sal_Unicode('='));
+ aResult.append(aValue);
+
+ if (pSuccObj < aSuccObjList.end() - 1)
+ {
+ if ( _bURLEncoded )
+ aResult.append(sal_Unicode('&'));
+ else
+ aResult.appendAscii("\r\n");
+ }
+ }
+
+
+ aSuccObjList.clear();
+
+ return aResult.makeStringAndClear();
+}
+
+//==============================================================================
+// html tools
+//------------------------------------------------------------------------
+::rtl::OUString ODatabaseForm::GetDataTextEncoded(const Reference<XControl>& SubmitButton, const ::com::sun::star::awt::MouseEvent& MouseEvt)
+{
+ return GetDataEncoded(false,SubmitButton,MouseEvt);
+}
+
+//------------------------------------------------------------------------
+Sequence<sal_Int8> ODatabaseForm::GetDataMultiPartEncoded(const Reference<XControl>& SubmitButton, const ::com::sun::star::awt::MouseEvent& MouseEvt, ::rtl::OUString& rContentType)
+{
+
+ // Parent erzeugen
+ INetMIMEMessage aParent;
+ aParent.EnableAttachChild( INETMSG_MULTIPART_FORM_DATA );
+
+
+ // Liste von successful Controls fuellen
+ HtmlSuccessfulObjList aSuccObjList;
+ FillSuccessfulList( aSuccObjList, SubmitButton, MouseEvt );
+
+
+ // Liste zu ::rtl::OUString zusammensetzen
+ ::rtl::OUString aResult;
+ for ( HtmlSuccessfulObjListIterator pSuccObj = aSuccObjList.begin();
+ pSuccObj < aSuccObjList.end();
+ ++pSuccObj
+ )
+ {
+ if( pSuccObj->nRepresentation == SUCCESSFUL_REPRESENT_TEXT )
+ InsertTextPart( aParent, pSuccObj->aName, pSuccObj->aValue );
+ else if( pSuccObj->nRepresentation == SUCCESSFUL_REPRESENT_FILE )
+ InsertFilePart( aParent, pSuccObj->aName, pSuccObj->aValue );
+ }
+
+
+ // Liste loeschen
+ aSuccObjList.clear();
+
+ // Fuer Parent MessageStream erzeugen
+ INetMIMEMessageStream aMessStream;
+ aMessStream.SetSourceMessage( &aParent );
+ aMessStream.GenerateHeader( sal_False );
+
+ // MessageStream in SvStream kopieren
+ SvMemoryStream aMemStream;
+ char* pBuf = new char[1025];
+ int nRead;
+ while( (nRead = aMessStream.Read(pBuf, 1024)) > 0 )
+ aMemStream.Write( pBuf, nRead );
+ delete[] pBuf;
+
+ aMemStream.Flush();
+ aMemStream.Seek( 0 );
+ void* pData = (void*)aMemStream.GetData();
+ sal_Int32 nLen = aMemStream.Seek(STREAM_SEEK_TO_END);
+
+ rContentType = UniString(aParent.GetContentType());
+ return Sequence<sal_Int8>((sal_Int8*)pData, nLen);
+}
+
+//------------------------------------------------------------------------
+namespace
+{
+ static void appendDigits( sal_Int32 _nNumber, sal_Int8 nDigits, ::rtl::OUStringBuffer& _rOut )
+ {
+ sal_Int32 nCurLen = _rOut.getLength();
+ _rOut.append( _nNumber );
+ while ( _rOut.getLength() - nCurLen < nDigits )
+ _rOut.insert( nCurLen, (sal_Unicode)'0' );
+ }
+}
+
+//------------------------------------------------------------------------
+void ODatabaseForm::AppendComponent(HtmlSuccessfulObjList& rList, const Reference<XPropertySet>& xComponentSet, const ::rtl::OUString& rNamePrefix,
+ const Reference<XControl>& rxSubmitButton, const ::com::sun::star::awt::MouseEvent& MouseEvt)
+{
+ if (!xComponentSet.is())
+ return;
+
+ // MIB 25.6.98: Geschachtelte Formulare abfangen ... oder muesste
+ // man sie submitten?
+ if (!hasProperty(PROPERTY_CLASSID, xComponentSet))
+ return;
+
+ // Namen ermitteln
+ if (!hasProperty(PROPERTY_NAME, xComponentSet))
+ return;
+
+ sal_Int16 nClassId = 0;
+ xComponentSet->getPropertyValue(PROPERTY_CLASSID) >>= nClassId;
+ ::rtl::OUString aName;
+ xComponentSet->getPropertyValue( PROPERTY_NAME ) >>= aName;
+ if( !aName.getLength() && nClassId != FormComponentType::IMAGEBUTTON)
+ return;
+ else // Name um den Prefix erweitern
+ aName = rNamePrefix + aName;
+
+ switch( nClassId )
+ {
+ // Buttons
+ case FormComponentType::COMMANDBUTTON:
+ {
+ // Es wird nur der gedrueckte Submit-Button ausgewertet
+ // MIB: Sofern ueberhaupt einer uebergeben wurde
+ if( rxSubmitButton.is() )
+ {
+ Reference<XPropertySet> xSubmitButtonComponent(rxSubmitButton->getModel(), UNO_QUERY);
+ if (xSubmitButtonComponent == xComponentSet && hasProperty(PROPERTY_LABEL, xComponentSet))
+ {
+ // <name>=<label>
+ ::rtl::OUString aLabel;
+ xComponentSet->getPropertyValue( PROPERTY_LABEL ) >>= aLabel;
+ rList.push_back( HtmlSuccessfulObj(aName, aLabel) );
+ }
+ }
+ } break;
+
+ // ImageButtons
+ case FormComponentType::IMAGEBUTTON:
+ {
+ // Es wird nur der gedrueckte Submit-Button ausgewertet
+ // MIB: Sofern ueberhaupt einer uebergeben wurde
+ if( rxSubmitButton.is() )
+ {
+ Reference<XPropertySet> xSubmitButtonComponent(rxSubmitButton->getModel(), UNO_QUERY);
+ if (xSubmitButtonComponent == xComponentSet)
+ {
+ // <name>.x=<pos.X>&<name>.y=<pos.Y>
+ ::rtl::OUString aLhs = aName;
+ ::rtl::OUString aRhs = ::rtl::OUString::valueOf( MouseEvt.X );
+
+ // nur wenn ein Name vorhanden ist, kann ein name.x
+ aLhs += aName.getLength() ? UniString::CreateFromAscii(".x") : UniString::CreateFromAscii("x");
+ rList.push_back( HtmlSuccessfulObj(aLhs, aRhs) );
+
+ aLhs = aName;
+ aRhs = ::rtl::OUString::valueOf( MouseEvt.Y );
+ aLhs += aName.getLength() ? UniString::CreateFromAscii(".y") : UniString::CreateFromAscii("y");
+ rList.push_back( HtmlSuccessfulObj(aLhs, aRhs) );
+
+ }
+ }
+ } break;
+
+ // CheckBoxen / RadioButtons
+ case FormComponentType::CHECKBOX:
+ case FormComponentType::RADIOBUTTON:
+ {
+ // <name>=<refValue>
+ if( !hasProperty(PROPERTY_STATE, xComponentSet) )
+ break;
+ sal_Int16 nChecked = 0;
+ xComponentSet->getPropertyValue( PROPERTY_STATE ) >>= nChecked;
+ if( nChecked != 1 )
+ break;
+
+ ::rtl::OUString aStrValue;
+ if( hasProperty(PROPERTY_REFVALUE, xComponentSet) )
+ xComponentSet->getPropertyValue( PROPERTY_REFVALUE ) >>= aStrValue;
+
+ rList.push_back( HtmlSuccessfulObj(aName, aStrValue) );
+ } break;
+
+ // Edit
+ case FormComponentType::TEXTFIELD:
+ {
+ // <name>=<text>
+ if( !hasProperty(PROPERTY_TEXT, xComponentSet) )
+ break;
+
+ // MIB: Spezial-Behandlung fuer Multiline-Edit nur dann, wenn
+ // es auch ein Control dazu gibt.
+ Any aTmp = xComponentSet->getPropertyValue( PROPERTY_MULTILINE );
+ sal_Bool bMulti = rxSubmitButton.is()
+ && (aTmp.getValueType().getTypeClass() == TypeClass_BOOLEAN)
+ && getBOOL(aTmp);
+ ::rtl::OUString sText;
+ if ( bMulti ) // Bei MultiLineEdit Text am Control abholen
+ {
+
+ Reference<XControlContainer> xControlContainer(rxSubmitButton->getContext(), UNO_QUERY);
+ if( !xControlContainer.is() ) break;
+
+ Sequence<Reference<XControl> > aControlSeq = xControlContainer->getControls();
+ Reference<XControl> xControl;
+ Reference<XFormComponent> xControlComponent;
+
+ // Richtiges Control suchen
+ sal_Int32 i;
+ for( i=0; i<aControlSeq.getLength(); i++ )
+ {
+ xControl = aControlSeq.getConstArray()[i];
+ Reference<XPropertySet> xModel(xControl->getModel(), UNO_QUERY);
+ if (xModel == xComponentSet)
+ {
+ Reference<XTextComponent> xTextComponent(xControl, UNO_QUERY);
+ if( xTextComponent.is() )
+ sText = xTextComponent->getText();
+ break;
+ }
+ }
+ // Control nicht gefunden oder nicht existent, (Edit im Grid)
+ if (i == aControlSeq.getLength())
+ xComponentSet->getPropertyValue( PROPERTY_TEXT ) >>= sText;
+ }
+ else
+ xComponentSet->getPropertyValue( PROPERTY_TEXT ) >>= sText;
+
+ rList.push_back( HtmlSuccessfulObj(aName, sText) );
+ } break;
+
+ // ComboBox, Patternfield
+ case FormComponentType::COMBOBOX:
+ case FormComponentType::PATTERNFIELD:
+ {
+ // <name>=<text>
+ if( hasProperty(PROPERTY_TEXT, xComponentSet) )
+ {
+ ::rtl::OUString aText;
+ xComponentSet->getPropertyValue( PROPERTY_TEXT ) >>= aText;
+ rList.push_back( HtmlSuccessfulObj(aName, aText) );
+ }
+ } break;
+ case FormComponentType::CURRENCYFIELD:
+ case FormComponentType::NUMERICFIELD:
+ {
+ // <name>=<wert> // wert wird als double mit Punkt als Decimaltrenner
+ // kein Wert angegeben (NULL) -> wert leer
+ if( hasProperty(PROPERTY_VALUE, xComponentSet) )
+ {
+ ::rtl::OUString aText;
+ Any aVal = xComponentSet->getPropertyValue( PROPERTY_VALUE );
+
+ double aDoubleVal = 0;
+ if (aVal >>= aDoubleVal)
+ {
+ sal_Int16 nScale = 0;
+ xComponentSet->getPropertyValue( PROPERTY_DECIMAL_ACCURACY ) >>= nScale;
+ aText = ::rtl::math::doubleToUString(aDoubleVal, rtl_math_StringFormat_F, nScale, '.', sal_True);
+ }
+ rList.push_back( HtmlSuccessfulObj(aName, aText) );
+ }
+ } break;
+ case FormComponentType::DATEFIELD:
+ {
+ // <name>=<wert> // Wert wird als Datum im Format (MM-DD-YYYY)
+ // kein Wert angegeben (NULL) -> wert leer
+ if( hasProperty(PROPERTY_DATE, xComponentSet) )
+ {
+ ::rtl::OUString aText;
+ Any aVal = xComponentSet->getPropertyValue( PROPERTY_DATE );
+ sal_Int32 nInt32Val = 0;
+ if (aVal >>= nInt32Val)
+ {
+ ::Date aDate( nInt32Val );
+ ::rtl::OUStringBuffer aBuffer;
+ appendDigits( aDate.GetMonth(), 2, aBuffer );
+ aBuffer.append( (sal_Unicode)'-' );
+ appendDigits( aDate.GetDay(), 2, aBuffer );
+ aBuffer.append( (sal_Unicode)'-' );
+ appendDigits( aDate.GetYear(), 4, aBuffer );
+ aText = aBuffer.makeStringAndClear();
+ }
+ rList.push_back( HtmlSuccessfulObj(aName, aText) );
+ }
+ } break;
+ case FormComponentType::TIMEFIELD:
+ {
+ // <name>=<wert> // Wert wird als Zeit im Format (HH:MM:SS) angegeben
+ // kein Wert angegeben (NULL) -> wert leer
+ if( hasProperty(PROPERTY_TIME, xComponentSet) )
+ {
+ ::rtl::OUString aText;
+ Any aVal = xComponentSet->getPropertyValue( PROPERTY_TIME );
+ sal_Int32 nInt32Val = 0;
+ if (aVal >>= nInt32Val)
+ {
+ ::Time aTime(nInt32Val);
+ ::rtl::OUStringBuffer aBuffer;
+ appendDigits( aTime.GetHour(), 2, aBuffer );
+ aBuffer.append( (sal_Unicode)'-' );
+ appendDigits( aTime.GetMin(), 2, aBuffer );
+ aBuffer.append( (sal_Unicode)'-' );
+ appendDigits( aTime.GetSec(), 2, aBuffer );
+ aText = aBuffer.makeStringAndClear();
+ }
+ rList.push_back( HtmlSuccessfulObj(aName, aText) );
+ }
+ } break;
+
+ // starform
+ case FormComponentType::HIDDENCONTROL:
+ {
+
+ // <name>=<value>
+ if( hasProperty(PROPERTY_HIDDEN_VALUE, xComponentSet) )
+ {
+ ::rtl::OUString aText;
+ xComponentSet->getPropertyValue( PROPERTY_HIDDEN_VALUE ) >>= aText;
+ rList.push_back( HtmlSuccessfulObj(aName, aText) );
+ }
+ } break;
+
+ // starform
+ case FormComponentType::FILECONTROL:
+ {
+ // <name>=<text>
+ if( hasProperty(PROPERTY_TEXT, xComponentSet) )
+ {
+
+ ::rtl::OUString aText;
+ xComponentSet->getPropertyValue( PROPERTY_TEXT ) >>= aText;
+ rList.push_back( HtmlSuccessfulObj(aName, aText, SUCCESSFUL_REPRESENT_FILE) );
+ }
+ } break;
+
+ // starform
+ case FormComponentType::LISTBOX:
+ {
+
+ // <name>=<Token0>&<name>=<Token1>&...&<name>=<TokenN> (Mehrfachselektion)
+ if (!hasProperty(PROPERTY_SELECT_SEQ, xComponentSet) ||
+ !hasProperty(PROPERTY_STRINGITEMLIST, xComponentSet))
+ break;
+
+ // angezeigte Werte
+ Sequence< ::rtl::OUString > aVisibleList;
+ xComponentSet->getPropertyValue( PROPERTY_STRINGITEMLIST ) >>= aVisibleList;
+ sal_Int32 nStringCnt = aVisibleList.getLength();
+ const ::rtl::OUString* pStrings = aVisibleList.getConstArray();
+
+ // Werte-Liste
+ Sequence< ::rtl::OUString > aValueList;
+ xComponentSet->getPropertyValue( PROPERTY_VALUE_SEQ ) >>= aValueList;
+ sal_Int32 nValCnt = aValueList.getLength();
+ const ::rtl::OUString* pVals = aValueList.getConstArray();
+
+ // Selektion
+ Sequence<sal_Int16> aSelectList;
+ xComponentSet->getPropertyValue( PROPERTY_SELECT_SEQ ) >>= aSelectList;
+ sal_Int32 nSelCount = aSelectList.getLength();
+ const sal_Int16* pSels = aSelectList.getConstArray();
+
+ // Einfach- oder Mehrfach-Selektion
+ // Bei Einfach-Selektionen beruecksichtigt MT nur den ersten Eintrag
+ // in der Liste.
+ if (nSelCount > 1 && !getBOOL(xComponentSet->getPropertyValue(PROPERTY_MULTISELECTION)))
+ nSelCount = 1;
+
+ // Die Indizes in der Selektions-Liste koennen auch ungueltig sein,
+ // also muss man die gueltigen erstmal raussuchen um die Laenge
+ // der neuen Liste zu bestimmen.
+ sal_Int32 nCurCnt = 0;
+ sal_Int32 i;
+ for( i=0; i<nSelCount; ++i )
+ {
+ if( pSels[i] < nStringCnt )
+ ++nCurCnt;
+ }
+
+ ::rtl::OUString aSubValue;
+ for(i=0; i<nCurCnt; ++i )
+ {
+ sal_Int16 nSelPos = pSels[i];
+ if (nSelPos < nValCnt && pVals[nSelPos].getLength())
+ {
+ aSubValue = pVals[nSelPos];
+ }
+ else
+ {
+ aSubValue = pStrings[nSelPos];
+ }
+ rList.push_back( HtmlSuccessfulObj(aName, aSubValue) );
+ }
+ } break;
+ case FormComponentType::GRIDCONTROL:
+ {
+ // Die einzelnen Spaltenwerte werden verschickt,
+ // der Name wird mit dem Prefix des Names des Grids erweitert
+ Reference<XIndexAccess> xContainer(xComponentSet, UNO_QUERY);
+ if (!xContainer.is())
+ break;
+
+ aName += UniString('.');
+
+ Reference<XPropertySet> xSet;
+ sal_Int32 nCount = xContainer->getCount();
+ // we know already how many objects should be appended,
+ // so why not allocate the space for them
+ rList.reserve( nCount + rList.capacity() ); // not size()
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ xContainer->getByIndex(i) >>= xSet;
+ if (xSet.is())
+ AppendComponent(rList, xSet, aName, rxSubmitButton, MouseEvt);
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+void ODatabaseForm::FillSuccessfulList( HtmlSuccessfulObjList& rList,
+ const Reference<XControl>& rxSubmitButton, const ::com::sun::star::awt::MouseEvent& MouseEvt )
+{
+ // Liste loeschen
+ rList.clear();
+ // Ueber Components iterieren
+ Reference<XPropertySet> xComponentSet;
+ ::rtl::OUString aPrefix;
+
+ // we know already how many objects should be appended,
+ // so why not allocate the space for them
+ rList.reserve( getCount() );
+ for( sal_Int32 nIndex=0; nIndex < getCount(); nIndex++ )
+ {
+ getByIndex( nIndex ) >>= xComponentSet;
+ AppendComponent(rList, xComponentSet, aPrefix, rxSubmitButton, MouseEvt);
+ }
+}
+
+//------------------------------------------------------------------------
+void ODatabaseForm::Encode( ::rtl::OUString& rString ) const
+{
+ ::rtl::OUString aResult;
+
+ // Immer ANSI #58641
+// rString.Convert(CHARSET_SYSTEM, CHARSET_ANSI);
+
+
+ // Zeilenendezeichen werden als CR dargestellt
+ UniString sConverter = rString;
+ sConverter.ConvertLineEnd( LINEEND_CR );
+ rString = sConverter;
+
+
+ // Jeden einzelnen Character ueberpruefen
+ sal_Int32 nStrLen = rString.getLength();
+ sal_Unicode nCharCode;
+ for( sal_Int32 nCurPos=0; nCurPos < nStrLen; ++nCurPos )
+ {
+ nCharCode = rString[nCurPos];
+
+ // Behandlung fuer chars, die kein alphanumerisches Zeichen sind
+ // und CharacterCodes > 127
+ if( (!isalnum(nCharCode) && nCharCode != (sal_Unicode)' ') || nCharCode > 127 )
+ {
+ switch( nCharCode )
+ {
+ case 13: // CR
+ aResult += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("%0D%0A") ); // Hex-Darstellung CR LF
+ break;
+
+
+ // Netscape Sonderbehandlung
+ case 42: // '*'
+ case 45: // '-'
+ case 46: // '.'
+ case 64: // '@'
+ case 95: // '_'
+ aResult += UniString(nCharCode);
+ break;
+
+ default:
+ {
+ // In Hex umrechnen
+ short nHi = ((sal_Int16)nCharCode) / 16;
+ short nLo = ((sal_Int16)nCharCode) - (nHi*16);
+ if( nHi > 9 ) nHi += (int)'A'-10; else nHi += (int)'0';
+ if( nLo > 9 ) nLo += (int)'A'-10; else nLo += (int)'0';
+ aResult += UniString('%');
+ aResult += UniString((sal_Unicode)nHi);
+ aResult += UniString((sal_Unicode)nLo);
+ }
+ }
+ }
+ else
+ aResult += UniString(nCharCode);
+ }
+
+
+ // Spaces durch '+' ersetzen
+ aResult = aResult.replace(' ', '+');
+
+ rString = aResult;
+}
+
+//------------------------------------------------------------------------
+void ODatabaseForm::InsertTextPart( INetMIMEMessage& rParent, const ::rtl::OUString& rName,
+ const ::rtl::OUString& rData )
+{
+
+ // Part als Message-Child erzeugen
+ INetMIMEMessage* pChild = new INetMIMEMessage();
+
+
+ // Header
+ ::rtl::OUString aContentDisp (RTL_CONSTASCII_USTRINGPARAM("form-data; name=\"") );
+ aContentDisp += rName;
+ aContentDisp += UniString('\"');
+ pChild->SetContentDisposition( aContentDisp );
+ pChild->SetContentType( UniString::CreateFromAscii("text/plain") );
+
+ rtl_TextEncoding eSystemEncoding = gsl_getSystemTextEncoding();
+ const sal_Char* pBestMatchingEncoding = rtl_getBestMimeCharsetFromTextEncoding( eSystemEncoding );
+ UniString aBestMatchingEncoding = UniString::CreateFromAscii( pBestMatchingEncoding );
+ pChild->SetContentTransferEncoding(aBestMatchingEncoding);
+
+ // Body
+ SvMemoryStream* pStream = new SvMemoryStream;
+ pStream->WriteLine( ByteString( UniString(rData), rtl_getTextEncodingFromMimeCharset(pBestMatchingEncoding) ) );
+ pStream->Flush();
+ pStream->Seek( 0 );
+ pChild->SetDocumentLB( new SvLockBytes(pStream, sal_True) );
+ rParent.AttachChild( *pChild );
+}
+
+//------------------------------------------------------------------------
+sal_Bool ODatabaseForm::InsertFilePart( INetMIMEMessage& rParent, const ::rtl::OUString& rName,
+ const ::rtl::OUString& rFileName )
+{
+ UniString aFileName( rFileName );
+ UniString aContentType(UniString::CreateFromAscii(CONTENT_TYPE_STR_TEXT_PLAIN));
+ SvStream *pStream = 0;
+
+ if( aFileName.Len() )
+ {
+ // Bisher koennen wir nur File-URLs verarbeiten
+ INetURLObject aURL;
+ aURL.SetSmartProtocol(INET_PROT_FILE);
+ aURL.SetSmartURL(rFileName);
+ if( INET_PROT_FILE == aURL.GetProtocol() )
+ {
+ aFileName = INetURLObject::decode(aURL.PathToFileName(), '%', INetURLObject::DECODE_UNAMBIGUOUS);
+ DirEntry aDirEntry( aFileName );
+ if( aDirEntry.Exists() )
+ {
+ pStream = ::utl::UcbStreamHelper::CreateStream(aFileName, STREAM_READ);
+ if (!pStream || (pStream->GetError() != ERRCODE_NONE))
+ {
+ delete pStream;
+ pStream = 0;
+ }
+ }
+ INetContentType eContentType = INetContentTypes::GetContentType4Extension(
+ aDirEntry.GetExtension() );
+ if (eContentType != CONTENT_TYPE_UNKNOWN)
+ aContentType = INetContentTypes::GetContentType(eContentType);
+ }
+ }
+
+ // Wenn irgendetwas nicht geklappt hat, legen wir einen leeren
+ // MemoryStream an
+ if( !pStream )
+ pStream = new SvMemoryStream;
+
+
+ // Part als Message-Child erzeugen
+ INetMIMEMessage* pChild = new INetMIMEMessage;
+
+
+ // Header
+ ::rtl::OUString aContentDisp (RTL_CONSTASCII_USTRINGPARAM( "form-data; name=\"") );
+ aContentDisp += rName;
+ aContentDisp += UniString('\"');
+ aContentDisp += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("; filename=\"") );
+ aContentDisp += aFileName;
+ aContentDisp += UniString('\"');
+ pChild->SetContentDisposition( aContentDisp );
+ pChild->SetContentType( aContentType );
+ pChild->SetContentTransferEncoding( UniString(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("8bit") ) ) );
+
+
+ // Body
+ pChild->SetDocumentLB( new SvLockBytes(pStream, sal_True) );
+ rParent.AttachChild( *pChild );
+
+ return sal_True;
+}
+
+//==============================================================================
+// internals
+//------------------------------------------------------------------------------
+void ODatabaseForm::onError( const SQLErrorEvent& _rEvent )
+{
+ m_aErrorListeners.notifyEach( &XSQLErrorListener::errorOccured, _rEvent );
+}
+
+//------------------------------------------------------------------------------
+void ODatabaseForm::onError( const SQLException& _rException, const ::rtl::OUString& _rContextDescription )
+{
+ if ( !m_aErrorListeners.getLength() )
+ return;
+
+ SQLErrorEvent aEvent( *this, makeAny( prependErrorInfo( _rException, *this, _rContextDescription ) ) );
+ onError( aEvent );
+}
+
+//------------------------------------------------------------------------------
+void ODatabaseForm::updateParameterInfo()
+{
+ m_aParameterManager.updateParameterInfo( m_aFilterManager );
+}
+
+//------------------------------------------------------------------------------
+bool ODatabaseForm::hasValidParent() const
+{
+ // do we have to fill the parameters again?
+ if (m_bSubForm)
+ {
+ Reference<XResultSet> xResultSet(m_xParent, UNO_QUERY);
+ if (!xResultSet.is())
+ {
+ OSL_FAIL("ODatabaseForm::hasValidParent() : no parent resultset !");
+ return false;
+ }
+ try
+ {
+ Reference< XPropertySet > xSet( m_xParent, UNO_QUERY );
+ Reference< XLoadable > xLoad( m_xParent, UNO_QUERY );
+ if ( xLoad->isLoaded()
+ && ( xResultSet->isBeforeFirst()
+ || xResultSet->isAfterLast()
+ || getBOOL( xSet->getPropertyValue( PROPERTY_ISNEW ) )
+ )
+ )
+ // the parent form is loaded and on a "virtual" row -> not valid
+ return false;
+ }
+ catch(Exception&)
+ {
+ // parent could be forwardonly?
+ return false;
+ }
+ }
+ return true;
+}
+
+//------------------------------------------------------------------------------
+bool ODatabaseForm::fillParameters( ::osl::ResettableMutexGuard& _rClearForNotifies, const Reference< XInteractionHandler >& _rxCompletionHandler )
+{
+ // do we have to fill the parameters again?
+ if ( !m_aParameterManager.isUpToDate() )
+ updateParameterInfo();
+
+ // is there a valid parent?
+ if ( m_bSubForm && !hasValidParent() )
+ return true;
+
+ // ensure we're connected
+ if ( !implEnsureConnection() )
+ return false;
+
+ if ( m_aParameterManager.isUpToDate() )
+ return m_aParameterManager.fillParameterValues( _rxCompletionHandler, _rClearForNotifies );
+
+ return true;
+}
+
+//------------------------------------------------------------------------------
+void ODatabaseForm::saveInsertOnlyState( )
+{
+ OSL_ENSURE( !m_aIgnoreResult.hasValue(), "ODatabaseForm::saveInsertOnlyState: overriding old value!" );
+ m_aIgnoreResult = m_xAggregateSet->getPropertyValue( PROPERTY_INSERTONLY );
+}
+
+//------------------------------------------------------------------------------
+void ODatabaseForm::restoreInsertOnlyState( )
+{
+ if ( m_aIgnoreResult.hasValue() )
+ {
+ m_xAggregateSet->setPropertyValue( PROPERTY_INSERTONLY, m_aIgnoreResult );
+ m_aIgnoreResult = Any();
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Bool ODatabaseForm::executeRowSet(::osl::ResettableMutexGuard& _rClearForNotifies, sal_Bool bMoveToFirst, const Reference< XInteractionHandler >& _rxCompletionHandler)
+{
+ if (!m_xAggregateAsRowSet.is())
+ return sal_False;
+
+ if (!fillParameters(_rClearForNotifies, _rxCompletionHandler))
+ return sal_False;
+
+ restoreInsertOnlyState( );
+
+ // ensure the aggregated row set has the correct properties
+ sal_Int32 nConcurrency = ResultSetConcurrency::READ_ONLY;
+
+ // if we have a parent, who is not positioned on a valid row
+ // we can't be updatable!
+ if (m_bSubForm && !hasValidParent())
+ {
+ nConcurrency = ResultSetConcurrency::READ_ONLY;
+
+ // don't use any parameters if we don't have a valid parent
+ m_aParameterManager.setAllParametersNull();
+
+ // switch to "insert only" mode
+ saveInsertOnlyState( );
+ m_xAggregateSet->setPropertyValue( PROPERTY_INSERTONLY, makeAny( sal_True ) );
+ }
+ else if (m_bAllowInsert || m_bAllowUpdate || m_bAllowDelete)
+ nConcurrency = ResultSetConcurrency::UPDATABLE;
+ else
+ nConcurrency = ResultSetConcurrency::READ_ONLY;
+
+ m_xAggregateSet->setPropertyValue( PROPERTY_RESULTSET_CONCURRENCY, makeAny( (sal_Int32)nConcurrency ) );
+ m_xAggregateSet->setPropertyValue( PROPERTY_RESULTSET_TYPE, makeAny( (sal_Int32)ResultSetType::SCROLL_SENSITIVE ) );
+
+ sal_Bool bSuccess = sal_False;
+ try
+ {
+ m_xAggregateAsRowSet->execute();
+ bSuccess = sal_True;
+ }
+ catch( const RowSetVetoException& eVeto )
+ {
+ (void)eVeto;
+ }
+ catch(SQLException& eDb)
+ {
+ _rClearForNotifies.clear();
+ if (m_sCurrentErrorContext.getLength())
+ onError(eDb, m_sCurrentErrorContext);
+ else
+ onError(eDb, FRM_RES_STRING(RID_STR_READERROR));
+ _rClearForNotifies.reset();
+
+ restoreInsertOnlyState( );
+ }
+
+ if (bSuccess)
+ {
+ // adjust the privilege property
+ // m_nPrivileges;
+ m_xAggregateSet->getPropertyValue(PROPERTY_PRIVILEGES) >>= m_nPrivileges;
+ if (!m_bAllowInsert)
+ m_nPrivileges &= ~Privilege::INSERT;
+ if (!m_bAllowUpdate)
+ m_nPrivileges &= ~Privilege::UPDATE;
+ if (!m_bAllowDelete)
+ m_nPrivileges &= ~Privilege::DELETE;
+
+ if (bMoveToFirst)
+ {
+ // the row set is positioned _before_ the first row (per definitionem), so move the set ...
+ try
+ {
+ // if we have an insert only rowset we move to the insert row
+ next();
+ if (((m_nPrivileges & Privilege::INSERT) == Privilege::INSERT)
+ && isAfterLast())
+ {
+ // move on the insert row of set
+ // resetting must be done later, after the load events have been posted
+ // see :moveToInsertRow and load , reload
+ Reference<XResultSetUpdate> xUpdate;
+ if (query_aggregation( m_xAggregate, xUpdate))
+ xUpdate->moveToInsertRow();
+ }
+ }
+ catch(SQLException& eDB)
+ {
+ _rClearForNotifies.clear();
+ if (m_sCurrentErrorContext.getLength())
+ onError(eDB, m_sCurrentErrorContext);
+ else
+ onError(eDB, FRM_RES_STRING(RID_STR_READERROR));
+ _rClearForNotifies.reset();
+ bSuccess = sal_False;
+ }
+ }
+ }
+ return bSuccess;
+}
+
+//------------------------------------------------------------------
+void ODatabaseForm::disposing()
+{
+ if (m_pAggregatePropertyMultiplexer)
+ m_pAggregatePropertyMultiplexer->dispose();
+
+ if (m_bLoaded)
+ unload();
+
+ // cancel the submit/reset-thread
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if (m_pThread)
+ {
+ m_pThread->release();
+ m_pThread = NULL;
+ }
+ }
+
+ EventObject aEvt(static_cast<XWeak*>(this));
+ m_aLoadListeners.disposeAndClear(aEvt);
+ m_aRowSetApproveListeners.disposeAndClear(aEvt);
+ m_aParameterManager.disposing( aEvt );
+ m_aResetListeners.disposing();
+ m_aSubmitListeners.disposeAndClear(aEvt);
+ m_aErrorListeners.disposeAndClear(aEvt);
+
+ m_aParameterManager.dispose(); // (to free any references it may have to me)
+ m_aFilterManager.dispose(); // (dito)
+
+ OFormComponents::disposing();
+ OPropertySetAggregationHelper::disposing();
+
+ // stop listening on the aggregate
+ if (m_xAggregateAsRowSet.is())
+ m_xAggregateAsRowSet->removeRowSetListener(this);
+
+ // dispose the active connection
+ Reference<XComponent> xAggregationComponent;
+ if (query_aggregation(m_xAggregate, xAggregationComponent))
+ xAggregationComponent->dispose();
+
+ m_aPropertyBagHelper.dispose();
+}
+
+//------------------------------------------------------------------------------
+Reference< XConnection > ODatabaseForm::getConnection()
+{
+ Reference< XConnection > xConn;
+ m_xAggregateSet->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ) >>= xConn;
+ return xConn;
+}
+
+//------------------------------------------------------------------------------
+::osl::Mutex& ODatabaseForm::getMutex()
+{
+ return m_aMutex;
+}
+
+//==============================================================================
+// property handling
+//------------------------------------------------------------------------------
+void ODatabaseForm::describeFixedAndAggregateProperties(
+ Sequence< Property >& _rProps,
+ Sequence< Property >& _rAggregateProps ) const
+{
+ BEGIN_DESCRIBE_AGGREGATION_PROPERTIES(22, m_xAggregateSet)
+ // we want to "override" the privileges, since we have additional "AllowInsert" etc. properties
+ RemoveProperty( _rAggregateProps, PROPERTY_PRIVILEGES );
+
+ // InsertOnly is also to be overridden, since we sometimes change it ourself
+ RemoveProperty( _rAggregateProps, PROPERTY_INSERTONLY );
+
+ // we remove and re-declare the DataSourceName property, 'cause we want it to be constrained, and the
+ // original property of our aggregate isn't
+ RemoveProperty( _rAggregateProps, PROPERTY_DATASOURCE );
+
+ // for connection sharing, we need to override the ActiveConnection property, too
+ RemoveProperty( _rAggregateProps, PROPERTY_ACTIVE_CONNECTION );
+
+ // the Filter property is also overwritten, since we have some implicit filters
+ // (e.g. the ones which result from linking master fields to detail fields
+ // via column names instead of parameters)
+ RemoveProperty( _rAggregateProps, PROPERTY_FILTER );
+ RemoveProperty( _rAggregateProps, PROPERTY_APPLYFILTER );
+
+ DECL_IFACE_PROP4(ACTIVE_CONNECTION, XConnection, BOUND, TRANSIENT, MAYBEVOID, CONSTRAINED);
+ DECL_BOOL_PROP2 ( APPLYFILTER, BOUND, MAYBEDEFAULT );
+ DECL_PROP1 ( NAME, ::rtl::OUString, BOUND );
+ DECL_PROP1 ( MASTERFIELDS, Sequence< ::rtl::OUString >, BOUND );
+ DECL_PROP1 ( DETAILFIELDS, Sequence< ::rtl::OUString >, BOUND );
+ DECL_PROP2 ( DATASOURCE, ::rtl::OUString, BOUND, CONSTRAINED );
+ DECL_PROP3 ( CYCLE, TabulatorCycle, BOUND, MAYBEVOID, MAYBEDEFAULT );
+ DECL_PROP2 ( FILTER, ::rtl::OUString, BOUND, MAYBEDEFAULT );
+ DECL_BOOL_PROP2 ( INSERTONLY, BOUND, MAYBEDEFAULT );
+ DECL_PROP1 ( NAVIGATION, NavigationBarMode, BOUND );
+ DECL_BOOL_PROP1 ( ALLOWADDITIONS, BOUND );
+ DECL_BOOL_PROP1 ( ALLOWEDITS, BOUND );
+ DECL_BOOL_PROP1 ( ALLOWDELETIONS, BOUND );
+ DECL_PROP2 ( PRIVILEGES, sal_Int32, TRANSIENT, READONLY );
+ DECL_PROP1 ( TARGET_URL, ::rtl::OUString, BOUND );
+ DECL_PROP1 ( TARGET_FRAME, ::rtl::OUString, BOUND );
+ DECL_PROP1 ( SUBMIT_METHOD, FormSubmitMethod, BOUND );
+ DECL_PROP1 ( SUBMIT_ENCODING, FormSubmitEncoding, BOUND );
+ DECL_BOOL_PROP3 ( DYNAMIC_CONTROL_BORDER, BOUND, MAYBEVOID, MAYBEDEFAULT );
+ DECL_PROP3 ( CONTROL_BORDER_COLOR_FOCUS, sal_Int32, BOUND, MAYBEVOID, MAYBEDEFAULT );
+ DECL_PROP3 ( CONTROL_BORDER_COLOR_MOUSE, sal_Int32, BOUND, MAYBEVOID, MAYBEDEFAULT );
+ DECL_PROP3 ( CONTROL_BORDER_COLOR_INVALID, sal_Int32, BOUND, MAYBEVOID, MAYBEDEFAULT );
+ END_DESCRIBE_PROPERTIES();
+}
+
+//------------------------------------------------------------------------------
+Reference< XMultiPropertySet > ODatabaseForm::getPropertiesInterface()
+{
+ return Reference< XMultiPropertySet >( *this, UNO_QUERY );
+}
+
+//------------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper& ODatabaseForm::getInfoHelper()
+{
+ return m_aPropertyBagHelper.getInfoHelper();
+}
+
+//------------------------------------------------------------------------------
+Reference< XPropertySetInfo > ODatabaseForm::getPropertySetInfo() throw( RuntimeException )
+{
+ return createPropertySetInfo( getInfoHelper() );
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::addProperty( const ::rtl::OUString& _rName, ::sal_Int16 _nAttributes, const Any& _rInitialValue ) throw (PropertyExistException, IllegalTypeException, IllegalArgumentException, RuntimeException)
+{
+ m_aPropertyBagHelper.addProperty( _rName, _nAttributes, _rInitialValue );
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::removeProperty( const ::rtl::OUString& _rName ) throw (UnknownPropertyException, NotRemoveableException, RuntimeException)
+{
+ m_aPropertyBagHelper.removeProperty( _rName );
+}
+
+//--------------------------------------------------------------------
+Sequence< PropertyValue > SAL_CALL ODatabaseForm::getPropertyValues() throw (RuntimeException)
+{
+ return m_aPropertyBagHelper.getPropertyValues();
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::setPropertyValues( const Sequence< PropertyValue >& _rProps ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
+{
+ m_aPropertyBagHelper.setPropertyValues( _rProps );
+}
+
+//------------------------------------------------------------------------------
+Any SAL_CALL ODatabaseForm::getWarnings( ) throw (SQLException, RuntimeException)
+{
+ return m_aWarnings.getWarnings();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::clearWarnings( ) throw (SQLException, RuntimeException)
+{
+ m_aWarnings.clearWarnings();
+}
+
+//------------------------------------------------------------------------------
+Reference< XCloneable > SAL_CALL ODatabaseForm::createClone( ) throw (RuntimeException)
+{
+ ODatabaseForm* pClone = new ODatabaseForm( *this );
+ osl_incrementInterlockedCount( &pClone->m_refCount );
+ pClone->clonedFrom( *this );
+ osl_decrementInterlockedCount( &pClone->m_refCount );
+ return pClone;
+}
+
+//------------------------------------------------------------------------------
+void ODatabaseForm::fire( sal_Int32* pnHandles, const Any* pNewValues, const Any* pOldValues, sal_Int32 nCount, sal_Bool bVetoable )
+{
+ // same as in getFastPropertyValue(sal_Int32) : if we're resetting currently don't fire any changes of the
+ // IsModified property from sal_False to sal_True, as this is only temporary 'til the reset is done
+ if (m_nResetsPending > 0)
+ {
+ // look for the PROPERTY_ID_ISMODIFIED
+ sal_Int32 nPos = 0;
+ for (nPos=0; nPos<nCount; ++nPos)
+ if (pnHandles[nPos] == PROPERTY_ID_ISMODIFIED)
+ break;
+
+ if ((nPos < nCount) && (pNewValues[nPos].getValueType().getTypeClass() == TypeClass_BOOLEAN) && getBOOL(pNewValues[nPos]))
+ { // yeah, we found it, and it changed to TRUE
+ if (nPos == 0)
+ { // just cut the first element
+ ++pnHandles;
+ ++pNewValues;
+ ++pOldValues;
+ --nCount;
+ }
+ else if (nPos == nCount - 1)
+ // just cut the last element
+ --nCount;
+ else
+ { // split into two base class calls
+ OPropertySetAggregationHelper::fire(pnHandles, pNewValues, pOldValues, nPos, bVetoable);
+ ++nPos;
+ OPropertySetAggregationHelper::fire(pnHandles + nPos, pNewValues + nPos, pOldValues + nPos, nCount - nPos, bVetoable);
+ return;
+ }
+ }
+ }
+
+ OPropertySetAggregationHelper::fire(pnHandles, pNewValues, pOldValues, nCount, bVetoable);
+}
+
+//------------------------------------------------------------------------------
+Any SAL_CALL ODatabaseForm::getFastPropertyValue( sal_Int32 nHandle )
+ throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+ if ((nHandle == PROPERTY_ID_ISMODIFIED) && (m_nResetsPending > 0))
+ return ::cppu::bool2any((sal_False));
+ // don't allow the aggregate which is currently being reset to return a (temporary) "yes"
+ else
+ return OPropertySetAggregationHelper::getFastPropertyValue(nHandle);
+}
+
+//------------------------------------------------------------------------------
+void ODatabaseForm::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
+{
+ switch (nHandle)
+ {
+ case PROPERTY_ID_INSERTONLY:
+ rValue <<= m_bInsertOnly;
+ break;
+
+ case PROPERTY_ID_FILTER:
+ rValue <<= m_aFilterManager.getFilterComponent( FilterManager::fcPublicFilter );
+ break;
+
+ case PROPERTY_ID_APPLYFILTER:
+ rValue <<= m_aFilterManager.isApplyPublicFilter();
+ break;
+
+ case PROPERTY_ID_DATASOURCE:
+ rValue = m_xAggregateSet->getPropertyValue( PROPERTY_DATASOURCE );
+ break;
+
+ case PROPERTY_ID_TARGET_URL:
+ rValue <<= m_aTargetURL;
+ break;
+ case PROPERTY_ID_TARGET_FRAME:
+ rValue <<= m_aTargetFrame;
+ break;
+ case PROPERTY_ID_SUBMIT_METHOD:
+ rValue <<= m_eSubmitMethod;
+ break;
+ case PROPERTY_ID_SUBMIT_ENCODING:
+ rValue <<= m_eSubmitEncoding;
+ break;
+ case PROPERTY_ID_NAME:
+ rValue <<= m_sName;
+ break;
+ case PROPERTY_ID_MASTERFIELDS:
+ rValue <<= m_aMasterFields;
+ break;
+ case PROPERTY_ID_DETAILFIELDS:
+ rValue <<= m_aDetailFields;
+ break;
+ case PROPERTY_ID_CYCLE:
+ rValue = m_aCycle;
+ break;
+ case PROPERTY_ID_NAVIGATION:
+ rValue <<= m_eNavigation;
+ break;
+ case PROPERTY_ID_ALLOWADDITIONS:
+ rValue <<= (sal_Bool)m_bAllowInsert;
+ break;
+ case PROPERTY_ID_ALLOWEDITS:
+ rValue <<= (sal_Bool)m_bAllowUpdate;
+ break;
+ case PROPERTY_ID_ALLOWDELETIONS:
+ rValue <<= (sal_Bool)m_bAllowDelete;
+ break;
+ case PROPERTY_ID_PRIVILEGES:
+ rValue <<= (sal_Int32)m_nPrivileges;
+ break;
+ case PROPERTY_ID_DYNAMIC_CONTROL_BORDER:
+ rValue = m_aDynamicControlBorder;
+ break;
+ case PROPERTY_ID_CONTROL_BORDER_COLOR_FOCUS:
+ rValue = m_aControlBorderColorFocus;
+ break;
+ case PROPERTY_ID_CONTROL_BORDER_COLOR_MOUSE:
+ rValue = m_aControlBorderColorMouse;
+ break;
+ case PROPERTY_ID_CONTROL_BORDER_COLOR_INVALID:
+ rValue = m_aControlBorderColorInvalid;
+ break;
+ default:
+ if ( m_aPropertyBagHelper.hasDynamicPropertyByHandle( nHandle ) )
+ m_aPropertyBagHelper.getDynamicFastPropertyValue( nHandle, rValue );
+ else
+ OPropertySetAggregationHelper::getFastPropertyValue( rValue, nHandle );
+ break;
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Bool ODatabaseForm::convertFastPropertyValue( Any& rConvertedValue, Any& rOldValue,
+ sal_Int32 nHandle, const Any& rValue ) throw( IllegalArgumentException )
+{
+ sal_Bool bModified(sal_False);
+ switch (nHandle)
+ {
+ case PROPERTY_ID_INSERTONLY:
+ bModified = tryPropertyValue( rConvertedValue, rOldValue, rValue, m_bInsertOnly );
+ break;
+
+ case PROPERTY_ID_FILTER:
+ bModified = tryPropertyValue( rConvertedValue, rOldValue, rValue, m_aFilterManager.getFilterComponent( FilterManager::fcPublicFilter ) );
+ break;
+
+ case PROPERTY_ID_APPLYFILTER:
+ bModified = tryPropertyValue( rConvertedValue, rOldValue, rValue, m_aFilterManager.isApplyPublicFilter() );
+ break;
+
+ case PROPERTY_ID_DATASOURCE:
+ {
+ Any aAggregateProperty;
+ getFastPropertyValue(aAggregateProperty, PROPERTY_ID_DATASOURCE);
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, aAggregateProperty, ::getCppuType(static_cast<const ::rtl::OUString*>(NULL)));
+ }
+ break;
+ case PROPERTY_ID_TARGET_URL:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aTargetURL);
+ break;
+ case PROPERTY_ID_TARGET_FRAME:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aTargetFrame);
+ break;
+ case PROPERTY_ID_SUBMIT_METHOD:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_eSubmitMethod);
+ break;
+ case PROPERTY_ID_SUBMIT_ENCODING:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_eSubmitEncoding);
+ break;
+ case PROPERTY_ID_NAME:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_sName);
+ break;
+ case PROPERTY_ID_MASTERFIELDS:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aMasterFields);
+ break;
+ case PROPERTY_ID_DETAILFIELDS:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aDetailFields);
+ break;
+ case PROPERTY_ID_CYCLE:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aCycle, ::getCppuType(static_cast<const TabulatorCycle*>(NULL)));
+ break;
+ case PROPERTY_ID_NAVIGATION:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_eNavigation);
+ break;
+ case PROPERTY_ID_ALLOWADDITIONS:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bAllowInsert);
+ break;
+ case PROPERTY_ID_ALLOWEDITS:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bAllowUpdate);
+ break;
+ case PROPERTY_ID_ALLOWDELETIONS:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bAllowDelete);
+ break;
+ case PROPERTY_ID_DYNAMIC_CONTROL_BORDER:
+ bModified = tryPropertyValue( rConvertedValue, rOldValue, rValue, m_aDynamicControlBorder, ::getBooleanCppuType() );
+ break;
+ case PROPERTY_ID_CONTROL_BORDER_COLOR_FOCUS:
+ bModified = tryPropertyValue( rConvertedValue, rOldValue, rValue, m_aControlBorderColorFocus, getCppuType( static_cast< sal_Int32* >( NULL ) ) );
+ break;
+ case PROPERTY_ID_CONTROL_BORDER_COLOR_MOUSE:
+ bModified = tryPropertyValue( rConvertedValue, rOldValue, rValue, m_aControlBorderColorMouse, getCppuType( static_cast< sal_Int32* >( NULL ) ) );
+ break;
+ case PROPERTY_ID_CONTROL_BORDER_COLOR_INVALID:
+ bModified = tryPropertyValue( rConvertedValue, rOldValue, rValue, m_aControlBorderColorInvalid, getCppuType( static_cast< sal_Int32* >( NULL ) ) );
+ break;
+ default:
+ if ( m_aPropertyBagHelper.hasDynamicPropertyByHandle ( nHandle ) )
+ bModified = m_aPropertyBagHelper.convertDynamicFastPropertyValue( nHandle, rValue, rConvertedValue, rOldValue );
+ else
+ bModified = OPropertySetAggregationHelper::convertFastPropertyValue( rConvertedValue, rOldValue, nHandle, rValue );
+ break;
+ }
+ return bModified;
+}
+
+//------------------------------------------------------------------------------
+void ODatabaseForm::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw( Exception )
+{
+ switch (nHandle)
+ {
+ case PROPERTY_ID_INSERTONLY:
+ rValue >>= m_bInsertOnly;
+ if ( m_aIgnoreResult.hasValue() )
+ m_aIgnoreResult <<= m_bInsertOnly;
+ else
+ m_xAggregateSet->setPropertyValue( PROPERTY_INSERTONLY, makeAny( m_bInsertOnly ) );
+ break;
+
+ case PROPERTY_ID_FILTER:
+ {
+ ::rtl::OUString sNewFilter;
+ rValue >>= sNewFilter;
+ m_aFilterManager.setFilterComponent( FilterManager::fcPublicFilter, sNewFilter );
+ }
+ break;
+
+ case PROPERTY_ID_APPLYFILTER:
+ {
+ sal_Bool bApply = sal_True;
+ rValue >>= bApply;
+ m_aFilterManager.setApplyPublicFilter( bApply );
+ }
+ break;
+
+ case PROPERTY_ID_DATASOURCE:
+ {
+ Reference< XConnection > xSomeConnection;
+ if ( ::dbtools::isEmbeddedInDatabase( getParent(), xSomeConnection ) )
+ throw PropertyVetoException();
+
+ try
+ {
+ m_xAggregateSet->setPropertyValue(PROPERTY_DATASOURCE, rValue);
+ }
+ catch(Exception&) { }
+ }
+ break;
+ case PROPERTY_ID_TARGET_URL:
+ rValue >>= m_aTargetURL;
+ break;
+ case PROPERTY_ID_TARGET_FRAME:
+ rValue >>= m_aTargetFrame;
+ break;
+ case PROPERTY_ID_SUBMIT_METHOD:
+ rValue >>= m_eSubmitMethod;
+ break;
+ case PROPERTY_ID_SUBMIT_ENCODING:
+ rValue >>= m_eSubmitEncoding;
+ break;
+ case PROPERTY_ID_NAME:
+ rValue >>= m_sName;
+ break;
+ case PROPERTY_ID_MASTERFIELDS:
+ rValue >>= m_aMasterFields;
+ invlidateParameters();
+ break;
+ case PROPERTY_ID_DETAILFIELDS:
+ rValue >>= m_aDetailFields;
+ invlidateParameters();
+ break;
+ case PROPERTY_ID_CYCLE:
+ m_aCycle = rValue;
+ break;
+ case PROPERTY_ID_NAVIGATION:
+ rValue >>= m_eNavigation;
+ break;
+ case PROPERTY_ID_ALLOWADDITIONS:
+ m_bAllowInsert = getBOOL(rValue);
+ break;
+ case PROPERTY_ID_ALLOWEDITS:
+ m_bAllowUpdate = getBOOL(rValue);
+ break;
+ case PROPERTY_ID_ALLOWDELETIONS:
+ m_bAllowDelete = getBOOL(rValue);
+ break;
+ case PROPERTY_ID_DYNAMIC_CONTROL_BORDER:
+ m_aDynamicControlBorder = rValue;
+ break;
+ case PROPERTY_ID_CONTROL_BORDER_COLOR_FOCUS:
+ m_aControlBorderColorFocus = rValue;
+ break;
+ case PROPERTY_ID_CONTROL_BORDER_COLOR_MOUSE:
+ m_aControlBorderColorMouse = rValue;
+ break;
+ case PROPERTY_ID_CONTROL_BORDER_COLOR_INVALID:
+ m_aControlBorderColorInvalid = rValue;
+ break;
+
+ case PROPERTY_ID_ACTIVE_CONNECTION:
+ {
+ Reference< XConnection > xOuterConnection;
+ if ( ::dbtools::isEmbeddedInDatabase( getParent(), xOuterConnection ) )
+ {
+ if ( xOuterConnection != Reference< XConnection >( rValue, UNO_QUERY ) )
+ // somebody's trying to set a connection which is not equal the connection
+ // implied by the database we're embedded in
+ throw PropertyVetoException();
+ }
+ OPropertySetAggregationHelper::setFastPropertyValue_NoBroadcast( nHandle, rValue );
+ break;
+ }
+
+ default:
+ if ( m_aPropertyBagHelper.hasDynamicPropertyByHandle( nHandle ) )
+ m_aPropertyBagHelper.setDynamicFastPropertyValue( nHandle, rValue );
+ else
+ OPropertySetAggregationHelper::setFastPropertyValue_NoBroadcast( nHandle, rValue );
+ break;
+ }
+}
+
+//------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::forwardingPropertyValue( sal_Int32 _nHandle )
+{
+ OSL_ENSURE( _nHandle == PROPERTY_ID_ACTIVE_CONNECTION, "ODatabaseForm::forwardingPropertyValue: unexpected property!" );
+ if ( _nHandle == PROPERTY_ID_ACTIVE_CONNECTION )
+ {
+ if ( m_bSharingConnection )
+ stopSharingConnection( );
+ m_bForwardingConnection = sal_True;
+ }
+}
+
+//------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::forwardedPropertyValue( sal_Int32 _nHandle, bool /*_bSuccess*/ )
+{
+ OSL_ENSURE( _nHandle == PROPERTY_ID_ACTIVE_CONNECTION, "ODatabaseForm::forwardedPropertyValue: unexpected property!" );
+ if ( _nHandle == PROPERTY_ID_ACTIVE_CONNECTION )
+ {
+ m_bForwardingConnection = sal_False;
+ }
+}
+
+//==============================================================================
+// com::sun::star::beans::XPropertyState
+//------------------------------------------------------------------
+PropertyState ODatabaseForm::getPropertyStateByHandle(sal_Int32 nHandle)
+{
+ PropertyState eState;
+ switch (nHandle)
+ {
+ case PROPERTY_ID_NAVIGATION:
+ return (NavigationBarMode_CURRENT == m_eNavigation) ? PropertyState_DEFAULT_VALUE : PropertyState_DIRECT_VALUE;
+
+ case PROPERTY_ID_CYCLE:
+ eState = m_aCycle.hasValue() ? PropertyState_DIRECT_VALUE : PropertyState_DEFAULT_VALUE;
+ break;
+
+ case PROPERTY_ID_INSERTONLY:
+ eState = m_bInsertOnly ? PropertyState_DIRECT_VALUE : PropertyState_DEFAULT_VALUE;
+ break;
+
+ case PROPERTY_ID_FILTER:
+ if ( !m_aFilterManager.getFilterComponent( FilterManager::fcPublicFilter ).getLength() )
+ eState = PropertyState_DEFAULT_VALUE;
+ else
+ eState = PropertyState_DIRECT_VALUE;
+ break;
+
+ case PROPERTY_ID_APPLYFILTER:
+ eState = m_aFilterManager.isApplyPublicFilter() ? PropertyState_DEFAULT_VALUE : PropertyState_DIRECT_VALUE;
+ break;
+
+ case PROPERTY_ID_DYNAMIC_CONTROL_BORDER:
+ eState = m_aDynamicControlBorder.hasValue() ? PropertyState_DIRECT_VALUE : PropertyState_DEFAULT_VALUE;
+ break;
+
+ case PROPERTY_ID_CONTROL_BORDER_COLOR_FOCUS:
+ eState = m_aControlBorderColorFocus.hasValue() ? PropertyState_DIRECT_VALUE : PropertyState_DEFAULT_VALUE;
+ break;
+
+ case PROPERTY_ID_CONTROL_BORDER_COLOR_MOUSE:
+ eState = m_aControlBorderColorMouse.hasValue() ? PropertyState_DIRECT_VALUE : PropertyState_DEFAULT_VALUE;
+ break;
+
+ case PROPERTY_ID_CONTROL_BORDER_COLOR_INVALID:
+ eState = m_aControlBorderColorInvalid.hasValue() ? PropertyState_DIRECT_VALUE : PropertyState_DEFAULT_VALUE;
+ break;
+
+ default:
+ eState = OPropertySetAggregationHelper::getPropertyStateByHandle(nHandle);
+ }
+ return eState;
+}
+
+//------------------------------------------------------------------
+void ODatabaseForm::setPropertyToDefaultByHandle(sal_Int32 nHandle)
+{
+ switch (nHandle)
+ {
+ case PROPERTY_ID_INSERTONLY:
+ case PROPERTY_ID_FILTER:
+ case PROPERTY_ID_APPLYFILTER:
+ case PROPERTY_ID_NAVIGATION:
+ case PROPERTY_ID_CYCLE:
+ case PROPERTY_ID_DYNAMIC_CONTROL_BORDER:
+ case PROPERTY_ID_CONTROL_BORDER_COLOR_FOCUS:
+ case PROPERTY_ID_CONTROL_BORDER_COLOR_MOUSE:
+ case PROPERTY_ID_CONTROL_BORDER_COLOR_INVALID:
+ setFastPropertyValue( nHandle, getPropertyDefaultByHandle( nHandle ) );
+ break;
+
+ default:
+ OPropertySetAggregationHelper::setPropertyToDefaultByHandle(nHandle);
+ }
+}
+
+//------------------------------------------------------------------
+Any ODatabaseForm::getPropertyDefaultByHandle( sal_Int32 nHandle ) const
+{
+ Any aReturn;
+ switch (nHandle)
+ {
+ case PROPERTY_ID_INSERTONLY:
+ case PROPERTY_ID_DYNAMIC_CONTROL_BORDER:
+ aReturn <<= sal_False;
+ break;
+
+ case PROPERTY_ID_FILTER:
+ aReturn <<= ::rtl::OUString();
+ break;
+
+ case PROPERTY_ID_APPLYFILTER:
+ aReturn <<= sal_True;
+ break;
+
+ case PROPERTY_ID_NAVIGATION:
+ aReturn = makeAny(NavigationBarMode_CURRENT);
+ break;
+
+ case PROPERTY_ID_CYCLE:
+ case PROPERTY_ID_CONTROL_BORDER_COLOR_FOCUS:
+ case PROPERTY_ID_CONTROL_BORDER_COLOR_MOUSE:
+ case PROPERTY_ID_CONTROL_BORDER_COLOR_INVALID:
+ break;
+
+ default:
+ if ( m_aPropertyBagHelper.hasDynamicPropertyByHandle( nHandle ) )
+ m_aPropertyBagHelper.getDynamicPropertyDefaultByHandle( nHandle, aReturn );
+ else
+ aReturn = OPropertySetAggregationHelper::getPropertyDefaultByHandle( nHandle );
+ break;
+ }
+ return aReturn;
+}
+
+//==============================================================================
+// com::sun::star::form::XReset
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::reset() throw( RuntimeException )
+{
+ ::osl::ResettableMutexGuard aGuard(m_aMutex);
+
+ if (isLoaded())
+ {
+ ::osl::MutexGuard aResetGuard(m_aResetSafety);
+ ++m_nResetsPending;
+ reset_impl(true);
+ return;
+ }
+
+ if ( !m_aResetListeners.empty() )
+ {
+ ::osl::MutexGuard aResetGuard(m_aResetSafety);
+ ++m_nResetsPending;
+ // create an own thread if we have (approve-)reset-listeners (so the listeners can't do that much damage
+ // to this thread which is probably the main one)
+ if (!m_pThread)
+ {
+ m_pThread = new OFormSubmitResetThread(this);
+ m_pThread->acquire();
+ m_pThread->create();
+ }
+ EventObject aEvt;
+ m_pThread->addEvent(&aEvt, sal_False);
+ }
+ else
+ {
+ // direct call without any approving by the listeners
+ aGuard.clear();
+
+ ::osl::MutexGuard aResetGuard(m_aResetSafety);
+ ++m_nResetsPending;
+ reset_impl(false);
+ }
+}
+
+//-----------------------------------------------------------------------------
+void ODatabaseForm::reset_impl(bool _bAproveByListeners)
+{
+ if ( _bAproveByListeners )
+ if ( !m_aResetListeners.approveReset() )
+ return;
+
+ ::osl::ResettableMutexGuard aResetGuard(m_aResetSafety);
+ // do we have a database connected form and stay on the insert row
+ sal_Bool bInsertRow = sal_False;
+ if (m_xAggregateSet.is())
+ bInsertRow = getBOOL(m_xAggregateSet->getPropertyValue(PROPERTY_ISNEW));
+ if (bInsertRow)
+ {
+ try
+ {
+ // Iterate through all columns and set the default value
+ Reference< XColumnsSupplier > xColsSuppl( m_xAggregateSet, UNO_QUERY );
+ Reference< XIndexAccess > xIndexCols( xColsSuppl->getColumns(), UNO_QUERY );
+ for (sal_Int32 i = 0; i < xIndexCols->getCount(); ++i)
+ {
+ Reference< XPropertySet > xColProps;
+ xIndexCols->getByIndex(i) >>= xColProps;
+
+ Reference< XColumnUpdate > xColUpdate( xColProps, UNO_QUERY );
+ if ( !xColUpdate.is() )
+ continue;
+
+ Reference< XPropertySetInfo > xPSI;
+ if ( xColProps.is() )
+ xPSI = xColProps->getPropertySetInfo( );
+
+ static const ::rtl::OUString PROPERTY_CONTROLDEFAULT( RTL_CONSTASCII_USTRINGPARAM( "ControlDefault" ) );
+ if ( xPSI.is() && xPSI->hasPropertyByName( PROPERTY_CONTROLDEFAULT ) )
+ {
+ Any aDefault = xColProps->getPropertyValue( PROPERTY_CONTROLDEFAULT );
+
+ sal_Bool bReadOnly = sal_False;
+ if ( xPSI->hasPropertyByName( PROPERTY_ISREADONLY ) )
+ xColProps->getPropertyValue( PROPERTY_ISREADONLY ) >>= bReadOnly;
+
+ if ( !bReadOnly )
+ {
+ try
+ {
+ if ( aDefault.hasValue() )
+ xColUpdate->updateObject( aDefault );
+ }
+ catch(Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+ }
+ }
+ }
+ catch(Exception&)
+ {
+ }
+
+ if (m_bSubForm)
+ {
+ Reference< XColumnsSupplier > xParentColSupp( m_xParent, UNO_QUERY );
+ Reference< XNameAccess > xParentCols;
+ if ( xParentColSupp.is() )
+ xParentCols = xParentColSupp->getColumns();
+
+ if ( xParentCols.is() && xParentCols->hasElements() && m_aMasterFields.getLength() )
+ {
+ try
+ {
+ // analyze our parameters
+ if ( !m_aParameterManager.isUpToDate() )
+ updateParameterInfo();
+
+ m_aParameterManager.resetParameterValues( );
+ }
+ catch(const Exception&)
+ {
+ OSL_FAIL("ODatabaseForm::reset_impl: could not initialize the master-detail-driven parameters!");
+ }
+ }
+ }
+ }
+
+ aResetGuard.clear();
+ // iterate through all components. don't use an XIndexAccess as this will cause massive
+ // problems with the count.
+ Reference<XEnumeration> xIter = createEnumeration();
+ while (xIter->hasMoreElements())
+ {
+ Reference<XReset> xReset;
+ xIter->nextElement() >>= xReset;
+ if (xReset.is())
+ {
+ // TODO : all reset-methods have to be thread-safe
+ xReset->reset();
+ }
+ }
+
+ aResetGuard.reset();
+ // ensure that the row isn't modified
+ // (do this _before_ the listeners are notified ! their reaction (maybe asynchronous) may depend
+ // on the modified state of the row)
+ if (bInsertRow)
+ m_xAggregateSet->setPropertyValue(PROPERTY_ISMODIFIED, ::cppu::bool2any(sal_Bool(sal_False)));
+
+ aResetGuard.clear();
+ {
+ m_aResetListeners.resetted();
+ }
+
+ aResetGuard.reset();
+ // and again : ensure the row isn't modified
+ // we already did this after we (and maybe our dependents) resetted the values, but the listeners may have changed the row, too
+ if (bInsertRow)
+ m_xAggregateSet->setPropertyValue(PROPERTY_ISMODIFIED, ::cppu::bool2any((sal_False)));
+
+ --m_nResetsPending;
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::addResetListener(const Reference<XResetListener>& _rListener) throw( RuntimeException )
+{
+ m_aResetListeners.addTypedListener( _rListener );
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::removeResetListener(const Reference<XResetListener>& _rListener) throw( RuntimeException )
+{
+ m_aResetListeners.removeTypedListener( _rListener );
+}
+
+//==============================================================================
+// com::sun::star::form::XSubmit
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::submit( const Reference<XControl>& Control,
+ const ::com::sun::star::awt::MouseEvent& MouseEvt ) throw( RuntimeException )
+{
+ {
+ ::osl::MutexGuard aGuard(m_aMutex);
+ // Sind Controls und eine Submit-URL vorhanden?
+ if( !getCount() || !m_aTargetURL.getLength() )
+ return;
+ }
+
+ ::osl::ClearableMutexGuard aGuard(m_aMutex);
+ if (m_aSubmitListeners.getLength())
+ {
+ // create an own thread if we have (approve-)submit-listeners (so the listeners can't do that much damage
+ // to this thread which is probably the main one)
+ if (!m_pThread)
+ {
+ m_pThread = new OFormSubmitResetThread(this);
+ m_pThread->acquire();
+ m_pThread->create();
+ }
+ m_pThread->addEvent(&MouseEvt, Control, sal_True);
+ }
+ else
+ {
+ // direct call without any approving by the listeners
+ aGuard.clear();
+ submit_impl( Control, MouseEvt, true );
+ }
+}
+// -----------------------------------------------------------------------------
+void lcl_dispatch(const Reference< XFrame >& xFrame,const Reference<XURLTransformer>& xTransformer,const ::rtl::OUString& aURLStr,const ::rtl::OUString& aReferer,const ::rtl::OUString& aTargetName
+ ,const ::rtl::OUString& aData,rtl_TextEncoding _eEncoding)
+{
+ URL aURL;
+ aURL.Complete = aURLStr;
+ xTransformer->parseStrict(aURL);
+
+ Reference< XDispatch > xDisp = Reference< XDispatchProvider > (xFrame,UNO_QUERY)->queryDispatch(aURL, aTargetName,
+ FrameSearchFlag::SELF | FrameSearchFlag::PARENT | FrameSearchFlag::CHILDREN |
+ FrameSearchFlag::SIBLINGS | FrameSearchFlag::CREATE | FrameSearchFlag::TASKS);
+
+ if (xDisp.is())
+ {
+ Sequence<PropertyValue> aArgs(2);
+ aArgs.getArray()[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Referer") );
+ aArgs.getArray()[0].Value <<= aReferer;
+
+ // build a sequence from the to-be-submitted string
+ ByteString a8BitData(aData.getStr(), (sal_uInt16)aData.getLength(), _eEncoding);
+ // always ANSI #58641
+ Sequence< sal_Int8 > aPostData((sal_Int8*)a8BitData.GetBuffer(), a8BitData.Len());
+ Reference< XInputStream > xPostData = new SequenceInputStream(aPostData);
+
+ aArgs.getArray()[1].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PostData") );
+ aArgs.getArray()[1].Value <<= xPostData;
+
+ xDisp->dispatch(aURL, aArgs);
+ } // if (xDisp.is())
+}
+//------------------------------------------------------------------------------
+void ODatabaseForm::submit_impl(const Reference<XControl>& Control, const ::com::sun::star::awt::MouseEvent& MouseEvt, bool _bAproveByListeners)
+{
+
+ if (_bAproveByListeners)
+ {
+ ::cppu::OInterfaceIteratorHelper aIter(m_aSubmitListeners);
+ EventObject aEvt(static_cast<XWeak*>(this));
+ sal_Bool bCanceled = sal_False;
+ while (aIter.hasMoreElements() && !bCanceled)
+ {
+ if (!((XSubmitListener*)aIter.next())->approveSubmit(aEvt))
+ bCanceled = sal_True;
+ }
+
+ if (bCanceled)
+ return;
+ }
+
+ FormSubmitEncoding eSubmitEncoding;
+ FormSubmitMethod eSubmitMethod;
+ ::rtl::OUString aURLStr;
+ ::rtl::OUString aReferer;
+ ::rtl::OUString aTargetName;
+ Reference< XModel > xModel;
+ {
+ SolarMutexGuard aGuard;
+ // starform->Forms
+
+ Reference<XChild> xParent(m_xParent, UNO_QUERY);
+
+ if (xParent.is())
+ xModel = getXModel(xParent->getParent());
+
+ if (xModel.is())
+ aReferer = xModel->getURL();
+
+ // TargetItem
+ aTargetName = m_aTargetFrame;
+
+ eSubmitEncoding = m_eSubmitEncoding;
+ eSubmitMethod = m_eSubmitMethod;
+ aURLStr = m_aTargetURL;
+ }
+
+ if (!xModel.is())
+ return;
+ Reference< XFrame > xFrame = xModel->getCurrentController()->getFrame();
+ if (!xFrame.is())
+ return;
+
+ Reference<XURLTransformer>
+ xTransformer(m_xServiceFactory->createInstance(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer") ) ), UNO_QUERY);
+ DBG_ASSERT(xTransformer.is(), "ODatabaseForm::submit_impl : could not create an URL transformer !");
+
+ // URL-Encoding
+ if( eSubmitEncoding == FormSubmitEncoding_URL )
+ {
+ ::rtl::OUString aData;
+ {
+ SolarMutexGuard aGuard;
+ aData = GetDataURLEncoded( Control, MouseEvt );
+ }
+
+ URL aURL;
+ // FormMethod GET
+ if( eSubmitMethod == FormSubmitMethod_GET )
+ {
+ INetURLObject aUrlObj( aURLStr, INetURLObject::WAS_ENCODED );
+ aUrlObj.SetParam( aData, INetURLObject::ENCODE_ALL );
+ aURL.Complete = aUrlObj.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS );
+ if (xTransformer.is())
+ xTransformer->parseStrict(aURL);
+
+ Reference< XDispatch > xDisp = Reference< XDispatchProvider > (xFrame,UNO_QUERY)->queryDispatch(aURL, aTargetName,
+ FrameSearchFlag::SELF | FrameSearchFlag::PARENT | FrameSearchFlag::CHILDREN |
+ FrameSearchFlag::SIBLINGS | FrameSearchFlag::CREATE | FrameSearchFlag::TASKS);
+
+ if (xDisp.is())
+ {
+ Sequence<PropertyValue> aArgs(1);
+ aArgs.getArray()->Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Referer") );
+ aArgs.getArray()->Value <<= aReferer;
+ xDisp->dispatch(aURL, aArgs);
+ }
+ }
+ // FormMethod POST
+ else if( eSubmitMethod == FormSubmitMethod_POST )
+ {
+ lcl_dispatch(xFrame,xTransformer,aURLStr,aReferer,aTargetName,aData,RTL_TEXTENCODING_MS_1252);
+ }
+ }
+ else if( eSubmitEncoding == FormSubmitEncoding_MULTIPART )
+ {
+ URL aURL;
+ aURL.Complete = aURLStr;
+ xTransformer->parseStrict(aURL);
+
+ Reference< XDispatch > xDisp = Reference< XDispatchProvider > (xFrame,UNO_QUERY)->queryDispatch(aURL, aTargetName,
+ FrameSearchFlag::SELF | FrameSearchFlag::PARENT | FrameSearchFlag::CHILDREN |
+ FrameSearchFlag::SIBLINGS | FrameSearchFlag::CREATE | FrameSearchFlag::TASKS);
+
+ if (xDisp.is())
+ {
+ ::rtl::OUString aContentType;
+ Sequence<sal_Int8> aData;
+ {
+ SolarMutexGuard aGuard;
+ aData = GetDataMultiPartEncoded(Control, MouseEvt, aContentType);
+ }
+ if (!aData.getLength())
+ return;
+
+ Sequence<PropertyValue> aArgs(3);
+ aArgs.getArray()[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Referer") );
+ aArgs.getArray()[0].Value <<= aReferer;
+ aArgs.getArray()[1].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ContentType") );
+ aArgs.getArray()[1].Value <<= aContentType;
+
+ // build a sequence from the to-be-submitted string
+ Reference< XInputStream > xPostData = new SequenceInputStream(aData);
+
+ aArgs.getArray()[2].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PostData") );
+ aArgs.getArray()[2].Value <<= xPostData;
+
+ xDisp->dispatch(aURL, aArgs);
+ }
+ }
+ else if( eSubmitEncoding == FormSubmitEncoding_TEXT )
+ {
+ ::rtl::OUString aData;
+ {
+ SolarMutexGuard aGuard;
+ aData = GetDataTextEncoded( Reference<XControl> (), MouseEvt );
+ }
+
+ lcl_dispatch(xFrame,xTransformer,aURLStr,aReferer,aTargetName,aData,osl_getThreadTextEncoding());
+ }
+ else {
+ OSL_FAIL("ODatabaseForm::submit_Impl : wrong encoding !");
+ }
+
+}
+
+// XSubmit
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::addSubmitListener(const Reference<XSubmitListener>& _rListener) throw( RuntimeException )
+{
+ m_aSubmitListeners.addInterface(_rListener);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::removeSubmitListener(const Reference<XSubmitListener>& _rListener) throw( RuntimeException )
+{
+ m_aSubmitListeners.removeInterface(_rListener);
+}
+
+//==============================================================================
+// com::sun::star::sdbc::XSQLErrorBroadcaster
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::addSQLErrorListener(const Reference<XSQLErrorListener>& _rListener) throw( RuntimeException )
+{
+ m_aErrorListeners.addInterface(_rListener);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::removeSQLErrorListener(const Reference<XSQLErrorListener>& _rListener) throw( RuntimeException )
+{
+ m_aErrorListeners.removeInterface(_rListener);
+}
+
+//------------------------------------------------------------------------------
+void ODatabaseForm::invlidateParameters()
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+ m_aParameterManager.clearAllParameterInformation();
+}
+
+//==============================================================================
+// OChangeListener
+//------------------------------------------------------------------------------
+void ODatabaseForm::_propertyChanged(const PropertyChangeEvent& evt) throw( RuntimeException )
+{
+ if ((0 == evt.PropertyName.compareToAscii(PROPERTY_ACTIVE_CONNECTION)) && !m_bForwardingConnection)
+ {
+ // the rowset changed its active connection itself (without interaction from our side), so
+ // we need to fire this event, too
+ sal_Int32 nHandle = PROPERTY_ID_ACTIVE_CONNECTION;
+ fire(&nHandle, &evt.NewValue, &evt.OldValue, 1, sal_False);
+ }
+ else // it was one of the statement relevant props
+ {
+ // if the statement has changed we have to delete the parameter info
+ invlidateParameters();
+ }
+}
+
+//==============================================================================
+// smartXChild
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::setParent(const InterfaceRef& Parent) throw ( ::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException)
+{
+ // SYNCHRONIZED ----->
+ ::osl::ResettableMutexGuard aGuard(m_aMutex);
+
+ Reference<XForm> xParentForm(getParent(), UNO_QUERY);
+ if (xParentForm.is())
+ {
+ try
+ {
+ Reference< XRowSetApproveBroadcaster > xParentApprBroadcast( xParentForm, UNO_QUERY_THROW );
+ xParentApprBroadcast->removeRowSetApproveListener( this );
+
+ Reference< XLoadable > xParentLoadable( xParentForm, UNO_QUERY_THROW );
+ xParentLoadable->removeLoadListener( this );
+
+ Reference< XPropertySet > xParentProperties( xParentForm, UNO_QUERY_THROW );
+ xParentProperties->removePropertyChangeListener( PROPERTY_ISNEW, this );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ OFormComponents::setParent(Parent);
+
+ xParentForm.set(getParent(), UNO_QUERY);
+ if ( xParentForm.is() )
+ {
+ try
+ {
+ Reference< XRowSetApproveBroadcaster > xParentApprBroadcast( xParentForm, UNO_QUERY_THROW );
+ xParentApprBroadcast->addRowSetApproveListener( this );
+
+ Reference< XLoadable > xParentLoadable( xParentForm, UNO_QUERY_THROW );
+ xParentLoadable->addLoadListener( this );
+
+ Reference< XPropertySet > xParentProperties( xParentForm, UNO_QUERY_THROW );
+ xParentProperties->addPropertyChangeListener( PROPERTY_ISNEW, this );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ Reference< XPropertySet > xAggregateProperties( m_xAggregateSet );
+ aGuard.clear();
+ // <----- SYNCHRONIZED
+
+ Reference< XConnection > xOuterConnection;
+ sal_Bool bIsEmbedded = ::dbtools::isEmbeddedInDatabase( Parent, xOuterConnection );
+
+ if ( bIsEmbedded )
+ xAggregateProperties->setPropertyValue( PROPERTY_DATASOURCE, makeAny( ::rtl::OUString() ) );
+}
+
+//==============================================================================
+// smartXTabControllerModel
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseForm::getGroupControl() throw(com::sun::star::uno::RuntimeException)
+{
+ ::osl::ResettableMutexGuard aGuard(m_aMutex);
+
+ // Sollen Controls in einer TabOrder gruppe zusammengefasst werden?
+ if (m_aCycle.hasValue())
+ {
+ sal_Int32 nCycle = 0;
+ ::cppu::enum2int(nCycle, m_aCycle);
+ return nCycle != TabulatorCycle_PAGE;
+ }
+
+ if (isLoaded() && getConnection().is())
+ return sal_True;
+
+ return sal_False;
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::setControlModels(const Sequence<Reference<XControlModel> >& rControls) throw( RuntimeException )
+{
+ ::osl::ResettableMutexGuard aGuard(m_aMutex);
+
+ // TabIndex in der Reihenfolge der Sequence setzen
+ const Reference<XControlModel>* pControls = rControls.getConstArray();
+ sal_Int16 nTabIndex = 1;
+ sal_Int32 nCount = getCount();
+ sal_Int32 nNewCount = rControls.getLength();
+
+ // HiddenControls und Formulare werden nicht aufgefuehrt
+ if (nNewCount <= nCount)
+ {
+ Any aElement;
+ for (sal_Int32 i=0; i < nNewCount; ++i, ++pControls)
+ {
+ Reference<XFormComponent> xComp(*pControls, UNO_QUERY);
+ if (xComp.is())
+ {
+ // suchen der Componente in der Liste
+ for (sal_Int32 j = 0; j < nCount; ++j)
+ {
+ Reference<XFormComponent> xElement;
+ ::cppu::extractInterface(xElement, getByIndex(j));
+ if (xComp == xElement)
+ {
+ Reference<XPropertySet> xSet(xComp, UNO_QUERY);
+ if (xSet.is() && hasProperty(PROPERTY_TABINDEX, xSet))
+ xSet->setPropertyValue( PROPERTY_TABINDEX, makeAny(nTabIndex++) );
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+Sequence<Reference<XControlModel> > SAL_CALL ODatabaseForm::getControlModels() throw( RuntimeException )
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+ return m_pGroupManager->getControlModels();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::setGroup( const Sequence<Reference<XControlModel> >& _rGroup, const ::rtl::OUString& Name ) throw( RuntimeException )
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ // Die Controls werden gruppiert, indem ihr Name dem Namen des ersten
+ // Controls der Sequenz angepasst wird
+ const Reference<XControlModel>* pControls = _rGroup.getConstArray();
+ Reference< XPropertySet > xSet;
+ ::rtl::OUString sGroupName( Name );
+
+ for( sal_Int32 i=0; i<_rGroup.getLength(); ++i, ++pControls )
+ {
+ xSet = xSet.query( *pControls );
+ if ( !xSet.is() )
+ {
+ // can't throw an exception other than a RuntimeException (which would not be appropriate),
+ // so we ignore (and only assert) this
+ OSL_FAIL( "ODatabaseForm::setGroup: invalid arguments!" );
+ continue;
+ }
+
+ if (!sGroupName.getLength())
+ xSet->getPropertyValue(PROPERTY_NAME) >>= sGroupName;
+ else
+ xSet->setPropertyValue(PROPERTY_NAME, makeAny(sGroupName));
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 SAL_CALL ODatabaseForm::getGroupCount() throw( RuntimeException )
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+ return m_pGroupManager->getGroupCount();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::getGroup( sal_Int32 nGroup, Sequence<Reference<XControlModel> >& _rGroup, ::rtl::OUString& _rName ) throw( RuntimeException )
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+ _rGroup.realloc(0);
+ _rName = ::rtl::OUString();
+
+ if ((nGroup < 0) || (nGroup >= m_pGroupManager->getGroupCount()))
+ return;
+ m_pGroupManager->getGroup( nGroup, _rGroup, _rName );
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::getGroupByName(const ::rtl::OUString& Name, Sequence< Reference<XControlModel> >& _rGroup) throw( RuntimeException )
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+ _rGroup.realloc(0);
+ m_pGroupManager->getGroupByName( Name, _rGroup );
+}
+
+//==============================================================================
+// com::sun::star::lang::XEventListener
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::disposing(const EventObject& Source) throw( RuntimeException )
+{
+ // does the call come from the connection which we are sharing with our parent?
+ if ( isSharingConnection() )
+ {
+ Reference< XConnection > xConnSource( Source.Source, UNO_QUERY );
+ if ( xConnSource.is() )
+ {
+#if OSL_DEBUG_LEVEL > 0
+ Reference< XConnection > xActiveConn;
+ m_xAggregateSet->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ) >>= xActiveConn;
+ OSL_ENSURE( xActiveConn.get() == xConnSource.get(), "ODatabaseForm::disposing: where did this come from?" );
+ // there should be exactly one XConnection object we're listening at - our aggregate connection
+#endif
+ disposingSharedConnection( xConnSource );
+ }
+ }
+
+ OInterfaceContainer::disposing(Source);
+
+ // does the disposing come from the aggregate ?
+ if (m_xAggregate.is())
+ { // no -> forward it
+ com::sun::star::uno::Reference<com::sun::star::lang::XEventListener> xListener;
+ if (query_aggregation(m_xAggregate, xListener))
+ xListener->disposing(Source);
+ }
+}
+
+//------------------------------------------------------------------------------
+void ODatabaseForm::impl_createLoadTimer()
+{
+ OSL_PRECOND( m_pLoadTimer == NULL, "ODatabaseForm::impl_createLoadTimer: timer already exists!" );
+ m_pLoadTimer = new Timer();
+ m_pLoadTimer->SetTimeout(100);
+ m_pLoadTimer->SetTimeoutHdl(LINK(this,ODatabaseForm,OnTimeout));
+}
+
+//==============================================================================
+// com::sun::star::form::XLoadListener
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::loaded(const EventObject& /*aEvent*/) throw( RuntimeException )
+{
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ Reference< XRowSet > xParentRowSet( m_xParent, UNO_QUERY_THROW );
+ xParentRowSet->addRowSetListener( this );
+
+ impl_createLoadTimer();
+ }
+
+ load_impl( sal_True );
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::unloading(const EventObject& /*aEvent*/) throw( RuntimeException )
+{
+ {
+ // now stop the rowset listening if we are a subform
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_pLoadTimer && m_pLoadTimer->IsActive() )
+ m_pLoadTimer->Stop();
+ DELETEZ( m_pLoadTimer );
+
+ Reference< XRowSet > xParentRowSet( m_xParent, UNO_QUERY_THROW );
+ xParentRowSet->removeRowSetListener( this );
+ }
+
+ unload();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::unloaded(const EventObject& /*aEvent*/) throw( RuntimeException )
+{
+ // nothing to do
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::reloading(const EventObject& /*aEvent*/) throw( RuntimeException )
+{
+ // now stop the rowset listening if we are a subform
+ ::osl::MutexGuard aGuard(m_aMutex);
+ Reference<XRowSet> xParentRowSet(m_xParent, UNO_QUERY);
+ if (xParentRowSet.is())
+ xParentRowSet->removeRowSetListener(this);
+
+ if (m_pLoadTimer && m_pLoadTimer->IsActive())
+ m_pLoadTimer->Stop();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::reloaded(const EventObject& /*aEvent*/) throw( RuntimeException )
+{
+ reload_impl(sal_True);
+ {
+ ::osl::MutexGuard aGuard(m_aMutex);
+ Reference<XRowSet> xParentRowSet(m_xParent, UNO_QUERY);
+ if (xParentRowSet.is())
+ xParentRowSet->addRowSetListener(this);
+ }
+}
+
+//------------------------------------------------------------------------------
+IMPL_LINK( ODatabaseForm, OnTimeout, void*, EMPTYARG )
+{
+ reload_impl(sal_True);
+ return 1;
+}
+
+//==============================================================================
+// com::sun::star::form::XLoadable
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::load() throw( RuntimeException )
+{
+ load_impl(sal_False);
+}
+
+//------------------------------------------------------------------------------
+sal_Bool ODatabaseForm::canShareConnection( const Reference< XPropertySet >& _rxParentProps )
+{
+ // our own data source
+ ::rtl::OUString sOwnDatasource;
+ m_xAggregateSet->getPropertyValue( PROPERTY_DATASOURCE ) >>= sOwnDatasource;
+
+ // our parents data source
+ ::rtl::OUString sParentDataSource;
+ OSL_ENSURE( _rxParentProps.is() && _rxParentProps->getPropertySetInfo().is() && _rxParentProps->getPropertySetInfo()->hasPropertyByName( PROPERTY_DATASOURCE ),
+ "ODatabaseForm::doShareConnection: invalid parent form!" );
+ if ( _rxParentProps.is() )
+ _rxParentProps->getPropertyValue( PROPERTY_DATASOURCE ) >>= sParentDataSource;
+
+ sal_Bool bCanShareConnection = sal_False;
+
+ // both rowsets share are connected to the same data source
+ if ( sParentDataSource == sOwnDatasource )
+ {
+ if ( 0 != sParentDataSource.getLength() )
+ // and it's really a data source name (not empty)
+ bCanShareConnection = sal_True;
+ else
+ { // the data source name is empty
+ // -> ook for the URL
+ ::rtl::OUString sParentURL;
+ ::rtl::OUString sMyURL;
+ _rxParentProps->getPropertyValue( PROPERTY_URL ) >>= sParentURL;
+ m_xAggregateSet->getPropertyValue( PROPERTY_URL ) >>= sMyURL;
+
+ bCanShareConnection = (sParentURL == sMyURL);
+ }
+ }
+
+ if ( bCanShareConnection )
+ {
+ // check for the user/password
+
+ // take the user property on the rowset (if any) into account
+ ::rtl::OUString sParentUser, sParentPwd;
+ _rxParentProps->getPropertyValue( PROPERTY_USER ) >>= sParentUser;
+ _rxParentProps->getPropertyValue( PROPERTY_PASSWORD ) >>= sParentPwd;
+
+ ::rtl::OUString sMyUser, sMyPwd;
+ m_xAggregateSet->getPropertyValue( PROPERTY_USER ) >>= sMyUser;
+ m_xAggregateSet->getPropertyValue( PROPERTY_PASSWORD ) >>= sMyPwd;
+
+ bCanShareConnection =
+ ( sParentUser == sMyUser )
+ && ( sParentPwd == sMyPwd );
+ }
+
+ return bCanShareConnection;
+}
+
+//------------------------------------------------------------------------------
+void ODatabaseForm::doShareConnection( const Reference< XPropertySet >& _rxParentProps )
+{
+ // get the conneciton of the parent
+ Reference< XConnection > xParentConn;
+ _rxParentProps->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ) >>= xParentConn;
+ OSL_ENSURE( xParentConn.is(), "ODatabaseForm::doShareConnection: we're a valid sub-form, but the parent has no connection?!" );
+
+ if ( xParentConn.is() )
+ {
+ // add as dispose listener to the connection
+ Reference< XComponent > xParentConnComp( xParentConn, UNO_QUERY );
+ OSL_ENSURE( xParentConnComp.is(), "ODatabaseForm::doShareConnection: invalid connection!" );
+ xParentConnComp->addEventListener( static_cast< XLoadListener* >( this ) );
+
+ // forward the connection to our own aggreagte
+ m_bForwardingConnection = sal_True;
+ m_xAggregateSet->setPropertyValue( PROPERTY_ACTIVE_CONNECTION, makeAny( xParentConn ) );
+ m_bForwardingConnection = sal_False;
+
+ m_bSharingConnection = sal_True;
+ }
+ else
+ m_bSharingConnection = sal_False;
+}
+
+//------------------------------------------------------------------------------
+void ODatabaseForm::disposingSharedConnection( const Reference< XConnection >& /*_rxConn*/ )
+{
+ stopSharingConnection();
+
+ // TODO: we could think about whether or not to re-connect.
+ unload( );
+}
+
+//------------------------------------------------------------------------------
+void ODatabaseForm::stopSharingConnection( )
+{
+ OSL_ENSURE( m_bSharingConnection, "ODatabaseForm::stopSharingConnection: invalid call!" );
+
+ if ( m_bSharingConnection )
+ {
+ // get the connection
+ Reference< XConnection > xSharedConn;
+ m_xAggregateSet->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ) >>= xSharedConn;
+ OSL_ENSURE( xSharedConn.is(), "ODatabaseForm::stopSharingConnection: there's no conn!" );
+
+ // remove ourself as event listener
+ Reference< XComponent > xSharedConnComp( xSharedConn, UNO_QUERY );
+ if ( xSharedConnComp.is() )
+ xSharedConnComp->removeEventListener( static_cast< XLoadListener* >( this ) );
+
+ // no need to dispose the conn: we're not the owner, this is our parent
+ // (in addition, this method may be called if the connection is beeing disposed while we use it)
+
+ // reset the property
+ xSharedConn.clear();
+ m_bForwardingConnection = sal_True;
+ m_xAggregateSet->setPropertyValue( PROPERTY_ACTIVE_CONNECTION, makeAny( xSharedConn ) );
+ m_bForwardingConnection = sal_False;
+
+ // reset the flag
+ m_bSharingConnection = sal_False;
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Bool ODatabaseForm::implEnsureConnection()
+{
+ try
+ {
+ if ( getConnection( ).is() )
+ // if our aggregate already has a connection, nothing needs to be done about it
+ return sal_True;
+
+ // see whether we're an embedded form
+ Reference< XConnection > xOuterConnection;
+ if ( ::dbtools::isEmbeddedInDatabase( getParent(), xOuterConnection ) )
+ {
+ m_xAggregateSet->setPropertyValue( PROPERTY_ACTIVE_CONNECTION, makeAny( xOuterConnection ) );
+ return xOuterConnection.is();
+ }
+
+ m_bSharingConnection = sal_False;
+
+ // if we're a sub form, we try to re-use the connection of our parent
+ if (m_bSubForm)
+ {
+ OSL_ENSURE( Reference< XForm >( getParent(), UNO_QUERY ).is(),
+ "ODatabaseForm::implEnsureConnection: m_bSubForm is TRUE, but the parent is no form?" );
+
+ Reference< XPropertySet > xParentProps( getParent(), UNO_QUERY );
+
+ // can we re-use (aka share) the connection of the parent?
+ if ( canShareConnection( xParentProps ) )
+ {
+ // yep -> do it
+ doShareConnection( xParentProps );
+ // success?
+ if ( m_bSharingConnection )
+ // yes -> outta here
+ return sal_True;
+ }
+ }
+
+ if (m_xAggregateSet.is())
+ {
+ Reference< XConnection > xConnection = connectRowset(
+ Reference<XRowSet> (m_xAggregate, UNO_QUERY),
+ m_xServiceFactory,
+ sal_True // set a calculated connection as ActiveConnection
+ );
+ return xConnection.is();
+ }
+ }
+ catch(SQLException& eDB)
+ {
+ onError(eDB, FRM_RES_STRING(RID_STR_CONNECTERROR));
+ }
+ catch( Exception )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ return sal_False;
+}
+
+//------------------------------------------------------------------------------
+void ODatabaseForm::load_impl(sal_Bool bCausedByParentForm, sal_Bool bMoveToFirst, const Reference< XInteractionHandler >& _rxCompletionHandler ) throw( RuntimeException )
+{
+ ::osl::ResettableMutexGuard aGuard(m_aMutex);
+
+ // are we already loaded?
+ if (isLoaded())
+ return;
+
+ m_bSubForm = bCausedByParentForm;
+
+ // if we don't have a connection, we are not intended to be a database form or the aggregate was not able
+ // to establish a connection
+ sal_Bool bConnected = implEnsureConnection();
+
+ // we don't have to execute if we do not have a command to execute
+ sal_Bool bExecute = bConnected && m_xAggregateSet.is() && getString(m_xAggregateSet->getPropertyValue(PROPERTY_COMMAND)).getLength();
+
+ // a database form always uses caching
+ // we use starting fetchsize with at least 10 rows
+ if (bConnected)
+ m_xAggregateSet->setPropertyValue(PROPERTY_FETCHSIZE, makeAny((sal_Int32)10));
+
+ // if we're loaded as sub form we got a "rowSetChanged" from the parent rowset _before_ we got the "loaded"
+ // so we don't need to execute the statement again, this was already done
+ // (and there were no relevant changes between these two listener calls, the "load" of a form is quite an
+ // atomar operation.)
+
+ sal_Bool bSuccess = sal_False;
+ if (bExecute)
+ {
+ m_sCurrentErrorContext = FRM_RES_STRING(RID_ERR_LOADING_FORM);
+ bSuccess = executeRowSet(aGuard, bMoveToFirst, _rxCompletionHandler);
+ }
+
+ if (bSuccess)
+ {
+ m_bLoaded = sal_True;
+ aGuard.clear();
+ EventObject aEvt(static_cast<XWeak*>(this));
+ m_aLoadListeners.notifyEach( &XLoadListener::loaded, aEvt );
+
+ // if we are on the insert row, we have to reset all controls
+ // to set the default values
+ if (bExecute && getBOOL(m_xAggregateSet->getPropertyValue(PROPERTY_ISNEW)))
+ reset();
+ }
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::unload() throw( RuntimeException )
+{
+ ::osl::ResettableMutexGuard aGuard(m_aMutex);
+ if (!isLoaded())
+ return;
+
+ DELETEZ(m_pLoadTimer);
+
+ aGuard.clear();
+ EventObject aEvt(static_cast<XWeak*>(this));
+ m_aLoadListeners.notifyEach( &XLoadListener::unloading, aEvt );
+
+ if (m_xAggregateAsRowSet.is())
+ {
+ // we may have reset the InsertOnly property on the aggregate - restore it
+ restoreInsertOnlyState( );
+
+ // clear the parameters if there are any
+ invlidateParameters();
+
+ try
+ {
+ // close the aggregate
+ Reference<XCloseable> xCloseable;
+ query_aggregation( m_xAggregate, xCloseable);
+ aGuard.clear();
+ if (xCloseable.is())
+ xCloseable->close();
+ }
+ catch( const SQLException& e )
+ {
+ (void)e;
+ }
+ aGuard.reset();
+ }
+
+ m_bLoaded = sal_False;
+
+ // if the connection we used while we were loaded is only shared with our parent, we
+ // reset it
+ if ( isSharingConnection() )
+ stopSharingConnection();
+
+ aGuard.clear();
+ m_aLoadListeners.notifyEach( &XLoadListener::unloaded, aEvt );
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::reload() throw( RuntimeException )
+{
+ reload_impl(sal_True);
+}
+
+//------------------------------------------------------------------------------
+void ODatabaseForm::reload_impl(sal_Bool bMoveToFirst, const Reference< XInteractionHandler >& _rxCompletionHandler ) throw( RuntimeException )
+{
+ ::osl::ResettableMutexGuard aGuard(m_aMutex);
+ if (!isLoaded())
+ return;
+
+ DocumentModifyGuard aModifyGuard( *this );
+ // ensures the document is not marked as "modified" just because we change some control's content during
+ // reloading ...
+
+ EventObject aEvent(static_cast<XWeak*>(this));
+ {
+ // only if there is no approve listener we can post the event at this time
+ // otherwise see approveRowsetChange
+ // the aprrovement is done by the aggregate
+ if (!m_aRowSetApproveListeners.getLength())
+ {
+ ::cppu::OInterfaceIteratorHelper aIter(m_aLoadListeners);
+ aGuard.clear();
+
+ while (aIter.hasMoreElements())
+ ((XLoadListener*)aIter.next())->reloading(aEvent);
+
+ aGuard.reset();
+ }
+ }
+
+ sal_Bool bSuccess = sal_True;
+ try
+ {
+ m_sCurrentErrorContext = FRM_RES_STRING(RID_ERR_REFRESHING_FORM);
+ bSuccess = executeRowSet(aGuard, bMoveToFirst, _rxCompletionHandler);
+ }
+ catch( const SQLException& e )
+ {
+ OSL_FAIL("ODatabaseForm::reload_impl : shouldn't executeRowSet catch this exception?");
+ (void)e;
+ }
+
+ if (bSuccess)
+ {
+ ::cppu::OInterfaceIteratorHelper aIter(m_aLoadListeners);
+ aGuard.clear();
+ while (aIter.hasMoreElements())
+ ((XLoadListener*)aIter.next())->reloaded(aEvent);
+
+ // if we are on the insert row, we have to reset all controls
+ // to set the default values
+ if (getBOOL(m_xAggregateSet->getPropertyValue(PROPERTY_ISNEW)))
+ reset();
+ }
+ else
+ m_bLoaded = sal_False;
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseForm::isLoaded() throw( RuntimeException )
+{
+ return m_bLoaded;
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::addLoadListener(const Reference<XLoadListener>& aListener) throw( RuntimeException )
+{
+ m_aLoadListeners.addInterface(aListener);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::removeLoadListener(const Reference<XLoadListener>& aListener) throw( RuntimeException )
+{
+ m_aLoadListeners.removeInterface(aListener);
+}
+
+//==============================================================================
+// com::sun::star::sdbc::XCloseable
+//==============================================================================
+void SAL_CALL ODatabaseForm::close() throw( SQLException, RuntimeException )
+{
+ // unload will close the aggregate
+ unload();
+}
+
+//==============================================================================
+// com::sun::star::sdbc::XRowSetListener
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::cursorMoved(const EventObject& /*event*/) throw( RuntimeException )
+{
+ // reload the subform with the new parameters of the parent
+ // do this handling delayed to provide of execute too many SQL Statements
+ ::osl::ResettableMutexGuard aGuard(m_aMutex);
+
+ DBG_ASSERT( m_pLoadTimer, "ODatabaseForm::cursorMoved: how can this happen?!" );
+ if ( !m_pLoadTimer )
+ impl_createLoadTimer();
+
+ if ( m_pLoadTimer->IsActive() )
+ m_pLoadTimer->Stop();
+
+ // and start the timer again
+ m_pLoadTimer->Start();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::rowChanged(const EventObject& /*event*/) throw( RuntimeException )
+{
+ // ignore it
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::rowSetChanged(const EventObject& /*event*/) throw( RuntimeException )
+{
+ // not interested in :
+ // if our parent is an ODatabaseForm, too, then after this rowSetChanged we'll get a "reloaded"
+ // or a "loaded" event.
+ // If somebody gave us another parent which is an XRowSet but doesn't handle an execute as
+ // "load" respectivly "reload" ... can't do anything ....
+}
+
+//------------------------------------------------------------------------------
+bool ODatabaseForm::impl_approveRowChange_throw( const EventObject& _rEvent, const bool _bAllowSQLException,
+ ::osl::ClearableMutexGuard& _rGuard )
+{
+ ::cppu::OInterfaceIteratorHelper aIter( m_aRowSetApproveListeners );
+ _rGuard.clear();
+ while ( aIter.hasMoreElements() )
+ {
+ Reference< XRowSetApproveListener > xListener( static_cast< XRowSetApproveListener* >( aIter.next() ) );
+ if ( !xListener.is() )
+ continue;
+
+ try
+ {
+ if ( !xListener->approveRowSetChange( _rEvent ) )
+ return false;
+ }
+ catch ( const DisposedException& e )
+ {
+ if ( e.Context == xListener )
+ aIter.remove();
+ }
+ catch ( const RuntimeException& ) { throw; }
+ catch ( const SQLException& )
+ {
+ if ( _bAllowSQLException )
+ throw;
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ catch ( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+ return true;
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseForm::approveCursorMove(const EventObject& event) throw( RuntimeException )
+{
+ // is our aggregate calling?
+ if (event.Source == InterfaceRef(static_cast<XWeak*>(this)))
+ {
+ // Our aggregate doesn't have any ApproveRowSetListeners (expect ourself), as we re-routed the queryInterface
+ // for XRowSetApproveBroadcaster-interface.
+ // So we have to multiplex this approve request.
+ ::cppu::OInterfaceIteratorHelper aIter( m_aRowSetApproveListeners );
+ while ( aIter.hasMoreElements() )
+ {
+ Reference< XRowSetApproveListener > xListener( static_cast< XRowSetApproveListener* >( aIter.next() ) );
+ if ( !xListener.is() )
+ continue;
+
+ try
+ {
+ if ( !xListener->approveCursorMove( event ) )
+ return sal_False;
+ }
+ catch ( const DisposedException& e )
+ {
+ if ( e.Context == xListener )
+ aIter.remove();
+ }
+ catch ( const RuntimeException& ) { throw; }
+ catch ( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+ return true;
+ }
+ else
+ {
+ // this is a call from our parent ...
+ // a parent's cursor move will result in a re-execute of our own row-set, so we have to
+ // ask our own RowSetChangesListeners, too
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+ if ( !impl_approveRowChange_throw( event, false, aGuard ) )
+ return sal_False;
+ }
+ return sal_True;
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseForm::approveRowChange(const RowChangeEvent& event) throw( RuntimeException )
+{
+ // is our aggregate calling?
+ if (event.Source == InterfaceRef(static_cast<XWeak*>(this)))
+ {
+ // Our aggregate doesn't have any ApproveRowSetListeners (expect ourself), as we re-routed the queryInterface
+ // for XRowSetApproveBroadcaster-interface.
+ // So we have to multiplex this approve request.
+ ::cppu::OInterfaceIteratorHelper aIter( m_aRowSetApproveListeners );
+ while ( aIter.hasMoreElements() )
+ {
+ Reference< XRowSetApproveListener > xListener( static_cast< XRowSetApproveListener* >( aIter.next() ) );
+ if ( !xListener.is() )
+ continue;
+
+ try
+ {
+ if ( !xListener->approveRowChange( event ) )
+ return false;
+ }
+ catch ( const DisposedException& e )
+ {
+ if ( e.Context == xListener )
+ aIter.remove();
+ }
+ catch ( const RuntimeException& ) { throw; }
+ catch ( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+ return true;
+ }
+ return sal_True;
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseForm::approveRowSetChange(const EventObject& event) throw( RuntimeException )
+{
+ if (event.Source == InterfaceRef(static_cast<XWeak*>(this))) // ignore our aggregate as we handle this approve ourself
+ {
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+ bool bWasLoaded = isLoaded();
+ if ( !impl_approveRowChange_throw( event, false, aGuard ) )
+ return sal_False;
+
+ if ( bWasLoaded )
+ {
+ m_aLoadListeners.notifyEach( &XLoadListener::reloading, event );
+ }
+ }
+ else
+ {
+ // this is a call from our parent ...
+ // a parent's cursor move will result in a re-execute of our own row-set, so we have to
+ // ask our own RowSetChangesListeners, too
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+ if ( !impl_approveRowChange_throw( event, false, aGuard ) )
+ return sal_False;
+ }
+ return sal_True;
+}
+
+//==============================================================================
+// com::sun::star::sdb::XRowSetApproveBroadcaster
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::addRowSetApproveListener(const Reference<XRowSetApproveListener>& _rListener) throw( RuntimeException )
+{
+ ::osl::ResettableMutexGuard aGuard(m_aMutex);
+ m_aRowSetApproveListeners.addInterface(_rListener);
+
+ // do we have to multiplex ?
+ if (m_aRowSetApproveListeners.getLength() == 1)
+ {
+ Reference<XRowSetApproveBroadcaster> xBroadcaster;
+ if (query_aggregation( m_xAggregate, xBroadcaster))
+ {
+ Reference<XRowSetApproveListener> xListener((XRowSetApproveListener*)this);
+ xBroadcaster->addRowSetApproveListener(xListener);
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::removeRowSetApproveListener(const Reference<XRowSetApproveListener>& _rListener) throw( RuntimeException )
+{
+ ::osl::ResettableMutexGuard aGuard(m_aMutex);
+ // do we have to remove the multiplex ?
+ m_aRowSetApproveListeners.removeInterface(_rListener);
+ if ( m_aRowSetApproveListeners.getLength() == 0 )
+ {
+ Reference<XRowSetApproveBroadcaster> xBroadcaster;
+ if (query_aggregation( m_xAggregate, xBroadcaster))
+ {
+ Reference<XRowSetApproveListener> xListener((XRowSetApproveListener*)this);
+ xBroadcaster->removeRowSetApproveListener(xListener);
+ }
+ }
+}
+
+//==============================================================================
+// com::sun:star::form::XDatabaseParameterBroadcaster
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::addDatabaseParameterListener(const Reference<XDatabaseParameterListener>& _rListener) throw( RuntimeException )
+{
+ m_aParameterManager.addParameterListener( _rListener );
+}
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::removeDatabaseParameterListener(const Reference<XDatabaseParameterListener>& _rListener) throw( RuntimeException )
+{
+ m_aParameterManager.removeParameterListener( _rListener );
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::addParameterListener(const Reference<XDatabaseParameterListener>& _rListener) throw( RuntimeException )
+{
+ ODatabaseForm::addDatabaseParameterListener( _rListener );
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::removeParameterListener(const Reference<XDatabaseParameterListener>& _rListener) throw( RuntimeException )
+{
+ ODatabaseForm::removeDatabaseParameterListener( _rListener );
+}
+
+//==============================================================================
+// com::sun::star::sdb::XCompletedExecution
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::executeWithCompletion( const Reference< XInteractionHandler >& _rxHandler ) throw(SQLException, RuntimeException)
+{
+ ::osl::ClearableMutexGuard aGuard(m_aMutex);
+ // the difference between execute and load is, that we position on the first row in case of load
+ // after execute we remain before the first row
+ if (!isLoaded())
+ {
+ aGuard.clear();
+ load_impl(sal_False, sal_False, _rxHandler);
+ }
+ else
+ {
+ EventObject event(static_cast< XWeak* >(this));
+ if ( !impl_approveRowChange_throw( event, true, aGuard ) )
+ return;
+
+ // we're loaded and somebody want's to execute ourself -> this means a reload
+ reload_impl(sal_False, _rxHandler);
+ }
+}
+
+//==============================================================================
+// com::sun::star::sdbc::XRowSet
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::execute() throw( SQLException, RuntimeException )
+{
+ ::osl::ResettableMutexGuard aGuard(m_aMutex);
+ // if somebody calls an execute and we're not loaded we reroute this call to our load method.
+
+ // the difference between execute and load is, that we position on the first row in case of load
+ // after execute we remain before the first row
+ if (!isLoaded())
+ {
+ aGuard.clear();
+ load_impl(sal_False, sal_False);
+ }
+ else
+ {
+ EventObject event(static_cast< XWeak* >(this));
+ if ( !impl_approveRowChange_throw( event, true, aGuard ) )
+ return;
+
+ // we're loaded and somebody want's to execute ourself -> this means a reload
+ reload_impl(sal_False);
+ }
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::addRowSetListener(const Reference<XRowSetListener>& _rListener) throw( RuntimeException )
+{
+ if (m_xAggregateAsRowSet.is())
+ m_xAggregateAsRowSet->addRowSetListener(_rListener);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::removeRowSetListener(const Reference<XRowSetListener>& _rListener) throw( RuntimeException )
+{
+ if (m_xAggregateAsRowSet.is())
+ m_xAggregateAsRowSet->removeRowSetListener(_rListener);
+}
+
+//==============================================================================
+// com::sun::star::sdbc::XResultSet
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseForm::next() throw( SQLException, RuntimeException )
+{
+ return m_xAggregateAsRowSet->next();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseForm::isBeforeFirst() throw( SQLException, RuntimeException )
+{
+ return m_xAggregateAsRowSet->isBeforeFirst();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseForm::isAfterLast() throw( SQLException, RuntimeException )
+{
+ return m_xAggregateAsRowSet->isAfterLast();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseForm::isFirst() throw( SQLException, RuntimeException )
+{
+ return m_xAggregateAsRowSet->isFirst();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseForm::isLast() throw( SQLException, RuntimeException )
+{
+ return m_xAggregateAsRowSet->isLast();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::beforeFirst() throw( SQLException, RuntimeException )
+{
+ m_xAggregateAsRowSet->beforeFirst();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::afterLast() throw( SQLException, RuntimeException )
+{
+ m_xAggregateAsRowSet->afterLast();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseForm::first() throw( SQLException, RuntimeException )
+{
+ return m_xAggregateAsRowSet->first();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseForm::last() throw( SQLException, RuntimeException )
+{
+ return m_xAggregateAsRowSet->last();
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 SAL_CALL ODatabaseForm::getRow() throw( SQLException, RuntimeException )
+{
+ return m_xAggregateAsRowSet->getRow();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseForm::absolute(sal_Int32 row) throw( SQLException, RuntimeException )
+{
+ return m_xAggregateAsRowSet->absolute(row);
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseForm::relative(sal_Int32 rows) throw( SQLException, RuntimeException )
+{
+ return m_xAggregateAsRowSet->relative(rows);
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseForm::previous() throw( SQLException, RuntimeException )
+{
+ return m_xAggregateAsRowSet->previous();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::refreshRow() throw( SQLException, RuntimeException )
+{
+ m_xAggregateAsRowSet->refreshRow();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseForm::rowUpdated() throw( SQLException, RuntimeException )
+{
+ return m_xAggregateAsRowSet->rowUpdated();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseForm::rowInserted() throw( SQLException, RuntimeException )
+{
+ return m_xAggregateAsRowSet->rowInserted();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseForm::rowDeleted() throw( SQLException, RuntimeException )
+{
+ return m_xAggregateAsRowSet->rowDeleted();
+}
+
+//------------------------------------------------------------------------------
+InterfaceRef SAL_CALL ODatabaseForm::getStatement() throw( SQLException, RuntimeException )
+{
+ return m_xAggregateAsRowSet->getStatement();
+}
+
+// com::sun::star::sdbc::XResultSetUpdate
+// exceptions during insert update and delete will be forwarded to the errorlistener
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::insertRow() throw( SQLException, RuntimeException )
+{
+ try
+ {
+ Reference<XResultSetUpdate> xUpdate;
+ if (query_aggregation( m_xAggregate, xUpdate))
+ xUpdate->insertRow();
+ }
+ catch( const RowSetVetoException& eVeto )
+ {
+ (void)eVeto;
+ throw;
+ }
+ catch(SQLException& eDb)
+ {
+ onError(eDb, FRM_RES_STRING(RID_STR_ERR_INSERTRECORD));
+ throw;
+ }
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::updateRow() throw( SQLException, RuntimeException )
+{
+ try
+ {
+ Reference<XResultSetUpdate> xUpdate;
+ if (query_aggregation( m_xAggregate, xUpdate))
+ xUpdate->updateRow();
+ }
+ catch( const RowSetVetoException& eVeto )
+ {
+ (void)eVeto;
+ throw;
+ }
+ catch(SQLException& eDb)
+ {
+ onError(eDb, FRM_RES_STRING(RID_STR_ERR_UPDATERECORD));
+ throw;
+ }
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::deleteRow() throw( SQLException, RuntimeException )
+{
+ try
+ {
+ Reference<XResultSetUpdate> xUpdate;
+ if (query_aggregation( m_xAggregate, xUpdate))
+ xUpdate->deleteRow();
+ }
+ catch( const RowSetVetoException& eVeto )
+ {
+ (void)eVeto;
+ throw;
+ }
+ catch(SQLException& eDb)
+ {
+ onError(eDb, FRM_RES_STRING(RID_STR_ERR_DELETERECORD));
+ throw;
+ }
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::cancelRowUpdates() throw( SQLException, RuntimeException )
+{
+ try
+ {
+ Reference<XResultSetUpdate> xUpdate;
+ if (query_aggregation( m_xAggregate, xUpdate))
+ xUpdate->cancelRowUpdates();
+ }
+ catch( const RowSetVetoException& eVeto )
+ {
+ (void)eVeto;
+ throw;
+ }
+ catch(SQLException& eDb)
+ {
+ onError(eDb, FRM_RES_STRING(RID_STR_ERR_INSERTRECORD));
+ throw;
+ }
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::moveToInsertRow() throw( SQLException, RuntimeException )
+{
+ Reference<XResultSetUpdate> xUpdate;
+ if (query_aggregation( m_xAggregate, xUpdate))
+ {
+ // _always_ move to the insert row
+ //
+ // Formerly, the following line was conditioned with a "not is new", means we did not move the aggregate
+ // to the insert row if it was already positioned there.
+ //
+ // This prevented the RowSet implementation from resetting it's column values. We, ourself, formerly
+ // did this reset of columns in reset_impl, where we set every column to the ControlDefault, or, if this
+ // was not present, to NULL. However, the problem with setting to NULL was #88888#, the problem with
+ // _not_ setting to NULL (which was the original fix for #88888#) was #97955#.
+ //
+ // So now we
+ // * move our aggregate to the insert row
+ // * in reset_impl
+ // - set the control defaults into the columns if not void
+ // - do _not_ set the columns to NULL if no control default is set
+ //
+ // Still, there is #72756#. During fixing this bug, DG introduced not calling the aggregate here. So
+ // in theory, we re-introduced #72756#. But the bug described therein does not happen anymore, as the
+ // preliminaries for it changed (no display of guessed values for new records with autoinc fields)
+ //
+ // BTW: the public Issuezilla bug is #i2815#
+ //
+ xUpdate->moveToInsertRow();
+
+ // then set the default values and the parameters given from the parent
+ reset();
+ }
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::moveToCurrentRow() throw( SQLException, RuntimeException )
+{
+ Reference<XResultSetUpdate> xUpdate;
+ if (query_aggregation( m_xAggregate, xUpdate))
+ xUpdate->moveToCurrentRow();
+}
+
+// com::sun::star::sdbcx::XDeleteRows
+//------------------------------------------------------------------------------
+Sequence<sal_Int32> SAL_CALL ODatabaseForm::deleteRows(const Sequence<Any>& rows) throw( SQLException, RuntimeException )
+{
+ try
+ {
+ Reference<XDeleteRows> xDelete;
+ if (query_aggregation( m_xAggregate, xDelete))
+ return xDelete->deleteRows(rows);
+ }
+ catch( const RowSetVetoException& eVeto )
+ {
+ (void)eVeto; // make compiler happy
+ throw;
+ }
+ catch(SQLException& eDb)
+ {
+ onError(eDb, FRM_RES_STRING(RID_STR_ERR_DELETERECORDS));
+ throw;
+ }
+
+ return Sequence< sal_Int32 >();
+}
+
+// com::sun::star::sdbc::XParameters
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::setNull(sal_Int32 parameterIndex, sal_Int32 sqlType) throw( SQLException, RuntimeException )
+{
+ m_aParameterManager.setNull(parameterIndex, sqlType);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::setObjectNull(sal_Int32 parameterIndex, sal_Int32 sqlType, const ::rtl::OUString& typeName) throw( SQLException, RuntimeException )
+{
+ m_aParameterManager.setObjectNull(parameterIndex, sqlType, typeName);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::setBoolean(sal_Int32 parameterIndex, sal_Bool x) throw( SQLException, RuntimeException )
+{
+ m_aParameterManager.setBoolean(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::setByte(sal_Int32 parameterIndex, sal_Int8 x) throw( SQLException, RuntimeException )
+{
+ m_aParameterManager.setByte(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::setShort(sal_Int32 parameterIndex, sal_Int16 x) throw( SQLException, RuntimeException )
+{
+ m_aParameterManager.setShort(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::setInt(sal_Int32 parameterIndex, sal_Int32 x) throw( SQLException, RuntimeException )
+{
+ m_aParameterManager.setInt(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::setLong(sal_Int32 parameterIndex, sal_Int64 x) throw( SQLException, RuntimeException )
+{
+ m_aParameterManager.setLong(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::setFloat(sal_Int32 parameterIndex, float x) throw( SQLException, RuntimeException )
+{
+ m_aParameterManager.setFloat(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::setDouble(sal_Int32 parameterIndex, double x) throw( SQLException, RuntimeException )
+{
+ m_aParameterManager.setDouble(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::setString(sal_Int32 parameterIndex, const ::rtl::OUString& x) throw( SQLException, RuntimeException )
+{
+ m_aParameterManager.setString(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::setBytes(sal_Int32 parameterIndex, const Sequence< sal_Int8 >& x) throw( SQLException, RuntimeException )
+{
+ m_aParameterManager.setBytes(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::setDate(sal_Int32 parameterIndex, const ::com::sun::star::util::Date& x) throw( SQLException, RuntimeException )
+{
+ m_aParameterManager.setDate(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::setTime(sal_Int32 parameterIndex, const ::com::sun::star::util::Time& x) throw( SQLException, RuntimeException )
+{
+ m_aParameterManager.setTime(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::setTimestamp(sal_Int32 parameterIndex, const ::com::sun::star::util::DateTime& x) throw( SQLException, RuntimeException )
+{
+ m_aParameterManager.setTimestamp(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::setBinaryStream(sal_Int32 parameterIndex, const Reference<XInputStream>& x, sal_Int32 length) throw( SQLException, RuntimeException )
+{
+ m_aParameterManager.setBinaryStream(parameterIndex, x, length);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::setCharacterStream(sal_Int32 parameterIndex, const Reference<XInputStream>& x, sal_Int32 length) throw( SQLException, RuntimeException )
+{
+ m_aParameterManager.setCharacterStream(parameterIndex, x, length);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::setObjectWithInfo(sal_Int32 parameterIndex, const Any& x, sal_Int32 targetSqlType, sal_Int32 scale) throw( SQLException, RuntimeException )
+{
+ m_aParameterManager.setObjectWithInfo(parameterIndex, x, targetSqlType, scale);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::setObject(sal_Int32 parameterIndex, const Any& x) throw( SQLException, RuntimeException )
+{
+ m_aParameterManager.setObject(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::setRef(sal_Int32 parameterIndex, const Reference<XRef>& x) throw( SQLException, RuntimeException )
+{
+ m_aParameterManager.setRef(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::setBlob(sal_Int32 parameterIndex, const Reference<XBlob>& x) throw( SQLException, RuntimeException )
+{
+ m_aParameterManager.setBlob(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::setClob(sal_Int32 parameterIndex, const Reference<XClob>& x) throw( SQLException, RuntimeException )
+{
+ m_aParameterManager.setClob(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::setArray(sal_Int32 parameterIndex, const Reference<XArray>& x) throw( SQLException, RuntimeException )
+{
+ m_aParameterManager.setArray(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::clearParameters() throw( SQLException, RuntimeException )
+{
+ m_aParameterManager.clearParameters();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::propertyChange( const PropertyChangeEvent& evt ) throw (RuntimeException)
+{
+ if ( evt.Source == m_xParent )
+ {
+ if ( evt.PropertyName == PROPERTY_ISNEW )
+ {
+ sal_Bool bCurrentIsNew( sal_False );
+ OSL_VERIFY( evt.NewValue >>= bCurrentIsNew );
+ if ( !bCurrentIsNew )
+ reload_impl( sal_True );
+ }
+ return;
+ }
+ OFormComponents::propertyChange( evt );
+}
+
+// com::sun::star::lang::XServiceInfo
+//------------------------------------------------------------------------------
+::rtl::OUString SAL_CALL ODatabaseForm::getImplementationName_Static()
+{
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.forms.ODatabaseForm" ) );
+}
+
+//------------------------------------------------------------------------------
+Sequence< ::rtl::OUString > SAL_CALL ODatabaseForm::getCompatibleServiceNames_Static()
+{
+ Sequence< ::rtl::OUString > aServices( 1 );
+ ::rtl::OUString* pServices = aServices.getArray();
+
+ *pServices++ = FRM_COMPONENT_FORM;
+
+ return aServices;
+}
+
+//------------------------------------------------------------------------------
+Sequence< ::rtl::OUString > SAL_CALL ODatabaseForm::getCurrentServiceNames_Static()
+{
+ Sequence< ::rtl::OUString > aServices( 5 );
+ ::rtl::OUString* pServices = aServices.getArray();
+
+ *pServices++ = FRM_SUN_FORMCOMPONENT;
+ *pServices++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.form.FormComponents") );
+ *pServices++ = FRM_SUN_COMPONENT_FORM;
+ *pServices++ = FRM_SUN_COMPONENT_HTMLFORM;
+ *pServices++ = FRM_SUN_COMPONENT_DATAFORM;
+
+ return aServices;
+}
+
+//------------------------------------------------------------------------------
+Sequence< ::rtl::OUString > SAL_CALL ODatabaseForm::getSupportedServiceNames_Static()
+{
+ return ::comphelper::concatSequences(
+ getCurrentServiceNames_Static(),
+ getCompatibleServiceNames_Static()
+ );
+}
+
+//------------------------------------------------------------------------------
+::rtl::OUString SAL_CALL ODatabaseForm::getImplementationName() throw( RuntimeException )
+{
+ return getImplementationName_Static();
+}
+
+//------------------------------------------------------------------------------
+Sequence< ::rtl::OUString > SAL_CALL ODatabaseForm::getSupportedServiceNames() throw( RuntimeException )
+{
+ // the services of our aggregate
+ Sequence< ::rtl::OUString > aServices;
+ Reference< XServiceInfo > xInfo;
+ if (query_aggregation(m_xAggregate, xInfo))
+ aServices = xInfo->getSupportedServiceNames();
+
+ // concat with out own services
+ return ::comphelper::concatSequences(
+ getCurrentServiceNames_Static(),
+ aServices
+ );
+ // use getCurrentXXX instead of getSupportedXXX, because at runtime, we do not want to have
+ // the compatible names
+ // This is maily to be consistent with the implementation before fixing #97083#, though the
+ // better solution _may_ be to return the compatible names at runtime, too
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseForm::supportsService(const ::rtl::OUString& ServiceName) throw( RuntimeException )
+{
+ Sequence< ::rtl::OUString > aSupported( getSupportedServiceNames() );
+ const ::rtl::OUString* pArray = aSupported.getConstArray();
+ for( sal_Int32 i = 0; i < aSupported.getLength(); ++i, ++pArray )
+ if( pArray->equals( ServiceName ) )
+ return sal_True;
+ return sal_False;
+}
+
+//==============================================================================
+// com::sun::star::io::XPersistObject
+//------------------------------------------------------------------------------
+
+const sal_uInt16 CYCLE = 0x0001;
+const sal_uInt16 DONTAPPLYFILTER = 0x0002;
+
+//------------------------------------------------------------------------------
+::rtl::OUString ODatabaseForm::getServiceName() throw( RuntimeException )
+{
+ return FRM_COMPONENT_FORM; // old (non-sun) name for compatibility !
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::write(const Reference<XObjectOutputStream>& _rxOutStream) throw( IOException, RuntimeException )
+{
+ DBG_ASSERT(m_xAggregateSet.is(), "ODatabaseForm::write : only to be called if the aggregate exists !");
+
+ // all children
+ OFormComponents::write(_rxOutStream);
+
+ // version
+ _rxOutStream->writeShort(0x0003);
+
+ // Name
+ _rxOutStream << m_sName;
+
+ ::rtl::OUString sDataSource;
+ if (m_xAggregateSet.is())
+ m_xAggregateSet->getPropertyValue(PROPERTY_DATASOURCE) >>= sDataSource;
+ _rxOutStream << sDataSource;
+
+ // former CursorSource
+ ::rtl::OUString sCommand;
+ if (m_xAggregateSet.is())
+ m_xAggregateSet->getPropertyValue(PROPERTY_COMMAND) >>= sCommand;
+ _rxOutStream << sCommand;
+
+ // former MasterFields
+ _rxOutStream << m_aMasterFields;
+ // former DetailFields
+ _rxOutStream << m_aDetailFields;
+
+ // former DataSelectionType
+ DataSelectionType eTranslated = DataSelectionType_TABLE;
+ if (m_xAggregateSet.is())
+ {
+ sal_Int32 nCommandType = 0;
+ m_xAggregateSet->getPropertyValue(PROPERTY_COMMANDTYPE) >>= nCommandType;
+ switch (nCommandType)
+ {
+ case CommandType::TABLE : eTranslated = DataSelectionType_TABLE; break;
+ case CommandType::QUERY : eTranslated = DataSelectionType_QUERY; break;
+ case CommandType::COMMAND:
+ {
+ sal_Bool bEscapeProcessing = getBOOL(m_xAggregateSet->getPropertyValue(PROPERTY_ESCAPE_PROCESSING));
+ eTranslated = bEscapeProcessing ? DataSelectionType_SQL : DataSelectionType_SQLPASSTHROUGH;
+ }
+ break;
+ default : OSL_FAIL("ODatabaseForm::write : wrong CommandType !");
+ }
+ }
+ _rxOutStream->writeShort((sal_Int16)eTranslated); // former DataSelectionType
+
+ // very old versions expect a CursorType here
+ _rxOutStream->writeShort(DatabaseCursorType_KEYSET);
+
+ _rxOutStream->writeBoolean(m_eNavigation != NavigationBarMode_NONE);
+
+ // former DataEntry
+ if (m_xAggregateSet.is())
+ _rxOutStream->writeBoolean(getBOOL(m_xAggregateSet->getPropertyValue(PROPERTY_INSERTONLY)));
+ else
+ _rxOutStream->writeBoolean(sal_False);
+
+ _rxOutStream->writeBoolean(m_bAllowInsert);
+ _rxOutStream->writeBoolean(m_bAllowUpdate);
+ _rxOutStream->writeBoolean(m_bAllowDelete);
+
+ // html form stuff
+ ::rtl::OUString sTmp = INetURLObject::decode( m_aTargetURL, '%', INetURLObject::DECODE_UNAMBIGUOUS);
+ _rxOutStream << sTmp;
+ _rxOutStream->writeShort( (sal_Int16)m_eSubmitMethod );
+ _rxOutStream->writeShort( (sal_Int16)m_eSubmitEncoding );
+ _rxOutStream << m_aTargetFrame;
+
+ // version 2 didn't know some options and the "default" state
+ sal_Int32 nCycle = TabulatorCycle_RECORDS;
+ if (m_aCycle.hasValue())
+ {
+ ::cppu::enum2int(nCycle, m_aCycle);
+ if (m_aCycle == TabulatorCycle_PAGE)
+ // unknown in earlier versions
+ nCycle = TabulatorCycle_RECORDS;
+ }
+ _rxOutStream->writeShort((sal_Int16) nCycle);
+
+ _rxOutStream->writeShort((sal_Int16)m_eNavigation);
+
+ ::rtl::OUString sFilter;
+ ::rtl::OUString sOrder;
+ if (m_xAggregateSet.is())
+ {
+ m_xAggregateSet->getPropertyValue(PROPERTY_FILTER) >>= sFilter;
+ m_xAggregateSet->getPropertyValue(PROPERTY_SORT) >>= sOrder;
+ }
+ _rxOutStream << sFilter;
+ _rxOutStream << sOrder;
+
+
+ // version 3
+ sal_uInt16 nAnyMask = 0;
+ if (m_aCycle.hasValue())
+ nAnyMask |= CYCLE;
+
+ if (m_xAggregateSet.is() && !getBOOL(m_xAggregateSet->getPropertyValue(PROPERTY_APPLYFILTER)))
+ nAnyMask |= DONTAPPLYFILTER;
+
+ _rxOutStream->writeShort(nAnyMask);
+
+ if (nAnyMask & CYCLE)
+ {
+ sal_Int32 nRealCycle = 0;
+ ::cppu::enum2int(nRealCycle, m_aCycle);
+ _rxOutStream->writeShort((sal_Int16)nRealCycle);
+ }
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::read(const Reference<XObjectInputStream>& _rxInStream) throw( IOException, RuntimeException )
+{
+ DBG_ASSERT(m_xAggregateSet.is(), "ODatabaseForm::read : only to be called if the aggregate exists !");
+
+ OFormComponents::read(_rxInStream);
+
+ // version
+ sal_uInt16 nVersion = _rxInStream->readShort();
+
+ _rxInStream >> m_sName;
+
+ ::rtl::OUString sAggregateProp;
+ _rxInStream >> sAggregateProp;
+ if (m_xAggregateSet.is())
+ m_xAggregateSet->setPropertyValue(PROPERTY_DATASOURCE, makeAny(sAggregateProp));
+ _rxInStream >> sAggregateProp;
+ if (m_xAggregateSet.is())
+ m_xAggregateSet->setPropertyValue(PROPERTY_COMMAND, makeAny(sAggregateProp));
+
+ _rxInStream >> m_aMasterFields;
+ _rxInStream >> m_aDetailFields;
+
+ sal_Int16 nCursorSourceType = _rxInStream->readShort();
+ sal_Int32 nCommandType = 0;
+ switch ((DataSelectionType)nCursorSourceType)
+ {
+ case DataSelectionType_TABLE : nCommandType = CommandType::TABLE; break;
+ case DataSelectionType_QUERY : nCommandType = CommandType::QUERY; break;
+ case DataSelectionType_SQL:
+ case DataSelectionType_SQLPASSTHROUGH:
+ {
+ nCommandType = CommandType::COMMAND;
+ sal_Bool bEscapeProcessing = ((DataSelectionType)nCursorSourceType) != DataSelectionType_SQLPASSTHROUGH;
+ m_xAggregateSet->setPropertyValue(PROPERTY_ESCAPE_PROCESSING, makeAny((sal_Bool)bEscapeProcessing));
+ }
+ break;
+ default : OSL_FAIL("ODatabaseForm::read : wrong CommandType !");
+ }
+ if (m_xAggregateSet.is())
+ m_xAggregateSet->setPropertyValue(PROPERTY_COMMANDTYPE, makeAny(nCommandType));
+
+ // obsolete
+ _rxInStream->readShort();
+
+ // navigation mode was a boolean in version 1
+ // war in der version 1 ein sal_Bool
+ sal_Bool bNavigation = _rxInStream->readBoolean();
+ if (nVersion == 1)
+ m_eNavigation = bNavigation ? NavigationBarMode_CURRENT : NavigationBarMode_NONE;
+
+ sal_Bool bInsertOnly = _rxInStream->readBoolean();
+ if (m_xAggregateSet.is())
+ m_xAggregateSet->setPropertyValue(PROPERTY_INSERTONLY, makeAny(bInsertOnly));
+
+ m_bAllowInsert = _rxInStream->readBoolean();
+ m_bAllowUpdate = _rxInStream->readBoolean();
+ m_bAllowDelete = _rxInStream->readBoolean();
+
+ // html stuff
+ ::rtl::OUString sTmp;
+ _rxInStream >> sTmp;
+ m_aTargetURL = INetURLObject::decode( sTmp, '%', INetURLObject::DECODE_UNAMBIGUOUS);
+ m_eSubmitMethod = (FormSubmitMethod)_rxInStream->readShort();
+ m_eSubmitEncoding = (FormSubmitEncoding)_rxInStream->readShort();
+ _rxInStream >> m_aTargetFrame;
+
+ if (nVersion > 1)
+ {
+ sal_Int32 nCycle = _rxInStream->readShort();
+ m_aCycle = ::cppu::int2enum(nCycle, ::getCppuType(static_cast<const TabulatorCycle*>(NULL)));
+ m_eNavigation = (NavigationBarMode)_rxInStream->readShort();
+
+ _rxInStream >> sAggregateProp;
+ setPropertyValue(PROPERTY_FILTER, makeAny(sAggregateProp));
+
+ _rxInStream >> sAggregateProp;
+ if (m_xAggregateSet.is())
+ m_xAggregateSet->setPropertyValue(PROPERTY_SORT, makeAny(sAggregateProp));
+ }
+
+ sal_uInt16 nAnyMask = 0;
+ if (nVersion > 2)
+ {
+ nAnyMask = _rxInStream->readShort();
+ if (nAnyMask & CYCLE)
+ {
+ sal_Int32 nCycle = _rxInStream->readShort();
+ m_aCycle = ::cppu::int2enum(nCycle, ::getCppuType(static_cast<const TabulatorCycle*>(NULL)));
+ }
+ else
+ m_aCycle.clear();
+ }
+ if (m_xAggregateSet.is())
+ m_xAggregateSet->setPropertyValue(PROPERTY_APPLYFILTER, makeAny((sal_Bool)((nAnyMask & DONTAPPLYFILTER) == 0)));
+}
+
+//------------------------------------------------------------------------------
+void ODatabaseForm::implInserted( const ElementDescription* _pElement )
+{
+ OFormComponents::implInserted( _pElement );
+
+ Reference< XSQLErrorBroadcaster > xBroadcaster( _pElement->xInterface, UNO_QUERY );
+ Reference< XForm > xForm ( _pElement->xInterface, UNO_QUERY );
+
+ if ( xBroadcaster.is() && !xForm.is() )
+ { // the object is an error broadcaster, but no form itself -> add ourself as listener
+ xBroadcaster->addSQLErrorListener( this );
+ }
+}
+
+//------------------------------------------------------------------------------
+void ODatabaseForm::implRemoved(const InterfaceRef& _rxObject)
+{
+ OFormComponents::implRemoved( _rxObject );
+
+ Reference<XSQLErrorBroadcaster> xBroadcaster(_rxObject, UNO_QUERY);
+ Reference<XForm> xForm(_rxObject, UNO_QUERY);
+ if (xBroadcaster.is() && !xForm.is())
+ { // the object is an error broadcaster, but no form itself -> remove ourself as listener
+ xBroadcaster->removeSQLErrorListener(this);
+ }
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::errorOccured(const SQLErrorEvent& _rEvent) throw( RuntimeException )
+{
+ // give it to my own error listener
+ onError(_rEvent);
+ // TODO : think about extending the chain with an SQLContext object saying
+ // "this was an error of one of my children"
+}
+
+// com::sun::star::container::XNamed
+//------------------------------------------------------------------------------
+::rtl::OUString SAL_CALL ODatabaseForm::getName() throw( RuntimeException )
+{
+ ::rtl::OUString sReturn;
+ OPropertySetHelper::getFastPropertyValue(PROPERTY_ID_NAME) >>= sReturn;
+ return sReturn;
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODatabaseForm::setName(const ::rtl::OUString& aName) throw( RuntimeException )
+{
+ setFastPropertyValue(PROPERTY_ID_NAME, makeAny(aName));
+}
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/DatabaseForm.hxx b/forms/source/component/DatabaseForm.hxx
new file mode 100644
index 000000000000..14fe7111e835
--- /dev/null
+++ b/forms/source/component/DatabaseForm.hxx
@@ -0,0 +1,569 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FRM_DATABASEFORM_HXX_
+#define _FRM_DATABASEFORM_HXX_
+
+#include "propertybaghelper.hxx"
+#include <com/sun/star/sdbc/XDataSource.hpp>
+#include <com/sun/star/sdb/XSQLErrorListener.hpp>
+#include <com/sun/star/io/XPersistObject.hpp>
+#include <com/sun/star/sdb/XSQLErrorBroadcaster.hpp>
+#include <com/sun/star/form/FormSubmitMethod.hpp>
+#include <com/sun/star/form/FormSubmitEncoding.hpp>
+#include <com/sun/star/form/XSubmit.hpp>
+#include <com/sun/star/form/XReset.hpp>
+#include <com/sun/star/form/XDatabaseParameterBroadcaster2.hpp>
+#include <com/sun/star/sdb/XCompletedExecution.hpp>
+#include <com/sun/star/sdbc/XRowSet.hpp>
+#include <com/sun/star/sdbcx/XDeleteRows.hpp>
+#include <com/sun/star/sdbc/XResultSetUpdate.hpp>
+#include <com/sun/star/sdb/XRowSetApproveListener.hpp>
+#include <com/sun/star/sdb/XRowSetApproveBroadcaster.hpp>
+#include <com/sun/star/form/NavigationBarMode.hpp>
+#include <com/sun/star/form/XLoadable.hpp>
+#include <com/sun/star/form/XLoadListener.hpp>
+#include <com/sun/star/form/XForm.hpp>
+#include <com/sun/star/awt/XTabControllerModel.hpp>
+#include <com/sun/star/script/XEventAttacherManager.hpp>
+#include <com/sun/star/sdbc/XRowSetListener.hpp>
+#include <com/sun/star/sdb/XResultSetAccess.hpp>
+#include <com/sun/star/sdbc/XCloseable.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/sdbc/XParameters.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <com/sun/star/beans/XPropertyContainer.hpp>
+#include <com/sun/star/beans/XPropertyAccess.hpp>
+#include <com/sun/star/sdbc/XWarningsSupplier.hpp>
+
+
+#include <tools/link.hxx>
+#include "InterfaceContainer.hxx"
+
+#include <connectivity/parameters.hxx>
+#include <connectivity/filtermanager.hxx>
+#include <connectivity/warningscontainer.hxx>
+
+#include "listenercontainers.hxx"
+#include "ids.hxx"
+#include <comphelper/propmultiplex.hxx>
+#include <comphelper/uno3.hxx>
+#include <comphelper/proparrhlp.hxx>
+#include <cppuhelper/implbase12.hxx>
+#include <cppuhelper/implbase4.hxx>
+#include <cppuhelper/implbase7.hxx>
+
+namespace com { namespace sun { namespace star { namespace sdbc {
+ class SQLException;
+} } } }
+
+class Timer;
+class INetMIMEMessage;
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+//========================================================================
+//= html tools
+//========================================================================
+
+const sal_uInt16 SUCCESSFUL_REPRESENT_TEXT = 0x0001;
+const sal_uInt16 SUCCESSFUL_REPRESENT_FILE = 0x0002;
+
+//------------------------------------------------------------------------------
+class HtmlSuccessfulObj
+{
+public:
+ ::rtl::OUString aName;
+ ::rtl::OUString aValue;
+ sal_uInt16 nRepresentation;
+
+ HtmlSuccessfulObj( const ::rtl::OUString& _rName, const ::rtl::OUString& _rValue,
+ sal_uInt16 _nRepresent = SUCCESSFUL_REPRESENT_TEXT )
+ :aName( _rName )
+ ,aValue( _rValue )
+ ,nRepresentation( _nRepresent )
+ {
+ }
+
+ HtmlSuccessfulObj()
+ {
+ }
+};
+
+
+DECLARE_STL_VECTOR(HtmlSuccessfulObj, HtmlSuccessfulObjList);
+
+//========================================================================
+class OGroupManager;
+class OFormSubmitResetThread;
+typedef ::cppu::ImplHelper12 < ::com::sun::star::form::XForm
+ , ::com::sun::star::awt::XTabControllerModel
+ , ::com::sun::star::form::XLoadListener
+ , ::com::sun::star::sdbc::XRowSetListener
+ , ::com::sun::star::sdb::XRowSetApproveListener
+ , ::com::sun::star::form::XDatabaseParameterBroadcaster2
+ , ::com::sun::star::sdb::XSQLErrorListener
+ , ::com::sun::star::sdb::XSQLErrorBroadcaster
+ , ::com::sun::star::form::XReset
+ , ::com::sun::star::form::XSubmit
+ , ::com::sun::star::form::XLoadable
+ , ::com::sun::star::container::XNamed
+ > ODatabaseForm_BASE1;
+
+
+typedef ::cppu::ImplHelper4 < ::com::sun::star::lang::XServiceInfo
+ , ::com::sun::star::beans::XPropertyContainer
+ , ::com::sun::star::beans::XPropertyAccess
+ , ::com::sun::star::sdbc::XWarningsSupplier
+ > ODatabaseForm_BASE2;
+
+typedef ::cppu::ImplHelper7< ::com::sun::star::sdbc::XCloseable,
+ ::com::sun::star::sdbc::XRowSet,
+ ::com::sun::star::sdb::XCompletedExecution,
+ ::com::sun::star::sdb::XRowSetApproveBroadcaster,
+ ::com::sun::star::sdbc::XResultSetUpdate,
+ ::com::sun::star::sdbcx::XDeleteRows,
+ ::com::sun::star::sdbc::XParameters > ODatabaseForm_BASE3;
+
+
+class ODatabaseForm :public OFormComponents
+ ,public OPropertySetAggregationHelper
+ ,public OPropertyChangeListener
+ ,public ODatabaseForm_BASE1
+ ,public ODatabaseForm_BASE2
+ ,public ODatabaseForm_BASE3
+ ,public IPropertyBagHelperContext
+{
+ friend class OFormSubmitResetThread;
+
+ OImplementationIdsRef m_aHoldIdHelper;
+
+ // listener administration
+ ::cppu::OInterfaceContainerHelper m_aLoadListeners;
+ ::cppu::OInterfaceContainerHelper m_aRowSetApproveListeners;
+ ::cppu::OInterfaceContainerHelper m_aRowSetListeners;
+ ::cppu::OInterfaceContainerHelper m_aSubmitListeners;
+ ::cppu::OInterfaceContainerHelper m_aErrorListeners;
+ ResetListeners m_aResetListeners;
+ ::osl::Mutex m_aResetSafety;
+ ::com::sun::star::uno::Any m_aCycle;
+ ::com::sun::star::uno::Any m_aIgnoreResult; // set when we are a subform and our master form positioned on a new row
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > m_aMasterFields;
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > m_aDetailFields;
+
+ // the object doin' most of the work - an SDB-rowset
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XAggregation> m_xAggregate;
+ // same object, interface as member because of performance reasons
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSet> m_xAggregateAsRowSet;
+
+ PropertyBagHelper m_aPropertyBagHelper;
+ ::dbtools::WarningsContainer m_aWarnings;
+ OPropertyChangeMultiplexer* m_pAggregatePropertyMultiplexer;
+ // Verwaltung der ControlGruppen
+ OGroupManager* m_pGroupManager;
+ ::dbtools::ParameterManager m_aParameterManager;
+ ::dbtools::FilterManager m_aFilterManager;
+ Timer* m_pLoadTimer;
+
+ OFormSubmitResetThread* m_pThread;
+ ::rtl::OUString m_sCurrentErrorContext;
+ // will be used as additional context information
+ // when an exception is catched and forwarded to the listeners
+
+ sal_Int32 m_nResetsPending;
+// <overwritten_properties>
+ sal_Int32 m_nPrivileges;
+ sal_Bool m_bInsertOnly;
+// </overwritten_properties>
+
+// <properties>
+ ::com::sun::star::uno::Any m_aControlBorderColorFocus;
+ ::com::sun::star::uno::Any m_aControlBorderColorMouse;
+ ::com::sun::star::uno::Any m_aControlBorderColorInvalid;
+ ::com::sun::star::uno::Any m_aDynamicControlBorder;
+ ::rtl::OUString m_sName;
+ ::rtl::OUString m_aTargetURL;
+ ::rtl::OUString m_aTargetFrame;
+ ::com::sun::star::form::FormSubmitMethod m_eSubmitMethod;
+ ::com::sun::star::form::FormSubmitEncoding m_eSubmitEncoding;
+ ::com::sun::star::form::NavigationBarMode m_eNavigation;
+ sal_Bool m_bAllowInsert : 1;
+ sal_Bool m_bAllowUpdate : 1;
+ sal_Bool m_bAllowDelete : 1;
+// </properties>
+ sal_Bool m_bLoaded : 1;
+ sal_Bool m_bSubForm : 1;
+ sal_Bool m_bForwardingConnection : 1; // sal_True if we're setting the ActiveConnection on the aggregate
+ sal_Bool m_bSharingConnection : 1; // sal_True if the connection we're using is shared with out parent
+
+public:
+ ODatabaseForm(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);
+ ODatabaseForm( const ODatabaseForm& _cloneSource );
+ ~ODatabaseForm();
+
+ // UNO binding
+ DECLARE_UNO3_AGG_DEFAULTS(ODatabaseForm, OFormComponents);
+ virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation(const ::com::sun::star::uno::Type& _rType) throw(::com::sun::star::uno::RuntimeException);
+
+ // XTypeProvider
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> SAL_CALL getTypes( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence<sal_Int8> SAL_CALL getImplementationId( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::lang::XComponent
+ virtual void SAL_CALL disposing();
+
+ // property handling
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
+ virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle ) const;
+ virtual sal_Bool SAL_CALL convertFastPropertyValue(::com::sun::star::uno::Any& rConvertedValue, ::com::sun::star::uno::Any& rOldValue, sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::lang::IllegalArgumentException);
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue) throw ( ::com::sun::star::uno::Exception );
+
+ ::com::sun::star::uno::Any SAL_CALL getFastPropertyValue( sal_Int32 nHandle )
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ void fire( sal_Int32 * pnHandles, const ::com::sun::star::uno::Any * pNewValues, const ::com::sun::star::uno::Any * pOldValues, sal_Int32 nCount, sal_Bool bVetoable );
+
+ // IPropertyBagHelperContext
+ virtual ::osl::Mutex& getMutex();
+ virtual void describeFixedAndAggregateProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& _out_rFixedProperties,
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& _out_rAggregateProperties
+ ) const;
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XMultiPropertySet >
+ getPropertiesInterface();
+
+ // com::sun::star::beans::XPropertyState
+ virtual ::com::sun::star::beans::PropertyState getPropertyStateByHandle(sal_Int32 nHandle);
+ virtual void setPropertyToDefaultByHandle(sal_Int32 nHandle);
+ virtual ::com::sun::star::uno::Any getPropertyDefaultByHandle(sal_Int32 nHandle) const;
+
+ // com::sun::star::sdbc::XSQLErrorBroadcaster
+ virtual void SAL_CALL addSQLErrorListener(const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XSQLErrorListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeSQLErrorListener(const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XSQLErrorListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::form::XForm
+ // nothing to implement
+
+ // com::sun::star::form::XReset
+ virtual void SAL_CALL reset() throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addResetListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XResetListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeResetListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XResetListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::form::XSubmit
+ virtual void SAL_CALL submit(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl>& aControl, const ::com::sun::star::awt::MouseEvent& aMouseEvt) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addSubmitListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XSubmitListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeSubmitListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XSubmitListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::container::XChild
+ virtual InterfaceRef SAL_CALL getParent() throw ( ::com::sun::star::uno::RuntimeException) { return OFormComponents::getParent(); }
+ virtual void SAL_CALL setParent(const InterfaceRef& Parent) throw ( :: com::sun::star::lang::NoSupportException , ::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::container::XNamed
+ virtual ::rtl::OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setName(const ::rtl::OUString& aName) throw(::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::awt::XTabControllerModel
+ virtual sal_Bool SAL_CALL getGroupControl() throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setGroupControl(sal_Bool /*_bGroupControl*/) throw(::com::sun::star::uno::RuntimeException) { }
+ virtual void SAL_CALL setControlModels(const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > >& _rControls) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > > SAL_CALL getControlModels() throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setGroup(const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > >& _rGroup, const ::rtl::OUString& _rGroupName) throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getGroupCount() throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL getGroup(sal_Int32 _nGroup, ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > >& _rxGroup, ::rtl::OUString& _rName) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL getGroupByName(const ::rtl::OUString& _rName, ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > >& _rxGroup) throw(::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::lang::XEventListener
+ virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& _rSource) throw(::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::form::XLoadListener
+ virtual void SAL_CALL loaded(const ::com::sun::star::lang::EventObject& aEvent) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL unloading(const ::com::sun::star::lang::EventObject& aEvent) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL unloaded(const ::com::sun::star::lang::EventObject& aEvent) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL reloading(const ::com::sun::star::lang::EventObject& aEvent) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL reloaded(const ::com::sun::star::lang::EventObject& aEvent) throw(::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::form::XLoadable
+ virtual void SAL_CALL load() throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL unload() throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL reload() throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL isLoaded() throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addLoadListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XLoadListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeLoadListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XLoadListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::sdbc::XCloseable
+ virtual void SAL_CALL close() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::sdbc::XRowSetListener
+ virtual void SAL_CALL cursorMoved(const ::com::sun::star::lang::EventObject& event) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL rowChanged(const ::com::sun::star::lang::EventObject& event) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL rowSetChanged(const ::com::sun::star::lang::EventObject& event) throw(::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::sdb::XRowSetApproveListener
+ virtual sal_Bool SAL_CALL approveCursorMove(const ::com::sun::star::lang::EventObject& event) throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL approveRowChange(const ::com::sun::star::sdb::RowChangeEvent& event) throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL approveRowSetChange(const ::com::sun::star::lang::EventObject& event) throw(::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::sdb::XRowSetApproveBroadcaster
+ virtual void SAL_CALL addRowSetApproveListener(const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XRowSetApproveListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeRowSetApproveListener(const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XRowSetApproveListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);
+
+ // com::sun:star::form::XDatabaseParameterBroadcaster2
+ virtual void SAL_CALL addDatabaseParameterListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XDatabaseParameterListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeDatabaseParameterListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XDatabaseParameterListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);
+
+ // com::sun:star::form::XDatabaseParameterBroadcaster
+ virtual void SAL_CALL addParameterListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XDatabaseParameterListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeParameterListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XDatabaseParameterListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::sdbc::XRowSet
+ virtual void SAL_CALL execute() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addRowSetListener(const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSetListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeRowSetListener(const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSetListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::sdb::XCompletedExecution
+ virtual void SAL_CALL executeWithCompletion( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& handler ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::sdbc::XResultSet
+ virtual sal_Bool SAL_CALL next() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL isBeforeFirst() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL isAfterLast() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL isFirst() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL isLast() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL beforeFirst() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL afterLast() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL first() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL last() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getRow() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL absolute(sal_Int32 row) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL relative(sal_Int32 rows) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL previous() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL refreshRow() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL rowUpdated() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL rowInserted() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL rowDeleted() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual InterfaceRef SAL_CALL getStatement() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::sdbc::XResultSetUpdate
+ virtual void SAL_CALL insertRow() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateRow() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL deleteRow() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL cancelRowUpdates() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL moveToInsertRow() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL moveToCurrentRow() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::sdbcx::XDeleteRows
+ virtual ::com::sun::star::uno::Sequence< sal_Int32 > SAL_CALL deleteRows(const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any>& rows) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::lang::XServiceInfo
+ virtual sal_Bool SAL_CALL supportsService(const ::rtl::OUString& ServiceName) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::lang::XServiceInfo - static version
+ static ::rtl::OUString SAL_CALL getImplementationName_Static();
+ static ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_Static();
+ static ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getCurrentServiceNames_Static();
+ static ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getCompatibleServiceNames_Static();
+ static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL Create( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory );
+
+ // com::sun::star::io::XPersistObject
+ virtual ::rtl::OUString SAL_CALL getServiceName() throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::sdbc::XSQLErrorListener
+ virtual void SAL_CALL errorOccured(const ::com::sun::star::sdb::SQLErrorEvent& aEvent) throw(::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::sdbc::XParameters
+ virtual void SAL_CALL setNull(sal_Int32 parameterIndex, sal_Int32 sqlType) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setObjectNull(sal_Int32 parameterIndex, sal_Int32 sqlType, const ::rtl::OUString& typeName) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setBoolean(sal_Int32 parameterIndex, sal_Bool x) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setByte(sal_Int32 parameterIndex, sal_Int8 x) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setShort(sal_Int32 parameterIndex, sal_Int16 x) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setInt(sal_Int32 parameterIndex, sal_Int32 x) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setLong(sal_Int32 parameterIndex, sal_Int64 x) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setFloat(sal_Int32 parameterIndex, float x) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setDouble(sal_Int32 parameterIndex, double x) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setString(sal_Int32 parameterIndex, const ::rtl::OUString& x) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setBytes(sal_Int32 parameterIndex, const ::com::sun::star::uno::Sequence< sal_Int8 >& x) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setDate(sal_Int32 parameterIndex, const ::com::sun::star::util::Date& x) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setTime(sal_Int32 parameterIndex, const ::com::sun::star::util::Time& x) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setTimestamp(sal_Int32 parameterIndex, const ::com::sun::star::util::DateTime& x) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setBinaryStream(sal_Int32 parameterIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream>& x, sal_Int32 length) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setCharacterStream(sal_Int32 parameterIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream>& x, sal_Int32 length) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setObject(sal_Int32 parameterIndex, const ::com::sun::star::uno::Any& x) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setObjectWithInfo(sal_Int32 parameterIndex, const ::com::sun::star::uno::Any& x, sal_Int32 targetSqlType, sal_Int32 scale) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setRef(sal_Int32 parameterIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRef>& x) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setBlob(sal_Int32 parameterIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XBlob>& x) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setClob(sal_Int32 parameterIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XClob>& x) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setArray(sal_Int32 parameterIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XArray>& x) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL clearParameters() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+ // XPropertyChangeListener
+ virtual void SAL_CALL propertyChange( const ::com::sun::star::beans::PropertyChangeEvent& evt ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XPropertyContainer
+ virtual void SAL_CALL addProperty( const ::rtl::OUString& Name, ::sal_Int16 Attributes, const ::com::sun::star::uno::Any& DefaultValue ) throw (::com::sun::star::beans::PropertyExistException, ::com::sun::star::beans::IllegalTypeException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeProperty( const ::rtl::OUString& Name ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::NotRemoveableException, ::com::sun::star::uno::RuntimeException);
+
+ // XPropertyAccess
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL getPropertyValues( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setPropertyValues( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aProps ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ using OPropertySetAggregationHelper::setPropertyValues;
+
+ // XWarningsSupplier
+ virtual ::com::sun::star::uno::Any SAL_CALL getWarnings( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL clearWarnings( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+ // XCloneable
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL createClone( ) throw (::com::sun::star::uno::RuntimeException);
+
+ inline void submitNBC( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl>& Control, const ::com::sun::star::awt::MouseEvent& MouseEvt );
+
+protected:
+ // OPropertySetAggregationHelper overridables
+ virtual void SAL_CALL forwardingPropertyValue( sal_Int32 _nHandle );
+ virtual void SAL_CALL forwardedPropertyValue( sal_Int32 _nHandle, bool _bSuccess );
+
+ // OInterfaceContainer overridables
+ virtual void implInserted( const ElementDescription* _pElement );
+ virtual void implRemoved(const InterfaceRef& _rxObject);
+
+ // OPropertyChangeListener
+ virtual void _propertyChanged( const ::com::sun::star::beans::PropertyChangeEvent& ) throw(::com::sun::star::uno::RuntimeException);
+
+private:
+ sal_Bool executeRowSet(::osl::ResettableMutexGuard& _rClearForNotifies, sal_Bool bMoveToFirst = sal_True,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& _rxCompletionHandler = ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >());
+ bool fillParameters(::osl::ResettableMutexGuard& _rClearForNotifies,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& _rxCompletionHandler = ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >());
+ void updateParameterInfo();
+ bool hasValidParent() const;
+
+ // impl methods
+ void load_impl(sal_Bool bCausedByParentForm, sal_Bool bMoveToFirst = sal_True,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& _rxCompletionHandler = ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >())
+ throw(::com::sun::star::uno::RuntimeException);
+ void reload_impl(sal_Bool bMoveToFirst,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& _rxCompletionHandler = ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >())
+ throw(::com::sun::star::uno::RuntimeException);
+ void submit_impl(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl>& Control, const ::com::sun::star::awt::MouseEvent& MouseEvt, bool _bAproveByListeners);
+ void reset_impl(bool _bAproveByListeners);
+
+ sal_Bool implEnsureConnection();
+
+ // connection sharing
+
+ /// checks if we can re-use (aka share) the connection of the given parent
+ sal_Bool canShareConnection( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxParentProps );
+
+ /// starts sharing the connection with the parent
+ void doShareConnection( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxParentProps );
+
+ /// stops sharing the connection with the parent
+ void stopSharingConnection( );
+
+ /// called when the connection which we share with our parent is beeing disposed
+ void disposingSharedConnection( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConn );
+
+ /// checks if we currently share our connection with our parent
+ sal_Bool isSharingConnection( ) const { return m_bSharingConnection; }
+
+ /** calls our row set approval listeners
+
+ @param _rEvent
+ the event to notify
+ @param _bAllowSQLException
+ <TRUE/> if SQLExceptions are allowed to leave the method
+ @param _rGuard
+ the guard to be cleared before actually calling into the listeners, but after making
+ a copy of the listeners array to operate on.
+ @return
+ <TRUE/> if and only if the execution has been approved
+ */
+ bool impl_approveRowChange_throw(
+ const ::com::sun::star::lang::EventObject& _rEvent,
+ const bool _bAllowSQLException,
+ ::osl::ClearableMutexGuard& _rGuard
+ );
+
+ /// invalidate all our parameter-related stuff
+ void invlidateParameters();
+
+ void saveInsertOnlyState( );
+ void restoreInsertOnlyState( );
+
+ // error handling
+ void onError(const ::com::sun::star::sdb::SQLErrorEvent& _rEvent);
+ void onError(const ::com::sun::star::sdbc::SQLException&, const ::rtl::OUString& _rContextDescription);
+
+ // html tools
+ ::rtl::OUString GetDataEncoded(bool _bURLEncoded,const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl>& SubmitButton, const ::com::sun::star::awt::MouseEvent& MouseEvt);
+ ::rtl::OUString GetDataURLEncoded(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl>& SubmitButton, const ::com::sun::star::awt::MouseEvent& MouseEvt);
+ ::rtl::OUString GetDataTextEncoded(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl>& SubmitButton, const ::com::sun::star::awt::MouseEvent& MouseEvt);
+ ::com::sun::star::uno::Sequence<sal_Int8> GetDataMultiPartEncoded(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl>& SubmitButton, const ::com::sun::star::awt::MouseEvent& MouseEvt,
+ ::rtl::OUString& rContentType);
+
+ void AppendComponent(HtmlSuccessfulObjList& rList, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& xComponentSet, const ::rtl::OUString& rNamePrefix,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl>& rxSubmitButton, const ::com::sun::star::awt::MouseEvent& MouseEvt);
+
+ void FillSuccessfulList(HtmlSuccessfulObjList& rList, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl>& rxSubmitButton, const ::com::sun::star::awt::MouseEvent& MouseEvt);
+
+ void InsertTextPart(INetMIMEMessage& rParent, const ::rtl::OUString& rName, const ::rtl::OUString& rData);
+ sal_Bool InsertFilePart(INetMIMEMessage& rParent, const ::rtl::OUString& rName, const ::rtl::OUString& rFileName);
+ void Encode(::rtl::OUString& rString) const;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > getConnection();
+
+ void impl_createLoadTimer();
+
+ void impl_construct();
+
+ DECL_LINK( OnTimeout, void* );
+protected:
+ using OPropertySetHelper::getPropertyValues;
+};
+
+inline void ODatabaseForm::submitNBC(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl>& Control, const ::com::sun::star::awt::MouseEvent& MouseEvt)
+{
+ submit_impl(Control, MouseEvt, sal_False);
+}
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+#endif // _FRM_DATABASEFORM_HXX_
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/Date.cxx b/forms/source/component/Date.cxx
new file mode 100644
index 000000000000..7a177d9ca6b6
--- /dev/null
+++ b/forms/source/component/Date.cxx
@@ -0,0 +1,365 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+#include "Date.hxx"
+#include <tools/debug.hxx>
+#include <tools/date.hxx>
+#include <connectivity/dbconversion.hxx>
+#include <com/sun/star/sdbc/DataType.hpp>
+
+using namespace dbtools;
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+using namespace ::com::sun::star;
+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::util;
+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;
+
+//------------------------------------------------------------------
+ODateControl::ODateControl(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OBoundControl(_rxFactory, VCL_CONTROL_DATEFIELD)
+{
+}
+
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL ODateControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
+{
+ return *(new ODateControl(_rxFactory));
+}
+
+//------------------------------------------------------------------------------
+Sequence<Type> ODateControl::_getTypes()
+{
+ return OBoundControl::_getTypes();
+}
+
+//------------------------------------------------------------------------------
+StringSequence SAL_CALL ODateControl::getSupportedServiceNames() throw()
+{
+ StringSequence aSupported = OBoundControl::getSupportedServiceNames();
+ aSupported.realloc(aSupported.getLength() + 1);
+
+ ::rtl::OUString*pArray = aSupported.getArray();
+ pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_DATEFIELD;
+ return aSupported;
+}
+
+/*************************************************************************/
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL ODateModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
+{
+ return *(new ODateModel(_rxFactory));
+}
+
+//------------------------------------------------------------------------------
+Sequence<Type> ODateModel::_getTypes()
+{
+ return OEditBaseModel::_getTypes();
+}
+
+//------------------------------------------------------------------
+DBG_NAME( ODateModel )
+//------------------------------------------------------------------
+ODateModel::ODateModel(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OEditBaseModel( _rxFactory, VCL_CONTROLMODEL_DATEFIELD, FRM_SUN_CONTROL_DATEFIELD, sal_True, sal_True )
+ // use the old control name for compytibility reasons
+ ,OLimitedFormats( _rxFactory, FormComponentType::DATEFIELD )
+{
+ DBG_CTOR( ODateModel, NULL );
+
+ m_nClassId = FormComponentType::DATEFIELD;
+ initValueProperty( PROPERTY_DATE, PROPERTY_ID_DATE );
+
+ setAggregateSet(m_xAggregateFastSet, getOriginalHandle(PROPERTY_ID_DATEFORMAT));
+
+ osl_incrementInterlockedCount( &m_refCount );
+ try
+ {
+ if ( m_xAggregateSet.is() )
+ m_xAggregateSet->setPropertyValue( PROPERTY_DATEMIN, makeAny( (sal_Int32)( ::Date( 1, 1, 1800 ).GetDate() ) ) );
+ }
+ catch( const Exception& )
+ {
+ OSL_FAIL( "ODateModel::ODateModel: caught an exception!" );
+ }
+ osl_decrementInterlockedCount( &m_refCount );
+}
+
+//------------------------------------------------------------------------------
+ODateModel::ODateModel( const ODateModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
+ :OEditBaseModel( _pOriginal, _rxFactory )
+ ,OLimitedFormats( _rxFactory, FormComponentType::DATEFIELD )
+{
+ DBG_CTOR( ODateModel, NULL );
+
+ setAggregateSet( m_xAggregateFastSet, getOriginalHandle( PROPERTY_ID_DATEFORMAT ) );
+}
+
+//------------------------------------------------------------------------------
+ODateModel::~ODateModel( )
+{
+ setAggregateSet(Reference< XFastPropertySet >(), -1);
+ DBG_DTOR( ODateModel, NULL );
+}
+
+// XCloneable
+//------------------------------------------------------------------------------
+IMPLEMENT_DEFAULT_CLONING( ODateModel )
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+StringSequence SAL_CALL ODateModel::getSupportedServiceNames() throw()
+{
+ StringSequence aSupported = OBoundControlModel::getSupportedServiceNames();
+
+ sal_Int32 nOldLen = aSupported.getLength();
+ aSupported.realloc( nOldLen + 8 );
+ ::rtl::OUString* pStoreTo = aSupported.getArray() + nOldLen;
+
+ *pStoreTo++ = BINDABLE_CONTROL_MODEL;
+ *pStoreTo++ = DATA_AWARE_CONTROL_MODEL;
+ *pStoreTo++ = VALIDATABLE_CONTROL_MODEL;
+
+ *pStoreTo++ = BINDABLE_DATA_AWARE_CONTROL_MODEL;
+ *pStoreTo++ = VALIDATABLE_BINDABLE_CONTROL_MODEL;
+
+ *pStoreTo++ = FRM_SUN_COMPONENT_DATEFIELD;
+ *pStoreTo++ = FRM_SUN_COMPONENT_DATABASE_DATEFIELD;
+ *pStoreTo++ = BINDABLE_DATABASE_DATE_FIELD;
+
+ return aSupported;
+}
+
+//------------------------------------------------------------------------------
+::rtl::OUString SAL_CALL ODateModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException)
+{
+ return FRM_COMPONENT_DATEFIELD; // old (non-sun) name for compatibility !
+}
+
+// XPropertySet
+//------------------------------------------------------------------------------
+void ODateModel::describeFixedProperties( Sequence< Property >& _rProps ) const
+{
+ BEGIN_DESCRIBE_PROPERTIES( 4, OEditBaseModel )
+ DECL_PROP3(DEFAULT_DATE, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID);
+ DECL_PROP1(TABINDEX, sal_Int16, BOUND);
+ DECL_PROP1(FORMATKEY, sal_Int32, TRANSIENT);
+ DECL_IFACE_PROP2(FORMATSSUPPLIER, XNumberFormatsSupplier, READONLY, TRANSIENT);
+ END_DESCRIBE_PROPERTIES();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODateModel::getFastPropertyValue(Any& _rValue, sal_Int32 _nHandle ) const
+{
+ switch (_nHandle)
+ {
+ case PROPERTY_ID_FORMATKEY:
+ getFormatKeyPropertyValue(_rValue);
+ break;
+ case PROPERTY_ID_FORMATSSUPPLIER:
+ _rValue <<= getFormatsSupplier();
+ break;
+ default:
+ OEditBaseModel::getFastPropertyValue(_rValue, _nHandle);
+ break;
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL ODateModel::convertFastPropertyValue(Any& _rConvertedValue, Any& _rOldValue,
+ sal_Int32 _nHandle, const Any& _rValue ) throw(IllegalArgumentException)
+{
+ if (PROPERTY_ID_FORMATKEY == _nHandle)
+ return convertFormatKeyPropertyValue(_rConvertedValue, _rOldValue, _rValue);
+ else
+ return OEditBaseModel::convertFastPropertyValue(_rConvertedValue, _rOldValue, _nHandle, _rValue );
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODateModel::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle, const Any& _rValue) throw ( ::com::sun::star::uno::Exception)
+{
+ if (PROPERTY_ID_FORMATKEY == _nHandle)
+ setFormatKeyPropertyValue(_rValue);
+ else
+ OEditBaseModel::setFastPropertyValue_NoBroadcast(_nHandle, _rValue);
+}
+
+// XLoadListener
+//------------------------------------------------------------------------------
+void ODateModel::onConnectedDbColumn( const Reference< XInterface >& _rxForm )
+{
+ OBoundControlModel::onConnectedDbColumn( _rxForm );
+ Reference<XPropertySet> xField = getField();
+ if (xField.is())
+ {
+ m_bDateTimeField = sal_False;
+ try
+ {
+ sal_Int32 nFieldType = 0;
+ xField->getPropertyValue(PROPERTY_FIELDTYPE) >>= nFieldType;
+ m_bDateTimeField = (nFieldType == DataType::TIMESTAMP);
+ }
+ catch(Exception&)
+ {
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Bool ODateModel::commitControlValueToDbColumn( bool /*_bPostReset*/ )
+{
+ Any aControlValue( m_xAggregateFastSet->getFastPropertyValue( getValuePropertyAggHandle() ) );
+ if ( !compare( aControlValue, m_aSaveValue ) )
+ {
+ if ( !aControlValue.hasValue() )
+ m_xColumnUpdate->updateNull();
+ else
+ {
+ try
+ {
+ util::Date aDate;
+ if ( !( aControlValue >>= aDate ) )
+ {
+ sal_Int32 nAsInt(0);
+ aControlValue >>= nAsInt;
+ aDate = DBTypeConversion::toDate(nAsInt);
+ }
+
+ if ( !m_bDateTimeField )
+ m_xColumnUpdate->updateDate( aDate );
+ else
+ {
+ util::DateTime aDateTime = m_xColumn->getTimestamp();
+ aDateTime.Day = aDate.Day;
+ aDateTime.Month = aDate.Month;
+ aDateTime.Year = aDate.Year;
+ m_xColumnUpdate->updateTimestamp( aDateTime );
+ }
+ }
+ catch(Exception&)
+ {
+ return sal_False;
+ }
+ }
+ m_aSaveValue = aControlValue;
+ }
+ return sal_True;
+}
+
+//------------------------------------------------------------------------------
+void ODateModel::impl_translateControlValueToUNODate( Any& _rUNOValue ) const
+{
+ _rUNOValue = getControlValue();
+ if ( _rUNOValue.hasValue() )
+ {
+ sal_Int32 nDate = 0;
+ OSL_VERIFY( _rUNOValue >>= nDate );
+ _rUNOValue <<= DBTypeConversion::toDate( nDate );
+ }
+}
+
+//------------------------------------------------------------------------------
+Any ODateModel::translateControlValueToExternalValue( ) const
+{
+ Any aExternalValue;
+ impl_translateControlValueToUNODate( aExternalValue );
+ return aExternalValue;
+}
+
+//------------------------------------------------------------------------------
+Any ODateModel::translateExternalValueToControlValue( const Any& _rExternalValue ) const
+{
+ Any aControlValue;
+ if ( _rExternalValue.hasValue() )
+ {
+ util::Date aDate;
+ OSL_VERIFY( _rExternalValue >>= aDate );
+ aControlValue <<= DBTypeConversion::toINT32( aDate );
+ }
+ return aControlValue;
+}
+
+//------------------------------------------------------------------------------
+Any ODateModel::translateControlValueToValidatableValue( ) const
+{
+ Any aValidatableValue;
+ impl_translateControlValueToUNODate( aValidatableValue );
+ return aValidatableValue;
+}
+
+//------------------------------------------------------------------------------
+Any ODateModel::translateDbColumnToControlValue()
+{
+ util::Date aDate = m_xColumn->getDate();
+ if (m_xColumn->wasNull())
+ m_aSaveValue.clear();
+ else
+ // the aggregated set expects an Int32 as value ...
+ m_aSaveValue <<= DBTypeConversion::toINT32(aDate);
+
+ return m_aSaveValue;
+}
+
+//------------------------------------------------------------------------------
+Any ODateModel::getDefaultForReset() const
+{
+ return m_aDefault;
+}
+
+//------------------------------------------------------------------------------
+void ODateModel::resetNoBroadcast()
+{
+ OEditBaseModel::resetNoBroadcast();
+ m_aSaveValue.clear();
+}
+
+//------------------------------------------------------------------------------
+Sequence< Type > ODateModel::getSupportedBindingTypes()
+{
+ return Sequence< Type >( &::getCppuType( static_cast< util::Date* >( NULL ) ), 1 );
+}
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/Date.hxx b/forms/source/component/Date.hxx
new file mode 100644
index 000000000000..790c8f027bfb
--- /dev/null
+++ b/forms/source/component/Date.hxx
@@ -0,0 +1,135 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FORMS_DATE_HXX_
+#define _FORMS_DATE_HXX_
+
+#include "EditBase.hxx"
+#include "limitedformats.hxx"
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+//==================================================================
+//= ODateModel
+//==================================================================
+class ODateModel
+ :public OEditBaseModel
+ ,public OLimitedFormats
+{
+ ::com::sun::star::uno::Any m_aSaveValue;
+ sal_Bool m_bDateTimeField;
+
+protected:
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();
+
+public:
+ DECLARE_DEFAULT_LEAF_XTOR( ODateModel );
+
+ // XPersistObject
+ virtual ::rtl::OUString SAL_CALL getServiceName() throw ( ::com::sun::star::uno::RuntimeException );
+
+ // ::com::sun::star::beans::XPropertySet
+ virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle ) const;
+ virtual sal_Bool SAL_CALL convertFastPropertyValue(::com::sun::star::uno::Any& rConvertedValue, ::com::sun::star::uno::Any& rOldValue,
+ sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
+ throw(::com::sun::star::lang::IllegalArgumentException);
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue) throw ( ::com::sun::star::uno::Exception);
+
+ // XServiceInfo
+ IMPLEMENTATION_NAME(ODateModel);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw();
+
+ // XPropertySet
+ using OEditBaseModel::getFastPropertyValue;
+
+ // OControlModel's property handling
+ virtual void describeFixedProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps
+ ) const;
+
+protected:
+ // OBoundControlModel overridables
+ virtual ::com::sun::star::uno::Any
+ translateDbColumnToControlValue( );
+ virtual sal_Bool commitControlValueToDbColumn( bool _bPostReset );
+
+ virtual ::com::sun::star::uno::Any
+ translateControlValueToExternalValue( ) const;
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type >
+ getSupportedBindingTypes();
+ virtual ::com::sun::star::uno::Any
+ translateExternalValueToControlValue( const ::com::sun::star::uno::Any& _rExternalValue ) const;
+
+ virtual ::com::sun::star::uno::Any
+ translateControlValueToValidatableValue( ) const;
+
+ virtual ::com::sun::star::uno::Any
+ getDefaultForReset() const;
+
+ virtual void resetNoBroadcast();
+
+ virtual void onConnectedDbColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxForm );
+
+protected:
+ DECLARE_XCLONEABLE();
+
+private:
+ /** translates the control value (the VCL-internal integer representation of a date) into
+ a UNO-Date.
+ */
+ void impl_translateControlValueToUNODate(
+ ::com::sun::star::uno::Any& _rUNOValue ) const;
+};
+
+//==================================================================
+//= ODateControl
+//==================================================================
+class ODateControl: public OBoundControl
+{
+protected:
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();
+
+public:
+ ODateControl(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);
+ DECLARE_UNO3_AGG_DEFAULTS(ODateControl, OBoundControl);
+
+// ::com::sun::star::lang::XServiceInfo
+ IMPLEMENTATION_NAME(ODateControl);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw();
+};
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+#endif // _FORMS_DATE_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/Edit.cxx b/forms/source/component/Edit.cxx
new file mode 100644
index 000000000000..d745a1b3837a
--- /dev/null
+++ b/forms/source/component/Edit.cxx
@@ -0,0 +1,767 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+
+#include "Edit.hxx"
+
+#include <com/sun/star/uno/Type.hxx>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/form/XSubmit.hpp>
+#include <com/sun/star/util/NumberFormat.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/awt/XVclWindowPeer.hpp>
+
+#include <vcl/svapp.hxx>
+#include <tools/wintypes.hxx>
+
+#include <connectivity/dbtools.hxx>
+#include <connectivity/formattedcolumnvalue.hxx>
+#include <connectivity/dbconversion.hxx>
+
+#include <tools/diagnose_ex.h>
+#include <tools/debug.hxx>
+
+#include <comphelper/container.hxx>
+#include <comphelper/numbers.hxx>
+
+using namespace dbtools;
+
+//.........................................................................
+namespace frm
+{
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::form;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::form::binding;
+
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL OEditControl_CreateInstance(const Reference< XMultiServiceFactory > & _rxFactory)
+{
+ return *(new OEditControl(_rxFactory));
+}
+
+//------------------------------------------------------------------------------
+Sequence<Type> OEditControl::_getTypes()
+{
+ static Sequence<Type> aTypes;
+ if (!aTypes.getLength())
+ {
+ // my two base classes
+ aTypes = concatSequences(OBoundControl::_getTypes(), OEditControl_BASE::getTypes());
+ }
+ return aTypes;
+}
+
+//------------------------------------------------------------------------------
+Any SAL_CALL OEditControl::queryAggregation(const Type& _rType) throw (RuntimeException)
+{
+ Any aReturn = OBoundControl::queryAggregation(_rType);
+ if (!aReturn.hasValue())
+ aReturn = OEditControl_BASE::queryInterface(_rType);
+
+ return aReturn;
+}
+
+DBG_NAME(OEditControl);
+//------------------------------------------------------------------------------
+OEditControl::OEditControl(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OBoundControl( _rxFactory, FRM_SUN_CONTROL_RICHTEXTCONTROL )
+ ,m_aChangeListeners(m_aMutex)
+ ,m_nKeyEvent( 0 )
+{
+ DBG_CTOR(OEditControl,NULL);
+
+ increment(m_refCount);
+ {
+ Reference<XWindow> xComp;
+ if (query_aggregation(m_xAggregate, xComp))
+ {
+ xComp->addFocusListener(this);
+ xComp->addKeyListener(this);
+ }
+ }
+ decrement(m_refCount);
+}
+
+//------------------------------------------------------------------------------
+OEditControl::~OEditControl()
+{
+ if( m_nKeyEvent )
+ Application::RemoveUserEvent( m_nKeyEvent );
+
+ if (!OComponentHelper::rBHelper.bDisposed)
+ {
+ acquire();
+ dispose();
+ }
+
+ DBG_DTOR(OEditControl,NULL);
+}
+
+// XChangeBroadcaster
+//------------------------------------------------------------------------------
+void OEditControl::addChangeListener(const Reference<XChangeListener>& l) throw ( ::com::sun::star::uno::RuntimeException)
+{
+ m_aChangeListeners.addInterface( l );
+}
+
+//------------------------------------------------------------------------------
+void OEditControl::removeChangeListener(const Reference<XChangeListener>& l) throw ( ::com::sun::star::uno::RuntimeException)
+{
+ m_aChangeListeners.removeInterface( l );
+}
+
+// OComponentHelper
+//------------------------------------------------------------------------------
+void OEditControl::disposing()
+{
+ OBoundControl::disposing();
+
+ EventObject aEvt(static_cast<XWeak*>(this));
+ m_aChangeListeners.disposeAndClear(aEvt);
+}
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+StringSequence OEditControl::getSupportedServiceNames() throw()
+{
+ StringSequence aSupported = OBoundControl::getSupportedServiceNames();
+ aSupported.realloc(aSupported.getLength() + 1);
+
+ ::rtl::OUString*pArray = aSupported.getArray();
+ pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_TEXTFIELD;
+ return aSupported;
+}
+
+// XEventListener
+//------------------------------------------------------------------------------
+void OEditControl::disposing(const EventObject& Source) throw( RuntimeException )
+{
+ OBoundControl::disposing(Source);
+}
+
+// XFocusListener
+//------------------------------------------------------------------------------
+void OEditControl::focusGained( const FocusEvent& /*e*/ ) throw ( ::com::sun::star::uno::RuntimeException)
+{
+ Reference<XPropertySet> xSet(getModel(), UNO_QUERY);
+ if (xSet.is())
+ xSet->getPropertyValue( PROPERTY_TEXT ) >>= m_aHtmlChangeValue;
+}
+
+//------------------------------------------------------------------------------
+void OEditControl::focusLost( const FocusEvent& /*e*/ ) throw ( ::com::sun::star::uno::RuntimeException)
+{
+ Reference<XPropertySet> xSet(getModel(), UNO_QUERY);
+ if (xSet.is())
+ {
+ ::rtl::OUString sNewHtmlChangeValue;
+ xSet->getPropertyValue( PROPERTY_TEXT ) >>= sNewHtmlChangeValue;
+ if( sNewHtmlChangeValue != m_aHtmlChangeValue )
+ {
+ EventObject aEvt( *this );
+ m_aChangeListeners.notifyEach( &XChangeListener::changed, aEvt );
+ }
+ }
+}
+
+// XKeyListener
+//------------------------------------------------------------------------------
+void OEditControl::keyPressed(const ::com::sun::star::awt::KeyEvent& e) throw ( ::com::sun::star::uno::RuntimeException)
+{
+ if( e.KeyCode != KEY_RETURN || e.Modifiers != 0 )
+ return;
+
+ // Steht das Control in einem Formular mit einer Submit-URL?
+ Reference<XPropertySet> xSet(getModel(), UNO_QUERY);
+ if( !xSet.is() )
+ return;
+
+ // nicht fuer multiline edits
+ Any aTmp( xSet->getPropertyValue(PROPERTY_MULTILINE));
+ if ((aTmp.getValueType().equals(::getBooleanCppuType())) && getBOOL(aTmp))
+ return;
+
+ Reference<XFormComponent> xFComp(xSet, UNO_QUERY);
+ InterfaceRef xParent = xFComp->getParent();
+ if( !xParent.is() )
+ return;
+
+ Reference<XPropertySet> xFormSet(xParent, UNO_QUERY);
+ if( !xFormSet.is() )
+ return;
+
+ aTmp = xFormSet->getPropertyValue( PROPERTY_TARGET_URL );
+ if (!aTmp.getValueType().equals(::getCppuType((const ::rtl::OUString*)NULL)) ||
+ !getString(aTmp).getLength() )
+ return;
+
+ Reference<XIndexAccess> xElements(xParent, UNO_QUERY);
+ sal_Int32 nCount = xElements->getCount();
+ if( nCount > 1 )
+ {
+ Reference<XPropertySet> xFCSet;
+ for( sal_Int32 nIndex=0; nIndex < nCount; nIndex++ )
+ {
+ // Any aElement(xElements->getByIndex(nIndex));
+ xElements->getByIndex(nIndex) >>= xFCSet;
+ OSL_ENSURE(xFCSet.is(),"OEditControl::keyPressed: No XPropertySet!");
+
+ if (hasProperty(PROPERTY_CLASSID, xFCSet) &&
+ getINT16(xFCSet->getPropertyValue(PROPERTY_CLASSID)) == FormComponentType::TEXTFIELD)
+ {
+ // 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, OEditControl,OnKeyPressed) );
+}
+
+//------------------------------------------------------------------------------
+void OEditControl::keyReleased(const ::com::sun::star::awt::KeyEvent& /*e*/) throw ( ::com::sun::star::uno::RuntimeException)
+{
+}
+
+//------------------------------------------------------------------------------
+IMPL_LINK(OEditControl, OnKeyPressed, void*, /*EMPTYARG*/)
+{
+ m_nKeyEvent = 0;
+
+ Reference<XFormComponent> xFComp(getModel(), UNO_QUERY);
+ InterfaceRef xParent = xFComp->getParent();
+ Reference<XSubmit> xSubmit(xParent, UNO_QUERY);
+ if (xSubmit.is())
+ xSubmit->submit( Reference<XControl>(), ::com::sun::star::awt::MouseEvent() );
+ return 0L;
+}
+
+//------------------------------------------------------------------
+void SAL_CALL OEditControl::createPeer( const Reference< XToolkit>& _rxToolkit, const Reference< XWindowPeer>& _rxParent ) throw ( RuntimeException )
+{
+ OBoundControl::createPeer(_rxToolkit, _rxParent);
+}
+
+/*************************************************************************/
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL OEditModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
+{
+ return *(new OEditModel(_rxFactory));
+}
+
+//------------------------------------------------------------------------------
+Sequence<Type> OEditModel::_getTypes()
+{
+ return OEditBaseModel::_getTypes();
+}
+
+
+DBG_NAME(OEditModel);
+//------------------------------------------------------------------
+OEditModel::OEditModel(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OEditBaseModel( _rxFactory, FRM_SUN_COMPONENT_RICHTEXTCONTROL, FRM_SUN_CONTROL_TEXTFIELD, sal_True, sal_True )
+ ,m_bMaxTextLenModified(sal_False)
+ ,m_bWritingFormattedFake(sal_False)
+{
+ DBG_CTOR(OEditModel,NULL);
+
+ m_nClassId = FormComponentType::TEXTFIELD;
+ initValueProperty( PROPERTY_TEXT, PROPERTY_ID_TEXT );
+}
+
+//------------------------------------------------------------------
+OEditModel::OEditModel( const OEditModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
+ :OEditBaseModel( _pOriginal, _rxFactory )
+ ,m_bMaxTextLenModified(sal_False)
+ ,m_bWritingFormattedFake(sal_False)
+{
+ DBG_CTOR( OEditModel, NULL );
+
+ // Note that most of the properties are not clone from the original object:
+ // Things as the format key, it's type, and such, depend on the field being part of a loaded form
+ // (they're initialized in onConnectedDbColumn). Even if the original object _is_ part of such a form, we ourself
+ // certainly aren't, so these members are defaulted. If we're inserted into a form which is already loaded,
+ // they will be set to new values, anyway ....
+}
+
+//------------------------------------------------------------------
+OEditModel::~OEditModel()
+{
+ if (!OComponentHelper::rBHelper.bDisposed)
+ {
+ acquire();
+ dispose();
+ }
+
+ DBG_DTOR(OEditModel,NULL);
+}
+
+//------------------------------------------------------------------------------
+IMPLEMENT_DEFAULT_CLONING( OEditModel )
+
+//------------------------------------------------------------------------------
+void OEditModel::disposing()
+{
+ OEditBaseModel::disposing();
+ m_pValueFormatter.reset();
+}
+
+// XPersistObject
+//------------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OEditModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException)
+{
+ return FRM_COMPONENT_EDIT; // old (non-sun) name for compatibility !
+}
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+StringSequence SAL_CALL OEditModel::getSupportedServiceNames() throw()
+{
+ StringSequence aSupported = OBoundControlModel::getSupportedServiceNames();
+
+ sal_Int32 nOldLen = aSupported.getLength();
+ aSupported.realloc( nOldLen + 8 );
+ ::rtl::OUString* pStoreTo = aSupported.getArray() + nOldLen;
+
+ *pStoreTo++ = BINDABLE_CONTROL_MODEL;
+ *pStoreTo++ = DATA_AWARE_CONTROL_MODEL;
+ *pStoreTo++ = VALIDATABLE_CONTROL_MODEL;
+
+ *pStoreTo++ = BINDABLE_DATA_AWARE_CONTROL_MODEL;
+ *pStoreTo++ = VALIDATABLE_BINDABLE_CONTROL_MODEL;
+
+ *pStoreTo++ = FRM_SUN_COMPONENT_TEXTFIELD;
+ *pStoreTo++ = FRM_SUN_COMPONENT_DATABASE_TEXTFIELD;
+ *pStoreTo++ = BINDABLE_DATABASE_TEXT_FIELD;
+
+ return aSupported;
+}
+
+// XPropertySet
+void SAL_CALL OEditModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle ) const
+{
+ if ( PROPERTY_ID_PERSISTENCE_MAXTEXTLENGTH == nHandle )
+ {
+ if ( m_bMaxTextLenModified )
+ rValue <<= sal_Int16(0);
+ else if ( m_xAggregateSet.is() )
+ rValue = m_xAggregateSet->getPropertyValue(PROPERTY_MAXTEXTLEN);
+ }
+ else
+ {
+ OEditBaseModel::getFastPropertyValue(rValue, nHandle );
+ }
+}
+
+//------------------------------------------------------------------------------
+void OEditModel::describeFixedProperties( Sequence< Property >& _rProps ) const
+{
+ BEGIN_DESCRIBE_PROPERTIES( 5, OEditBaseModel )
+ DECL_PROP2(PERSISTENCE_MAXTEXTLENGTH,sal_Int16, READONLY, TRANSIENT);
+ DECL_PROP2(DEFAULT_TEXT, ::rtl::OUString, BOUND, MAYBEDEFAULT);
+ DECL_BOOL_PROP1(EMPTY_IS_NULL, BOUND);
+ DECL_PROP1(TABINDEX, sal_Int16, BOUND);
+ DECL_BOOL_PROP2(FILTERPROPOSAL, BOUND, MAYBEDEFAULT);
+ END_DESCRIBE_PROPERTIES();
+}
+
+//------------------------------------------------------------------------------
+void OEditModel::describeAggregateProperties( Sequence< Property >& _rAggregateProps ) const
+{
+ OEditBaseModel::describeAggregateProperties( _rAggregateProps );
+
+ // our aggregate is a rich text model, which also derives from OControlModel, as
+ // do we, so we need to remove some duplicate properties
+ RemoveProperty( _rAggregateProps, PROPERTY_TABINDEX );
+ RemoveProperty( _rAggregateProps, PROPERTY_CLASSID );
+ RemoveProperty( _rAggregateProps, PROPERTY_NAME );
+ RemoveProperty( _rAggregateProps, PROPERTY_TAG );
+ RemoveProperty( _rAggregateProps, PROPERTY_NATIVE_LOOK );
+
+}
+
+//------------------------------------------------------------------------------
+bool OEditModel::implActsAsRichText( ) const
+{
+ sal_Bool bActAsRichText = sal_False;
+ if ( m_xAggregateSet.is() )
+ {
+ OSL_VERIFY( m_xAggregateSet->getPropertyValue( PROPERTY_RICH_TEXT ) >>= bActAsRichText );
+ }
+ return bActAsRichText;
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OEditModel::reset( ) throw(RuntimeException)
+{
+ // no reset if we currently act as rich text control
+ if ( implActsAsRichText() )
+ return;
+
+ OEditBaseModel::reset();
+}
+
+//------------------------------------------------------------------------------
+namespace
+{
+ void lcl_transferProperties( const Reference< XPropertySet >& _rxSource, const Reference< XPropertySet >& _rxDest )
+ {
+ try
+ {
+ Reference< XPropertySetInfo > xSourceInfo;
+ if ( _rxSource.is() )
+ xSourceInfo = _rxSource->getPropertySetInfo();
+
+ Reference< XPropertySetInfo > xDestInfo;
+ if ( _rxDest.is() )
+ xDestInfo = _rxDest->getPropertySetInfo();
+
+ if ( !xSourceInfo.is() || !xDestInfo.is() )
+ {
+ OSL_FAIL( "lcl_transferProperties: invalid property set(s)!" );
+ return;
+ }
+
+ Sequence< Property > aSourceProps( xSourceInfo->getProperties() );
+ const Property* pSourceProps = aSourceProps.getConstArray();
+ const Property* pSourcePropsEnd = aSourceProps.getConstArray() + aSourceProps.getLength();
+ while ( pSourceProps != pSourcePropsEnd )
+ {
+ if ( !xDestInfo->hasPropertyByName( pSourceProps->Name ) )
+ {
+ ++pSourceProps;
+ continue;
+ }
+
+ Property aDestProp( xDestInfo->getPropertyByName( pSourceProps->Name ) );
+ if ( 0 != ( aDestProp.Attributes & PropertyAttribute::READONLY ) )
+ {
+ ++pSourceProps;
+ continue;
+ }
+
+ try
+ {
+ _rxDest->setPropertyValue( pSourceProps->Name, _rxSource->getPropertyValue( pSourceProps->Name ) );
+ }
+ catch( IllegalArgumentException e )
+ {
+#if OSL_DEBUG_LEVEL > 0
+ ::rtl::OString sMessage( "could not transfer the property named '" );
+ sMessage += ::rtl::OString( pSourceProps->Name.getStr(), pSourceProps->Name.getLength(), RTL_TEXTENCODING_ASCII_US );
+ sMessage += ::rtl::OString( "'." );
+ if ( e.Message.getLength() )
+ {
+ sMessage += ::rtl::OString( "\n\nMessage:\n" );
+ sMessage += ::rtl::OString( e.Message.getStr(), e.Message.getLength(), RTL_TEXTENCODING_ASCII_US );
+ }
+ OSL_FAIL( sMessage.getStr() );
+#endif
+ }
+
+ ++pSourceProps;
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void OEditModel::writeAggregate( const Reference< XObjectOutputStream >& _rxOutStream ) const
+{
+ // we need to fake the writing of our aggregate. Since #i24387#, we have another aggregate,
+ // but for compatibility, we need to use an "old" aggregate for writing and reading
+
+ Reference< XPropertySet > xFakedAggregate(
+ getContext().createComponent( (rtl::OUString)VCL_CONTROLMODEL_EDIT ),
+ UNO_QUERY
+ );
+ OSL_ENSURE( xFakedAggregate.is(), "OEditModel::writeAggregate: could not create an old EditControlModel!" );
+ if ( !xFakedAggregate.is() )
+ return;
+
+ lcl_transferProperties( m_xAggregateSet, xFakedAggregate );
+
+ Reference< XPersistObject > xFakedPersist( xFakedAggregate, UNO_QUERY );
+ OSL_ENSURE( xFakedPersist.is(), "OEditModel::writeAggregate: no XPersistObject!" );
+ if ( xFakedPersist.is() )
+ xFakedPersist->write( _rxOutStream );
+}
+
+//------------------------------------------------------------------------------
+void OEditModel::readAggregate( const Reference< XObjectInputStream >& _rxInStream )
+{
+ // we need to fake the reading of our aggregate. Since #i24387#, we have another aggregate,
+ // but for compatibility, we need to use an "old" aggregate for writing and reading
+
+ Reference< XPropertySet > xFakedAggregate(
+ getContext().createComponent( (rtl::OUString)VCL_CONTROLMODEL_EDIT ),
+ UNO_QUERY
+ );
+ Reference< XPersistObject > xFakedPersist( xFakedAggregate, UNO_QUERY );
+ OSL_ENSURE( xFakedPersist.is(), "OEditModel::readAggregate: no XPersistObject, or no faked aggregate at all!" );
+ if ( xFakedPersist.is() )
+ {
+ xFakedPersist->read( _rxInStream );
+ lcl_transferProperties( xFakedAggregate, m_xAggregateSet );
+ }
+}
+
+//------------------------------------------------------------------------------
+void OEditModel::write(const Reference<XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
+{
+ Any aCurrentText;
+ sal_Int16 nOldTextLen = 0;
+ // bin ich gerade loaded und habe dazu zeitweilig die MaxTextLen umgesetzt ?
+ if ( m_bMaxTextLenModified )
+ { // -> fuer die Dauer des Speicherns meinem aggregierten Model die alte TextLen einreden
+
+ // before doing this we have to save the current text value of the aggregate, as this may be affected by resetting the text len
+ aCurrentText = m_xAggregateSet->getPropertyValue(PROPERTY_TEXT);
+
+ m_xAggregateSet->getPropertyValue(PROPERTY_MAXTEXTLEN) >>= nOldTextLen;
+ m_xAggregateSet->setPropertyValue(PROPERTY_MAXTEXTLEN, makeAny((sal_Int16)0));
+ }
+
+ OEditBaseModel::write(_rxOutStream);
+
+ if ( m_bMaxTextLenModified )
+ { // wieder zuruecksetzen
+ m_xAggregateSet->setPropertyValue(PROPERTY_MAXTEXTLEN, makeAny(nOldTextLen));
+ // and reset the text
+ // First we set it to an empty string : Without this the second setPropertyValue would not do anything as it thinks
+ // we aren't changing the prop (it didn't notify the - implicite - change of the text prop while setting the max text len)
+ // This seems to be a bug with in toolkit's EditControl-implementation.
+ m_xAggregateSet->setPropertyValue(PROPERTY_TEXT, makeAny(::rtl::OUString()));
+ m_xAggregateSet->setPropertyValue(PROPERTY_TEXT, aCurrentText);
+ }
+}
+
+//------------------------------------------------------------------------------
+void OEditModel::read(const Reference<XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
+{
+ OEditBaseModel::read(_rxInStream);
+
+ // Some versions (5.1 'til about 552) wrote a wrong DefaultControl-property value which is unknown
+ // to older versions (5.0).
+ // correct this ...
+ if (m_xAggregateSet.is())
+ {
+ Any aDefaultControl = m_xAggregateSet->getPropertyValue(PROPERTY_DEFAULTCONTROL);
+ if ( (aDefaultControl.getValueType().getTypeClass() == TypeClass_STRING)
+ && (getString(aDefaultControl).compareTo(STARDIV_ONE_FORM_CONTROL_TEXTFIELD) == COMPARE_EQUAL)
+ )
+ {
+ m_xAggregateSet->setPropertyValue( PROPERTY_DEFAULTCONTROL, makeAny( (::rtl::OUString)STARDIV_ONE_FORM_CONTROL_EDIT ) );
+ // Older as well as current versions should understand this : the former knew only the STARDIV_ONE_FORM_CONTROL_EDIT,
+ // the latter are registered for both STARDIV_ONE_FORM_CONTROL_EDIT and STARDIV_ONE_FORM_CONTROL_TEXTFIELD.
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_uInt16 OEditModel::getPersistenceFlags() const
+{
+ sal_uInt16 nFlags = OEditBaseModel::getPersistenceFlags();
+
+ if (m_bWritingFormattedFake)
+ nFlags |= PF_FAKE_FORMATTED_FIELD;
+
+ return nFlags;
+}
+
+//------------------------------------------------------------------------------
+void OEditModel::onConnectedDbColumn( const Reference< XInterface >& _rxForm )
+{
+ Reference< XPropertySet > xField = getField();
+ if ( xField.is() )
+ {
+ m_pValueFormatter.reset( new ::dbtools::FormattedColumnValue( getContext(), Reference< XRowSet >( _rxForm, UNO_QUERY ), xField ) );
+
+ if ( m_pValueFormatter->getKeyType() != NumberFormat::SCIENTIFIC )
+ {
+ m_bMaxTextLenModified = getINT16(m_xAggregateSet->getPropertyValue(PROPERTY_MAXTEXTLEN)) != 0;
+ if ( !m_bMaxTextLenModified )
+ {
+ sal_Int32 nFieldLen = 0;
+ xField->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Precision") ) ) >>= nFieldLen;
+
+ if (nFieldLen && nFieldLen <= USHRT_MAX)
+ {
+ Any aVal;
+ aVal <<= (sal_Int16)nFieldLen;
+ m_xAggregateSet->setPropertyValue(PROPERTY_MAXTEXTLEN, aVal);
+
+ m_bMaxTextLenModified = sal_True;
+ }
+ }
+ else
+ m_bMaxTextLenModified = sal_False; // to get sure that the text len won't be set in unloaded
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void OEditModel::onDisconnectedDbColumn()
+{
+ OEditBaseModel::onDisconnectedDbColumn();
+
+ m_pValueFormatter.reset();
+
+ if ( hasField() && m_bMaxTextLenModified )
+ {
+ Any aVal;
+ aVal <<= (sal_Int16)0; // nur wenn es 0 war, habe ich es in onConnectedDbColumn umgesetzt
+ m_xAggregateSet->setPropertyValue(PROPERTY_MAXTEXTLEN, aVal);
+ m_bMaxTextLenModified = sal_False;
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OEditModel::approveDbColumnType( sal_Int32 _nColumnType )
+{
+ // if we act as rich text curently, we do not allow binding to a database column
+ if ( implActsAsRichText() )
+ return sal_False;
+
+ return OEditBaseModel::approveDbColumnType( _nColumnType );
+}
+
+//------------------------------------------------------------------------------
+void OEditModel::resetNoBroadcast()
+{
+ OEditBaseModel::resetNoBroadcast();
+ m_aLastKnownValue.clear();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OEditModel::commitControlValueToDbColumn( bool /*_bPostReset*/ )
+{
+ Any aNewValue( m_xAggregateFastSet->getFastPropertyValue( getValuePropertyAggHandle() ) );
+
+ if ( aNewValue != m_aLastKnownValue )
+ {
+ ::rtl::OUString sNewValue;
+ aNewValue >>= sNewValue;
+
+ if ( !aNewValue.hasValue()
+ || ( !sNewValue.getLength() // an empty string
+ && m_bEmptyIsNull // which should be interpreted as NULL
+ )
+ )
+ {
+ m_xColumnUpdate->updateNull();
+ }
+ else
+ {
+ OSL_PRECOND( m_pValueFormatter.get(), "OEditModel::commitControlValueToDbColumn: no value formatter!" );
+ try
+ {
+ if ( m_pValueFormatter.get() )
+ {
+ if ( !m_pValueFormatter->setFormattedValue( sNewValue ) )
+ return sal_False;
+ }
+ else
+ m_xColumnUpdate->updateString( sNewValue );
+ }
+ catch ( const Exception& )
+ {
+ return sal_False;
+ }
+ }
+ m_aLastKnownValue = aNewValue;
+ }
+
+ return sal_True;
+}
+
+//------------------------------------------------------------------------------
+Any OEditModel::translateDbColumnToControlValue()
+{
+ OSL_PRECOND( m_pValueFormatter.get(), "OEditModel::translateDbColumnToControlValue: no value formatter!" );
+ if ( m_pValueFormatter.get() )
+ {
+ ::rtl::OUString sValue( m_pValueFormatter->getFormattedValue() );
+ if ( !sValue.getLength()
+ && m_pValueFormatter->getColumn().is()
+ && m_pValueFormatter->getColumn()->wasNull()
+ )
+ {
+ m_aLastKnownValue.clear();
+ }
+ else
+ {
+ // #i2817# OJ
+ sal_uInt16 nMaxTextLen = getINT16( m_xAggregateSet->getPropertyValue( PROPERTY_MAXTEXTLEN ) );
+ if ( nMaxTextLen && sValue.getLength() > nMaxTextLen )
+ {
+ sal_Int32 nDiff = sValue.getLength() - nMaxTextLen;
+ sValue = sValue.replaceAt( nMaxTextLen, nDiff, ::rtl::OUString() );
+ }
+
+ m_aLastKnownValue <<= sValue;
+ }
+ }
+ else
+ m_aLastKnownValue.clear();
+
+ return m_aLastKnownValue.hasValue() ? m_aLastKnownValue : makeAny( ::rtl::OUString() );
+ // (m_aLastKnownValue is alllowed to be VOID, the control value isn't)
+}
+
+//------------------------------------------------------------------------------
+Any OEditModel::getDefaultForReset() const
+{
+ return makeAny( m_aDefaultText );
+}
+
+//.........................................................................
+}
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/Edit.hxx b/forms/source/component/Edit.hxx
new file mode 100644
index 000000000000..e3c84612443f
--- /dev/null
+++ b/forms/source/component/Edit.hxx
@@ -0,0 +1,190 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FORMS_EDIT_HXX_
+#define _FORMS_EDIT_HXX_
+
+#include "EditBase.hxx"
+
+#include <cppuhelper/implbase3.hxx>
+
+namespace dbtools { class FormattedColumnValue; }
+
+//.........................................................................
+namespace frm
+{
+
+//==================================================================
+//= OEditModel
+//==================================================================
+class OEditModel
+ :public OEditBaseModel
+{
+ ::com::sun::star::uno::Any m_aLastKnownValue;
+ ::std::auto_ptr< ::dbtools::FormattedColumnValue >
+ m_pValueFormatter;
+ sal_Bool m_bMaxTextLenModified : 1; // set to <TRUE/> when we change the MaxTextLen of the aggregate
+
+ sal_Bool m_bWritingFormattedFake : 1;
+ // are we writing something which should be interpreted as formatted upon reading?
+
+protected:
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();
+
+ DECLARE_DEFAULT_LEAF_XTOR( OEditModel );
+
+ void enableFormattedWriteFake() { m_bWritingFormattedFake = sal_True; }
+ void disableFormattedWriteFake() { m_bWritingFormattedFake = sal_False; }
+ sal_Bool lastReadWasFormattedFake() const { return (getLastReadVersion() & PF_FAKE_FORMATTED_FIELD) != 0; }
+
+ friend InterfaceRef SAL_CALL OEditModel_CreateInstance(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);
+ friend class OFormattedFieldWrapper;
+ friend class OFormattedModel; // temporary
+
+public:
+ virtual void SAL_CALL disposing();
+
+ // XPropertySet
+ virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle ) const;
+
+ // XPersistObject
+ virtual void SAL_CALL write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getServiceName() throw ( ::com::sun::star::uno::RuntimeException);
+
+ // XPropertySet
+ using OBoundControlModel::getFastPropertyValue;
+
+ // XReset
+ virtual void SAL_CALL reset( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ IMPLEMENTATION_NAME(OEditModel);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw();
+
+ // OControlModel's property handling
+ virtual void describeFixedProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps
+ ) const;
+ virtual void describeAggregateProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rAggregateProps
+ ) const;
+
+ // XEventListener
+ using OBoundControlModel::disposing;
+
+protected:
+ // OControlModel overridables
+ virtual void writeAggregate( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream >& _rxOutStream ) const;
+ virtual void readAggregate( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream >& _rxInStream );
+
+ // OBoundControlModel overridables
+ virtual ::com::sun::star::uno::Any
+ translateDbColumnToControlValue( );
+ virtual sal_Bool commitControlValueToDbColumn( bool _bPostReset );
+
+ virtual ::com::sun::star::uno::Any
+ getDefaultForReset() const;
+
+ virtual void onConnectedDbColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxForm );
+ virtual void onDisconnectedDbColumn();
+
+ virtual sal_Bool approveDbColumnType( sal_Int32 _nColumnType );
+
+ virtual void resetNoBroadcast();
+
+protected:
+ virtual sal_uInt16 getPersistenceFlags() const;
+
+ DECLARE_XCLONEABLE();
+
+private:
+ bool implActsAsRichText( ) const;
+};
+
+//==================================================================
+//= OEditControl
+//==================================================================
+typedef ::cppu::ImplHelper3< ::com::sun::star::awt::XFocusListener,
+ ::com::sun::star::awt::XKeyListener,
+ ::com::sun::star::form::XChangeBroadcaster > OEditControl_BASE;
+
+class OEditControl : public OBoundControl
+ ,public OEditControl_BASE
+{
+ ::cppu::OInterfaceContainerHelper
+ m_aChangeListeners;
+
+ ::rtl::OUString m_aHtmlChangeValue;
+ sal_uInt32 m_nKeyEvent;
+
+public:
+ OEditControl(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);
+ virtual ~OEditControl();
+
+ DECLARE_UNO3_AGG_DEFAULTS(OEditControl, OBoundControl);
+ virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation(const ::com::sun::star::uno::Type& _rType) throw(::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();
+
+// OComponentHelper
+ virtual void SAL_CALL disposing();
+
+// ::com::sun::star::lang::XEventListener
+ virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& _rSource) throw(::com::sun::star::uno::RuntimeException);
+
+// ::com::sun::star::lang::XServiceInfo
+ IMPLEMENTATION_NAME(OEditControl);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw();
+
+// ::com::sun::star::form::XChangeBroadcaster
+ virtual void SAL_CALL addChangeListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XChangeListener>& _rxListener) throw ( ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeChangeListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XChangeListener>& _rxListener) throw ( ::com::sun::star::uno::RuntimeException);
+
+// ::com::sun::star::awt::XFocusListener
+ virtual void SAL_CALL focusGained( const ::com::sun::star::awt::FocusEvent& e ) throw ( ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL focusLost( const ::com::sun::star::awt::FocusEvent& e ) throw ( ::com::sun::star::uno::RuntimeException);
+
+// ::com::sun::star::awt::XKeyListener
+ virtual void SAL_CALL keyPressed(const ::com::sun::star::awt::KeyEvent& e) throw ( ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL keyReleased(const ::com::sun::star::awt::KeyEvent& e) throw ( ::com::sun::star::uno::RuntimeException);
+
+ // XControl
+ virtual void SAL_CALL createPeer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit >& _rxToolkit, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >& _rxParent ) throw ( ::com::sun::star::uno::RuntimeException );
+
+private:
+ DECL_LINK( OnKeyPressed, void* );
+};
+
+//.........................................................................
+}
+//.........................................................................
+
+#endif // _FORMS_EDIT_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/EditBase.cxx b/forms/source/component/EditBase.cxx
new file mode 100644
index 000000000000..10903bdfee55
--- /dev/null
+++ b/forms/source/component/EditBase.cxx
@@ -0,0 +1,361 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+#include "EditBase.hxx"
+#include "property.hxx"
+#include "property.hrc"
+#include "services.hxx"
+#include <tools/debug.hxx>
+#include <comphelper/basicio.hxx>
+#include <cppuhelper/queryinterface.hxx>
+#include "frm_resource.hxx"
+#include "frm_resource.hrc"
+
+//.........................................................................
+namespace frm
+{
+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;
+
+const sal_uInt16 DEFAULT_LONG = 0x0001;
+const sal_uInt16 DEFAULT_DOUBLE = 0x0002;
+const sal_uInt16 FILTERPROPOSAL = 0x0004;
+
+DBG_NAME( OEditBaseModel )
+//------------------------------------------------------------------
+OEditBaseModel::OEditBaseModel( const Reference< XMultiServiceFactory >& _rxFactory, const ::rtl::OUString& rUnoControlModelName,
+ const ::rtl::OUString& rDefault, const sal_Bool _bSupportExternalBinding, const sal_Bool _bSupportsValidation )
+ :OBoundControlModel( _rxFactory, rUnoControlModelName, rDefault, sal_True, _bSupportExternalBinding, _bSupportsValidation )
+ ,m_nLastReadVersion(0)
+ ,m_bEmptyIsNull(sal_True)
+ ,m_bFilterProposal(sal_False)
+{
+ DBG_CTOR( OEditBaseModel, NULL );
+}
+
+//------------------------------------------------------------------
+OEditBaseModel::OEditBaseModel( const OEditBaseModel* _pOriginal, const Reference< XMultiServiceFactory >& _rxFactory )
+ :OBoundControlModel( _pOriginal, _rxFactory )
+ ,m_nLastReadVersion(0)
+{
+ DBG_CTOR( OEditBaseModel, NULL );
+
+ m_bFilterProposal = _pOriginal->m_bFilterProposal;
+ m_bEmptyIsNull = _pOriginal->m_bEmptyIsNull;
+ m_aDefault = _pOriginal->m_aDefault;
+ m_aDefaultText = _pOriginal->m_aDefaultText;
+}
+
+//------------------------------------------------------------------
+OEditBaseModel::~OEditBaseModel( )
+{
+ DBG_DTOR( OEditBaseModel, NULL );
+}
+
+// XPersist
+//------------------------------------------------------------------------------
+void OEditBaseModel::write(const Reference<XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
+{
+ OBoundControlModel::write(_rxOutStream);
+
+ // Version
+ sal_uInt16 nVersionId = 0x0005;
+ DBG_ASSERT((getPersistenceFlags() & ~PF_SPECIAL_FLAGS) == 0,
+ "OEditBaseModel::write : invalid special version flags !");
+ // please don't use other flags, older versions can't interpret them !
+
+ nVersionId |= getPersistenceFlags();
+ _rxOutStream->writeShort(nVersionId);
+
+ // Name
+ _rxOutStream->writeShort(0); // obsolete
+ _rxOutStream << m_aDefaultText;
+
+ // Maskierung fuer any
+ sal_uInt16 nAnyMask = 0;
+ if (m_aDefault.getValueType().getTypeClass() == TypeClass_LONG)
+ nAnyMask |= DEFAULT_LONG;
+ else if (m_aDefault.getValueType().getTypeClass() == TypeClass_DOUBLE)
+ nAnyMask |= DEFAULT_DOUBLE;
+
+ if (m_bFilterProposal) // da boolean, kein Wert speichern
+ nAnyMask |= FILTERPROPOSAL;
+
+ _rxOutStream->writeBoolean(m_bEmptyIsNull);
+ _rxOutStream->writeShort(nAnyMask);
+
+ if ((nAnyMask & DEFAULT_LONG) == DEFAULT_LONG)
+ _rxOutStream->writeLong(getINT32(m_aDefault));
+ else if ((nAnyMask & DEFAULT_DOUBLE) == DEFAULT_DOUBLE)
+ _rxOutStream->writeDouble(getDouble(m_aDefault));
+
+ // since version 5 we write the help text
+ writeHelpTextCompatibly(_rxOutStream);
+ // (that's potentially bad : at the time I added the above line we had two derived classes : OEditModel and
+ // OFormattedModel. The first one does not have an own version handling, so it can't write the help text itself,
+ // the second one does it's own writing (reading) after calling our method, so normally we shouldn't write any
+ // additional members as this is not compatible to older office versions.
+ // We decided to place the writing of the help text here as it seems the less worse alternative. There is no delivered
+ // office version including formatted controls (and thus the OFormattedModel), and the OFormattedModel::read seems
+ // robust against this change (as it will read a wrong and unknown file version and thus set it's members to defaults).
+
+ if ((nVersionId & PF_HANDLE_COMMON_PROPS) != 0)
+ writeCommonEditProperties(_rxOutStream);
+
+ // !!! properties common to all OEditBaseModel derived classes should be written in writeCommonEditProperties !!!
+}
+
+//------------------------------------------------------------------------------
+sal_uInt16 OEditBaseModel::getPersistenceFlags() const
+{
+ return PF_HANDLE_COMMON_PROPS;
+}
+
+//------------------------------------------------------------------------------
+void OEditBaseModel::read(const Reference<XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
+{
+ OBoundControlModel::read(_rxInStream);
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ // Version eigene Versionsnummer
+ sal_uInt16 nVersion = _rxInStream->readShort();
+ m_nLastReadVersion = nVersion;
+
+ sal_Bool bHandleCommonProps = (nVersion & PF_HANDLE_COMMON_PROPS) != 0;
+ nVersion = nVersion & ~PF_SPECIAL_FLAGS;
+
+ // obsolete
+ _rxInStream->readShort();
+
+ _rxInStream >> m_aDefaultText;
+
+ if (nVersion >= 0x0003)
+ {
+ m_bEmptyIsNull = _rxInStream->readBoolean();
+
+ sal_uInt16 nAnyMask = _rxInStream->readShort();
+ if ((nAnyMask & DEFAULT_LONG) == DEFAULT_LONG)
+ {
+ sal_Int32 nValue = _rxInStream->readLong();
+ m_aDefault <<= (sal_Int32)nValue;
+ }
+ else if ((nAnyMask & DEFAULT_DOUBLE) == DEFAULT_DOUBLE)
+ {
+ double fValue = _rxInStream->readDouble();
+ m_aDefault <<= (double)fValue;
+ }
+
+ if ((nAnyMask & FILTERPROPOSAL) == FILTERPROPOSAL)
+ m_bFilterProposal = sal_True;
+ }
+
+ if (nVersion > 4)
+ readHelpTextCompatibly(_rxInStream);
+
+ if (bHandleCommonProps)
+ readCommonEditProperties(_rxInStream);
+
+ // Nach dem Lesen die Defaultwerte anzeigen
+ if ( getControlSource().getLength() )
+ // (not if we don't have a control source - the "State" property acts like it is persistent, then)
+ resetNoBroadcast();
+};
+
+//------------------------------------------------------------------------------
+void OEditBaseModel::defaultCommonEditProperties()
+{
+ OBoundControlModel::defaultCommonProperties();
+ // no own common properties at the moment
+}
+
+//------------------------------------------------------------------------------
+void OEditBaseModel::readCommonEditProperties(const Reference<XObjectInputStream>& _rxInStream)
+{
+ sal_Int32 nLen = _rxInStream->readLong();
+
+ Reference<XMarkableStream> xMark(_rxInStream, UNO_QUERY);
+ DBG_ASSERT(xMark.is(), "OBoundControlModel::readCommonProperties : can only work with markable streams !");
+ sal_Int32 nMark = xMark->createMark();
+
+ // read properties common to all OBoundControlModels
+ OBoundControlModel::readCommonProperties(_rxInStream);
+
+ // read properties common to all OEditBaseModels
+
+ // skip the remaining bytes
+ xMark->jumpToMark(nMark);
+ _rxInStream->skipBytes(nLen);
+ xMark->deleteMark(nMark);
+}
+
+//------------------------------------------------------------------------------
+void OEditBaseModel::writeCommonEditProperties(const Reference<XObjectOutputStream>& _rxOutStream)
+{
+ Reference<XMarkableStream> xMark(_rxOutStream, UNO_QUERY);
+ DBG_ASSERT(xMark.is(), "OEditBaseModel::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 properties common to all OBoundControlModels
+ OBoundControlModel::writeCommonProperties(_rxOutStream);
+
+ // write properties common to all OEditBaseModels
+
+ // close the block - write the correct length at the beginning
+ nLen = xMark->offsetToMark(nMark) - sizeof(nLen);
+ xMark->jumpToMark(nMark);
+ _rxOutStream->writeLong(nLen);
+ xMark->jumpToFurthest();
+ xMark->deleteMark(nMark);
+}
+
+//------------------------------------------------------------------------------
+void OEditBaseModel::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
+{
+ switch (nHandle)
+ {
+ case PROPERTY_ID_EMPTY_IS_NULL:
+ rValue <<= (sal_Bool)m_bEmptyIsNull;
+ break;
+ case PROPERTY_ID_FILTERPROPOSAL:
+ rValue <<= (sal_Bool)m_bFilterProposal;
+ break;
+ case PROPERTY_ID_DEFAULT_TEXT:
+ rValue <<= m_aDefaultText;
+ break;
+ case PROPERTY_ID_DEFAULT_VALUE:
+ case PROPERTY_ID_DEFAULT_DATE:
+ case PROPERTY_ID_DEFAULT_TIME:
+ rValue = m_aDefault;
+ break;
+ default:
+ OBoundControlModel::getFastPropertyValue(rValue, nHandle);
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OEditBaseModel::convertFastPropertyValue( Any& rConvertedValue, Any& rOldValue,
+ sal_Int32 nHandle, const Any& rValue ) throw( IllegalArgumentException )
+{
+ sal_Bool bModified(sal_False);
+ switch (nHandle)
+ {
+ case PROPERTY_ID_EMPTY_IS_NULL:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bEmptyIsNull);
+ break;
+ case PROPERTY_ID_FILTERPROPOSAL:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bFilterProposal);
+ break;
+ case PROPERTY_ID_DEFAULT_TEXT:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aDefaultText);
+ break;
+ case PROPERTY_ID_DEFAULT_VALUE:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aDefault, ::getCppuType((const double*)0));
+ break;
+ case PROPERTY_ID_DEFAULT_DATE:
+ case PROPERTY_ID_DEFAULT_TIME:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aDefault, ::getCppuType((const sal_Int32*)0));
+ break;
+ default:
+ bModified = OBoundControlModel::convertFastPropertyValue(
+ rConvertedValue,
+ rOldValue,
+ nHandle,
+ rValue);
+ }
+ return bModified;
+}
+
+//------------------------------------------------------------------------------
+void OEditBaseModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw ( ::com::sun::star::uno::Exception)
+{
+ switch (nHandle)
+ {
+ case PROPERTY_ID_EMPTY_IS_NULL:
+ DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_BOOLEAN, "invalid type" );
+ m_bEmptyIsNull = getBOOL(rValue);
+ break;
+ case PROPERTY_ID_FILTERPROPOSAL:
+ DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_BOOLEAN, "invalid type" );
+ m_bFilterProposal = getBOOL(rValue);
+ break;
+ // Aenderung der defaultwerte fuehrt zu reset
+ case PROPERTY_ID_DEFAULT_TEXT:
+ DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_STRING, "invalid type" );
+ rValue >>= m_aDefaultText;
+ resetNoBroadcast();
+ break;
+ case PROPERTY_ID_DEFAULT_VALUE:
+ case PROPERTY_ID_DEFAULT_DATE:
+ case PROPERTY_ID_DEFAULT_TIME:
+ m_aDefault = rValue;
+ resetNoBroadcast();
+ break;
+ default:
+ OBoundControlModel::setFastPropertyValue_NoBroadcast(nHandle, rValue );
+ }
+}
+
+//XPropertyState
+//------------------------------------------------------------------------------
+Any OEditBaseModel::getPropertyDefaultByHandle( sal_Int32 nHandle ) const
+{
+ switch (nHandle)
+ {
+ case PROPERTY_ID_DEFAULT_TEXT:
+ return makeAny(::rtl::OUString());
+ case PROPERTY_ID_FILTERPROPOSAL:
+ return Any(makeAny((sal_Bool)sal_False));
+ case PROPERTY_ID_DEFAULT_VALUE:
+ case PROPERTY_ID_DEFAULT_DATE:
+ case PROPERTY_ID_DEFAULT_TIME:
+ return Any();
+ default:
+ return OBoundControlModel::getPropertyDefaultByHandle(nHandle);
+ }
+}
+
+//.........................................................................
+}
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/EditBase.hxx b/forms/source/component/EditBase.hxx
new file mode 100644
index 000000000000..497fd570d522
--- /dev/null
+++ b/forms/source/component/EditBase.hxx
@@ -0,0 +1,115 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FORMS_EDITBASE_HXX_
+#define _FORMS_EDITBASE_HXX_
+
+#include "FormComponent.hxx"
+#include <tools/date.hxx>
+#include <tools/link.hxx>
+#include <com/sun/star/util/XNumberFormatter.hpp>
+#include <com/sun/star/awt/XFocusListener.hpp>
+#include <com/sun/star/awt/XKeyListener.hpp>
+#include <com/sun/star/form/XChangeBroadcaster.hpp>
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+
+// persistence flags for use with the version id
+#define PF_HANDLE_COMMON_PROPS 0x8000
+ // Derived classes which use their own persistence methods (read/write) and have an own
+ // version handling therein may want to clear this flag in getPersistenceFlags.
+ // If done so, this class will write an version without a call to writeCommonEditProperties.
+#define PF_FAKE_FORMATTED_FIELD 0x4000
+ // .... hmmm .... a fake, as the name suggests. see OFormattedFieldWrapper
+#define PF_RESERVED_2 0x2000
+#define PF_RESERVED_3 0x1000
+#define PF_RESERVED_4 0x0800
+#define PF_RESERVED_5 0x0400
+#define PF_RESERVED_6 0x0200
+#define PF_RESERVED_7 0x0100
+
+#define PF_SPECIAL_FLAGS 0xFF00
+
+//.........................................................................
+namespace frm
+{
+
+//==================================================================
+//= OEditBaseModel
+//==================================================================
+class OEditBaseModel : public OBoundControlModel
+{
+ sal_Int16 m_nLastReadVersion;
+
+protected:
+// [properties] fuer all Editierfelder
+ ::com::sun::star::uno::Any m_aDefault;
+ ::rtl::OUString m_aDefaultText; // default value
+ sal_Bool m_bEmptyIsNull : 1; // empty string will be interepreted as NULL when committing
+ sal_Bool m_bFilterProposal : 1; // use a list of possible value in filtermode
+// [properties]
+
+ sal_Int16 getLastReadVersion() const { return m_nLastReadVersion; }
+
+public:
+ DECLARE_DEFAULT_BOUND_XTOR( OEditBaseModel );
+
+ // XPersistObject
+ virtual void SAL_CALL write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ // XPropertySet
+ virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle ) const;
+ virtual sal_Bool SAL_CALL convertFastPropertyValue(::com::sun::star::uno::Any& rConvertedValue, ::com::sun::star::uno::Any& rOldValue,
+ sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
+ throw(::com::sun::star::lang::IllegalArgumentException);
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue) throw ( ::com::sun::star::uno::Exception);
+ using ::cppu::OPropertySetHelper::getFastPropertyValue;
+
+ // XPropertyState
+ virtual ::com::sun::star::uno::Any getPropertyDefaultByHandle( sal_Int32 nHandle ) const;
+
+protected:
+ // new properties common to all edit models should be handled with the following two methods
+ void SAL_CALL readCommonEditProperties(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream);
+ void SAL_CALL writeCommonEditProperties(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream);
+ void defaultCommonEditProperties();
+
+ virtual sal_uInt16 getPersistenceFlags() const;
+ // derived classes may use this if they want this base class to write additinal version flags
+ // (one of the PF_.... constants). After ::read they may ask for that flags with getLastReadVersion
+};
+
+//.........................................................................
+}
+//.........................................................................
+
+#endif // _FORMS_EDITBASE_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/EventThread.cxx b/forms/source/component/EventThread.cxx
new file mode 100644
index 000000000000..c729ae4350d4
--- /dev/null
+++ b/forms/source/component/EventThread.cxx
@@ -0,0 +1,242 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+#include "EventThread.hxx"
+#include <comphelper/guarding.hxx>
+#include <tools/debug.hxx>
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::lang;
+
+DBG_NAME( OComponentEventThread )
+OComponentEventThread::OComponentEventThread( ::cppu::OComponentHelper* pCompImpl ) :
+ m_pCompImpl( pCompImpl )
+{
+ DBG_CTOR( OComponentEventThread, NULL );
+
+ increment(m_refCount);
+
+ // Eine Referenz des Controls halten
+ {
+ InterfaceRef xIFace(static_cast<XWeak*>(pCompImpl));
+ query_interface(xIFace, m_xComp);
+ }
+
+ // und uns an dem Control anmelden
+ {
+ Reference<XEventListener> xEvtLstnr = static_cast<XEventListener*>(this);
+ m_xComp->addEventListener( xEvtLstnr );
+ }
+
+ decrement(m_refCount);
+}
+
+OComponentEventThread::~OComponentEventThread()
+{
+ DBG_DTOR( OComponentEventThread, NULL );
+
+ DBG_ASSERT( m_aEvents.size() == 0,
+ "OComponentEventThread::~OComponentEventThread: Kein dispose gerufen?" );
+
+ impl_clearEventQueue();
+}
+
+Any SAL_CALL OComponentEventThread::queryInterface(const Type& _rType) throw (RuntimeException)
+{
+ Any aReturn;
+
+ aReturn = OWeakObject::queryInterface(_rType);
+
+ if (!aReturn.hasValue())
+ aReturn = ::cppu::queryInterface(_rType,
+ static_cast<XEventListener*>(this)
+ );
+
+ return aReturn;
+}
+
+void OComponentEventThread::impl_clearEventQueue()
+{
+ while ( m_aEvents.size() )
+ {
+ delete *m_aEvents.begin();
+ m_aEvents.erase( m_aEvents.begin() );
+ }
+ m_aControls.erase( m_aControls.begin(), m_aControls.end() );
+ m_aFlags.erase( m_aFlags.begin(), m_aFlags.end() );
+}
+
+void OComponentEventThread::disposing( const EventObject& evt ) throw ( ::com::sun::star::uno::RuntimeException)
+{
+ if( evt.Source == m_xComp )
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ // Event-Listener abmelden
+ Reference<XEventListener> xEvtLstnr = static_cast<XEventListener*>(this);
+ m_xComp->removeEventListener( xEvtLstnr );
+
+ // Event-Queue loeschen
+ impl_clearEventQueue();
+
+ // Das Control loslassen und pCompImpl auf 0 setzen, damit der
+ // Thread weiss, dass er sich beenden soll.
+ m_xComp = 0;
+ m_pCompImpl = 0;
+
+ // Den Thread aufwecken und beenden.
+ m_aCond.set();
+ terminate();
+ }
+}
+
+void OComponentEventThread::addEvent( const EventObject* _pEvt, sal_Bool bFlag )
+{
+ Reference<XControl> xTmp;
+ addEvent( _pEvt, xTmp, bFlag );
+}
+
+void OComponentEventThread::addEvent( const EventObject* _pEvt,
+ const Reference<XControl>& rControl,
+ sal_Bool bFlag )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ // Daten in die Queue stellen
+ m_aEvents.push_back( cloneEvent( _pEvt ) );
+
+ Reference<XWeak> xWeakControl(rControl, UNO_QUERY);
+ Reference<XAdapter> xControlAdapter = xWeakControl.is() ? xWeakControl->queryAdapter() : Reference<XAdapter>();
+ m_aControls.push_back( xControlAdapter );
+
+ m_aFlags.push_back( bFlag );
+
+ // Thread aufwecken
+ m_aCond.set();
+}
+
+void OComponentEventThread::implStarted( )
+{
+ acquire( );
+}
+
+void OComponentEventThread::implTerminated( )
+{
+ release( );
+}
+
+void SAL_CALL OComponentEventThread::kill()
+{
+ OComponentEventThread_TBASE::terminate();
+ OComponentEventThread_TBASE::join();
+
+ implTerminated( );
+}
+
+void SAL_CALL OComponentEventThread::onTerminated()
+{
+ OComponentEventThread_TBASE::onTerminated();
+
+ implTerminated( );
+}
+
+void OComponentEventThread::run()
+{
+ implStarted( );
+
+ // uns selbst festhalten, damit wir nicht geloescht werden,
+ // wenn zwischendrinne mal ein dispose gerufen wird.
+ InterfaceRef xThis(static_cast<XWeak*>(this));
+
+ do
+ {
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ while( m_aEvents.size() > 0 )
+ {
+ // Das Control holen und festhalten, damit es waehrend des
+ // actionPerformed nicht geloescht werden kann.
+ Reference<XComponent> xComp = m_xComp;
+ ::cppu::OComponentHelper *pCompImpl = m_pCompImpl;
+
+ ThreadEvents::iterator firstEvent( m_aEvents.begin() );
+ EventObject* pEvt = *firstEvent;
+ m_aEvents.erase( firstEvent );
+
+ ThreadObjects::iterator firstControl( m_aControls.begin() );
+ Reference<XAdapter> xControlAdapter = *firstControl;
+ m_aControls.erase( firstControl );
+
+ ThreadBools::iterator firstFlag( m_aFlags.begin() );
+ sal_Bool bFlag = *firstFlag;
+ m_aFlags.erase( firstFlag );
+
+ {
+ MutexRelease aReleaseOnce(m_aMutex);
+ // Weil ein queryHardRef eine Exception schmeissen kann sollte
+ // es nicht bei gelocktem Mutex aufgerufen werden.
+ Reference<XControl> xControl;
+ if ( xControlAdapter.is() )
+ query_interface(xControlAdapter->queryAdapted(), xControl);
+
+ if( xComp.is() )
+ processEvent( pCompImpl, pEvt, xControl, bFlag );
+ }
+
+ delete pEvt;
+ };
+
+ // Nach einem dispose kennen wir das Control nicht mehr. Dann darf
+ // auch nicht gewartet werden.
+ if( !m_xComp.is() )
+ return;
+
+ // Warte-Bedingung zuruecksetzen
+ m_aCond.reset();
+ {
+ MutexRelease aReleaseOnce(m_aMutex);
+ // und warten ... falls nicht zwischenzeitlich doch noch ein
+ // Event eingetroffen ist.
+ m_aCond.wait();
+ }
+ }
+ while( sal_True );
+}
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/EventThread.hxx b/forms/source/component/EventThread.hxx
new file mode 100644
index 000000000000..195a354fbd7a
--- /dev/null
+++ b/forms/source/component/EventThread.hxx
@@ -0,0 +1,128 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FRM_EVENT_THREAD_HXX_
+#define _FRM_EVENT_THREAD_HXX_
+
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/lang/EventObject.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/awt/XControl.hpp>
+#include <osl/thread.hxx>
+
+
+#include <osl/conditn.hxx>
+#include <cppuhelper/component.hxx>
+#include <comphelper/stl_types.hxx>
+#include <comphelper/uno3.hxx>
+using namespace comphelper;
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+// ***************************************************************************************************
+// ***************************************************************************************************
+
+typedef ::osl::Thread OComponentEventThread_TBASE;
+class OComponentEventThread
+ :public OComponentEventThread_TBASE
+ ,public ::com::sun::star::lang::XEventListener
+ ,public ::cppu::OWeakObject
+{
+ DECLARE_STL_VECTOR(::com::sun::star::lang::EventObject*, ThreadEvents);
+ DECLARE_STL_VECTOR(::com::sun::star::uno::Reference< ::com::sun::star::uno::XAdapter> , ThreadObjects);
+ DECLARE_STL_VECTOR(sal_Bool, ThreadBools);
+
+ ::osl::Mutex m_aMutex;
+ ::osl::Condition m_aCond; // Queue gefuellt?
+ ThreadEvents m_aEvents; // Event-Queue
+ ThreadObjects m_aControls; // Control fuer Submit
+ ThreadBools m_aFlags; // Flags fuer Submit/Reset
+
+ ::cppu::OComponentHelper* m_pCompImpl; // Implementierung des Controls
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent> m_xComp; // ::com::sun::star::lang::XComponent des Controls
+
+protected:
+
+ // XThread
+ virtual void SAL_CALL run();
+
+ virtual void SAL_CALL kill();
+ virtual void SAL_CALL onTerminated();
+
+ // Die folgende Methode wird gerufen um das Event unter Beruecksichtigung
+ // seines Typs zu duplizieren.
+ virtual ::com::sun::star::lang::EventObject* cloneEvent(const ::com::sun::star::lang::EventObject* _pEvt) const = 0;
+
+ // Ein Event bearbeiten. Der Mutex ist dabei nicht gelockt, pCompImpl
+ // bleibt aber in jedem Fall gueltig. Bei pEvt kann es sich auch um
+ // einen abgeleiteten Typ handeln, naemlich den, den cloneEvent
+ // zurueckgibt. rControl ist nur gesetzt, wenn beim addEvent ein
+ // Control uebergeben wurde. Da das Control nur als WeakRef gehalten
+ // wird kann es auch zwischenzeitlich verschwinden.
+ virtual void processEvent( ::cppu::OComponentHelper* _pCompImpl,
+ const ::com::sun::star::lang::EventObject* _pEvt,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl>& _rControl,
+ sal_Bool _bFlag) = 0;
+
+public:
+
+ // UNO Anbindung
+ DECLARE_UNO3_DEFAULTS(OComponentEventThread, OWeakObject);
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface(const ::com::sun::star::uno::Type& _rType) throw (::com::sun::star::uno::RuntimeException);
+
+ OComponentEventThread(::cppu::OComponentHelper* pCompImpl);
+ virtual ~OComponentEventThread();
+
+ void addEvent( const ::com::sun::star::lang::EventObject* _pEvt, sal_Bool bFlag = sal_False );
+ void addEvent( const ::com::sun::star::lang::EventObject* _pEvt, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl>& rControl,
+ sal_Bool bFlag = sal_False );
+
+ // ::com::sun::star::lang::XEventListener
+ virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& _rSource ) throw (::com::sun::star::uno::RuntimeException);
+
+/* resolve ambiguity : both OWeakObject and OObject have these memory operators */
+ void * SAL_CALL operator new( size_t size ) throw() { return osl::Thread::operator new(size); }
+ void SAL_CALL operator delete( void * p ) throw() { osl::Thread::operator delete(p); }
+
+private:
+ void implStarted( );
+ void implTerminated( );
+
+ void impl_clearEventQueue();
+};
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+#endif // _FRM_EVENT_THREAD_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/File.cxx b/forms/source/component/File.cxx
new file mode 100644
index 000000000000..170241c6eba2
--- /dev/null
+++ b/forms/source/component/File.cxx
@@ -0,0 +1,306 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+
+
+#include "File.hxx"
+
+#include <com/sun/star/form/FormComponentType.hpp>
+
+#include "property.hrc"
+#include "services.hxx"
+#include <tools/debug.hxx>
+#include <comphelper/container.hxx>
+#include <comphelper/basicio.hxx>
+#include <comphelper/guarding.hxx>
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+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;
+
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL OFileControlModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
+{
+ return *(new OFileControlModel(_rxFactory));
+}
+
+//------------------------------------------------------------------------------
+Sequence<Type> OFileControlModel::_getTypes()
+{
+ static Sequence<Type> aTypes;
+ if (!aTypes.getLength())
+ {
+ // my base class
+ Sequence<Type> aBaseClassTypes = OControlModel::_getTypes();
+
+ Sequence<Type> aOwnTypes(1);
+ Type* pOwnTypes = aOwnTypes.getArray();
+ pOwnTypes[0] = getCppuType((Reference<XReset>*)NULL);
+
+ aTypes = concatSequences(aBaseClassTypes, aOwnTypes);
+ }
+ return aTypes;
+}
+
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+StringSequence OFileControlModel::getSupportedServiceNames() throw(RuntimeException)
+{
+ StringSequence aSupported = OControlModel::getSupportedServiceNames();
+ aSupported.realloc(aSupported.getLength() + 1);
+
+ ::rtl::OUString*pArray = aSupported.getArray();
+ pArray[aSupported.getLength()-1] = FRM_SUN_COMPONENT_FILECONTROL;
+ return aSupported;
+}
+
+//------------------------------------------------------------------
+DBG_NAME( OFileControlModel )
+//------------------------------------------------------------------
+OFileControlModel::OFileControlModel(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OControlModel(_rxFactory, VCL_CONTROLMODEL_FILECONTROL)
+ ,m_aResetListeners(m_aMutex)
+{
+ DBG_CTOR( OFileControlModel, NULL );
+ m_nClassId = FormComponentType::FILECONTROL;
+}
+
+//------------------------------------------------------------------
+OFileControlModel::OFileControlModel( const OFileControlModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
+ :OControlModel( _pOriginal, _rxFactory )
+ ,m_aResetListeners( m_aMutex )
+{
+ DBG_CTOR( OFileControlModel, NULL );
+
+ m_sDefaultValue = _pOriginal->m_sDefaultValue;
+}
+
+//------------------------------------------------------------------
+OFileControlModel::~OFileControlModel()
+{
+ if (!OComponentHelper::rBHelper.bDisposed)
+ {
+ acquire();
+ dispose();
+ }
+ DBG_DTOR( OFileControlModel, NULL );
+}
+
+//------------------------------------------------------------------------------
+IMPLEMENT_DEFAULT_CLONING( OFileControlModel )
+
+//------------------------------------------------------------------------------
+Any SAL_CALL OFileControlModel::queryAggregation(const Type& _rType) throw (RuntimeException)
+{
+ Any aReturn = OControlModel::queryAggregation(_rType);
+ if (!aReturn.hasValue())
+ aReturn = ::cppu::queryInterface(_rType
+ ,static_cast<XReset*>(this)
+ );
+
+ return aReturn;
+}
+
+// OComponentHelper
+//-----------------------------------------------------------------------------
+void OFileControlModel::disposing()
+{
+ OControlModel::disposing();
+
+ EventObject aEvt(static_cast<XWeak*>(this));
+ m_aResetListeners.disposeAndClear(aEvt);
+}
+
+//------------------------------------------------------------------------------
+Any OFileControlModel::getPropertyDefaultByHandle( sal_Int32 _nHandle ) const
+{
+ Any aReturn;
+ switch ( _nHandle )
+ {
+ case PROPERTY_ID_DEFAULT_TEXT:
+ return makeAny( ::rtl::OUString() );
+ }
+ return OControlModel::getPropertyDefaultByHandle( _nHandle );
+}
+
+//------------------------------------------------------------------------------
+void OFileControlModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle) const
+{
+ switch (nHandle)
+ {
+ case PROPERTY_ID_DEFAULT_TEXT : rValue <<= m_sDefaultValue; break;
+ default:
+ OControlModel::getFastPropertyValue(rValue, nHandle);
+ }
+}
+
+//------------------------------------------------------------------------------
+void OFileControlModel::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const Any& rValue) throw ( ::com::sun::star::uno::Exception)
+{
+ switch (nHandle)
+ {
+ case PROPERTY_ID_DEFAULT_TEXT :
+ DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_STRING, "OFileControlModel::setFastPropertyValue_NoBroadcast : invalid type !" );
+ rValue >>= m_sDefaultValue;
+ break;
+ default:
+ OControlModel::setFastPropertyValue_NoBroadcast(nHandle, rValue);
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OFileControlModel::convertFastPropertyValue(Any& rConvertedValue, Any& rOldValue, sal_Int32 nHandle, const Any& rValue)
+ throw( IllegalArgumentException )
+{
+ switch (nHandle)
+ {
+ case PROPERTY_ID_DEFAULT_TEXT :
+ return tryPropertyValue(rConvertedValue, rOldValue, rValue, m_sDefaultValue);
+ default:
+ return OControlModel::convertFastPropertyValue(rConvertedValue, rOldValue, nHandle, rValue);
+ }
+}
+
+//------------------------------------------------------------------------------
+void OFileControlModel::describeFixedProperties( Sequence< Property >& _rProps ) const
+{
+ BEGIN_DESCRIBE_PROPERTIES( 2, OControlModel )
+ DECL_PROP1(DEFAULT_TEXT, ::rtl::OUString, BOUND);
+ DECL_PROP1(TABINDEX, sal_Int16, BOUND);
+ END_DESCRIBE_PROPERTIES();
+}
+
+//------------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OFileControlModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException)
+{
+ return FRM_COMPONENT_FILECONTROL; // old (non-sun) name for compatibility !
+}
+
+//------------------------------------------------------------------------------
+void OFileControlModel::write(const Reference<stario::XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
+{
+ OControlModel::write(_rxOutStream);
+
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ // Version
+ _rxOutStream->writeShort(0x0002);
+ // Default-Wert
+ _rxOutStream << m_sDefaultValue;
+ writeHelpTextCompatibly(_rxOutStream);
+}
+
+//------------------------------------------------------------------------------
+void OFileControlModel::read(const Reference<stario::XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
+{
+ OControlModel::read(_rxInStream);
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ // Version
+ sal_uInt16 nVersion = _rxInStream->readShort();
+ // Default-Wert
+ switch (nVersion)
+ {
+ case 1:
+ _rxInStream >> m_sDefaultValue; break;
+ case 2:
+ _rxInStream >> m_sDefaultValue;
+ readHelpTextCompatibly(_rxInStream);
+ break;
+ default:
+ OSL_FAIL("OFileControlModel::read : unknown version !");
+ m_sDefaultValue = ::rtl::OUString();
+ }
+
+ // Nach dem Lesen die Defaultwerte anzeigen
+// _reset();
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL OFileControlModel::reset() throw ( ::com::sun::star::uno::RuntimeException)
+{
+ ::cppu::OInterfaceIteratorHelper aIter(m_aResetListeners);
+ EventObject aEvt(static_cast<XWeak*>(this));
+ sal_Bool bContinue = sal_True;
+ while (aIter.hasMoreElements() && bContinue)
+ bContinue =((XResetListener*)aIter.next())->approveReset(aEvt);
+
+ if (bContinue)
+ {
+ {
+ // Wenn Models threadSave
+ ::osl::MutexGuard aGuard(m_aMutex);
+ _reset();
+ }
+ m_aResetListeners.notifyEach( &XResetListener::resetted, aEvt );
+ }
+}
+
+//-----------------------------------------------------------------------------
+void OFileControlModel::addResetListener(const Reference<XResetListener>& _rxListener) throw ( ::com::sun::star::uno::RuntimeException)
+{
+ m_aResetListeners.addInterface(_rxListener);
+}
+
+//-----------------------------------------------------------------------------
+void OFileControlModel::removeResetListener(const Reference<XResetListener>& _rxListener) throw ( ::com::sun::star::uno::RuntimeException)
+{
+ m_aResetListeners.removeInterface(_rxListener);
+}
+
+//------------------------------------------------------------------------------
+void OFileControlModel::_reset()
+{
+ { // 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
+ MutexRelease aRelease(m_aMutex);
+ m_xAggregateSet->setPropertyValue(PROPERTY_TEXT, makeAny(m_sDefaultValue));
+ }
+}
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/File.hxx b/forms/source/component/File.hxx
new file mode 100644
index 000000000000..02a09eedc198
--- /dev/null
+++ b/forms/source/component/File.hxx
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FORMS_FILE_HXX_
+#define _FORMS_FILE_HXX_
+
+#include "FormComponent.hxx"
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+//==================================================================
+// OFileControlModel
+//==================================================================
+class OFileControlModel
+ :public OControlModel
+ ,public ::com::sun::star::form::XReset
+{
+ ::cppu::OInterfaceContainerHelper m_aResetListeners;
+ ::rtl::OUString m_sDefaultValue;
+
+protected:
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();
+
+public:
+ DECLARE_DEFAULT_LEAF_XTOR( OFileControlModel );
+
+ DECLARE_UNO3_AGG_DEFAULTS(OFileControlModel, OControlModel);
+ virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation(const ::com::sun::star::uno::Type& _rType) throw(::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ IMPLEMENTATION_NAME(OFileControlModel);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
+
+ // OComponentHelper
+ virtual void SAL_CALL disposing();
+
+ // XPropertySet and friends
+ virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const;
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue) throw ( ::com::sun::star::uno::Exception);
+
+ virtual sal_Bool SAL_CALL convertFastPropertyValue(::com::sun::star::uno::Any& rConvertedValue, ::com::sun::star::uno::Any& rOldValue, sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
+ throw(::com::sun::star::lang::IllegalArgumentException);
+
+ virtual ::com::sun::star::uno::Any getPropertyDefaultByHandle( sal_Int32 _nHandle ) const;
+
+ // XPersistObject
+ virtual ::rtl::OUString SAL_CALL getServiceName() throw ( ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw ( ::com ::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw ( ::com ::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ // XReset
+ virtual void SAL_CALL reset() throw ( ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addResetListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XResetListener>& _rxListener) throw ( ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeResetListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XResetListener>& _rxListener) throw ( ::com::sun::star::uno::RuntimeException);
+
+ // OControlModel's property handling
+ virtual void describeFixedProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps
+ ) const;
+
+ // prevent method hiding
+ using OControlModel::disposing;
+ using OControlModel::getFastPropertyValue;
+
+protected:
+ virtual void _reset();
+
+ DECLARE_XCLONEABLE();
+};
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+#endif // _FORMS_FILE_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/Filter.cxx b/forms/source/component/Filter.cxx
new file mode 100644
index 000000000000..69643053bed8
--- /dev/null
+++ b/forms/source/component/Filter.cxx
@@ -0,0 +1,913 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+
+
+#include "Filter.hxx"
+#include "FormComponent.hxx"
+#include "frm_module.hxx"
+#include "frm_resource.hrc"
+#include "frm_resource.hxx"
+#include "property.hrc"
+#include "property.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/awt/VclWindowPeerAttribute.hpp>
+#include <com/sun/star/awt/XCheckBox.hpp>
+#include <com/sun/star/awt/XComboBox.hpp>
+#include <com/sun/star/awt/XListBox.hpp>
+#include <com/sun/star/awt/XRadioButton.hpp>
+#include <com/sun/star/awt/XVclWindowPeer.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/form/FormComponentType.hpp>
+#include <com/sun/star/sdb/BooleanComparisonMode.hpp>
+#include <com/sun/star/sdb/XColumn.hpp>
+#include <com/sun/star/sdb/XSQLQueryComposerFactory.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/sdbc/XRowSet.hpp>
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <com/sun/star/awt/XItemList.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/numbers.hxx>
+#include <comphelper/property.hxx>
+#include <connectivity/dbconversion.hxx>
+#include <connectivity/dbtools.hxx>
+#include <connectivity/formattedcolumnvalue.hxx>
+#include <connectivity/predicateinput.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <tools/diagnose_ex.h>
+#include <unotools/localedatawrapper.hxx>
+#include <vcl/stdtext.hxx>
+#include <vcl/svapp.hxx>
+#include <tools/wintypes.hxx>
+
+//--------------------------------------------------------------------------
+extern "C" void SAL_CALL createRegistryInfo_OFilterControl()
+{
+ static ::frm::OMultiInstanceAutoRegistration< ::frm::OFilterControl > aAutoRegistration;
+}
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::awt;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::sdb;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::sdbcx;
+ using namespace ::com::sun::star::util;
+ using namespace ::com::sun::star::form;
+ using namespace ::com::sun::star::container;
+ using namespace ::com::sun::star::ui::dialogs;
+
+ using namespace ::connectivity;
+
+ //=====================================================================
+ // OFilterControl
+ //=====================================================================
+ //---------------------------------------------------------------------
+ OFilterControl::OFilterControl( const Reference< XMultiServiceFactory >& _rxORB )
+ :UnoControl( _rxORB )
+ ,m_aTextListeners( *this )
+ ,m_aParser( _rxORB )
+ ,m_nControlClass( FormComponentType::TEXTFIELD )
+ ,m_bFilterList( sal_False )
+ ,m_bMultiLine( sal_False )
+ ,m_bFilterListFilled( sal_False )
+ {
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool OFilterControl::ensureInitialized( )
+ {
+ if ( !m_xField.is() )
+ {
+ OSL_FAIL( "OFilterControl::ensureInitialized: improperly initialized: no field!" );
+ return sal_False;
+ }
+
+ if ( !m_xConnection.is() )
+ {
+ OSL_FAIL( "OFilterControl::ensureInitialized: improperly initialized: no connection!" );
+ return sal_False;
+ }
+
+ if ( !m_xFormatter.is() )
+ {
+ // we can create one from the connection, if it's an SDB connection
+ Reference< XNumberFormatsSupplier > xFormatSupplier = ::dbtools::getNumberFormats( m_xConnection, sal_True, maContext.getLegacyServiceFactory() );
+
+ if ( xFormatSupplier.is() )
+ {
+ maContext.createComponent( "com.sun.star.util.NumberFormatter", m_xFormatter );
+ if ( m_xFormatter.is() )
+ m_xFormatter->attachNumberFormatsSupplier( xFormatSupplier );
+ }
+ }
+ if ( !m_xFormatter.is() )
+ {
+ OSL_FAIL( "OFilterControl::ensureInitialized: no number formatter!" );
+ // no fallback anymore
+ return sal_False;
+ }
+
+ return sal_True;
+ }
+
+ //---------------------------------------------------------------------
+ Any SAL_CALL OFilterControl::queryAggregation( const Type & rType ) throw(RuntimeException)
+ {
+ Any aRet = UnoControl::queryAggregation( rType);
+ if(!aRet.hasValue())
+ aRet = OFilterControl_BASE::queryInterface(rType);
+
+ return aRet;
+ }
+
+ //------------------------------------------------------------------
+ ::rtl::OUString OFilterControl::GetComponentServiceName()
+ {
+ ::rtl::OUString aServiceName;
+ switch (m_nControlClass)
+ {
+ case FormComponentType::RADIOBUTTON:
+ aServiceName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("radiobutton") );
+ break;
+ case FormComponentType::CHECKBOX:
+ aServiceName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("checkbox") );
+ break;
+ case FormComponentType::COMBOBOX:
+ aServiceName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("combobox") );
+ break;
+ case FormComponentType::LISTBOX:
+ aServiceName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("listbox") );
+ break;
+ default:
+ if (m_bMultiLine)
+ aServiceName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MultiLineEdit") );
+ else
+ aServiceName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Edit") );
+ }
+ return aServiceName;
+ }
+
+ // XComponent
+ //---------------------------------------------------------------------
+ void OFilterControl::dispose() throw( RuntimeException )
+ {
+ EventObject aEvt(*this);
+ m_aTextListeners.disposeAndClear( aEvt );
+ UnoControl::dispose();
+ }
+
+ //---------------------------------------------------------------------
+ void OFilterControl::createPeer( const Reference< XToolkit > & rxToolkit, const Reference< XWindowPeer > & rParentPeer ) throw(RuntimeException)
+ {
+ UnoControl::createPeer( rxToolkit, rParentPeer );
+
+ try
+ {
+ Reference< XVclWindowPeer > xVclWindow( getPeer(), UNO_QUERY_THROW );
+ switch ( m_nControlClass )
+ {
+ case FormComponentType::CHECKBOX:
+ {
+ // checkboxes always have a tristate-mode
+ xVclWindow->setProperty( PROPERTY_TRISTATE, makeAny( sal_Bool( sal_True ) ) );
+ xVclWindow->setProperty( PROPERTY_STATE, makeAny( sal_Int32( STATE_DONTKNOW ) ) );
+
+ Reference< XCheckBox > xBox( getPeer(), UNO_QUERY_THROW );
+ xBox->addItemListener( this );
+
+ }
+ break;
+
+ case FormComponentType::RADIOBUTTON:
+ {
+ xVclWindow->setProperty( PROPERTY_STATE, makeAny( sal_Int32( STATE_NOCHECK ) ) );
+
+ Reference< XRadioButton > xRadio( getPeer(), UNO_QUERY_THROW );
+ xRadio->addItemListener( this );
+ }
+ break;
+
+ case FormComponentType::LISTBOX:
+ {
+ Reference< XListBox > xListBox( getPeer(), UNO_QUERY_THROW );
+ xListBox->addItemListener( this );
+ }
+ // no break
+
+ case FormComponentType::COMBOBOX:
+ {
+ xVclWindow->setProperty(PROPERTY_AUTOCOMPLETE, makeAny( sal_Bool( sal_True ) ) );
+ }
+ // no break
+
+ default:
+ {
+ Reference< XWindow > xWindow( getPeer(), UNO_QUERY );
+ xWindow->addFocusListener( this );
+
+ Reference< XTextComponent > xText( getPeer(), UNO_QUERY );
+ if (xText.is())
+ xText->setMaxTextLen(0);
+ }
+ break;
+ }
+
+ OControl::initFormControlPeer( getPeer() );
+
+ // filter controls are _never_ readonly
+ Reference< XPropertySet > xModel( getModel(), UNO_QUERY_THROW );
+ Reference< XPropertySetInfo > xModelPSI( xModel->getPropertySetInfo(), UNO_SET_THROW );
+ if ( xModelPSI->hasPropertyByName( PROPERTY_READONLY ) )
+ xVclWindow->setProperty( PROPERTY_READONLY, makeAny( sal_Bool( sal_False ) ) );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ if (m_bFilterList)
+ m_bFilterListFilled = sal_False;
+ }
+
+ //---------------------------------------------------------------------
+ void OFilterControl::PrepareWindowDescriptor( WindowDescriptor& rDescr )
+ {
+ if (m_bFilterList)
+ rDescr.WindowAttributes |= VclWindowPeerAttribute::DROPDOWN;
+ }
+
+ //---------------------------------------------------------------------
+ void OFilterControl::ImplSetPeerProperty( const ::rtl::OUString& rPropName, const Any& rVal )
+ {
+ // these properties are ignored
+ if (rPropName == PROPERTY_TEXT ||
+ rPropName == PROPERTY_STATE)
+ return;
+
+ UnoControl::ImplSetPeerProperty( rPropName, rVal );
+ }
+
+ // XEventListener
+ //---------------------------------------------------------------------
+ void SAL_CALL OFilterControl::disposing(const EventObject& Source) throw( RuntimeException )
+ {
+ UnoControl::disposing(Source);
+ }
+
+ // XItemListener
+ //---------------------------------------------------------------------
+ void SAL_CALL OFilterControl::itemStateChanged( const ItemEvent& rEvent ) throw(RuntimeException)
+ {
+ ::rtl::OUStringBuffer aText;
+ switch (m_nControlClass)
+ {
+ case FormComponentType::CHECKBOX:
+ {
+ if ( ( rEvent.Selected == STATE_CHECK ) || ( rEvent.Selected == STATE_NOCHECK ) )
+ {
+ sal_Int32 nBooleanComparisonMode = ::dbtools::DatabaseMetaData( m_xConnection ).getBooleanComparisonMode();
+
+ bool bSelected = ( rEvent.Selected == STATE_CHECK );
+
+ ::rtl::OUString sExpressionMarker( RTL_CONSTASCII_USTRINGPARAM( "$expression$" ) );
+ ::dbtools::getBoleanComparisonPredicate(
+ sExpressionMarker,
+ bSelected,
+ nBooleanComparisonMode,
+ aText
+ );
+
+ ::rtl::OUString sText( aText.makeStringAndClear() );
+ sal_Int32 nMarkerPos( sText.indexOf( sExpressionMarker ) );
+ OSL_ENSURE( nMarkerPos == 0, "OFilterControl::itemStateChanged: unsupported boolean comparison mode!" );
+ // If this assertion fails, then getBoleanComparisonPredicate created a predicate which
+ // does not start with the expression we gave it. The only known case is when
+ // the comparison mode is ACCESS_COMPAT, and the value is TRUE. In this case,
+ // the expression is rather complex.
+ // Well, so this is a known issue - the filter controls (and thus the form based filter)
+ // do not work with boolean MS Access fields.
+ // To fix this, we would probably have to revert here to always return "1" or "0" as normalized
+ // filter, and change our client code to properly translate this (which could be some effort).
+ if ( nMarkerPos == 0 )
+ aText.append( sText.copy( sExpressionMarker.getLength() ) );
+ else
+ {
+ // fallback
+ aText.appendAscii( bSelected ? "1" : "0" );
+ }
+ }
+ }
+ break;
+
+ case FormComponentType::LISTBOX:
+ {
+ try
+ {
+ const Reference< XItemList > xItemList( getModel(), UNO_QUERY_THROW );
+ ::rtl::OUString sItemText( xItemList->getItemText( rEvent.Selected ) );
+
+ const MapString2String::const_iterator itemPos = m_aDisplayItemToValueItem.find( sItemText );
+ if ( itemPos != m_aDisplayItemToValueItem.end() )
+ {
+ sItemText = itemPos->second;
+ if ( sItemText.getLength() )
+ {
+ ::dbtools::OPredicateInputController aPredicateInput( maContext.getLegacyServiceFactory(), m_xConnection, getParseContext() );
+ ::rtl::OUString sErrorMessage;
+ OSL_VERIFY( aPredicateInput.normalizePredicateString( sItemText, m_xField, &sErrorMessage ) );
+ }
+ }
+ aText.append( sItemText );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+ break;
+
+ case FormComponentType::RADIOBUTTON:
+ {
+ if ( rEvent.Selected == STATE_CHECK )
+ aText.append( ::comphelper::getString( Reference< XPropertySet >( getModel(), UNO_QUERY )->getPropertyValue( PROPERTY_REFVALUE ) ) );
+ }
+ break;
+ }
+
+ ::rtl::OUString sText( aText.makeStringAndClear() );
+ if ( m_aText.compareTo( sText ) )
+ {
+ m_aText = sText;
+ TextEvent aEvt;
+ aEvt.Source = *this;
+ ::cppu::OInterfaceIteratorHelper aIt( m_aTextListeners );
+ while( aIt.hasMoreElements() )
+ ((XTextListener *)aIt.next())->textChanged( aEvt );
+ }
+ }
+
+ //---------------------------------------------------------------------
+ void OFilterControl::implInitFilterList()
+ {
+ if ( !ensureInitialized( ) )
+ // already asserted in ensureInitialized
+ return;
+
+ // ensure the cursor and the statement are disposed as soon as we leave
+ ::utl::SharedUNOComponent< XResultSet > xListCursor;
+ ::utl::SharedUNOComponent< XStatement > xStatement;
+
+ try
+ {
+ m_bFilterListFilled = sal_True;
+
+ if ( !m_xField.is() )
+ return;
+
+ ::rtl::OUString sFieldName;
+ m_xField->getPropertyValue( PROPERTY_NAME ) >>= sFieldName;
+
+ // here we need a table to which the field belongs to
+ const Reference< XChild > xModelAsChild( getModel(), UNO_QUERY_THROW );
+ const Reference< XRowSet > xForm( xModelAsChild->getParent(), UNO_QUERY_THROW );
+ const Reference< XPropertySet > xFormProps( xForm, UNO_QUERY_THROW );
+
+ // create a query composer
+ Reference< XColumnsSupplier > xSuppColumns;
+ xFormProps->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SingleSelectQueryComposer"))) >>= xSuppColumns;
+
+ const Reference< XConnection > xConnection( ::dbtools::getConnection( xForm ), UNO_SET_THROW );
+ const Reference< XNameAccess > xFieldNames( xSuppColumns->getColumns(), UNO_SET_THROW );
+ if ( !xFieldNames->hasByName( sFieldName ) )
+ return;
+ ::rtl::OUString sRealFieldName, sTableName;
+ const Reference< XPropertySet > xComposerFieldProps( xFieldNames->getByName( sFieldName ), UNO_QUERY_THROW );
+ xComposerFieldProps->getPropertyValue( PROPERTY_REALNAME ) >>= sRealFieldName;
+ xComposerFieldProps->getPropertyValue( PROPERTY_TABLENAME ) >>= sTableName;
+
+ // obtain the table of the field
+ const Reference< XTablesSupplier > xSuppTables( xSuppColumns, UNO_QUERY_THROW );
+ const Reference< XNameAccess > xTablesNames( xSuppTables->getTables(), UNO_SET_THROW );
+ const Reference< XNamed > xNamedTable( xTablesNames->getByName( sTableName ), UNO_QUERY_THROW );
+ sTableName = xNamedTable->getName();
+
+ // create a statement selecting all values for the given field
+ ::rtl::OUStringBuffer aStatement;
+
+ const Reference< XDatabaseMetaData > xMeta( xConnection->getMetaData(), UNO_SET_THROW );
+ const ::rtl::OUString sQuoteChar = xMeta->getIdentifierQuoteString();
+
+ aStatement.appendAscii( "SELECT DISTINCT " );
+ aStatement.append( sQuoteChar );
+ aStatement.append( sRealFieldName );
+ aStatement.append( sQuoteChar );
+
+ // if the field had an alias in our form's statement, give it this alias in the new statement, too
+ if ( sFieldName.getLength() && ( sFieldName != sRealFieldName ) )
+ {
+ aStatement.appendAscii(" AS ");
+ aStatement.append( sQuoteChar );
+ aStatement.append( sFieldName );
+ aStatement.append( sQuoteChar );
+ }
+
+ aStatement.appendAscii( " FROM " );
+
+ ::rtl::OUString sCatalog, sSchema, sTable;
+ ::dbtools::qualifiedNameComponents( xMeta, sTableName, sCatalog, sSchema, sTable, ::dbtools::eInDataManipulation );
+ aStatement.append( ::dbtools::composeTableNameForSelect( xConnection, sCatalog, sSchema, sTable ) );
+
+ // execute the statement
+ xStatement.reset( xConnection->createStatement() );
+ const ::rtl::OUString sSelectStatement( aStatement.makeStringAndClear( ) );
+ xListCursor.reset( xStatement->executeQuery( sSelectStatement ) );
+
+ // retrieve the one column which we take the values from
+ const Reference< XColumnsSupplier > xSupplyCols( xListCursor, UNO_QUERY_THROW );
+ const Reference< XIndexAccess > xFields( xSupplyCols->getColumns(), UNO_QUERY_THROW );
+ const Reference< XPropertySet > xDataField( xFields->getByIndex(0), UNO_QUERY_THROW );
+
+ // ensure the values will be formatted according to the field format
+ const ::dbtools::FormattedColumnValue aFormatter( m_xFormatter, xDataField );
+
+ ::std::vector< ::rtl::OUString > aProposals;
+ aProposals.reserve(16);
+
+ while ( xListCursor->next() && ( aProposals.size() < size_t( SHRT_MAX ) ) )
+ {
+ const ::rtl::OUString sCurrentValue = aFormatter.getFormattedValue();
+ aProposals.push_back( sCurrentValue );
+ }
+
+ // fill the list items into our peer
+ Sequence< ::rtl::OUString> aStringSeq( aProposals.size() );
+ ::std::copy( aProposals.begin(), aProposals.end(), aStringSeq.getArray() );
+
+ const Reference< XComboBox > xComboBox( getPeer(), UNO_QUERY_THROW );
+ xComboBox->addItems( aStringSeq, 0 );
+
+ // set the drop down line count to something reasonable
+ const sal_Int16 nLineCount = ::std::min( sal_Int16( 16 ), sal_Int16( aStringSeq.getLength() ) );
+ xComboBox->setDropDownLineCount( nLineCount );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ // XFocusListener
+ //---------------------------------------------------------------------
+ void SAL_CALL OFilterControl::focusGained(const FocusEvent& /*e*/) throw( RuntimeException )
+ {
+ // should we fill the combobox?
+ if (m_bFilterList && !m_bFilterListFilled)
+ implInitFilterList();
+ }
+
+ //---------------------------------------------------------------------
+ void SAL_CALL OFilterControl::focusLost(const FocusEvent& /*e*/) throw( RuntimeException )
+ {
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool SAL_CALL OFilterControl::commit() throw(RuntimeException)
+ {
+ if ( !ensureInitialized( ) )
+ // already asserted in ensureInitialized
+ return sal_True;
+
+ ::rtl::OUString aText;
+ switch (m_nControlClass)
+ {
+ case FormComponentType::TEXTFIELD:
+ case FormComponentType::COMBOBOX:
+ {
+ Reference< XTextComponent > xText( getPeer(), UNO_QUERY );
+ if (xText.is())
+ aText = xText->getText();
+ } break;
+ default:
+ return sal_True;
+ }
+ if (m_aText.compareTo(aText))
+ {
+ // check the text with the SQL-Parser
+ ::rtl::OUString aNewText(aText);
+ aNewText.trim();
+ if ( aNewText.getLength() )
+ {
+ ::dbtools::OPredicateInputController aPredicateInput( maContext.getLegacyServiceFactory(), m_xConnection, getParseContext() );
+ ::rtl::OUString sErrorMessage;
+ if ( !aPredicateInput.normalizePredicateString( aNewText, m_xField, &sErrorMessage ) )
+ {
+ // display the error and outta here
+ SQLContext aError;
+ aError.Message = String( FRM_RES_STRING( RID_STR_SYNTAXERROR ) );
+ aError.Details = sErrorMessage;
+ displayException( aError );
+ return sal_False;
+ }
+ }
+
+ setText(aNewText);
+ TextEvent aEvt;
+ aEvt.Source = *this;
+ ::cppu::OInterfaceIteratorHelper aIt( m_aTextListeners );
+ while( aIt.hasMoreElements() )
+ static_cast< XTextListener* >( aIt.next() )->textChanged( aEvt );
+ }
+ return sal_True;
+ }
+
+ // XTextComponent
+ //---------------------------------------------------------------------
+ void SAL_CALL OFilterControl::addTextListener(const Reference< XTextListener > & l) throw(RuntimeException)
+ {
+ m_aTextListeners.addInterface( l );
+ }
+
+ //---------------------------------------------------------------------
+ void SAL_CALL OFilterControl::removeTextListener(const Reference< XTextListener > & l) throw(RuntimeException)
+ {
+ m_aTextListeners.removeInterface( l );
+ }
+
+ //---------------------------------------------------------------------
+ void SAL_CALL OFilterControl::setText( const ::rtl::OUString& aText ) throw(RuntimeException)
+ {
+ if ( !ensureInitialized( ) )
+ // already asserted in ensureInitialized
+ return;
+
+ switch (m_nControlClass)
+ {
+ case FormComponentType::CHECKBOX:
+ {
+ Reference< XVclWindowPeer > xVclWindow( getPeer(), UNO_QUERY );
+ if (xVclWindow.is())
+ {
+ Any aValue;
+ if ( aText.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "1" ) )
+ || aText.equalsIgnoreAsciiCaseAscii( "TRUE" )
+ || aText.equalsIgnoreAsciiCaseAscii( "IS TRUE" )
+ )
+ {
+ aValue <<= (sal_Int32)STATE_CHECK;
+ }
+ else if ( aText.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "0" ) )
+ || aText.equalsIgnoreAsciiCaseAscii( "FALSE" )
+ )
+ {
+ aValue <<= (sal_Int32)STATE_NOCHECK;
+ }
+ else
+ aValue <<= (sal_Int32)STATE_DONTKNOW;
+
+ m_aText = aText;
+ xVclWindow->setProperty( PROPERTY_STATE, aValue );
+ }
+ } break;
+ case FormComponentType::RADIOBUTTON:
+ {
+ Reference< XVclWindowPeer > xVclWindow( getPeer(), UNO_QUERY );
+ if (xVclWindow.is())
+ {
+ ::rtl::OUString aRefText = ::comphelper::getString(com::sun::star::uno::Reference< XPropertySet > (getModel(), UNO_QUERY)->getPropertyValue(PROPERTY_REFVALUE));
+ Any aValue;
+ if (aText == aRefText)
+ aValue <<= (sal_Int32)STATE_CHECK;
+ else
+ aValue <<= (sal_Int32)STATE_NOCHECK;
+ m_aText = aText;
+ xVclWindow->setProperty(PROPERTY_STATE, aValue);
+ }
+ } break;
+ case FormComponentType::LISTBOX:
+ {
+ Reference< XListBox > xListBox( getPeer(), UNO_QUERY );
+ if (xListBox.is())
+ {
+ m_aText = aText;
+ xListBox->selectItem(m_aText, sal_True);
+ if ( xListBox->getSelectedItemPos() >= 0 )
+ {
+ const bool isQuoted = ( aText.getLength() > 0 )
+ && ( aText[0] == '\'' )
+ && ( aText[aText.getLength() - 1] == '\'' );
+ if ( isQuoted )
+ {
+ xListBox->selectItem( aText.copy( 1, aText.getLength() - 2 ), sal_True );
+ }
+ }
+ }
+ } break;
+ default:
+ {
+ Reference< XTextComponent > xText( getPeer(), UNO_QUERY );
+ if (xText.is())
+ {
+ m_aText = aText;
+ xText->setText(aText);
+ }
+ }
+ }
+ }
+
+ //---------------------------------------------------------------------
+ void SAL_CALL OFilterControl::insertText( const ::com::sun::star::awt::Selection& rSel, const ::rtl::OUString& aText ) throw(::com::sun::star::uno::RuntimeException)
+ {
+ Reference< XTextComponent > xText( getPeer(), UNO_QUERY );
+ if (xText.is())
+ {
+ xText->insertText(rSel, aText);
+ m_aText = xText->getText();
+ }
+ }
+
+ //---------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL OFilterControl::getText() throw(RuntimeException)
+ {
+ return m_aText;
+ }
+
+ //---------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL OFilterControl::getSelectedText( void ) throw(RuntimeException)
+ {
+ ::rtl::OUString aSelected;
+ Reference< XTextComponent > xText( getPeer(), UNO_QUERY );
+ if (xText.is())
+ aSelected = xText->getSelectedText();
+
+ return aSelected;
+ }
+
+ //---------------------------------------------------------------------
+ void SAL_CALL OFilterControl::setSelection( const ::com::sun::star::awt::Selection& aSelection ) throw(::com::sun::star::uno::RuntimeException)
+ {
+ Reference< XTextComponent > xText( getPeer(), UNO_QUERY );
+ if (xText.is())
+ xText->setSelection( aSelection );
+ }
+
+ //---------------------------------------------------------------------
+ ::com::sun::star::awt::Selection SAL_CALL OFilterControl::getSelection( void ) throw(::com::sun::star::uno::RuntimeException)
+ {
+ ::com::sun::star::awt::Selection aSel;
+ Reference< XTextComponent > xText( getPeer(), UNO_QUERY );
+ if (xText.is())
+ aSel = xText->getSelection();
+ return aSel;
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool SAL_CALL OFilterControl::isEditable( void ) throw(RuntimeException)
+ {
+ Reference< XTextComponent > xText( getPeer(), UNO_QUERY );
+ return xText.is() && xText->isEditable();
+ }
+
+ //---------------------------------------------------------------------
+ void SAL_CALL OFilterControl::setEditable( sal_Bool bEditable ) throw(RuntimeException)
+ {
+ Reference< XTextComponent > xText( getPeer(), UNO_QUERY );
+ if (xText.is())
+ xText->setEditable(bEditable);
+ }
+
+ //---------------------------------------------------------------------
+ sal_Int16 SAL_CALL OFilterControl::getMaxTextLen() throw(RuntimeException)
+ {
+ Reference< XTextComponent > xText( getPeer(), UNO_QUERY );
+ return xText.is() ? xText->getMaxTextLen() : 0;
+ }
+
+ //---------------------------------------------------------------------
+ void SAL_CALL OFilterControl::setMaxTextLen( sal_Int16 nLength ) throw(RuntimeException)
+ {
+ Reference< XTextComponent > xText( getPeer(), UNO_QUERY );
+ if (xText.is())
+ xText->setMaxTextLen(nLength);
+ }
+
+ //---------------------------------------------------------------------
+ void OFilterControl::displayException( const ::com::sun::star::sdb::SQLContext& _rExcept )
+ {
+ try
+ {
+ Sequence< Any > aArgs(2);
+ aArgs[0] <<= PropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SQLException") ), 0, makeAny( _rExcept ), PropertyState_DIRECT_VALUE);
+ aArgs[1] <<= PropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParentWindow") ), 0, makeAny( m_xMessageParent ), PropertyState_DIRECT_VALUE);
+
+ static ::rtl::OUString s_sDialogServiceName (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.ErrorMessageDialog") );
+
+ Reference< XExecutableDialog > xErrorDialog( maContext.createComponentWithArguments( s_sDialogServiceName, aArgs ), UNO_QUERY );
+ if ( xErrorDialog.is() )
+ xErrorDialog->execute();
+ else
+ {
+ Window* pMessageParent = VCLUnoHelper::GetWindow( m_xMessageParent );
+ ShowServiceNotAvailableError( pMessageParent, s_sDialogServiceName, sal_True );
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ //---------------------------------------------------------------------
+ void SAL_CALL OFilterControl::initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException)
+ {
+ const Any* pArguments = aArguments.getConstArray();
+ const Any* pArgumentsEnd = pArguments + aArguments.getLength();
+
+ PropertyValue aProp;
+ NamedValue aValue;
+ const ::rtl::OUString* pName = NULL;
+ const Any* pValue = NULL;
+
+ for ( ; pArguments != pArgumentsEnd; ++pArguments )
+ {
+ // we recognize PropertyValues and NamedValues
+ if ( *pArguments >>= aProp )
+ {
+ pName = &aProp.Name;
+ pValue = &aProp.Value;
+ }
+ else if ( *pArguments >>= aValue )
+ {
+ pName = &aValue.Name;
+ pValue = &aValue.Value;
+ }
+ else
+ {
+ OSL_FAIL( "OFilterControl::initialize: unrecognized argument!" );
+ continue;
+ }
+
+ if ( 0 == pName->compareToAscii( "MessageParent" ) )
+ {
+ // the message parent
+ *pValue >>= m_xMessageParent;
+ OSL_ENSURE( m_xMessageParent.is(), "OFilterControl::initialize: invalid MessageParent!" );
+ }
+ else if ( 0 == pName->compareToAscii( "NumberFormatter" ) )
+ {
+ // the number format. This argument is optional.
+ *pValue >>= m_xFormatter;
+ OSL_ENSURE( m_xFormatter.is(), "OFilterControl::initialize: invalid NumberFormatter!" );
+ }
+ else if ( 0 == pName->compareToAscii( "ControlModel" ) )
+ {
+ // the control model for which we act as filter control
+ Reference< XPropertySet > xControlModel;
+ if ( !(*pValue >>= xControlModel ) || !xControlModel.is() )
+ {
+ OSL_FAIL( "OFilterControl::initialize: invalid control model argument!" );
+ continue;
+ }
+
+ // some properties which are "derived" from the control model we're working for
+ // ...................................................
+ // the field
+ m_xField.clear();
+ OSL_ENSURE( ::comphelper::hasProperty( PROPERTY_BOUNDFIELD, xControlModel ), "OFilterControl::initialize: control model needs a bound field property!" );
+ xControlModel->getPropertyValue( PROPERTY_BOUNDFIELD ) >>= m_xField;
+
+ // ...................................................
+ // filter list and control class
+ m_bFilterList = ::comphelper::hasProperty( PROPERTY_FILTERPROPOSAL, xControlModel ) && ::comphelper::getBOOL( xControlModel->getPropertyValue( PROPERTY_FILTERPROPOSAL ) );
+ if ( m_bFilterList )
+ m_nControlClass = FormComponentType::COMBOBOX;
+ else
+ {
+ sal_Int16 nClassId = ::comphelper::getINT16( xControlModel->getPropertyValue( PROPERTY_CLASSID ) );
+ switch (nClassId)
+ {
+ case FormComponentType::CHECKBOX:
+ case FormComponentType::RADIOBUTTON:
+ case FormComponentType::LISTBOX:
+ case FormComponentType::COMBOBOX:
+ m_nControlClass = nClassId;
+ if ( FormComponentType::LISTBOX == nClassId )
+ {
+ Sequence< ::rtl::OUString > aDisplayItems;
+ OSL_VERIFY( xControlModel->getPropertyValue( PROPERTY_STRINGITEMLIST ) >>= aDisplayItems );
+ Sequence< ::rtl::OUString > aValueItems;
+ OSL_VERIFY( xControlModel->getPropertyValue( PROPERTY_VALUE_SEQ ) >>= aValueItems );
+ OSL_ENSURE( aDisplayItems.getLength() == aValueItems.getLength(), "OFilterControl::initialize: inconsistent item lists!" );
+ for ( sal_Int32 i=0; i < ::std::min( aDisplayItems.getLength(), aValueItems.getLength() ); ++i )
+ m_aDisplayItemToValueItem[ aDisplayItems[i] ] = aValueItems[i];
+ }
+ break;
+ default:
+ m_bMultiLine = ::comphelper::hasProperty( PROPERTY_MULTILINE, xControlModel ) && ::comphelper::getBOOL( xControlModel->getPropertyValue( PROPERTY_MULTILINE ) );
+ m_nControlClass = FormComponentType::TEXTFIELD;
+ break;
+ }
+ }
+
+ // ...................................................
+ // the connection meta data for the form which we're working for
+ Reference< XChild > xModel( xControlModel, UNO_QUERY );
+ Reference< XRowSet > xForm;
+ if ( xModel.is() )
+ xForm = xForm.query( xModel->getParent() );
+ m_xConnection = ::dbtools::getConnection( xForm );
+ OSL_ENSURE( m_xConnection.is(), "OFilterControl::initialize: unable to determine the form's connection!" );
+ }
+ }
+ }
+
+ //---------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL OFilterControl::getImplementationName( ) throw (RuntimeException)
+ {
+ return getImplementationName_Static();
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool SAL_CALL OFilterControl::supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException)
+ {
+ Sequence< ::rtl::OUString > aSupported( getSupportedServiceNames() );
+ const ::rtl::OUString* pArray = aSupported.getConstArray();
+ for( sal_Int32 i = 0; i < aSupported.getLength(); ++i, ++pArray )
+ if( pArray->equals( ServiceName ) )
+ return sal_True;
+ return sal_False;
+ }
+
+ //---------------------------------------------------------------------
+ Sequence< ::rtl::OUString > SAL_CALL OFilterControl::getSupportedServiceNames( ) throw (RuntimeException)
+ {
+ return getSupportedServiceNames_Static();
+ }
+
+ //---------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL OFilterControl::getImplementationName_Static()
+ {
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.forms.OFilterControl" ) );
+ }
+
+ //---------------------------------------------------------------------
+ Sequence< ::rtl::OUString > SAL_CALL OFilterControl::getSupportedServiceNames_Static()
+ {
+ Sequence< ::rtl::OUString > aNames( 2 );
+ aNames[ 0 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.control.FilterControl" ) );
+ aNames[ 1 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControl" ) );
+ return aNames;
+ }
+
+ //---------------------------------------------------------------------
+ Reference< XInterface > SAL_CALL OFilterControl::Create( const Reference< XMultiServiceFactory >& _rxFactory )
+ {
+ return static_cast< XServiceInfo* >( new OFilterControl( _rxFactory ) );
+ }
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/Filter.hxx b/forms/source/component/Filter.hxx
new file mode 100644
index 000000000000..97b291db9fbb
--- /dev/null
+++ b/forms/source/component/Filter.hxx
@@ -0,0 +1,161 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef FORMS_COMPONENT_FILTER_HXX
+#define FORMS_COMPONENT_FILTER_HXX
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/form/XBoundComponent.hpp>
+#include <com/sun/star/util/XNumberFormatter.hpp>
+#include <com/sun/star/awt/XTextComponent.hpp>
+#include <com/sun/star/sdb/SQLContext.hpp>
+#include <toolkit/controls/unocontrol.hxx>
+
+#include <toolkit/helper/listenermultiplexer.hxx>
+#include <cppuhelper/implbase5.hxx>
+#include <comphelper/uno3.hxx>
+#include <comphelper/componentcontext.hxx>
+#include <cppuhelper/implbase4.hxx>
+#include <connectivity/sqlparse.hxx>
+#include <svx/ParseContext.hxx>
+
+#include <boost/unordered_map.hpp>
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+ //=====================================================================
+ // OFilterControl
+ //=====================================================================
+ typedef ::cppu::ImplHelper5 < ::com::sun::star::awt::XTextComponent
+ , ::com::sun::star::awt::XFocusListener
+ , ::com::sun::star::awt::XItemListener
+ , ::com::sun::star::form::XBoundComponent
+ , ::com::sun::star::lang::XInitialization
+ > OFilterControl_BASE;
+
+ class OFilterControl :public UnoControl
+ ,public OFilterControl_BASE
+ ,public ::svxform::OParseContextClient
+ {
+ TextListenerMultiplexer m_aTextListeners;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > m_xField;
+ ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter > m_xFormatter;
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > m_xConnection;
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData > m_xMetaData;
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > m_xMessageParent;
+
+ typedef ::boost::unordered_map< ::rtl::OUString, ::rtl::OUString, ::rtl::OUStringHash > MapString2String;
+ MapString2String m_aDisplayItemToValueItem;
+
+ ::rtl::OUString m_aText;
+ ::connectivity::OSQLParser m_aParser;
+ sal_Int16 m_nControlClass; // which kind of control do we use?
+ sal_Bool m_bFilterList : 1;
+ sal_Bool m_bMultiLine : 1;
+ sal_Bool m_bFilterListFilled : 1;
+
+ private:
+// OFilterControl(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB);
+
+ void implInitFilterList();
+
+ public:
+ OFilterControl( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB );
+
+ DECLARE_UNO3_AGG_DEFAULTS(OFilterControl,OWeakAggObject);
+ ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException);
+
+ virtual ::rtl::OUString GetComponentServiceName();
+ virtual void SAL_CALL createPeer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit > & rxToolkit, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > & rParentPeer ) throw( ::com::sun::star::uno::RuntimeException );
+
+ // ::com::sun::star::lang::XComponent
+ virtual void SAL_CALL dispose(void) throw( ::com::sun::star::uno::RuntimeException );
+
+ // ::com::sun::star::awt::XTextComponent
+ virtual void SAL_CALL addTextListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextListener > & l ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL removeTextListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextListener > & l ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL setText( const ::rtl::OUString& aText ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL insertText( const ::com::sun::star::awt::Selection& rSel, const ::rtl::OUString& aText ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual ::rtl::OUString SAL_CALL getText() throw( ::com::sun::star::uno::RuntimeException );
+ virtual ::rtl::OUString SAL_CALL getSelectedText() throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL setSelection( const ::com::sun::star::awt::Selection& aSelection ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::awt::Selection SAL_CALL getSelection() throw( ::com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL isEditable() throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL setEditable( sal_Bool bEditable ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL setMaxTextLen( sal_Int16 nLength ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual sal_Int16 SAL_CALL getMaxTextLen() throw( ::com::sun::star::uno::RuntimeException );
+
+ // ::com::sun::star::form::XBoundComponent
+ virtual void SAL_CALL addUpdateListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XUpdateListener > & /*l*/) throw( ::com::sun::star::uno::RuntimeException ) {}
+ virtual void SAL_CALL removeUpdateListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XUpdateListener > & /*l*/) throw( ::com::sun::star::uno::RuntimeException ) {}
+ virtual sal_Bool SAL_CALL commit() throw( ::com::sun::star::uno::RuntimeException );
+
+ // ::com::sun::star::lang::XEventListener
+ virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw( ::com::sun::star::uno::RuntimeException );
+
+ // ::com::sun::star::awt::XFocusListener
+ virtual void SAL_CALL focusGained(const ::com::sun::star::awt::FocusEvent& e) throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL focusLost(const ::com::sun::star::awt::FocusEvent& e) throw( ::com::sun::star::uno::RuntimeException );
+
+ // ::com::sun::star::awt::XItemListener
+ virtual void SAL_CALL itemStateChanged(const ::com::sun::star::awt::ItemEvent& rEvent) throw( ::com::sun::star::uno::RuntimeException );
+
+ // ::com::sun::star::util::XInitialization
+ virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::lang::XServiceInfo - static version
+ static ::rtl::OUString SAL_CALL getImplementationName_Static();
+ static ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_Static();
+ static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL Create( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory );
+
+ protected:
+ virtual void PrepareWindowDescriptor( ::com::sun::star::awt::WindowDescriptor& rDesc );
+ virtual void ImplSetPeerProperty( const ::rtl::OUString& rPropName, const ::com::sun::star::uno::Any& rVal );
+
+ sal_Bool ensureInitialized( );
+
+ void displayException( const ::com::sun::star::sdb::SQLContext& _rExcept );
+ };
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+#endif // FORMS_COMPONENT_FILTER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/FixedText.cxx b/forms/source/component/FixedText.cxx
new file mode 100644
index 000000000000..2a27fbc2d4c5
--- /dev/null
+++ b/forms/source/component/FixedText.cxx
@@ -0,0 +1,138 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+
+
+#include "FixedText.hxx"
+#include "services.hxx"
+#include "property.hrc"
+#include "property.hxx"
+#include <tools/debug.hxx>
+
+//.........................................................................
+namespace frm
+{
+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;
+
+//------------------------------------------------------------------------------
+InterfaceRef SAL_CALL OFixedTextModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory) throw (RuntimeException)
+{
+ return *(new OFixedTextModel(_rxFactory));
+}
+
+//------------------------------------------------------------------
+DBG_NAME( OFixedTextModel )
+//------------------------------------------------------------------
+OFixedTextModel::OFixedTextModel( const Reference<XMultiServiceFactory>& _rxFactory )
+ :OControlModel(_rxFactory, VCL_CONTROLMODEL_FIXEDTEXT)
+
+{
+ DBG_CTOR( OFixedTextModel, NULL );
+ m_nClassId = FormComponentType::FIXEDTEXT;
+}
+
+//------------------------------------------------------------------
+OFixedTextModel::OFixedTextModel( const OFixedTextModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
+ :OControlModel( _pOriginal, _rxFactory )
+
+{
+ DBG_CTOR( OFixedTextModel, NULL );
+}
+
+//------------------------------------------------------------------
+OFixedTextModel::~OFixedTextModel( )
+{
+ DBG_DTOR( OFixedTextModel, NULL );
+}
+
+//------------------------------------------------------------------------------
+IMPLEMENT_DEFAULT_CLONING( OFixedTextModel )
+
+//------------------------------------------------------------------------------
+StringSequence SAL_CALL OFixedTextModel::getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException)
+{
+ StringSequence aSupported = OControlModel::getSupportedServiceNames();
+ aSupported.realloc(aSupported.getLength() + 1);
+
+ ::rtl::OUString* pArray = aSupported.getArray();
+ pArray[aSupported.getLength()-1] = FRM_SUN_COMPONENT_FIXEDTEXT;
+ return aSupported;
+}
+
+//------------------------------------------------------------------------------
+void OFixedTextModel::describeAggregateProperties( Sequence< Property >& _rAggregateProps ) const
+{
+ OControlModel::describeAggregateProperties( _rAggregateProps );
+ RemoveProperty( _rAggregateProps, PROPERTY_TABSTOP );
+}
+
+//------------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OFixedTextModel::getServiceName() throw(RuntimeException)
+{
+ return FRM_COMPONENT_FIXEDTEXT; // old (non-sun) name for compatibility !
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OFixedTextModel::write(const Reference<XObjectOutputStream>& _rxOutStream)
+ throw(IOException, RuntimeException)
+{
+ OControlModel::write(_rxOutStream);
+
+ // Version
+ _rxOutStream->writeShort(0x0002);
+ writeHelpTextCompatibly(_rxOutStream);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OFixedTextModel::read(const Reference<XObjectInputStream>& _rxInStream) throw(IOException, RuntimeException)
+{
+ OControlModel::read(_rxInStream);
+
+ // Version
+ sal_Int16 nVersion = _rxInStream->readShort();
+ if (nVersion > 1)
+ readHelpTextCompatibly(_rxInStream);
+}
+
+//.........................................................................
+}
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/FixedText.hxx b/forms/source/component/FixedText.hxx
new file mode 100644
index 000000000000..a6b92a1e510f
--- /dev/null
+++ b/forms/source/component/FixedText.hxx
@@ -0,0 +1,73 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FORMS_FIXEDTEXT_HXX_
+#define _FORMS_FIXEDTEXT_HXX_
+
+#include "FormComponent.hxx"
+
+//.........................................................................
+namespace frm
+{
+
+//==================================================================
+// OFixedTextModel
+//==================================================================
+class OFixedTextModel
+ :public OControlModel
+{
+public:
+ DECLARE_DEFAULT_LEAF_XTOR( OFixedTextModel );
+
+// XServiceInfo
+ IMPLEMENTATION_NAME(OFixedTextModel);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
+
+// XPersistObject
+ virtual ::rtl::OUString SAL_CALL getServiceName() throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL
+ write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL
+ read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ // OControlModel's property handling
+ virtual void describeAggregateProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps
+ ) const;
+
+protected:
+ DECLARE_XCLONEABLE();
+};
+
+//.........................................................................
+}
+//.........................................................................
+
+#endif // _FORMS_FIXEDTEXT_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/FormComponent.cxx b/forms/source/component/FormComponent.cxx
new file mode 100644
index 000000000000..14c9f4fce067
--- /dev/null
+++ b/forms/source/component/FormComponent.cxx
@@ -0,0 +1,3070 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+
+#include "componenttools.hxx"
+#include "FormComponent.hxx"
+#include "frm_resource.hrc"
+#include "frm_resource.hxx"
+#include "property.hrc"
+#include "services.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/awt/XTextComponent.hpp>
+#include <com/sun/star/awt/XVclWindowPeer.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/form/XForm.hpp>
+#include <com/sun/star/form/XLoadable.hpp>
+#include <com/sun/star/io/XMarkableStream.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/sdb/XRowSetChangeBroadcaster.hpp>
+#include <com/sun/star/sdb/XRowSetSupplier.hpp>
+#include <com/sun/star/sdbc/ColumnValue.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/util/XModifyBroadcaster.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/basicio.hxx>
+#include <comphelper/guarding.hxx>
+#include <comphelper/listenernotification.hxx>
+#include <comphelper/property.hxx>
+#include <connectivity/dbtools.hxx>
+#include <cppuhelper/queryinterface.hxx>
+#include <rtl/logfile.hxx>
+#include <toolkit/helper/emptyfontdescriptor.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+
+#include <functional>
+#include <algorithm>
+
+
+//... namespace frm .......................................................
+namespace frm
+{
+//.........................................................................
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::sdb;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::sdbcx;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::container;
+ using namespace ::com::sun::star::form;
+ using namespace ::com::sun::star::awt;
+ using namespace ::com::sun::star::io;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::util;
+ using namespace ::com::sun::star::form::binding;
+ using namespace ::com::sun::star::form::validation;
+ using namespace ::dbtools;
+ using namespace ::comphelper;
+
+ //=========================================================================
+ //= FieldChangeNotifier
+ //=========================================================================
+ //-------------------------------------------------------------------------
+ void ControlModelLock::impl_notifyAll_nothrow()
+ {
+ m_rModel.firePropertyChanges( m_aHandles, m_aOldValues, m_aNewValues, OControlModel::LockAccess() );
+ }
+
+ //-------------------------------------------------------------------------
+ void ControlModelLock::addPropertyNotification( const sal_Int32 _nHandle, const Any& _rOldValue, const Any& _rNewValue )
+ {
+ sal_Int32 nOldLength = m_aHandles.getLength();
+ if ( ( nOldLength != m_aOldValues.getLength() )
+ || ( nOldLength != m_aNewValues.getLength() )
+ )
+ throw RuntimeException( ::rtl::OUString(), m_rModel );
+
+ m_aHandles.realloc( nOldLength + 1 );
+ m_aHandles[ nOldLength ] = _nHandle;
+ m_aOldValues.realloc( nOldLength + 1 );
+ m_aOldValues[ nOldLength ] = _rOldValue;
+ m_aNewValues.realloc( nOldLength + 1 );
+ m_aNewValues[ nOldLength ] = _rNewValue;
+ }
+
+ //=========================================================================
+ //= FieldChangeNotifier
+ //=========================================================================
+ //-------------------------------------------------------------------------
+ class FieldChangeNotifier
+ {
+ public:
+ FieldChangeNotifier( ControlModelLock& _rLock )
+ :m_rLock( _rLock )
+ ,m_rModel( dynamic_cast< OBoundControlModel& >( _rLock.getModel() ) )
+ {
+ m_xOldField = m_rModel.getField();
+ }
+
+ ~FieldChangeNotifier()
+ {
+ Reference< XPropertySet > xNewField( m_rModel.getField() );
+ if ( m_xOldField != xNewField )
+ m_rLock.addPropertyNotification( PROPERTY_ID_BOUNDFIELD, makeAny( m_xOldField ), makeAny( xNewField ) );
+ }
+
+ private:
+ ControlModelLock& m_rLock;
+ OBoundControlModel& m_rModel;
+ Reference< XPropertySet > m_xOldField;
+ };
+
+//=============================================================================
+//= base class for form layer controls
+//=============================================================================
+DBG_NAME(frm_OControl)
+//------------------------------------------------------------------------------
+OControl::OControl( const Reference< XMultiServiceFactory >& _rxFactory, const rtl::OUString& _rAggregateService, const sal_Bool _bSetDelegator )
+ :OComponentHelper(m_aMutex)
+ ,m_aContext( _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 );
+ {
+ m_xAggregate = m_xAggregate.query( _rxFactory->createInstance( _rAggregateService ) );
+ m_xControl = m_xControl.query( m_xAggregate );
+ }
+ decrement( m_refCount );
+
+ if ( _bSetDelegator )
+ doSetDelegator();
+}
+
+//------------------------------------------------------------------------------
+OControl::~OControl()
+{
+ DBG_DTOR(frm_OControl, NULL);
+ doResetDelegator();
+}
+
+//------------------------------------------------------------------------------
+void OControl::doResetDelegator()
+{
+ if ( m_xAggregate.is() )
+ m_xAggregate->setDelegator( NULL );
+}
+
+//------------------------------------------------------------------------------
+void OControl::doSetDelegator()
+{
+ increment( m_refCount );
+ if ( m_xAggregate.is() )
+ { // those brackets are important for some compilers, don't remove!
+ // (they ensure that the temporary object created in the line below
+ // is destroyed *before* the refcount-decrement)
+ m_xAggregate->setDelegator( static_cast< XWeak* >( this ) );
+ }
+ decrement( m_refCount );
+}
+
+// UNO Anbindung
+//------------------------------------------------------------------------------
+Any SAL_CALL OControl::queryAggregation( const Type& _rType ) throw(RuntimeException)
+{
+ // ask the base class
+ Any aReturn( OComponentHelper::queryAggregation(_rType) );
+ // ask our own interfaces
+ if (!aReturn.hasValue())
+ {
+ aReturn = OControl_BASE::queryInterface(_rType);
+ // ask our aggregate
+ if (!aReturn.hasValue() && m_xAggregate.is())
+ aReturn = m_xAggregate->queryAggregation(_rType);
+ }
+
+ return aReturn;
+}
+
+//------------------------------------------------------------------------------
+Sequence<sal_Int8> SAL_CALL OControl::getImplementationId() throw(RuntimeException)
+{
+ return OImplementationIds::getImplementationId(getTypes());
+}
+
+//------------------------------------------------------------------------------
+Sequence<Type> SAL_CALL OControl::getTypes() throw(RuntimeException)
+{
+ TypeBag aTypes( _getTypes() );
+
+ Reference< XTypeProvider > xProv;
+ if ( query_aggregation( m_xAggregate, xProv ) )
+ aTypes.addTypes( xProv->getTypes() );
+
+ return aTypes.getTypes();
+}
+
+//------------------------------------------------------------------------------
+Sequence<Type> OControl::_getTypes()
+{
+ return TypeBag( OComponentHelper::getTypes(), OControl_BASE::getTypes() ).getTypes();
+}
+
+//------------------------------------------------------------------------------
+void OControl::initFormControlPeer( const Reference< XWindowPeer >& /*_rxPeer*/ )
+{
+ // nothing to do here
+}
+
+// OComponentHelper
+//------------------------------------------------------------------------------
+void OControl::disposing()
+{
+ OComponentHelper::disposing();
+
+ m_aWindowStateGuard.attach( NULL, NULL );
+
+ Reference< XComponent > xComp;
+ if (query_aggregation(m_xAggregate, xComp))
+ xComp->dispose();
+}
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL OControl::supportsService(const rtl::OUString& _rsServiceName) throw ( RuntimeException)
+{
+ Sequence<rtl::OUString> aSupported = getSupportedServiceNames();
+ 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;
+}
+
+//------------------------------------------------------------------------------
+Sequence< ::rtl::OUString > OControl::getAggregateServiceNames()
+{
+ Sequence< ::rtl::OUString > aAggServices;
+ Reference< XServiceInfo > xInfo;
+ if ( query_aggregation( m_xAggregate, xInfo ) )
+ aAggServices = xInfo->getSupportedServiceNames();
+ return aAggServices;
+}
+
+//------------------------------------------------------------------------------
+Sequence<rtl::OUString> SAL_CALL OControl::getSupportedServiceNames() throw(RuntimeException)
+{
+ return ::comphelper::concatSequences(
+ getAggregateServiceNames(),
+ getSupportedServiceNames_Static()
+ );
+}
+
+//------------------------------------------------------------------------------
+Sequence< ::rtl::OUString > SAL_CALL OControl::getSupportedServiceNames_Static() throw( RuntimeException )
+{
+ // no own supported service names
+ return Sequence< ::rtl::OUString >();
+}
+
+// XEventListener
+//------------------------------------------------------------------------------
+void SAL_CALL OControl::disposing(const com::sun::star::lang::EventObject& _rEvent) throw (RuntimeException)
+{
+ Reference< XInterface > xAggAsIface;
+ query_aggregation(m_xAggregate, xAggAsIface);
+
+ // does the disposing come from the aggregate ?
+ if (xAggAsIface != Reference< XInterface >(_rEvent.Source, UNO_QUERY))
+ { // no -> forward it
+ Reference<com::sun::star::lang::XEventListener> xListener;
+ if (query_aggregation(m_xAggregate, xListener))
+ xListener->disposing(_rEvent);
+ }
+}
+
+// XControl
+//------------------------------------------------------------------------------
+void SAL_CALL OControl::setContext(const Reference< XInterface >& Context) throw (RuntimeException)
+{
+ if (m_xControl.is())
+ m_xControl->setContext(Context);
+}
+
+//------------------------------------------------------------------------------
+Reference< XInterface > SAL_CALL OControl::getContext() throw (RuntimeException)
+{
+ return m_xControl.is() ? m_xControl->getContext() : Reference< XInterface >();
+}
+
+//------------------------------------------------------------------------------
+void OControl::impl_resetStateGuard_nothrow()
+{
+ Reference< XWindow2 > xWindow;
+ Reference< XControlModel > xModel;
+ try
+ {
+ xWindow.set( getPeer(), UNO_QUERY );
+ xModel.set( getModel(), UNO_QUERY );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ m_aWindowStateGuard.attach( xWindow, xModel );
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OControl::createPeer(const Reference<XToolkit>& _rxToolkit, const Reference<XWindowPeer>& _rxParent) throw (RuntimeException)
+{
+ if ( m_xControl.is() )
+ {
+ m_xControl->createPeer( _rxToolkit, _rxParent );
+
+ initFormControlPeer( getPeer() );
+
+ impl_resetStateGuard_nothrow();
+ }
+}
+
+//------------------------------------------------------------------------------
+Reference<XWindowPeer> SAL_CALL OControl::getPeer() throw ( RuntimeException)
+{
+ return m_xControl.is() ? m_xControl->getPeer() : Reference<XWindowPeer>();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL OControl::setModel(const Reference<XControlModel>& Model) throw ( RuntimeException)
+{
+ if ( !m_xControl.is() )
+ return sal_False;
+
+ sal_Bool bSuccess = m_xControl->setModel( Model );
+ impl_resetStateGuard_nothrow();
+ return bSuccess;
+}
+
+//------------------------------------------------------------------------------
+Reference<XControlModel> SAL_CALL OControl::getModel() throw ( RuntimeException)
+{
+ return m_xControl.is() ? m_xControl->getModel() : Reference<XControlModel>();
+}
+
+//------------------------------------------------------------------------------
+Reference<XView> SAL_CALL OControl::getView() throw ( RuntimeException)
+{
+ return m_xControl.is() ? m_xControl->getView() : Reference<XView>();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OControl::setDesignMode(sal_Bool bOn) throw ( RuntimeException)
+{
+ if (m_xControl.is())
+ m_xControl->setDesignMode(bOn);
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL OControl::isDesignMode() throw ( RuntimeException)
+{
+ return m_xControl.is() ? m_xControl->isDesignMode() : sal_True;
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL OControl::isTransparent() throw ( RuntimeException)
+{
+ return m_xControl.is() ? m_xControl->isTransparent() : sal_True;
+}
+
+//==================================================================
+//= OBoundControl
+//==================================================================
+DBG_NAME(frm_OBoundControl);
+//------------------------------------------------------------------
+OBoundControl::OBoundControl( const Reference< XMultiServiceFactory >& _rxFactory,
+ const ::rtl::OUString& _rAggregateService, const sal_Bool _bSetDelegator )
+ :OControl( _rxFactory, _rAggregateService, _bSetDelegator )
+ ,m_bLocked(sal_False)
+ ,m_aOriginalFont( EmptyFontDescriptor() )
+ ,m_nOriginalTextLineColor( 0 )
+{
+ DBG_CTOR(frm_OBoundControl, NULL);
+}
+
+//------------------------------------------------------------------
+OBoundControl::~OBoundControl()
+{
+ DBG_DTOR(frm_OBoundControl, NULL);
+}
+// -----------------------------------------------------------------------------
+Sequence< Type> OBoundControl::_getTypes()
+{
+ return TypeBag( OControl::_getTypes(), OBoundControl_BASE::getTypes() ).getTypes();
+}
+//------------------------------------------------------------------
+Any SAL_CALL OBoundControl::queryAggregation(const Type& _rType) throw(RuntimeException)
+{
+ Any aReturn;
+
+ // XTypeProvider first - don't ask the OBoundControl_BASE, it would deliver incomplete types
+ if ( _rType.equals( ::getCppuType( static_cast< Reference< XTypeProvider >* >( NULL ) ) ) )
+ aReturn = OControl::queryAggregation( _rType );
+
+ // ask our own interfaces
+ // (do this first (except XTypeProvider ) - we want to "overwrite" XPropertiesChangeListener)
+ if ( !aReturn.hasValue() )
+ aReturn = OBoundControl_BASE::queryInterface( _rType );
+
+ // ask the base class
+ if ( !aReturn.hasValue() )
+ aReturn = OControl::queryAggregation( _rType );
+
+ return aReturn;
+}
+
+//------------------------------------------------------------------
+sal_Bool SAL_CALL OBoundControl::getLock() throw(RuntimeException)
+{
+ return m_bLocked;
+}
+
+//------------------------------------------------------------------
+void SAL_CALL OBoundControl::setLock(sal_Bool _bLock) throw(RuntimeException)
+{
+ 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();
+ Reference< XTextComponent > xText( xPeer, UNO_QUERY );
+
+ if ( xText.is() )
+ xText->setEditable( !_bLock );
+ else
+ {
+ // disable the window
+ Reference< XWindow > xComp( xPeer, UNO_QUERY );
+ if ( xComp.is() )
+ xComp->setEnable( !_bLock );
+ }
+}
+
+//--------------------------------------------------------------------
+sal_Bool SAL_CALL OBoundControl::setModel( const Reference< XControlModel >& _rxModel ) throw (RuntimeException)
+{
+ return OControl::setModel( _rxModel );
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL OBoundControl::disposing(const EventObject& Source) throw (RuntimeException)
+{
+ // just disambiguate
+ OControl::disposing(Source);
+}
+
+//--------------------------------------------------------------------
+void OBoundControl::disposing()
+{
+ OControl::disposing();
+}
+
+//==================================================================
+//= OControlModel
+//==================================================================
+DBG_NAME(OControlModel)
+//------------------------------------------------------------------
+Sequence<sal_Int8> SAL_CALL OControlModel::getImplementationId() throw(RuntimeException)
+{
+ return OImplementationIds::getImplementationId(getTypes());
+}
+
+//------------------------------------------------------------------
+Sequence<Type> SAL_CALL OControlModel::getTypes() throw(RuntimeException)
+{
+ TypeBag aTypes( _getTypes() );
+
+ Reference< XTypeProvider > xProv;
+ if ( query_aggregation( m_xAggregate, xProv ) )
+ aTypes.addTypes( xProv->getTypes() );
+
+ return aTypes.getTypes();
+}
+
+//------------------------------------------------------------------------------
+Sequence<Type> OControlModel::_getTypes()
+{
+ return TypeBag( OComponentHelper::getTypes(),
+ OPropertySetAggregationHelper::getTypes(),
+ OControlModel_BASE::getTypes()
+ ).getTypes();
+}
+
+//------------------------------------------------------------------
+Any SAL_CALL OControlModel::queryAggregation(const Type& _rType) throw (RuntimeException)
+{
+ // base class 1
+ Any aReturn(OComponentHelper::queryAggregation(_rType));
+
+ // base class 2
+ if (!aReturn.hasValue())
+ {
+ aReturn = OControlModel_BASE::queryInterface(_rType);
+
+ // our own interfaces
+ if (!aReturn.hasValue())
+ {
+ aReturn = OPropertySetAggregationHelper::queryInterface(_rType);
+ // our aggregate
+ if (!aReturn.hasValue() && m_xAggregate.is() && !_rType.equals(::getCppuType(static_cast< Reference< XCloneable>* >(NULL))))
+ aReturn = m_xAggregate->queryAggregation(_rType);
+ }
+ }
+ return aReturn;
+}
+
+//------------------------------------------------------------------------------
+void OControlModel::readHelpTextCompatibly(const staruno::Reference< stario::XObjectInputStream >& _rxInStream)
+{
+ ::rtl::OUString sHelpText;
+ ::comphelper::operator>>( _rxInStream, sHelpText);
+ try
+ {
+ if (m_xAggregateSet.is())
+ m_xAggregateSet->setPropertyValue(PROPERTY_HELPTEXT, makeAny(sHelpText));
+ }
+ catch(const Exception&)
+ {
+ OSL_FAIL("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_FAIL("OControlModel::writeHelpTextCompatibly: could not retrieve the property value from the aggregate!");
+ }
+ ::comphelper::operator<<( _rxOutStream, sHelpText);
+}
+
+//------------------------------------------------------------------
+OControlModel::OControlModel(
+ const Reference<com::sun::star::lang::XMultiServiceFactory>& _rxFactory,
+ const ::rtl::OUString& _rUnoControlModelTypeName,
+ const ::rtl::OUString& rDefault, const sal_Bool _bSetDelegator)
+ :OComponentHelper(m_aMutex)
+ ,OPropertySetAggregationHelper(OComponentHelper::rBHelper)
+ ,m_aContext( _rxFactory )
+ ,m_lockCount( 0 )
+ ,m_aPropertyBagHelper( *this )
+ ,m_nTabIndex(FRM_DEFAULT_TABINDEX)
+ ,m_nClassId(FormComponentType::CONTROL)
+ ,m_bNativeLook( sal_False )
+ // form controls are usually embedded into documents, not dialogs, and in documents
+ // the native look is ugly ....
+ // #i37342#
+{
+ DBG_CTOR(OControlModel, NULL);
+ if (_rUnoControlModelTypeName.getLength()) // the is a model we have to aggregate
+ {
+ increment(m_refCount);
+
+ {
+ m_xAggregate = Reference<XAggregation>(_rxFactory->createInstance(_rUnoControlModelTypeName), UNO_QUERY);
+ setAggregation(m_xAggregate);
+
+ if ( m_xAggregateSet.is() )
+ {
+ try
+ {
+ if ( rDefault.getLength() )
+ m_xAggregateSet->setPropertyValue( PROPERTY_DEFAULTCONTROL, makeAny( rDefault ) );
+ }
+ catch( const Exception& )
+ {
+ OSL_FAIL( "OControlModel::OControlModel: caught an exception!" );
+ }
+ }
+ }
+
+ if (_bSetDelegator)
+ doSetDelegator();
+
+ // Refcount wieder bei NULL
+ decrement(m_refCount);
+ }
+}
+
+//------------------------------------------------------------------
+OControlModel::OControlModel( const OControlModel* _pOriginal, const Reference< XMultiServiceFactory>& _rxFactory, const sal_Bool _bCloneAggregate, const sal_Bool _bSetDelegator )
+ :OComponentHelper( m_aMutex )
+ ,OPropertySetAggregationHelper( OComponentHelper::rBHelper )
+ ,m_aContext( _rxFactory )
+ ,m_lockCount( 0 )
+ ,m_aPropertyBagHelper( *this )
+ ,m_nTabIndex( FRM_DEFAULT_TABINDEX )
+ ,m_nClassId( FormComponentType::CONTROL )
+{
+ DBG_CTOR( OControlModel, NULL );
+ DBG_ASSERT( _pOriginal, "OControlModel::OControlModel: invalid original!" );
+
+ // copy members
+ m_aName = _pOriginal->m_aName;
+ m_aTag = _pOriginal->m_aTag;
+ m_nTabIndex = _pOriginal->m_nTabIndex;
+ m_nClassId = _pOriginal->m_nClassId;
+ m_bNativeLook = _pOriginal->m_bNativeLook;
+
+ if ( _bCloneAggregate )
+ {
+ // temporarily increment refcount because of temporary references to ourself in the following
+ increment( m_refCount );
+
+ {
+ // transfer the (only, at the very moment!) ref count
+ m_xAggregate = createAggregateClone( _pOriginal );
+
+ // set aggregation (retrieve other direct interfaces of the aggregate)
+ setAggregation( m_xAggregate );
+ }
+
+ // set the delegator, if allowed by our derived class
+ if ( _bSetDelegator )
+ doSetDelegator();
+
+ // decrement ref count
+ decrement( m_refCount );
+ }
+}
+
+//------------------------------------------------------------------
+OControlModel::~OControlModel()
+{
+ // release the aggregate
+ doResetDelegator( );
+
+ DBG_DTOR(OControlModel, NULL);
+}
+
+//------------------------------------------------------------------
+void OControlModel::clonedFrom( const OControlModel* /*_pOriginal*/ )
+{
+ // nothing to do in this base class
+}
+
+//------------------------------------------------------------------------------
+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);
+}
+
+// XChild
+//------------------------------------------------------------------------------
+Reference< XInterface > SAL_CALL OControlModel::getParent() throw(RuntimeException)
+{
+ return m_xParent;
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OControlModel::setParent(const Reference< XInterface >& _rxParent) throw(com::sun::star::lang::NoSupportException, RuntimeException)
+{
+ osl::MutexGuard aGuard(m_aMutex);
+
+ Reference<XComponent> xComp(m_xParent, UNO_QUERY);
+ if (xComp.is())
+ xComp->removeEventListener(static_cast<XPropertiesChangeListener*>(this));
+
+ m_xParent = _rxParent;
+ xComp = xComp.query( m_xParent );
+
+ if ( xComp.is() )
+ xComp->addEventListener(static_cast<XPropertiesChangeListener*>(this));
+}
+
+// XNamed
+//------------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OControlModel::getName() throw(RuntimeException)
+{
+ ::rtl::OUString aReturn;
+ OPropertySetHelper::getFastPropertyValue(PROPERTY_ID_NAME) >>= aReturn;
+ return aReturn;
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OControlModel::setName(const ::rtl::OUString& _rName) throw(RuntimeException)
+{
+ setFastPropertyValue(PROPERTY_ID_NAME, makeAny(_rName));
+}
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL OControlModel::supportsService(const rtl::OUString& _rServiceName) throw ( RuntimeException)
+{
+ Sequence<rtl::OUString> aSupported = getSupportedServiceNames();
+ 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;
+}
+
+//------------------------------------------------------------------------------
+Sequence< ::rtl::OUString > OControlModel::getAggregateServiceNames()
+{
+ Sequence< ::rtl::OUString > aAggServices;
+ Reference< XServiceInfo > xInfo;
+ if ( query_aggregation( m_xAggregate, xInfo ) )
+ aAggServices = xInfo->getSupportedServiceNames();
+ return aAggServices;
+}
+
+//------------------------------------------------------------------------------
+Sequence<rtl::OUString> SAL_CALL OControlModel::getSupportedServiceNames() throw(RuntimeException)
+{
+ return ::comphelper::concatSequences(
+ getAggregateServiceNames(),
+ getSupportedServiceNames_Static()
+ );
+}
+
+//------------------------------------------------------------------------------
+Sequence< ::rtl::OUString > SAL_CALL OControlModel::getSupportedServiceNames_Static() throw( RuntimeException )
+{
+ Sequence< ::rtl::OUString > aServiceNames( 2 );
+ aServiceNames[ 0 ] = FRM_SUN_FORMCOMPONENT;
+ aServiceNames[ 1 ] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.form.FormControlModel") );
+ return aServiceNames;
+}
+
+// XEventListener
+//------------------------------------------------------------------------------
+void SAL_CALL OControlModel::disposing(const com::sun::star::lang::EventObject& _rSource) throw (RuntimeException)
+{
+ // release the parent
+ if (_rSource.Source == m_xParent)
+ {
+ osl::MutexGuard aGuard(m_aMutex);
+ m_xParent = NULL;
+ }
+ else
+ {
+ Reference<com::sun::star::lang::XEventListener> xEvtLst;
+ 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;
+ if (query_aggregation(m_xAggregate, xComp))
+ xComp->dispose();
+
+ setParent(Reference<XFormComponent>());
+
+ m_aPropertyBagHelper.dispose();
+}
+
+//------------------------------------------------------------------------------
+void OControlModel::writeAggregate( const Reference< XObjectOutputStream >& _rxOutStream ) const
+{
+ Reference< XPersistObject > xPersist;
+ if ( query_aggregation( m_xAggregate, xPersist ) )
+ xPersist->write( _rxOutStream );
+}
+
+//------------------------------------------------------------------------------
+void OControlModel::readAggregate( const Reference< XObjectInputStream >& _rxInStream )
+{
+ Reference< XPersistObject > xPersist;
+ if ( query_aggregation( m_xAggregate, xPersist ) )
+ xPersist->read( _rxInStream );
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OControlModel::write(const Reference<stario::XObjectOutputStream>& _rxOutStream)
+ throw(stario::IOException, RuntimeException)
+{
+ 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 )
+ );
+ }
+
+ sal_Int32 nMark = xMark->createMark();
+ sal_Int32 nLen = 0;
+
+ _rxOutStream->writeLong(nLen);
+
+ writeAggregate( _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
+ ::comphelper::operator<<( _rxOutStream, m_aName);
+ _rxOutStream->writeShort(m_nTabIndex);
+ ::comphelper::operator<<( _rxOutStream, m_aTag); // 3. version
+
+ // !!! 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 !!!
+}
+
+//------------------------------------------------------------------------------
+void OControlModel::read(const Reference<stario::XObjectInputStream>& InStream) throw (::com::sun::star::io::IOException, RuntimeException)
+{
+ 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 )
+ );
+ }
+
+ // 1. Lesen des UnoControls
+ sal_Int32 nLen = InStream->readLong();
+ if (nLen)
+ {
+ sal_Int32 nMark = xMark->createMark();
+
+ try
+ {
+ readAggregate( InStream );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ xMark->jumpToMark(nMark);
+ InStream->skipBytes(nLen);
+ xMark->deleteMark(nMark);
+ }
+
+ // 2. Lesen des Versionsnummer
+ sal_uInt16 nVersion = InStream->readShort();
+
+ // 3. Lesen der allgemeinen Properties
+ ::comphelper::operator>>( InStream, m_aName);
+ m_nTabIndex = InStream->readShort();
+
+ if (nVersion > 0x0002)
+ ::comphelper::operator>>( InStream, m_aTag);
+
+ // we had a version where we wrote the help text
+ if (nVersion == 0x0004)
+ readHelpTextCompatibly(InStream);
+
+ 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 )
+{
+ // simply compare the current and the default value
+ Any aCurrentValue = getPropertyDefaultByHandle( _nHandle );
+ Any aDefaultValue; getFastPropertyValue( aDefaultValue, _nHandle );
+
+ sal_Bool bEqual = uno_type_equalData(
+ const_cast< void* >( aCurrentValue.getValue() ), aCurrentValue.getValueType().getTypeLibType(),
+ const_cast< void* >( aDefaultValue.getValue() ), aDefaultValue.getValueType().getTypeLibType(),
+ reinterpret_cast< uno_QueryInterfaceFunc >(cpp_queryInterface),
+ reinterpret_cast< uno_ReleaseFunc >(cpp_release)
+ );
+ return bEqual ? PropertyState_DEFAULT_VALUE : 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;
+
+ case PROPERTY_ID_NATIVE_LOOK:
+ aReturn <<= (sal_Bool)sal_True;
+ break;
+
+ default:
+ if ( m_aPropertyBagHelper.hasDynamicPropertyByHandle( _nHandle ) )
+ m_aPropertyBagHelper.getDynamicPropertyDefaultByHandle( _nHandle, aReturn );
+ else
+ OSL_FAIL( "OControlModel::convertFastPropertyValue: unknown handle!" );
+ }
+ return aReturn;
+}
+
+//------------------------------------------------------------------------------
+void OControlModel::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const
+{
+ 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;
+ case PROPERTY_ID_NATIVE_LOOK:
+ _rValue <<= (sal_Bool)m_bNativeLook;
+ break;
+ default:
+ if ( m_aPropertyBagHelper.hasDynamicPropertyByHandle( _nHandle ) )
+ m_aPropertyBagHelper.getDynamicFastPropertyValue( _nHandle, _rValue );
+ else
+ OPropertySetAggregationHelper::getFastPropertyValue( _rValue, _nHandle );
+ break;
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OControlModel::convertFastPropertyValue(
+ Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue)
+ throw (com::sun::star::lang::IllegalArgumentException)
+{
+ 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;
+ case PROPERTY_ID_NATIVE_LOOK:
+ bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_bNativeLook);
+ break;
+ default:
+ if ( m_aPropertyBagHelper.hasDynamicPropertyByHandle( _nHandle ) )
+ bModified = m_aPropertyBagHelper.convertDynamicFastPropertyValue( _nHandle, _rValue, _rConvertedValue, _rOldValue );
+ else
+ OSL_FAIL( "OControlModel::convertFastPropertyValue: unknown handle!" );
+ break;
+ }
+ return bModified;
+}
+
+//------------------------------------------------------------------------------
+void OControlModel::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle, const Any& _rValue)
+ throw (Exception)
+{
+ 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;
+ case PROPERTY_ID_NATIVE_LOOK:
+ OSL_VERIFY( _rValue >>= m_bNativeLook );
+ break;
+ default:
+ if ( m_aPropertyBagHelper.hasDynamicPropertyByHandle( _nHandle ) )
+ m_aPropertyBagHelper.setDynamicFastPropertyValue( _nHandle, _rValue );
+ else
+ OSL_FAIL( "OControlModel::setFastPropertyValue_NoBroadcast: unknown handle!" );
+ break;
+ }
+}
+
+//------------------------------------------------------------------------------
+void OControlModel::describeFixedProperties( Sequence< Property >& _rProps ) const
+{
+ BEGIN_DESCRIBE_BASE_PROPERTIES( 4 )
+ DECL_PROP2 (CLASSID, sal_Int16, READONLY, TRANSIENT);
+ DECL_PROP1 (NAME, ::rtl::OUString, BOUND);
+ DECL_BOOL_PROP2 (NATIVE_LOOK, BOUND, TRANSIENT);
+ DECL_PROP1 (TAG, ::rtl::OUString, BOUND);
+ END_DESCRIBE_PROPERTIES()
+}
+
+//------------------------------------------------------------------------------
+void OControlModel::describeAggregateProperties( Sequence< Property >& /* [out] */ _rAggregateProps ) const
+{
+ if ( m_xAggregateSet.is() )
+ {
+ Reference< XPropertySetInfo > xPSI( m_xAggregateSet->getPropertySetInfo() );
+ if ( xPSI.is() )
+ _rAggregateProps = xPSI->getProperties();
+ }
+}
+
+//------------------------------------------------------------------------------
+::osl::Mutex& OControlModel::getMutex()
+{
+ return m_aMutex;
+}
+
+//------------------------------------------------------------------------------
+void OControlModel::describeFixedAndAggregateProperties( Sequence< Property >& _out_rFixedProperties, Sequence< Property >& _out_rAggregateProperties ) const
+{
+ describeFixedProperties( _out_rFixedProperties );
+ describeAggregateProperties( _out_rAggregateProperties );
+}
+
+//------------------------------------------------------------------------------
+Reference< XMultiPropertySet > OControlModel::getPropertiesInterface()
+{
+ return Reference< XMultiPropertySet >( *this, UNO_QUERY );
+}
+
+//------------------------------------------------------------------------------
+Reference< XPropertySetInfo> SAL_CALL OControlModel::getPropertySetInfo() throw( RuntimeException)
+{
+ return createPropertySetInfo( getInfoHelper() );
+}
+
+//------------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper& OControlModel::getInfoHelper()
+{
+ return m_aPropertyBagHelper.getInfoHelper();
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL OControlModel::addProperty( const ::rtl::OUString& _rName, ::sal_Int16 _nAttributes, const Any& _rInitialValue ) throw (PropertyExistException, IllegalTypeException, IllegalArgumentException, RuntimeException)
+{
+ m_aPropertyBagHelper.addProperty( _rName, _nAttributes, _rInitialValue );
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL OControlModel::removeProperty( const ::rtl::OUString& _rName ) throw (UnknownPropertyException, NotRemoveableException, RuntimeException)
+{
+ m_aPropertyBagHelper.removeProperty( _rName );
+}
+
+//--------------------------------------------------------------------
+Sequence< PropertyValue > SAL_CALL OControlModel::getPropertyValues() throw (RuntimeException)
+{
+ return m_aPropertyBagHelper.getPropertyValues();
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL OControlModel::setPropertyValues( const Sequence< PropertyValue >& _rProps ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
+{
+ m_aPropertyBagHelper.setPropertyValues( _rProps );
+}
+
+//--------------------------------------------------------------------
+void OControlModel::lockInstance( LockAccess )
+{
+ m_aMutex.acquire();
+ osl_incrementInterlockedCount( &m_lockCount );
+}
+
+//--------------------------------------------------------------------
+oslInterlockedCount OControlModel::unlockInstance( LockAccess )
+{
+ OSL_ENSURE( m_lockCount > 0, "OControlModel::unlockInstance: not locked!" );
+ oslInterlockedCount lockCount = osl_decrementInterlockedCount( &m_lockCount );
+ m_aMutex.release();
+ return lockCount;
+}
+
+//--------------------------------------------------------------------
+void OControlModel::firePropertyChanges( const Sequence< sal_Int32 >& _rHandles, const Sequence< Any >& _rOldValues,
+ const Sequence< Any >& _rNewValues, LockAccess )
+{
+ OPropertySetHelper::fire(
+ const_cast< Sequence< sal_Int32 >& >( _rHandles ).getArray(),
+ _rNewValues.getConstArray(),
+ _rOldValues.getConstArray(),
+ _rHandles.getLength(),
+ sal_False
+ );
+}
+
+//==================================================================
+//= OBoundControlModel
+//==================================================================
+DBG_NAME(frm_OBoundControlModel);
+//------------------------------------------------------------------
+Any SAL_CALL OBoundControlModel::queryAggregation( const Type& _rType ) throw (RuntimeException)
+{
+ Any aReturn( OControlModel::queryAggregation(_rType) );
+ if (!aReturn.hasValue())
+ {
+ aReturn = OBoundControlModel_BASE1::queryInterface(_rType);
+
+ if ( !aReturn.hasValue() && m_bCommitable )
+ aReturn = OBoundControlModel_COMMITTING::queryInterface( _rType );
+
+ if ( !aReturn.hasValue() && m_bSupportsExternalBinding )
+ aReturn = OBoundControlModel_BINDING::queryInterface( _rType );
+
+ if ( !aReturn.hasValue() && m_bSupportsValidation )
+ aReturn = OBoundControlModel_VALIDATION::queryInterface( _rType );
+ }
+
+ return aReturn;
+}
+
+//------------------------------------------------------------------
+OBoundControlModel::OBoundControlModel(
+ const Reference< XMultiServiceFactory>& _rxFactory,
+ const ::rtl::OUString& _rUnoControlModelTypeName, const ::rtl::OUString& _rDefault,
+ const sal_Bool _bCommitable, const sal_Bool _bSupportExternalBinding, const sal_Bool _bSupportsValidation )
+ :OControlModel( _rxFactory, _rUnoControlModelTypeName, _rDefault, sal_False )
+ ,OPropertyChangeListener( m_aMutex )
+ ,m_xField()
+ ,m_xAmbientForm()
+ ,m_nValuePropertyAggregateHandle( -1 )
+ ,m_nFieldType( DataType::OTHER )
+ ,m_bValuePropertyMayBeVoid( false )
+ ,m_aResetHelper( *this, m_aMutex )
+ ,m_aUpdateListeners(m_aMutex)
+ ,m_aFormComponentListeners( m_aMutex )
+ ,m_bInputRequired( sal_True )
+ ,m_pAggPropMultiplexer( NULL )
+ ,m_bFormListening( false )
+ ,m_bLoaded(sal_False)
+ ,m_bRequired(sal_False)
+ ,m_bCommitable(_bCommitable)
+ ,m_bSupportsExternalBinding( _bSupportExternalBinding )
+ ,m_bSupportsValidation( _bSupportsValidation )
+ ,m_bForwardValueChanges(sal_True)
+ ,m_bTransferingValue( sal_False )
+ ,m_bIsCurrentValueValid( sal_True )
+ ,m_bBindingControlsRO( sal_False )
+ ,m_bBindingControlsEnable( sal_False )
+ ,m_eControlValueChangeInstigator( eOther )
+ ,m_aLabelServiceName(FRM_SUN_COMPONENT_FIXEDTEXT)
+{
+ DBG_CTOR(frm_OBoundControlModel, NULL);
+
+ // start property listening at the aggregate
+ implInitAggMultiplexer( );
+}
+
+//------------------------------------------------------------------
+OBoundControlModel::OBoundControlModel(
+ const OBoundControlModel* _pOriginal, const Reference< XMultiServiceFactory>& _rxFactory )
+ :OControlModel( _pOriginal, _rxFactory, sal_True, sal_False )
+ ,OPropertyChangeListener( m_aMutex )
+ ,m_xField()
+ ,m_xAmbientForm()
+ ,m_nValuePropertyAggregateHandle( _pOriginal->m_nValuePropertyAggregateHandle )
+ ,m_nFieldType( DataType::OTHER )
+ ,m_bValuePropertyMayBeVoid( _pOriginal->m_bValuePropertyMayBeVoid )
+ ,m_aResetHelper( *this, m_aMutex )
+ ,m_aUpdateListeners( m_aMutex )
+ ,m_aFormComponentListeners( m_aMutex )
+ ,m_xValidator( _pOriginal->m_xValidator )
+ ,m_bInputRequired( sal_True )
+ ,m_pAggPropMultiplexer( NULL )
+ ,m_bFormListening( false )
+ ,m_bLoaded( sal_False )
+ ,m_bRequired( sal_False )
+ ,m_bCommitable( _pOriginal->m_bCommitable )
+ ,m_bSupportsExternalBinding( _pOriginal->m_bSupportsExternalBinding )
+ ,m_bSupportsValidation( _pOriginal->m_bSupportsValidation )
+ ,m_bForwardValueChanges( sal_True )
+ ,m_bTransferingValue( sal_False )
+ ,m_bIsCurrentValueValid( _pOriginal->m_bIsCurrentValueValid )
+ ,m_bBindingControlsRO( sal_False )
+ ,m_bBindingControlsEnable( sal_False )
+ ,m_eControlValueChangeInstigator( eOther )
+{
+ DBG_CTOR(frm_OBoundControlModel, NULL);
+
+ // start property listening at the aggregate
+ implInitAggMultiplexer( );
+
+ m_aLabelServiceName = _pOriginal->m_aLabelServiceName;
+ m_sValuePropertyName = _pOriginal->m_sValuePropertyName;
+ m_nValuePropertyAggregateHandle = _pOriginal->m_nValuePropertyAggregateHandle;
+ m_bValuePropertyMayBeVoid = _pOriginal->m_bValuePropertyMayBeVoid;
+ m_aValuePropertyType = _pOriginal->m_aValuePropertyType;
+ m_aControlSource = _pOriginal->m_aControlSource;
+ m_bInputRequired = _pOriginal->m_bInputRequired;
+ // m_xLabelControl, though being a property, is not to be cloned, not even the reference will be transfered.
+ // (the former should be clear - a clone of the object we're only referencing does not make sense)
+ // (the second would violate the restriction for label controls that they're part of the
+ // same form component hierarchy - we ourself are no part, yet, so we can't have a label control)
+
+ // start listening for changes at the value property
+ implInitValuePropertyListening( );
+}
+
+//------------------------------------------------------------------
+OBoundControlModel::~OBoundControlModel()
+{
+ if ( !OComponentHelper::rBHelper.bDisposed )
+ {
+ acquire();
+ dispose();
+ }
+
+ doResetDelegator( );
+
+ OSL_ENSURE( m_pAggPropMultiplexer, "OBoundControlModel::~OBoundControlModel: what about my property multiplexer?" );
+ if ( m_pAggPropMultiplexer )
+ {
+ m_pAggPropMultiplexer->dispose();
+ m_pAggPropMultiplexer->release();
+ m_pAggPropMultiplexer = NULL;
+ }
+
+ DBG_DTOR(frm_OBoundControlModel, NULL);
+}
+
+//------------------------------------------------------------------
+void OBoundControlModel::clonedFrom( const OControlModel* _pOriginal )
+{
+ const OBoundControlModel* pBoundOriginal = static_cast< const OBoundControlModel* >( _pOriginal );
+ // the value binding can be handled as if somebody called setValueBinding here
+ // By definition, bindings can be share between bindables
+ if ( pBoundOriginal && pBoundOriginal->m_xExternalBinding.is() )
+ {
+ try
+ {
+ setValueBinding( pBoundOriginal->m_xExternalBinding );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+void OBoundControlModel::implInitAggMultiplexer( )
+{
+ increment( m_refCount );
+ if ( m_xAggregateSet.is() )
+ {
+ m_pAggPropMultiplexer = new OPropertyChangeMultiplexer( this, m_xAggregateSet, sal_False );
+ m_pAggPropMultiplexer->acquire();
+ }
+ decrement( m_refCount );
+
+ doSetDelegator();
+}
+
+//-----------------------------------------------------------------------------
+void OBoundControlModel::implInitValuePropertyListening( ) const
+{
+ // start listening for changes at the value property
+ // There are three pre-requisites for this to be done:
+ // 1. We support external value bindings. In this case, the changes in the control value need to
+ // be propagated to the external binding immediately when they happen
+ // 2. We support external validation. In this case, we need to listen for changes in the value
+ // property, since we need to revalidate then.
+ // 3. We are not committable. In this case, changes in the control value need to be propagated
+ // to the database column immediately when they happen.
+ if ( m_bSupportsExternalBinding || m_bSupportsValidation || !m_bCommitable )
+ {
+ OSL_ENSURE( m_pAggPropMultiplexer, "OBoundControlModel::implInitValuePropertyListening: no multiplexer!" );
+ if ( m_pAggPropMultiplexer && m_sValuePropertyName.getLength() )
+ m_pAggPropMultiplexer->addProperty( m_sValuePropertyName );
+ }
+}
+
+//-----------------------------------------------------------------------------
+void OBoundControlModel::initOwnValueProperty( const ::rtl::OUString& i_rValuePropertyName )
+{
+ OSL_PRECOND( !m_sValuePropertyName.getLength() && -1 == m_nValuePropertyAggregateHandle,
+ "OBoundControlModel::initOwnValueProperty: value property is already initialized!" );
+ OSL_ENSURE( i_rValuePropertyName.getLength(), "OBoundControlModel::initOwnValueProperty: invalid property name!" );
+ m_sValuePropertyName = i_rValuePropertyName;
+}
+
+//-----------------------------------------------------------------------------
+void OBoundControlModel::initValueProperty( const ::rtl::OUString& _rValuePropertyName, sal_Int32 _nValuePropertyExternalHandle )
+{
+ OSL_PRECOND( !m_sValuePropertyName.getLength() && -1 == m_nValuePropertyAggregateHandle,
+ "OBoundControlModel::initValueProperty: value property is already initialized!" );
+ OSL_ENSURE( _rValuePropertyName.getLength(), "OBoundControlModel::initValueProperty: invalid property name!" );
+ OSL_ENSURE( _nValuePropertyExternalHandle != -1, "OBoundControlModel::initValueProperty: invalid property handle!" );
+
+ m_sValuePropertyName = _rValuePropertyName;
+ m_nValuePropertyAggregateHandle = getOriginalHandle( _nValuePropertyExternalHandle );
+ OSL_ENSURE( m_nValuePropertyAggregateHandle != -1, "OBoundControlModel::initValueProperty: unable to find the original handle!" );
+
+ if ( m_nValuePropertyAggregateHandle != -1 )
+ {
+ Reference< XPropertySetInfo > xPropInfo( m_xAggregateSet->getPropertySetInfo(), UNO_SET_THROW );
+ Property aValuePropDesc = xPropInfo->getPropertyByName( m_sValuePropertyName );
+ m_aValuePropertyType = aValuePropDesc.Type;
+ m_bValuePropertyMayBeVoid = ( aValuePropDesc.Attributes & PropertyAttribute::MAYBEVOID ) != 0;
+ }
+
+ // start listening for changes at the value property
+ implInitValuePropertyListening( );
+}
+
+//-----------------------------------------------------------------------------
+void OBoundControlModel::suspendValueListening( )
+{
+ OSL_PRECOND( m_sValuePropertyName.getLength(), "OBoundControlModel::suspendValueListening: don't have a value property!" );
+ OSL_PRECOND( m_pAggPropMultiplexer, "OBoundControlModel::suspendValueListening: I *am* not listening!" );
+
+ if ( m_pAggPropMultiplexer )
+ m_pAggPropMultiplexer->lock();
+}
+
+//-----------------------------------------------------------------------------
+void OBoundControlModel::resumeValueListening( )
+{
+ OSL_PRECOND( m_sValuePropertyName.getLength(), "OBoundControlModel::resumeValueListening: don't have a value property!" );
+ OSL_PRECOND( m_pAggPropMultiplexer, "OBoundControlModel::resumeValueListening: I *am* not listening at all!" );
+ OSL_PRECOND( !m_pAggPropMultiplexer || m_pAggPropMultiplexer->locked(), "OBoundControlModel::resumeValueListening: listening not suspended currently!" );
+
+ if ( m_pAggPropMultiplexer )
+ m_pAggPropMultiplexer->unlock();
+}
+
+//-----------------------------------------------------------------------------
+Sequence< Type > OBoundControlModel::_getTypes()
+{
+ TypeBag aTypes(
+ OControlModel::_getTypes(),
+ OBoundControlModel_BASE1::getTypes()
+ );
+
+ if ( m_bCommitable )
+ aTypes.addTypes( OBoundControlModel_COMMITTING::getTypes() );
+
+ if ( m_bSupportsExternalBinding )
+ aTypes.addTypes( OBoundControlModel_BINDING::getTypes() );
+
+ if ( m_bSupportsValidation )
+ aTypes.addTypes( OBoundControlModel_VALIDATION::getTypes() );
+
+ return aTypes.getTypes();
+}
+
+// OComponentHelper
+//-----------------------------------------------------------------------------
+void OBoundControlModel::disposing()
+{
+ OControlModel::disposing();
+
+ ::osl::ClearableMutexGuard aGuard(m_aMutex);
+
+ if ( m_pAggPropMultiplexer )
+ m_pAggPropMultiplexer->dispose();
+
+ // notify all our listeners
+ com::sun::star::lang::EventObject aEvt( static_cast< XWeak* >( this ) );
+ m_aUpdateListeners.disposeAndClear( aEvt );
+ m_aResetHelper.disposing();
+
+ // disconnect from our database column
+ // TODO: could we replace the following 5 lines with a call to impl_disconnectDatabaseColumn_noNotify?
+ // The only more thing which it does is calling onDisconnectedDbColumn - could this
+ // cause trouble? At least when we continue to call OControlModel::disposing before, it *may*.
+ if ( hasField() )
+ {
+ getField()->removePropertyChangeListener( PROPERTY_VALUE, this );
+ resetField();
+ }
+ m_xCursor = NULL;
+
+ Reference< XComponent > xComp( m_xLabelControl, UNO_QUERY );
+ if ( xComp.is() )
+ xComp->removeEventListener(static_cast< XEventListener* >( static_cast< XPropertyChangeListener* >( this ) ) );
+
+ // disconnect from our external value binding
+ if ( hasExternalValueBinding() )
+ disconnectExternalValueBinding();
+
+ // dito for the validator
+ if ( hasValidator() )
+ disconnectValidator( );
+}
+
+//------------------------------------------------------------------------------
+void OBoundControlModel::onValuePropertyChange( ControlModelLock& i_rControLock )
+{
+ if ( hasExternalValueBinding() )
+ { // the control value changed, while we have an external value binding
+ // -> forward the value to it
+ if ( m_eControlValueChangeInstigator != eExternalBinding )
+ transferControlValueToExternal( i_rControLock );
+ }
+ else if ( !m_bCommitable && m_xColumnUpdate.is() )
+ { // the control value changed, while we are bound to a database column,
+ // but not committable (which means changes in the control have to be reflected to
+ // the underlying database column immediately)
+ // -> forward the value to the database column
+ if ( m_eControlValueChangeInstigator != eDbColumnBinding )
+ commitControlValueToDbColumn( false );
+ }
+
+ // validate the new value
+ if ( m_bSupportsValidation )
+ recheckValidity( true );
+}
+
+//------------------------------------------------------------------------------
+void OBoundControlModel::_propertyChanged( const PropertyChangeEvent& _rEvt ) throw ( RuntimeException )
+{
+ ControlModelLock aLock( *this );
+
+ OSL_ENSURE( _rEvt.PropertyName == m_sValuePropertyName,
+ "OBoundControlModel::_propertyChanged: where did this come from (1)?" );
+ OSL_ENSURE( m_pAggPropMultiplexer && !m_pAggPropMultiplexer->locked(),
+ "OBoundControlModel::_propertyChanged: where did this come from (2)?" );
+
+ if ( _rEvt.PropertyName == m_sValuePropertyName )
+ {
+ onValuePropertyChange( aLock );
+ }
+}
+
+//------------------------------------------------------------------------------
+void OBoundControlModel::startAggregatePropertyListening( const ::rtl::OUString& _rPropertyName )
+{
+ OSL_PRECOND( m_pAggPropMultiplexer, "OBoundControlModel::startAggregatePropertyListening: no multiplexer!" );
+ OSL_ENSURE( _rPropertyName.getLength(), "OBoundControlModel::startAggregatePropertyListening: invalid property name!" );
+
+ if ( m_pAggPropMultiplexer && _rPropertyName.getLength() )
+ {
+ m_pAggPropMultiplexer->addProperty( _rPropertyName );
+ }
+}
+
+//------------------------------------------------------------------------------
+void OBoundControlModel::doFormListening( const bool _bStart )
+{
+ OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::doFormListening: external value binding should overrule the database binding!" );
+
+ if ( isFormListening() == _bStart )
+ return;
+
+ if ( m_xAmbientForm.is() )
+ _bStart ? m_xAmbientForm->addLoadListener( this ) : m_xAmbientForm->removeLoadListener( this );
+
+ Reference< XLoadable > xParentLoadable( getParent(), UNO_QUERY );
+ if ( getParent().is() && !xParentLoadable.is() )
+ {
+ // if our parent does not directly support the XLoadable interface, then it might support the
+ // XRowSetSupplier/XRowSetChangeBroadcaster interfaces. In this case we have to listen for changes
+ // broadcasted by the latter.
+ Reference< XRowSetChangeBroadcaster > xRowSetBroadcaster( getParent(), UNO_QUERY );
+ if ( xRowSetBroadcaster.is() )
+ _bStart ? xRowSetBroadcaster->addRowSetChangeListener( this ) : xRowSetBroadcaster->removeRowSetChangeListener( this );
+ }
+
+ m_bFormListening = _bStart && m_xAmbientForm.is();
+}
+
+// XChild
+//------------------------------------------------------------------------------
+void SAL_CALL OBoundControlModel::setParent(const Reference<XInterface>& _rxParent) throw(com::sun::star::lang::NoSupportException, RuntimeException)
+{
+ ControlModelLock aLock( *this );
+ FieldChangeNotifier aBoundFieldNotifier( aLock );
+
+ if ( getParent() == _rxParent )
+ return;
+
+ // disconnect from database column (which is controlled by parent, directly or indirectly)
+ if ( hasField() )
+ impl_disconnectDatabaseColumn_noNotify();
+
+ // log off old listeners
+ if ( isFormListening() )
+ doFormListening( false );
+
+ // actually set the new parent
+ OControlModel::setParent( _rxParent );
+
+ // a new parent means a new ambient form
+ impl_determineAmbientForm_nothrow();
+
+ if ( !hasExternalValueBinding() )
+ {
+ // log on new listeners
+ doFormListening( true );
+
+ // re-connect to database column of the new parent
+ if ( m_xAmbientForm.is() && m_xAmbientForm->isLoaded() )
+ impl_connectDatabaseColumn_noNotify( false );
+ }
+}
+
+// XEventListener
+//------------------------------------------------------------------------------
+void SAL_CALL OBoundControlModel::disposing(const com::sun::star::lang::EventObject& _rEvent) throw (RuntimeException)
+{
+ ControlModelLock aLock( *this );
+
+ if ( _rEvent.Source == getField() )
+ {
+ resetField();
+ }
+ else if ( _rEvent.Source == m_xLabelControl )
+ {
+ Reference<XPropertySet> xOldValue = m_xLabelControl;
+ m_xLabelControl = NULL;
+
+ // fire a propertyChanged (when we leave aLock's scope)
+ aLock.addPropertyNotification( PROPERTY_ID_CONTROLLABEL, makeAny( xOldValue ), makeAny( m_xLabelControl ) );
+ }
+ else if ( _rEvent.Source == m_xExternalBinding )
+ { // *first* check for the external binding
+ disconnectExternalValueBinding( );
+ }
+ else if ( _rEvent.Source == m_xValidator )
+ { // *then* check for the validator. Reason is that bindings may also act as validator at the same
+ // time, in this case, the validator is automatically revoked when the binding is revoked
+ disconnectValidator( );
+ }
+ else
+ OControlModel::disposing(_rEvent);
+}
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+StringSequence SAL_CALL OBoundControlModel::getSupportedServiceNames() throw(RuntimeException)
+{
+ return ::comphelper::concatSequences(
+ getAggregateServiceNames(),
+ getSupportedServiceNames_Static()
+ );
+}
+
+//------------------------------------------------------------------------------
+Sequence< ::rtl::OUString > SAL_CALL OBoundControlModel::getSupportedServiceNames_Static() throw( RuntimeException )
+{
+ Sequence< ::rtl::OUString > aOwnServiceNames( 1 );
+ aOwnServiceNames[ 0 ] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.form.DataAwareControlModel") );
+
+ return ::comphelper::concatSequences(
+ OControlModel::getSupportedServiceNames_Static(),
+ aOwnServiceNames
+ );
+}
+
+// XPersist
+//------------------------------------------------------------------------------
+void SAL_CALL OBoundControlModel::write( const Reference<stario::XObjectOutputStream>& _rxOutStream ) throw(stario::IOException, RuntimeException)
+{
+ OControlModel::write(_rxOutStream);
+
+ osl::MutexGuard aGuard(m_aMutex);
+
+ // Version
+ _rxOutStream->writeShort(0x0002);
+
+ // Controlsource
+ ::comphelper::operator<<( _rxOutStream, m_aControlSource);
+
+ // !!! 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 !!!
+}
+
+//------------------------------------------------------------------------------
+void OBoundControlModel::defaultCommonProperties()
+{
+ Reference<com::sun::star::lang::XComponent> xComp(m_xLabelControl, UNO_QUERY);
+ if (xComp.is())
+ xComp->removeEventListener(static_cast<com::sun::star::lang::XEventListener*>(static_cast<XPropertyChangeListener*>(this)));
+ m_xLabelControl = NULL;
+}
+
+//------------------------------------------------------------------------------
+void OBoundControlModel::readCommonProperties(const Reference<stario::XObjectInputStream>& _rxInStream)
+{
+ sal_Int32 nLen = _rxInStream->readLong();
+
+ Reference<stario::XMarkableStream> xMark(_rxInStream, UNO_QUERY);
+ DBG_ASSERT(xMark.is(), "OBoundControlModel::readCommonProperties : can only work with markable streams !");
+ sal_Int32 nMark = xMark->createMark();
+
+ // read the reference to the label control
+ Reference<stario::XPersistObject> xPersist;
+ sal_Int32 nUsedFlag;
+ nUsedFlag = _rxInStream->readLong();
+ if (nUsedFlag)
+ xPersist = _rxInStream->readObject();
+ m_xLabelControl = m_xLabelControl.query( xPersist );
+ Reference< XComponent > xComp( m_xLabelControl, UNO_QUERY );
+ if (xComp.is())
+ xComp->addEventListener(static_cast<com::sun::star::lang::XEventListener*>(static_cast<XPropertyChangeListener*>(this)));
+
+ // read any other new common properties here
+
+ // skip the remaining bytes
+ xMark->jumpToMark(nMark);
+ _rxInStream->skipBytes(nLen);
+ xMark->deleteMark(nMark);
+}
+
+//------------------------------------------------------------------------------
+void OBoundControlModel::writeCommonProperties(const Reference<stario::XObjectOutputStream>& _rxOutStream)
+{
+ Reference<stario::XMarkableStream> xMark(_rxOutStream, UNO_QUERY);
+ 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
+ Reference<stario::XPersistObject> xPersist(m_xLabelControl, UNO_QUERY);
+ 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);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OBoundControlModel::read( const Reference< stario::XObjectInputStream >& _rxInStream ) throw(stario::IOException, RuntimeException)
+{
+ OControlModel::read(_rxInStream);
+
+ osl::MutexGuard aGuard(m_aMutex);
+ sal_uInt16 nVersion = _rxInStream->readShort(); (void)nVersion;
+ ::comphelper::operator>>( _rxInStream, m_aControlSource);
+}
+
+//------------------------------------------------------------------------------
+void OBoundControlModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle) const
+{
+ switch (nHandle)
+ {
+ case PROPERTY_ID_INPUT_REQUIRED:
+ rValue <<= m_bInputRequired;
+ break;
+ case PROPERTY_ID_CONTROLSOURCEPROPERTY:
+ rValue <<= m_sValuePropertyName;
+ break;
+ case PROPERTY_ID_CONTROLSOURCE:
+ rValue <<= m_aControlSource;
+ break;
+ case PROPERTY_ID_BOUNDFIELD:
+ rValue <<= getField();
+ 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(
+ Any& _rConvertedValue, Any& _rOldValue,
+ sal_Int32 _nHandle,
+ const Any& _rValue)
+ throw (com::sun::star::lang::IllegalArgumentException)
+{
+ sal_Bool bModified(sal_False);
+ switch (_nHandle)
+ {
+ case PROPERTY_ID_INPUT_REQUIRED:
+ bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, m_bInputRequired );
+ break;
+ case PROPERTY_ID_CONTROLSOURCE:
+ bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_aControlSource);
+ break;
+ case PROPERTY_ID_BOUNDFIELD:
+ OSL_FAIL( "OBoundControlModel::convertFastPropertyValue: BoundField should be a read-only property !" );
+ throw com::sun::star::lang::IllegalArgumentException();
+ case PROPERTY_ID_CONTROLLABEL:
+ if (!_rValue.hasValue())
+ { // property set to void
+ _rConvertedValue = Any();
+ getFastPropertyValue(_rOldValue, _nHandle);
+ bModified = m_xLabelControl.is();
+ }
+ else
+ {
+ bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_xLabelControl);
+ if (!m_xLabelControl.is())
+ // an empty interface is interpreted as VOID
+ _rOldValue.clear();
+ }
+ break;
+ default:
+ bModified = OControlModel::convertFastPropertyValue(_rConvertedValue, _rOldValue, _nHandle, _rValue);
+ }
+ return bModified;
+}
+
+//------------------------------------------------------------------------------
+Any OBoundControlModel::getPropertyDefaultByHandle( sal_Int32 _nHandle ) const
+{
+ Any aDefault;
+ switch ( _nHandle )
+ {
+ case PROPERTY_ID_INPUT_REQUIRED:
+ aDefault <<= sal_Bool( sal_True );
+ break;
+
+ case PROPERTY_ID_CONTROLSOURCE:
+ aDefault <<= ::rtl::OUString();
+ break;
+
+ case PROPERTY_ID_CONTROLLABEL:
+ aDefault <<= Reference< XPropertySet >();
+ break;
+ }
+ return aDefault;
+}
+
+//------------------------------------------------------------------------------
+void OBoundControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw (Exception)
+{
+ switch (nHandle)
+ {
+ case PROPERTY_ID_INPUT_REQUIRED:
+ OSL_VERIFY( rValue >>= m_bInputRequired );
+ break;
+ case PROPERTY_ID_CONTROLSOURCE:
+ OSL_VERIFY( rValue >>= m_aControlSource );
+ break;
+ case PROPERTY_ID_BOUNDFIELD:
+ OSL_FAIL("OBoundControlModel::setFastPropertyValue_NoBroadcast : BoundField should be a read-only property !");
+ throw com::sun::star::lang::IllegalArgumentException();
+ case PROPERTY_ID_CONTROLLABEL:
+ {
+ if ( rValue.hasValue() && ( rValue.getValueTypeClass() != TypeClass_INTERFACE ) )
+ throw com::sun::star::lang::IllegalArgumentException();
+
+ Reference< XInterface > xNewValue( rValue, UNO_QUERY );
+ if ( !xNewValue.is() )
+ { // set property to "void"
+ Reference< XComponent > xComp( m_xLabelControl, UNO_QUERY );
+ if ( xComp.is() )
+ xComp->removeEventListener( static_cast< XPropertyChangeListener* >( this ) );
+ m_xLabelControl = NULL;
+ break;
+ }
+
+ Reference< XControlModel > xAsModel ( xNewValue, UNO_QUERY );
+ Reference< XServiceInfo > xAsServiceInfo ( xAsModel, UNO_QUERY );
+ Reference< XPropertySet > xAsPropSet ( xAsServiceInfo, UNO_QUERY );
+ Reference< XChild > xAsChild ( xAsPropSet, UNO_QUERY );
+ if ( !xAsChild.is() || !xAsServiceInfo->supportsService( m_aLabelServiceName ) )
+ {
+ throw com::sun::star::lang::IllegalArgumentException();
+ }
+
+ // check if weself and the given model have a common anchestor (up to the forms collection)
+ Reference<XChild> xCont;
+ query_interface(static_cast<XWeak*>(this), xCont);
+ Reference< XInterface > xMyTopLevel = xCont->getParent();
+ while (xMyTopLevel.is())
+ {
+ Reference<XForm> xAsForm(xMyTopLevel, UNO_QUERY);
+ if (!xAsForm.is())
+ // found my root
+ break;
+
+ Reference<XChild> xLoopAsChild(xMyTopLevel, UNO_QUERY);
+ xMyTopLevel = xLoopAsChild.is() ? xLoopAsChild->getParent() : Reference< XInterface >();
+ }
+ Reference< XInterface > xNewTopLevel = xAsChild->getParent();
+ while (xNewTopLevel.is())
+ {
+ Reference<XForm> xAsForm(xNewTopLevel, UNO_QUERY);
+ if (!xAsForm.is())
+ break;
+
+ Reference<XChild> xLoopAsChild(xNewTopLevel, UNO_QUERY);
+ xNewTopLevel = xLoopAsChild.is() ? xLoopAsChild->getParent() : Reference< XInterface >();
+ }
+ if (xNewTopLevel != xMyTopLevel)
+ {
+ // the both objects don't belong to the same forms collection -> not acceptable
+ throw com::sun::star::lang::IllegalArgumentException();
+ }
+
+ m_xLabelControl = xAsPropSet;
+ Reference<com::sun::star::lang::XComponent> xComp(m_xLabelControl, UNO_QUERY);
+ if (xComp.is())
+ xComp->addEventListener(static_cast<com::sun::star::lang::XEventListener*>(static_cast<XPropertyChangeListener*>(this)));
+ }
+ break;
+ default:
+ OControlModel::setFastPropertyValue_NoBroadcast(nHandle, rValue );
+ }
+}
+
+// XPropertyChangeListener
+//------------------------------------------------------------------------------
+void SAL_CALL OBoundControlModel::propertyChange( const PropertyChangeEvent& evt ) throw(RuntimeException)
+{
+ // if the DBColumn value changed, transfer it to the control
+ if ( evt.PropertyName.equals( PROPERTY_VALUE ) )
+ {
+ OSL_ENSURE( evt.Source == getField(), "OBoundControlModel::propertyChange: value changes from components other than our database colum?" );
+ osl::MutexGuard aGuard(m_aMutex);
+ if ( m_bForwardValueChanges && m_xColumn.is() )
+ transferDbValueToControl();
+ }
+ else
+ {
+ OSL_ENSURE( evt.Source == m_xExternalBinding, "OBoundControlModel::propertyChange: where did this come from?" );
+
+ // our binding has properties which can control properties of ourself
+ ::rtl::OUString sBindingControlledProperty;
+ bool bForwardToLabelControl = false;
+ if ( evt.PropertyName.equals( PROPERTY_READONLY ) )
+ {
+ sBindingControlledProperty = PROPERTY_READONLY;
+ }
+ else if ( evt.PropertyName.equals( PROPERTY_RELEVANT ) )
+ {
+ sBindingControlledProperty = PROPERTY_ENABLED;
+ bForwardToLabelControl = true;
+ }
+ else
+ return;
+
+ try
+ {
+ setPropertyValue( sBindingControlledProperty, evt.NewValue );
+ if ( bForwardToLabelControl && m_xLabelControl.is() )
+ m_xLabelControl->setPropertyValue( sBindingControlledProperty, evt.NewValue );
+ }
+ catch( const Exception& )
+ {
+ OSL_FAIL( "OBoundControlModel::propertyChange: could not adjust my binding-controlled property!" );
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OBoundControlModel::onRowSetChanged( const EventObject& /*i_Event*/ ) throw (RuntimeException)
+{
+ ControlModelLock aLock( *this );
+ FieldChangeNotifier aBoundFieldNotifier( aLock );
+
+ // disconnect from database column (which is controlled by parent, directly or indirectly)
+ if ( hasField() )
+ impl_disconnectDatabaseColumn_noNotify();
+
+ // log off old listeners
+ if ( isFormListening() )
+ doFormListening( false );
+
+ // determine the new ambient form
+ impl_determineAmbientForm_nothrow();
+
+ // log on new listeners
+ doFormListening( true );
+
+ // re-connect to database column if needed and possible
+ if ( m_xAmbientForm.is() && m_xAmbientForm->isLoaded() )
+ impl_connectDatabaseColumn_noNotify( false );
+}
+
+// XBoundComponent
+//------------------------------------------------------------------------------
+void SAL_CALL OBoundControlModel::addUpdateListener(const Reference<XUpdateListener>& _rxListener) throw(RuntimeException)
+{
+ m_aUpdateListeners.addInterface(_rxListener);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OBoundControlModel::removeUpdateListener(const Reference< XUpdateListener>& _rxListener) throw(RuntimeException)
+{
+ m_aUpdateListeners.removeInterface(_rxListener);
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL OBoundControlModel::commit() throw(RuntimeException)
+{
+ ControlModelLock aLock( *this );
+
+ OSL_PRECOND( m_bCommitable, "OBoundControlModel::commit: invalid call (I'm not commitable !) " );
+ if ( hasExternalValueBinding() )
+ {
+ // in most cases, no action is required: For most derivees, we know the value property of
+ // our control (see initValueProperty), and when an external binding is active, we
+ // instantly forward all changes in this property to the external binding.
+ if ( !m_sValuePropertyName.getLength() )
+ // but for those derivees which did not use this feature, we need an
+ // explicit transfer
+ transferControlValueToExternal( aLock );
+ return sal_True;
+ }
+
+ OSL_ENSURE( !hasExternalValueBinding(), "OBoundControlModel::commit: control flow broken!" );
+ // we reach this only if we're not working with an external binding
+
+ if ( !hasField() )
+ return sal_True;
+
+ ::cppu::OInterfaceIteratorHelper aIter( m_aUpdateListeners );
+ EventObject aEvent;
+ aEvent.Source = static_cast< XWeak* >( this );
+ sal_Bool bSuccess = sal_True;
+
+ aLock.release();
+ // >>>>>>>> ----- UNSAFE ----- >>>>>>>>
+ while (aIter.hasMoreElements() && bSuccess)
+ bSuccess = static_cast< XUpdateListener* >( aIter.next() )->approveUpdate( aEvent );
+ // <<<<<<<< ----- UNSAFE ----- <<<<<<<<
+ aLock.acquire();
+
+ if ( bSuccess )
+ {
+ try
+ {
+ if ( m_xColumnUpdate.is() )
+ bSuccess = commitControlValueToDbColumn( sal_False );
+ }
+ catch(Exception&)
+ {
+ bSuccess = sal_False;
+ }
+ }
+
+ if ( bSuccess )
+ {
+ aLock.release();
+ m_aUpdateListeners.notifyEach( &XUpdateListener::updated, aEvent );
+ }
+
+ return bSuccess;
+}
+
+//------------------------------------------------------------------------------
+void OBoundControlModel::resetField()
+{
+ m_xColumnUpdate.clear();
+ m_xColumn.clear();
+ m_xField.clear();
+ m_nFieldType = DataType::OTHER;
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OBoundControlModel::connectToField(const Reference<XRowSet>& rForm)
+{
+ OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::connectToField: invalid call (have an external binding)!" );
+
+ // wenn eine Verbindung zur Datenbank existiert
+ if (rForm.is() && getConnection(rForm).is())
+ {
+ // Feld bestimmen und PropertyChangeListener
+ m_xCursor = rForm;
+ Reference<XPropertySet> xFieldCandidate;
+
+ if (m_xCursor.is())
+ {
+ Reference<XColumnsSupplier> xColumnsSupplier(m_xCursor, UNO_QUERY);
+ DBG_ASSERT(xColumnsSupplier.is(), "OBoundControlModel::connectToField : the row set should support the com::sun::star::sdb::ResultSet service !");
+ if (xColumnsSupplier.is())
+ {
+ Reference<XNameAccess> xColumns(xColumnsSupplier->getColumns(), UNO_QUERY);
+ if (xColumns.is() && xColumns->hasByName(m_aControlSource))
+ {
+ OSL_VERIFY( xColumns->getByName(m_aControlSource) >>= xFieldCandidate );
+ }
+ }
+ }
+
+ try
+ {
+ sal_Int32 nFieldType = DataType::OTHER;
+ if ( xFieldCandidate.is() )
+ {
+ xFieldCandidate->getPropertyValue( PROPERTY_FIELDTYPE ) >>= nFieldType;
+ if ( approveDbColumnType( nFieldType ) )
+ impl_setField_noNotify( xFieldCandidate );
+ }
+ else
+ impl_setField_noNotify( NULL );
+
+ if ( m_xField.is() )
+ {
+ if( m_xField->getPropertySetInfo()->hasPropertyByName( PROPERTY_VALUE ) )
+ {
+ m_nFieldType = nFieldType;
+
+ // an wertaenderungen horchen
+ m_xField->addPropertyChangeListener( PROPERTY_VALUE, this );
+ m_xColumnUpdate = Reference< XColumnUpdate >( m_xField, UNO_QUERY );
+ m_xColumn = Reference< XColumn >( m_xField, UNO_QUERY );
+
+ sal_Int32 nNullableFlag = ColumnValue::NO_NULLS;
+ m_xField->getPropertyValue(PROPERTY_ISNULLABLE) >>= nNullableFlag;
+ m_bRequired = (ColumnValue::NO_NULLS == nNullableFlag);
+ // we're optimistic : in case of ColumnValue_NULLABLE_UNKNOWN we assume nullability ....
+ }
+ else
+ {
+ OSL_FAIL("OBoundControlModel::connectToField: property NAME not supported!");
+ impl_setField_noNotify( NULL );
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ resetField();
+ }
+ }
+ return hasField();
+}
+
+//------------------------------------------------------------------------------
+void OBoundControlModel::initFromField( const Reference< XRowSet >& _rxRowSet )
+{
+ // but only if the rowset if posisitioned on a valid record
+ if ( hasField() && _rxRowSet.is() )
+ {
+ if ( !_rxRowSet->isBeforeFirst() && !_rxRowSet->isAfterLast() )
+ transferDbValueToControl();
+ else
+ // reset the field if the row set is empty
+ // #i30661#
+ resetNoBroadcast();
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OBoundControlModel::approveDbColumnType(sal_Int32 _nColumnType)
+{
+ OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::approveDbColumnType: invalid call (have an external binding)!" );
+
+ 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))
+ return sal_False;
+
+ return sal_True;
+}
+
+//------------------------------------------------------------------------------
+void OBoundControlModel::impl_determineAmbientForm_nothrow()
+{
+ Reference< XInterface > xParent( const_cast< OBoundControlModel* >( this )->getParent() );
+
+ m_xAmbientForm.set( xParent, UNO_QUERY );
+ if ( !m_xAmbientForm.is() )
+ {
+ Reference< XRowSetSupplier > xSupRowSet( xParent, UNO_QUERY );
+ if ( xSupRowSet.is() )
+ m_xAmbientForm.set( xSupRowSet->getRowSet(), UNO_QUERY );
+ }
+}
+
+//------------------------------------------------------------------------------
+void OBoundControlModel::impl_connectDatabaseColumn_noNotify( bool _bFromReload )
+{
+ OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::impl_connectDatabaseColumn_noNotify: not to be called with an external value binding!" );
+
+ // consistency checks
+ DBG_ASSERT( !( hasField() && !_bFromReload ),
+ "OBoundControlModel::impl_connectDatabaseColumn_noNotify: the form is just *loaded*, but we already have a field!" );
+ (void)_bFromReload;
+
+ Reference< XRowSet > xRowSet( m_xAmbientForm, UNO_QUERY );
+ OSL_ENSURE( xRowSet.is(), "OBoundControlModel::impl_connectDatabaseColumn_noNotify: no row set!" );
+ if ( !xRowSet.is() )
+ return;
+
+ if ( !hasField() )
+ {
+ // connect to the column
+ connectToField( xRowSet );
+ }
+
+ // now that we're connected (more or less, even if we did not find a column),
+ // we definately want to forward any potentially occuring value changes
+ m_bForwardValueChanges = sal_True;
+
+ // let derived classes react on this new connection
+ m_bLoaded = sal_True;
+ onConnectedDbColumn( xRowSet );
+
+ // initially transfer the db column value to the control, if we successfully connected to a database column
+ if ( hasField() )
+ initFromField( xRowSet );
+}
+
+//------------------------------------------------------------------------------
+void OBoundControlModel::impl_disconnectDatabaseColumn_noNotify()
+{
+ OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::impl_disconnectDatabaseColumn_noNotify: not to be called with an external value binding!" );
+
+ // let derived classes react on this
+ onDisconnectedDbColumn();
+
+ if ( hasField() )
+ {
+ getField()->removePropertyChangeListener( PROPERTY_VALUE, this );
+ resetField();
+ }
+
+ m_xCursor = NULL;
+ m_bLoaded = sal_False;
+}
+
+//==============================================================================
+// XLoadListener
+//------------------------------------------------------------------------------
+void SAL_CALL OBoundControlModel::loaded( const EventObject& _rEvent ) throw(RuntimeException)
+{
+ ControlModelLock aLock( *this );
+ FieldChangeNotifier aBoundFieldNotifier( aLock );
+
+ OSL_ENSURE( _rEvent.Source == m_xAmbientForm, "OBoundControlModel::loaded: where does this come from?" );
+ (void)_rEvent;
+
+ OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::loaded: we should never reach this with an external value binding!" );
+ if ( hasExternalValueBinding() )
+ return;
+
+ impl_connectDatabaseColumn_noNotify( false );
+}
+
+
+//------------------------------------------------------------------------------
+void SAL_CALL OBoundControlModel::unloaded( const com::sun::star::lang::EventObject& /*aEvent*/ ) throw(RuntimeException)
+{
+ OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::unloaded: we should never reach this with an external value binding!" );
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OBoundControlModel::reloading( const com::sun::star::lang::EventObject& /*aEvent*/ ) throw(RuntimeException)
+{
+ OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::reloading: we should never reach this with an external value binding!" );
+ if ( hasExternalValueBinding() )
+ return;
+
+ osl::MutexGuard aGuard(m_aMutex);
+ m_bForwardValueChanges = sal_False;
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OBoundControlModel::unloading(const com::sun::star::lang::EventObject& /*aEvent*/) throw(RuntimeException)
+{
+ ControlModelLock aLock( *this );
+ FieldChangeNotifier aBoundFieldNotifier( aLock );
+
+ OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::unloading: we should never reach this with an external value binding!" );
+ if ( hasExternalValueBinding() )
+ return;
+
+ impl_disconnectDatabaseColumn_noNotify();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OBoundControlModel::reloaded( const EventObject& _rEvent ) throw(RuntimeException)
+{
+ ControlModelLock aLock( *this );
+ FieldChangeNotifier aBoundFieldNotifier( aLock );
+
+ OSL_ENSURE( _rEvent.Source == m_xAmbientForm, "OBoundControlModel::reloaded: where does this come from?" );
+ (void)_rEvent;
+
+ OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::reloaded: we should never reach this with an external value binding!" );
+ if ( hasExternalValueBinding() )
+ return;
+
+ impl_connectDatabaseColumn_noNotify( true );
+}
+
+//------------------------------------------------------------------------------
+void OBoundControlModel::setControlValue( const Any& _rValue, ValueChangeInstigator _eInstigator )
+{
+ m_eControlValueChangeInstigator = _eInstigator;
+ doSetControlValue( _rValue );
+ m_eControlValueChangeInstigator = eOther;
+}
+
+//------------------------------------------------------------------------------
+void OBoundControlModel::doSetControlValue( const Any& _rValue )
+{
+ OSL_PRECOND( m_xAggregateFastSet.is() && m_xAggregateSet.is(),
+ "OBoundControlModel::doSetControlValue: invalid aggregate !" );
+ OSL_PRECOND( m_sValuePropertyName.getLength() || ( m_nValuePropertyAggregateHandle != -1 ),
+ "OBoundControlModel::doSetControlValue: please override if you have own value property handling!" );
+
+ try
+ {
+ // release our mutex once (it's acquired in one of the the calling methods), 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
+ MutexRelease aRelease( m_aMutex );
+ if ( ( m_nValuePropertyAggregateHandle != -1 ) && m_xAggregateFastSet.is() )
+ {
+ m_xAggregateFastSet->setFastPropertyValue( m_nValuePropertyAggregateHandle, _rValue );
+ }
+ else if ( m_sValuePropertyName.getLength() && m_xAggregateSet.is() )
+ {
+ m_xAggregateSet->setPropertyValue( m_sValuePropertyName, _rValue );
+ }
+ }
+ catch( const Exception& )
+ {
+ OSL_FAIL( "OBoundControlModel::doSetControlValue: caught an exception!" );
+ }
+}
+
+//------------------------------------------------------------------------------
+void OBoundControlModel::onConnectedValidator( )
+{
+ try
+ {
+ // if we have an external validator, we do not want the control to force invalid
+ // inputs to the default value. Instead, invalid inputs should be translated
+ // to NaN (not a number)
+ Reference< XPropertySetInfo > xAggregatePropertyInfo;
+ if ( m_xAggregateSet.is() )
+ xAggregatePropertyInfo = m_xAggregateSet->getPropertySetInfo();
+ if ( xAggregatePropertyInfo.is() && xAggregatePropertyInfo->hasPropertyByName( PROPERTY_ENFORCE_FORMAT ) )
+ m_xAggregateSet->setPropertyValue( PROPERTY_ENFORCE_FORMAT, makeAny( (sal_Bool)sal_False ) );
+ }
+ catch( const Exception& )
+ {
+ OSL_FAIL( "OBoundControlModel::onConnectedValidator: caught an exception!" );
+ }
+ recheckValidity( false );
+}
+
+//------------------------------------------------------------------------------
+void OBoundControlModel::onDisconnectedValidator( )
+{
+ try
+ {
+ Reference< XPropertySetInfo > xAggregatePropertyInfo;
+ if ( m_xAggregateSet.is() )
+ xAggregatePropertyInfo = m_xAggregateSet->getPropertySetInfo();
+ if ( xAggregatePropertyInfo.is() && xAggregatePropertyInfo->hasPropertyByName( PROPERTY_ENFORCE_FORMAT ) )
+ m_xAggregateSet->setPropertyValue( PROPERTY_ENFORCE_FORMAT, makeAny( (sal_Bool)sal_True ) );
+ }
+ catch( const Exception& )
+ {
+ OSL_FAIL( "OBoundControlModel::onDisconnectedValidator: caught an exception!" );
+ }
+ recheckValidity( false );
+}
+
+//------------------------------------------------------------------------------
+void OBoundControlModel::onConnectedExternalValue( )
+{
+ calculateExternalValueType();
+}
+
+//------------------------------------------------------------------------------
+void OBoundControlModel::onDisconnectedExternalValue( )
+{
+}
+
+//------------------------------------------------------------------------------
+void OBoundControlModel::onConnectedDbColumn( const Reference< XInterface >& /*_rxForm*/ )
+{
+ OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::onConnectedDbColumn: how this? There's an external value binding!" );
+}
+
+//------------------------------------------------------------------------------
+void OBoundControlModel::onDisconnectedDbColumn()
+{
+ OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::onDisconnectedDbColumn: how this? There's an external value binding!" );
+}
+
+// XReset
+//-----------------------------------------------------------------------------
+Any OBoundControlModel::getDefaultForReset() const
+{
+ return Any();
+}
+
+//-----------------------------------------------------------------------------
+void OBoundControlModel::resetNoBroadcast()
+{
+ setControlValue( getDefaultForReset(), eOther );
+}
+
+//-----------------------------------------------------------------------------
+void OBoundControlModel::addResetListener(const Reference<XResetListener>& l) throw (RuntimeException)
+{
+ m_aResetHelper.addResetListener( l );
+}
+
+//-----------------------------------------------------------------------------
+void OBoundControlModel::removeResetListener(const Reference<XResetListener>& l) throw (RuntimeException)
+{
+ m_aResetHelper.removeResetListener( l );
+}
+
+//-----------------------------------------------------------------------------
+void OBoundControlModel::reset() throw (RuntimeException)
+{
+ if ( !m_aResetHelper.approveReset() )
+ return;
+
+ ControlModelLock aLock( *this );
+
+ // on a new record?
+ sal_Bool bIsNewRecord = sal_False;
+ Reference<XPropertySet> xSet( m_xCursor, UNO_QUERY );
+ if ( xSet.is() )
+ {
+ try
+ {
+ xSet->getPropertyValue( PROPERTY_ISNEW ) >>= bIsNewRecord;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ // cursor on an invalid row?
+ sal_Bool bInvalidCursorPosition = sal_True;
+ try
+ {
+ bInvalidCursorPosition = m_xCursor.is()
+ && ( m_xCursor->isAfterLast()
+ || m_xCursor->isBeforeFirst()
+ )
+ && !bIsNewRecord;
+ }
+ catch( const SQLException& )
+ {
+ OSL_FAIL( "OBoundControlModel::reset: caught an SQL exception!" );
+ }
+ // #i24495# - don't count the insert row as "invalid"
+
+ sal_Bool bSimpleReset =
+ ( !m_xColumn.is() // no connection to a database column
+ || ( m_xCursor.is() // OR we have an improperly positioned cursor
+ && bInvalidCursorPosition
+ )
+ || hasExternalValueBinding() // OR we have an external value binding
+ );
+
+ if ( !bSimpleReset )
+ {
+ // The default values will be set if and only if the current value of the field which we're bound
+ // to is NULL.
+ // Else, the current field value should be refreshed
+ // This behaviour is not completely ... "matured": What should happen if the field as well as the
+ // control have a default value?
+
+ sal_Bool bIsNull = sal_True;
+ // we have to access the field content at least once to get a reliable result by XColumn::wasNull
+ try
+ {
+ // normally, we'd do a getString here. However, this is extremely expensive in the case
+ // of binary fields. Unfortunately, getString is the only method which is guaranteed
+ // to *always* succeed, all other getXXX methods may fail if the column is asked for a
+ // non-convertible type
+ sal_Int32 nFieldType = DataType::OBJECT;
+ getField()->getPropertyValue( PROPERTY_FIELDTYPE ) >>= nFieldType;
+ if ( ( nFieldType == DataType::BINARY )
+ || ( nFieldType == DataType::VARBINARY )
+ || ( nFieldType == DataType::LONGVARBINARY )
+ || ( nFieldType == DataType::OBJECT )
+ /*|| ( nFieldType == DataType::CLOB )*/
+ )
+ m_xColumn->getBinaryStream();
+ else if ( nFieldType == DataType::BLOB )
+ m_xColumn->getBlob();
+ else
+ m_xColumn->getString();
+
+ bIsNull = m_xColumn->wasNull();
+ }
+ catch(Exception&)
+ {
+ OSL_FAIL("OBoundControlModel::reset: this should have succeeded in all cases!");
+ }
+
+ sal_Bool bNeedValueTransfer = sal_True;
+
+ if ( bIsNull )
+ {
+ if ( bIsNewRecord )
+ {
+ // reset the control to it's default
+ resetNoBroadcast();
+ // and immediately commit the changes to the DB column, to keep consistency
+ commitControlValueToDbColumn( sal_True );
+
+ bNeedValueTransfer = sal_False;
+ }
+ }
+
+ if ( bNeedValueTransfer )
+ transferDbValueToControl();
+ }
+ else
+ {
+ resetNoBroadcast();
+
+ // transfer to the external binding, if necessary
+ if ( hasExternalValueBinding() )
+ transferControlValueToExternal( aLock );
+ }
+
+ // revalidate, if necessary
+ if ( hasValidator() )
+ recheckValidity( true );
+
+ aLock.release();
+
+ m_aResetHelper.notifyResetted();
+}
+
+// -----------------------------------------------------------------------------
+void OBoundControlModel::impl_setField_noNotify( const Reference< XPropertySet>& _rxField )
+{
+ DBG_ASSERT( !hasExternalValueBinding(), "OBoundControlModel::impl_setField_noNotify: We have an external value binding!" );
+ m_xField = _rxField;
+}
+
+//--------------------------------------------------------------------
+sal_Bool OBoundControlModel::impl_approveValueBinding_nolock( const Reference< XValueBinding >& _rxBinding )
+{
+ if ( !_rxBinding.is() )
+ return sal_False;
+
+ Sequence< Type > aTypeCandidates;
+ {
+ // SYNCHRONIZED -->
+ ::osl::MutexGuard aGuard( m_aMutex );
+ aTypeCandidates = getSupportedBindingTypes();
+ // <-- SYNCHRONIZED
+ }
+
+ for ( const Type* pType = aTypeCandidates.getConstArray();
+ pType != aTypeCandidates.getConstArray() + aTypeCandidates.getLength();
+ ++pType
+ )
+ {
+ if ( _rxBinding->supportsType( *pType ) )
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+//--------------------------------------------------------------------
+void OBoundControlModel::connectExternalValueBinding(
+ const Reference< XValueBinding >& _rxBinding, ControlModelLock& _rInstanceLock )
+{
+ OSL_PRECOND( _rxBinding.is(), "OBoundControlModel::connectExternalValueBinding: invalid binding instance!" );
+ OSL_PRECOND( !hasExternalValueBinding( ), "OBoundControlModel::connectExternalValueBinding: precond not met (currently have a binding)!" );
+
+ // if we're connected to a database column, suspend this
+ if ( hasField() )
+ impl_disconnectDatabaseColumn_noNotify();
+
+ // suspend listening for load-related events at out ambient form.
+ // This is because an external value binding overrules a possible database binding.
+ if ( isFormListening() )
+ doFormListening( false );
+
+ // remember this new binding
+ m_xExternalBinding = _rxBinding;
+
+ // tell the derivee
+ onConnectedExternalValue();
+
+ try
+ {
+ // add as value listener so we get notified when the value changes
+ Reference< XModifyBroadcaster > xModifiable( m_xExternalBinding, UNO_QUERY );
+ if ( xModifiable.is() )
+ xModifiable->addModifyListener( this );
+
+ // add as property change listener for some (possibly present) properties we're
+ // interested in
+ Reference< XPropertySet > xBindingProps( m_xExternalBinding, UNO_QUERY );
+ Reference< XPropertySetInfo > xBindingPropsInfo( xBindingProps.is() ? xBindingProps->getPropertySetInfo() : Reference< XPropertySetInfo >() );
+ if ( xBindingPropsInfo.is() )
+ {
+ if ( xBindingPropsInfo->hasPropertyByName( PROPERTY_READONLY ) )
+ {
+ xBindingProps->addPropertyChangeListener( PROPERTY_READONLY, this );
+ m_bBindingControlsRO = sal_True;
+ }
+ if ( xBindingPropsInfo->hasPropertyByName( PROPERTY_RELEVANT ) )
+ {
+ xBindingProps->addPropertyChangeListener( PROPERTY_RELEVANT, this );
+ m_bBindingControlsEnable = sal_True;
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ // propagate our new value
+ transferExternalValueToControl( _rInstanceLock );
+
+ // if the binding is also a validator, use it, too. This is a constraint of the
+ // com.sun.star.form.binding.ValidatableBindableFormComponent service
+ if ( m_bSupportsValidation )
+ {
+ try
+ {
+ Reference< XValidator > xAsValidator( _rxBinding, UNO_QUERY );
+ if ( xAsValidator.is() )
+ setValidator( xAsValidator );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+}
+
+//--------------------------------------------------------------------
+void OBoundControlModel::disconnectExternalValueBinding( )
+{
+ try
+ {
+ // not listening at the binding anymore
+ Reference< XModifyBroadcaster > xModifiable( m_xExternalBinding, UNO_QUERY );
+ if ( xModifiable.is() )
+ xModifiable->removeModifyListener( this );
+
+ // remove as property change listener
+ Reference< XPropertySet > xBindingProps( m_xExternalBinding, UNO_QUERY );
+ if ( m_bBindingControlsRO )
+ xBindingProps->removePropertyChangeListener( PROPERTY_READONLY, this );
+ if ( m_bBindingControlsEnable )
+ xBindingProps->removePropertyChangeListener( PROPERTY_RELEVANT, this );
+ }
+ catch( const Exception& )
+ {
+ OSL_FAIL( "OBoundControlModel::disconnectExternalValueBinding: caught an exception!" );
+ }
+
+ // if the binding also acts as our validator, disconnect the validator, too
+ if ( ( m_xExternalBinding == m_xValidator ) && m_xValidator.is() )
+ disconnectValidator( );
+
+ // no binding anymore
+ m_xExternalBinding.clear();
+
+ // be a load listener at our form, again. This was suspended while we had
+ // an external value binding in place.
+ doFormListening( true );
+
+ // re-connect to database column of the new parent
+ if ( m_xAmbientForm.is() && m_xAmbientForm->isLoaded() )
+ impl_connectDatabaseColumn_noNotify( false );
+
+ // tell the derivee
+ onDisconnectedExternalValue();
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL OBoundControlModel::setValueBinding( const Reference< XValueBinding >& _rxBinding ) throw (IncompatibleTypesException, RuntimeException)
+{
+ OSL_PRECOND( m_bSupportsExternalBinding, "OBoundControlModel::setValueBinding: How did you reach this method?" );
+ // the interface for this method should not have been exposed if we do not
+ // support binding to external data
+ // allow reset
+ if ( _rxBinding.is() && !impl_approveValueBinding_nolock( _rxBinding ) )
+ {
+ throw IncompatibleTypesException(
+ FRM_RES_STRING( RID_STR_INCOMPATIBLE_TYPES ),
+ *this
+ );
+ }
+
+ ControlModelLock aLock( *this );
+
+ // since a ValueBinding overrules any potentially active database binding, the change in a ValueBinding
+ // might trigger a change in our BoundField.
+ FieldChangeNotifier aBoundFieldNotifier( aLock );
+
+ // disconnect from the old binding
+ if ( hasExternalValueBinding() )
+ disconnectExternalValueBinding( );
+
+ // connect to the new binding
+ if ( _rxBinding.is() )
+ connectExternalValueBinding( _rxBinding, aLock );
+}
+
+//--------------------------------------------------------------------
+Reference< XValueBinding > SAL_CALL OBoundControlModel::getValueBinding( ) throw (RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ OSL_PRECOND( m_bSupportsExternalBinding, "OBoundControlModel::getValueBinding: How did you reach this method?" );
+ // the interface for this method should not have been exposed if we do not
+ // support binding to external data
+
+ return m_xExternalBinding;
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL OBoundControlModel::modified( const EventObject& _rEvent ) throw ( RuntimeException )
+{
+ ControlModelLock aLock( *this );
+
+ OSL_PRECOND( hasExternalValueBinding(), "OBoundControlModel::modified: Where did this come from?" );
+ if ( !m_bTransferingValue && ( m_xExternalBinding == _rEvent.Source ) && m_xExternalBinding.is() )
+ {
+ transferExternalValueToControl( aLock );
+ }
+}
+
+//--------------------------------------------------------------------
+void OBoundControlModel::transferDbValueToControl( )
+{
+ try
+ {
+ setControlValue( translateDbColumnToControlValue(), eDbColumnBinding );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+
+//------------------------------------------------------------------------------
+void OBoundControlModel::transferExternalValueToControl( ControlModelLock& _rInstanceLock )
+{
+ Reference< XValueBinding > xExternalBinding( m_xExternalBinding );
+ Type aValueExchangeType( getExternalValueType() );
+
+ _rInstanceLock.release();
+ // >>>>>>>> ----- UNSAFE ----- >>>>>>>>
+ Any aExternalValue;
+ try
+ {
+ aExternalValue = xExternalBinding->getValue( aValueExchangeType );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ // <<<<<<<< ----- UNSAFE ----- <<<<<<<<
+ _rInstanceLock.acquire();
+
+ setControlValue( translateExternalValueToControlValue( aExternalValue ), eExternalBinding );
+}
+
+//------------------------------------------------------------------------------
+void OBoundControlModel::transferControlValueToExternal( ControlModelLock& _rInstanceLock )
+{
+ OSL_PRECOND( m_bSupportsExternalBinding && hasExternalValueBinding(),
+ "OBoundControlModel::transferControlValueToExternal: precondition not met!" );
+
+ if ( m_xExternalBinding.is() )
+ {
+ Any aExternalValue( translateControlValueToExternalValue() );
+ m_bTransferingValue = sal_True;
+
+ _rInstanceLock.release();
+ // >>>>>>>> ----- UNSAFE ----- >>>>>>>>
+ try
+ {
+ m_xExternalBinding->setValue( aExternalValue );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ // <<<<<<<< ----- UNSAFE ----- <<<<<<<<
+ _rInstanceLock.acquire();
+
+ m_bTransferingValue = sal_False;
+ }
+}
+
+// -----------------------------------------------------------------------------
+Sequence< Type > OBoundControlModel::getSupportedBindingTypes()
+{
+ return Sequence< Type >( &m_aValuePropertyType, 1 );
+}
+
+//-----------------------------------------------------------------------------
+void OBoundControlModel::calculateExternalValueType()
+{
+ m_aExternalValueType = Type();
+ if ( !m_xExternalBinding.is() )
+ return;
+
+ Sequence< Type > aTypeCandidates( getSupportedBindingTypes() );
+ for ( const Type* pTypeCandidate = aTypeCandidates.getConstArray();
+ pTypeCandidate != aTypeCandidates.getConstArray() + aTypeCandidates.getLength();
+ ++pTypeCandidate
+ )
+ {
+ if ( m_xExternalBinding->supportsType( *pTypeCandidate ) )
+ {
+ m_aExternalValueType = *pTypeCandidate;
+ break;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+Any OBoundControlModel::translateExternalValueToControlValue( const Any& _rExternalValue ) const
+{
+ OSL_PRECOND( m_bSupportsExternalBinding && hasExternalValueBinding(),
+ "OBoundControlModel::translateExternalValueToControlValue: precondition not met!" );
+
+ Any aControlValue( _rExternalValue );
+
+ // if the external value is VOID, and our value property is not allowed to be VOID,
+ // then default-construct a value
+ if ( !aControlValue.hasValue() && !m_bValuePropertyMayBeVoid )
+ aControlValue.setValue( NULL, m_aValuePropertyType );
+
+ // outta here
+ return aControlValue;
+}
+
+//------------------------------------------------------------------------------
+Any OBoundControlModel::translateControlValueToExternalValue( ) const
+{
+ return getControlValue( );
+}
+
+//------------------------------------------------------------------------------
+Any OBoundControlModel::translateControlValueToValidatableValue( ) const
+{
+ OSL_PRECOND( m_xValidator.is(), "OBoundControlModel::translateControlValueToValidatableValue: no validator, so why should I?" );
+ if ( ( m_xValidator == m_xExternalBinding ) && m_xValidator.is() )
+ return translateControlValueToExternalValue();
+ return getControlValue();
+}
+
+//------------------------------------------------------------------------------
+Any OBoundControlModel::getControlValue( ) const
+{
+ OSL_PRECOND( m_xAggregateFastSet.is() && m_xAggregateSet.is(),
+ "OBoundControlModel::getControlValue: invalid aggregate !" );
+ OSL_PRECOND( m_sValuePropertyName.getLength() || ( m_nValuePropertyAggregateHandle != -1 ),
+ "OBoundControlModel::getControlValue: please override if you have own value property handling!" );
+
+ // determine the current control value
+ Any aControlValue;
+ if ( ( m_nValuePropertyAggregateHandle != -1 ) && m_xAggregateFastSet.is() )
+ {
+ aControlValue = m_xAggregateFastSet->getFastPropertyValue( m_nValuePropertyAggregateHandle );
+ }
+ else if ( m_sValuePropertyName.getLength() && m_xAggregateSet.is() )
+ {
+ aControlValue = m_xAggregateSet->getPropertyValue( m_sValuePropertyName );
+ }
+
+ return aControlValue;
+}
+
+//--------------------------------------------------------------------
+void OBoundControlModel::connectValidator( const Reference< XValidator >& _rxValidator )
+{
+ OSL_PRECOND( _rxValidator.is(), "OBoundControlModel::connectValidator: invalid validator instance!" );
+ OSL_PRECOND( !hasValidator( ), "OBoundControlModel::connectValidator: precond not met (have a validator currently)!" );
+
+ m_xValidator = _rxValidator;
+
+ // add as value listener so we get notified when the value changes
+ if ( m_xValidator.is() )
+ {
+ try
+ {
+ m_xValidator->addValidityConstraintListener( this );
+ }
+ catch( const RuntimeException& )
+ {
+ }
+ }
+
+ onConnectedValidator( );
+}
+
+//--------------------------------------------------------------------
+void OBoundControlModel::disconnectValidator( )
+{
+ OSL_PRECOND( hasValidator( ), "OBoundControlModel::connectValidator: precond not met (don't have a validator currently)!" );
+
+ // add as value listener so we get notified when the value changes
+ if ( m_xValidator.is() )
+ {
+ try
+ {
+ m_xValidator->removeValidityConstraintListener( this );
+ }
+ catch( const RuntimeException& )
+ {
+ }
+ }
+
+ m_xValidator.clear();
+
+ onDisconnectedValidator( );
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL OBoundControlModel::setValidator( const Reference< XValidator >& _rxValidator ) throw (VetoException,RuntimeException)
+{
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+ OSL_PRECOND( m_bSupportsValidation, "OBoundControlModel::setValidator: How did you reach this method?" );
+ // the interface for this method should not have been exposed if we do not
+ // support validation
+
+ // early out if the validator does not change
+ if( _rxValidator == m_xValidator )
+ return;
+
+ if ( m_xValidator.is() && ( m_xValidator == m_xExternalBinding ) )
+ throw VetoException(
+ FRM_RES_STRING( RID_STR_INVALID_VALIDATOR ),
+ *this
+ );
+
+ // disconnect from the old validator
+ if ( hasValidator() )
+ disconnectValidator( );
+
+ // connect to the new validator
+ if ( _rxValidator.is() )
+ connectValidator( _rxValidator );
+}
+
+//--------------------------------------------------------------------
+Reference< XValidator > SAL_CALL OBoundControlModel::getValidator( ) throw (RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ OSL_PRECOND( m_bSupportsValidation, "OBoundControlModel::getValidator: How did you reach this method?" );
+ // the interface for this method should not have been exposed if we do not
+ // support validation
+
+ return m_xValidator;
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL OBoundControlModel::validityConstraintChanged( const EventObject& /*Source*/ ) throw (RuntimeException)
+{
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+ OSL_PRECOND( m_bSupportsValidation, "OBoundControlModel::validityConstraintChanged: How did you reach this method?" );
+ // the interface for this method should not have been exposed if we do not
+ // support validation
+
+ recheckValidity( false );
+}
+
+//--------------------------------------------------------------------
+sal_Bool SAL_CALL OBoundControlModel::isValid( ) throw (RuntimeException)
+{
+ return m_bIsCurrentValueValid;
+}
+
+//--------------------------------------------------------------------
+::com::sun::star::uno::Any OBoundControlModel::getCurrentFormComponentValue() const
+{
+ if ( hasValidator() )
+ return translateControlValueToValidatableValue();
+ return getControlValue();
+}
+
+//--------------------------------------------------------------------
+Any SAL_CALL OBoundControlModel::getCurrentValue( ) throw (RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ return getCurrentFormComponentValue();
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL OBoundControlModel::addFormComponentValidityListener( const Reference< validation::XFormComponentValidityListener >& Listener ) throw (NullPointerException, RuntimeException)
+{
+ if ( Listener.is() )
+ m_aFormComponentListeners.addInterface( Listener );
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL OBoundControlModel::removeFormComponentValidityListener( const Reference< validation::XFormComponentValidityListener >& Listener ) throw (NullPointerException, RuntimeException)
+{
+ if ( Listener.is() )
+ m_aFormComponentListeners.removeInterface( Listener );
+}
+
+//--------------------------------------------------------------------
+void OBoundControlModel::recheckValidity( bool _bForceNotification )
+{
+ try
+ {
+ sal_Bool bIsCurrentlyValid = sal_True;
+ if ( hasValidator() )
+ bIsCurrentlyValid = m_xValidator->isValid( translateControlValueToValidatableValue() );
+
+ if ( ( bIsCurrentlyValid != m_bIsCurrentValueValid ) || _bForceNotification )
+ {
+ m_bIsCurrentValueValid = bIsCurrentlyValid;
+
+ // release our mutex for the notifications
+ MutexRelease aRelease( m_aMutex );
+ m_aFormComponentListeners.notifyEach( &validation::XFormComponentValidityListener::componentValidityChanged, EventObject( *this ) );
+ }
+ }
+ catch( const Exception& )
+ {
+ OSL_FAIL( "OBoundControlModel::recheckValidity: caught an exception!" );
+ }
+}
+
+//------------------------------------------------------------------------------
+void OBoundControlModel::describeFixedProperties( Sequence< Property >& _rProps ) const
+{
+ BEGIN_DESCRIBE_PROPERTIES( 5, OControlModel )
+ DECL_PROP1 ( CONTROLSOURCE, ::rtl::OUString, BOUND );
+ DECL_IFACE_PROP3( BOUNDFIELD, XPropertySet, BOUND, READONLY, TRANSIENT );
+ DECL_IFACE_PROP2( CONTROLLABEL, XPropertySet, BOUND, MAYBEVOID );
+ DECL_PROP2 ( CONTROLSOURCEPROPERTY, ::rtl::OUString, READONLY, TRANSIENT );
+ DECL_BOOL_PROP1 ( INPUT_REQUIRED, BOUND );
+ END_DESCRIBE_PROPERTIES()
+}
+
+// -----------------------------------------------------------------------------
+
+//.........................................................................
+}
+//... namespace frm .......................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/FormattedField.cxx b/forms/source/component/FormattedField.cxx
new file mode 100644
index 000000000000..871385c207a6
--- /dev/null
+++ b/forms/source/component/FormattedField.cxx
@@ -0,0 +1,1257 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+
+#include "FormattedField.hxx"
+#include "services.hxx"
+#include "property.hrc"
+#include "property.hxx"
+#include "frm_resource.hxx"
+#include "frm_resource.hrc"
+#include "propertybaghelper.hxx"
+#include <comphelper/sequence.hxx>
+#include <comphelper/numbers.hxx>
+#include <connectivity/dbtools.hxx>
+#include <connectivity/dbconversion.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/numuno.hxx>
+#include <vcl/svapp.hxx>
+#include <tools/debug.hxx>
+#include <tools/wintypes.hxx>
+#include <i18npool/mslangid.hxx>
+#include <rtl/textenc.h>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/util/NumberFormat.hpp>
+#include <com/sun/star/util/Date.hpp>
+#include <com/sun/star/util/Time.hpp>
+#include <com/sun/star/awt/MouseEvent.hpp>
+#include <com/sun/star/form/XSubmit.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/awt/XKeyListener.hpp>
+#include <com/sun/star/form/FormComponentType.hpp>
+#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#include <com/sun/star/form/XForm.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <osl/mutex.hxx>
+ // needed as long as we use the SolarMutex
+#include <comphelper/streamsection.hxx>
+#include <cppuhelper/weakref.hxx>
+#include <unotools/desktopterminationobserver.hxx>
+
+#include <list>
+#include <algorithm>
+
+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;
+using namespace ::com::sun::star::form::binding;
+
+namespace
+{
+ typedef com::sun::star::util::Date UNODate;
+ typedef com::sun::star::util::Time UNOTime;
+ typedef com::sun::star::util::DateTime UNODateTime;
+}
+
+//.........................................................................
+namespace frm
+{
+
+/*************************************************************************/
+
+class StandardFormatsSupplier : protected SvNumberFormatsSupplierObj, public ::utl::ITerminationListener
+{
+protected:
+ SvNumberFormatter* m_pMyPrivateFormatter;
+ static WeakReference< XNumberFormatsSupplier > s_xDefaultFormatsSupplier;
+
+public:
+ static Reference< XNumberFormatsSupplier > get( const Reference< XMultiServiceFactory >& _rxORB );
+
+ using SvNumberFormatsSupplierObj::operator new;
+ using SvNumberFormatsSupplierObj::operator delete;
+
+protected:
+ StandardFormatsSupplier(const Reference<XMultiServiceFactory>& _rxFactory,LanguageType _eSysLanguage);
+ ~StandardFormatsSupplier();
+
+protected:
+ virtual bool queryTermination() const;
+ virtual void notifyTermination();
+};
+
+//------------------------------------------------------------------
+WeakReference< XNumberFormatsSupplier > StandardFormatsSupplier::s_xDefaultFormatsSupplier;
+
+//------------------------------------------------------------------
+StandardFormatsSupplier::StandardFormatsSupplier(const Reference< XMultiServiceFactory > & _rxFactory,LanguageType _eSysLanguage)
+ :SvNumberFormatsSupplierObj()
+ ,m_pMyPrivateFormatter(new SvNumberFormatter(_rxFactory, _eSysLanguage))
+{
+ SetNumberFormatter(m_pMyPrivateFormatter);
+
+ // #i29147#
+ ::utl::DesktopTerminationObserver::registerTerminationListener( this );
+}
+
+//------------------------------------------------------------------
+StandardFormatsSupplier::~StandardFormatsSupplier()
+{
+ ::utl::DesktopTerminationObserver::revokeTerminationListener( this );
+
+ DELETEZ( m_pMyPrivateFormatter );
+}
+
+//------------------------------------------------------------------
+Reference< XNumberFormatsSupplier > StandardFormatsSupplier::get( const Reference< XMultiServiceFactory >& _rxORB )
+{
+ LanguageType eSysLanguage = LANGUAGE_SYSTEM;
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ Reference< XNumberFormatsSupplier > xSupplier = s_xDefaultFormatsSupplier;
+ if ( xSupplier.is() )
+ return xSupplier;
+
+ // get the Office's locale
+ const Locale& rSysLocale = SvtSysLocale().GetLocaleData().getLocale();
+ // translate
+ eSysLanguage = MsLangId::convertLocaleToLanguage( rSysLocale );
+ }
+
+ StandardFormatsSupplier* pSupplier = new StandardFormatsSupplier( _rxORB, eSysLanguage );
+ Reference< XNumberFormatsSupplier > xNewlyCreatedSupplier( pSupplier );
+
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ Reference< XNumberFormatsSupplier > xSupplier = s_xDefaultFormatsSupplier;
+ if ( xSupplier.is() )
+ // somebody used the small time frame where the mutex was not locked to create and set
+ // the supplier
+ return xSupplier;
+
+ s_xDefaultFormatsSupplier = xNewlyCreatedSupplier;
+ }
+
+ return xNewlyCreatedSupplier;
+}
+
+//------------------------------------------------------------------
+bool StandardFormatsSupplier::queryTermination() const
+{
+ return true;
+}
+
+//------------------------------------------------------------------
+void StandardFormatsSupplier::notifyTermination()
+{
+ Reference< XNumberFormatsSupplier > xKeepAlive = this;
+ // when the application is terminating, release our static reference so that we are cleared/destructed
+ // earlier than upon unloading the library
+ // #i29147#
+ s_xDefaultFormatsSupplier = WeakReference< XNumberFormatsSupplier >( );
+
+ SetNumberFormatter( NULL );
+ DELETEZ( m_pMyPrivateFormatter );
+}
+
+/*************************************************************************/
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL OFormattedControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
+{
+ return *(new OFormattedControl(_rxFactory));
+}
+
+//------------------------------------------------------------------
+Sequence<Type> OFormattedControl::_getTypes()
+{
+ return ::comphelper::concatSequences(
+ OFormattedControl_BASE::getTypes(),
+ OBoundControl::_getTypes()
+ );
+}
+
+//------------------------------------------------------------------
+Any SAL_CALL OFormattedControl::queryAggregation(const Type& _rType) throw (RuntimeException)
+{
+ Any aReturn = OBoundControl::queryAggregation(_rType);
+ if (!aReturn.hasValue())
+ aReturn = OFormattedControl_BASE::queryInterface(_rType);
+ return aReturn;
+}
+
+
+DBG_NAME(OFormattedControl);
+//------------------------------------------------------------------------------
+OFormattedControl::OFormattedControl(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OBoundControl(_rxFactory, VCL_CONTROL_FORMATTEDFIELD)
+ ,m_nKeyEvent(0)
+{
+ DBG_CTOR(OFormattedControl,NULL);
+
+ increment(m_refCount);
+ {
+ Reference<XWindow> xComp;
+ if (query_aggregation(m_xAggregate, xComp))
+ {
+ xComp->addKeyListener(this);
+ }
+ }
+ decrement(m_refCount);
+}
+
+//------------------------------------------------------------------------------
+OFormattedControl::~OFormattedControl()
+{
+ if( m_nKeyEvent )
+ Application::RemoveUserEvent( m_nKeyEvent );
+
+ if (!OComponentHelper::rBHelper.bDisposed)
+ {
+ acquire();
+ dispose();
+ }
+
+ DBG_DTOR(OFormattedControl,NULL);
+}
+
+// XKeyListener
+//------------------------------------------------------------------------------
+void OFormattedControl::disposing(const EventObject& _rSource) throw(RuntimeException)
+{
+ OBoundControl::disposing(_rSource);
+}
+
+//------------------------------------------------------------------------------
+void OFormattedControl::keyPressed(const ::com::sun::star::awt::KeyEvent& e) throw ( ::com::sun::star::uno::RuntimeException)
+{
+ if( e.KeyCode != KEY_RETURN || e.Modifiers != 0 )
+ return;
+
+ // Steht das Control in einem Formular mit einer Submit-URL?
+ Reference<com::sun::star::beans::XPropertySet> xSet(getModel(), UNO_QUERY);
+ if( !xSet.is() )
+ return;
+
+ Reference<XFormComponent> xFComp(xSet, UNO_QUERY);
+ InterfaceRef xParent = xFComp->getParent();
+ if( !xParent.is() )
+ return;
+
+ Reference<com::sun::star::beans::XPropertySet> xFormSet(xParent, UNO_QUERY);
+ if( !xFormSet.is() )
+ return;
+
+ Any aTmp(xFormSet->getPropertyValue( PROPERTY_TARGET_URL ));
+ if (!isA(aTmp, static_cast< ::rtl::OUString* >(NULL)) ||
+ !getString(aTmp).getLength() )
+ return;
+
+ Reference<XIndexAccess> xElements(xParent, UNO_QUERY);
+ sal_Int32 nCount = xElements->getCount();
+ if( nCount > 1 )
+ {
+
+ Reference<com::sun::star::beans::XPropertySet> xFCSet;
+ for( sal_Int32 nIndex=0; nIndex < nCount; nIndex++ )
+ {
+ // Any aElement(xElements->getByIndex(nIndex));
+ xElements->getByIndex(nIndex) >>= xFCSet;
+
+ if (hasProperty(PROPERTY_CLASSID, xFCSet) &&
+ getINT16(xFCSet->getPropertyValue(PROPERTY_CLASSID)) == FormComponentType::TEXTFIELD)
+ {
+ // 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) );
+}
+
+//------------------------------------------------------------------------------
+void OFormattedControl::keyReleased(const ::com::sun::star::awt::KeyEvent& /*e*/) throw ( ::com::sun::star::uno::RuntimeException)
+{
+}
+
+//------------------------------------------------------------------------------
+IMPL_LINK(OFormattedControl, OnKeyPressed, void*, /*EMPTYARG*/)
+{
+ m_nKeyEvent = 0;
+
+ Reference<XFormComponent> xFComp(getModel(), UNO_QUERY);
+ InterfaceRef xParent = xFComp->getParent();
+ Reference<XSubmit> xSubmit(xParent, UNO_QUERY);
+ if (xSubmit.is())
+ xSubmit->submit( Reference<XControl> (), ::com::sun::star::awt::MouseEvent() );
+ 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) throw ( ::com::sun::star::uno::RuntimeException)
+{
+ OBoundControl::setDesignMode(bOn);
+}
+
+/*************************************************************************/
+DBG_NAME(OFormattedModel)
+//------------------------------------------------------------------
+void OFormattedModel::implConstruct()
+{
+ // members
+ m_bOriginalNumeric = sal_False;
+ m_bNumeric = sal_False;
+ m_xOriginalFormatter = NULL;
+ m_nKeyType = NumberFormat::UNDEFINED;
+ m_aNullDate = DBTypeConversion::getStandardDate();
+ m_nFieldType = DataType::OTHER;
+
+ // default our formats supplier
+ increment(m_refCount);
+ setPropertyToDefaultByHandle(PROPERTY_ID_FORMATSSUPPLIER);
+ decrement(m_refCount);
+
+ startAggregatePropertyListening( PROPERTY_FORMATKEY );
+ startAggregatePropertyListening( PROPERTY_FORMATSSUPPLIER );
+}
+
+//------------------------------------------------------------------
+OFormattedModel::OFormattedModel(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OEditBaseModel(_rxFactory, VCL_CONTROLMODEL_FORMATTEDFIELD, FRM_SUN_CONTROL_FORMATTEDFIELD, sal_True, sal_True )
+ // use the old control name for compytibility reasons
+ ,OErrorBroadcaster( OComponentHelper::rBHelper )
+{
+ DBG_CTOR(OFormattedModel, NULL);
+
+ implConstruct();
+
+ m_nClassId = FormComponentType::TEXTFIELD;
+ initValueProperty( PROPERTY_EFFECTIVE_VALUE, PROPERTY_ID_EFFECTIVE_VALUE );
+}
+
+//------------------------------------------------------------------
+OFormattedModel::OFormattedModel( const OFormattedModel* _pOriginal, const Reference< XMultiServiceFactory >& _rxFactory )
+ :OEditBaseModel( _pOriginal, _rxFactory )
+ ,OErrorBroadcaster( OComponentHelper::rBHelper )
+{
+ DBG_CTOR(OFormattedModel, NULL);
+
+ implConstruct();
+}
+
+//------------------------------------------------------------------------------
+OFormattedModel::~OFormattedModel()
+{
+ DBG_DTOR(OFormattedModel, NULL);
+}
+
+// XCloneable
+//------------------------------------------------------------------------------
+IMPLEMENT_DEFAULT_CLONING( OFormattedModel )
+
+//------------------------------------------------------------------------------
+void SAL_CALL OFormattedModel::disposing()
+{
+ OErrorBroadcaster::disposing();
+ OEditBaseModel::disposing();
+}
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+StringSequence OFormattedModel::getSupportedServiceNames() throw()
+{
+ StringSequence aSupported = OEditBaseModel::getSupportedServiceNames();
+
+ sal_Int32 nOldLen = aSupported.getLength();
+ aSupported.realloc( nOldLen + 8 );
+ ::rtl::OUString* pStoreTo = aSupported.getArray() + nOldLen;
+
+ *pStoreTo++ = BINDABLE_CONTROL_MODEL;
+ *pStoreTo++ = DATA_AWARE_CONTROL_MODEL;
+ *pStoreTo++ = VALIDATABLE_CONTROL_MODEL;
+
+ *pStoreTo++ = BINDABLE_DATA_AWARE_CONTROL_MODEL;
+ *pStoreTo++ = VALIDATABLE_BINDABLE_CONTROL_MODEL;
+
+ *pStoreTo++ = FRM_SUN_COMPONENT_FORMATTEDFIELD;
+ *pStoreTo++ = FRM_SUN_COMPONENT_DATABASE_FORMATTEDFIELD;
+ *pStoreTo++ = BINDABLE_DATABASE_FORMATTED_FIELD;
+
+ return aSupported;
+}
+
+// XAggregation
+//------------------------------------------------------------------------------
+Any SAL_CALL OFormattedModel::queryAggregation(const Type& _rType) throw(RuntimeException)
+{
+ Any aReturn = OEditBaseModel::queryAggregation( _rType );
+ return aReturn.hasValue() ? aReturn : OErrorBroadcaster::queryInterface( _rType );
+}
+
+// XTypeProvider
+//------------------------------------------------------------------------------
+Sequence< Type > OFormattedModel::_getTypes()
+{
+ return ::comphelper::concatSequences(
+ OEditBaseModel::_getTypes(),
+ OErrorBroadcaster::getTypes()
+ );
+}
+
+// XPersistObject
+//------------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OFormattedModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException)
+{
+ return ::rtl::OUString(FRM_COMPONENT_EDIT);
+}
+
+// XPropertySet
+//------------------------------------------------------------------------------
+void OFormattedModel::describeFixedProperties( Sequence< Property >& _rProps ) const
+{
+ BEGIN_DESCRIBE_PROPERTIES( 3, OEditBaseModel )
+ DECL_BOOL_PROP1(EMPTY_IS_NULL, BOUND);
+ DECL_PROP1(TABINDEX, sal_Int16, BOUND);
+ DECL_BOOL_PROP2(FILTERPROPOSAL, BOUND, MAYBEDEFAULT);
+ END_DESCRIBE_PROPERTIES();
+}
+
+//------------------------------------------------------------------------------
+void OFormattedModel::describeAggregateProperties( Sequence< Property >& _rAggregateProps ) const
+{
+ OEditBaseModel::describeAggregateProperties( _rAggregateProps );
+
+ // 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, 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 ...)
+ ModifyPropertyAttributes(_rAggregateProps, PROPERTY_FORMATKEY, 0, 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
+}
+
+//------------------------------------------------------------------------------
+void OFormattedModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle) const
+{
+ OEditBaseModel::getFastPropertyValue(rValue, nHandle);
+}
+
+//------------------------------------------------------------------------------
+void OFormattedModel::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const Any& rValue) throw ( ::com::sun::star::uno::Exception)
+{
+ OEditBaseModel::setFastPropertyValue_NoBroadcast(nHandle, rValue);
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OFormattedModel::convertFastPropertyValue(Any& rConvertedValue, Any& rOldValue, sal_Int32 nHandle, const Any& rValue)
+ throw( IllegalArgumentException )
+{
+ return OEditBaseModel::convertFastPropertyValue(rConvertedValue, rOldValue, nHandle, rValue);
+}
+
+//------------------------------------------------------------------------------
+void OFormattedModel::setPropertyToDefaultByHandle(sal_Int32 nHandle)
+{
+ if (nHandle == PROPERTY_ID_FORMATSSUPPLIER)
+ {
+ Reference<XNumberFormatsSupplier> xSupplier = calcDefaultFormatsSupplier();
+ DBG_ASSERT(m_xAggregateSet.is(), "OFormattedModel::setPropertyToDefaultByHandle(FORMATSSUPPLIER) : have no aggregate !");
+ if (m_xAggregateSet.is())
+ m_xAggregateSet->setPropertyValue(PROPERTY_FORMATSSUPPLIER, makeAny(xSupplier));
+ }
+ else
+ OEditBaseModel::setPropertyToDefaultByHandle(nHandle);
+}
+
+//------------------------------------------------------------------------------
+void OFormattedModel::setPropertyToDefault(const ::rtl::OUString& aPropertyName) throw( com::sun::star::beans::UnknownPropertyException, RuntimeException )
+{
+ OPropertyArrayAggregationHelper& rPH = m_aPropertyBagHelper.getInfoHelper();
+ sal_Int32 nHandle = rPH.getHandleByName( aPropertyName );
+
+ if (nHandle == PROPERTY_ID_FORMATSSUPPLIER)
+ setPropertyToDefaultByHandle(PROPERTY_ID_FORMATSSUPPLIER);
+ else
+ OEditBaseModel::setPropertyToDefault(aPropertyName);
+}
+
+//------------------------------------------------------------------------------
+Any OFormattedModel::getPropertyDefaultByHandle( sal_Int32 nHandle ) const
+{
+ if (nHandle == PROPERTY_ID_FORMATSSUPPLIER)
+ {
+ Reference<XNumberFormatsSupplier> xSupplier = calcDefaultFormatsSupplier();
+ return makeAny(xSupplier);
+ }
+ else
+ return OEditBaseModel::getPropertyDefaultByHandle(nHandle);
+}
+
+//------------------------------------------------------------------------------
+Any SAL_CALL OFormattedModel::getPropertyDefault( const ::rtl::OUString& aPropertyName ) throw( com::sun::star::beans::UnknownPropertyException, RuntimeException )
+{
+ OPropertyArrayAggregationHelper& rPH = m_aPropertyBagHelper.getInfoHelper();
+ sal_Int32 nHandle = rPH.getHandleByName( aPropertyName );
+
+ if (nHandle == PROPERTY_ID_FORMATSSUPPLIER)
+ return getPropertyDefaultByHandle(PROPERTY_ID_FORMATSSUPPLIER);
+ else
+ return OEditBaseModel::getPropertyDefault(aPropertyName);
+}
+
+//------------------------------------------------------------------------------
+void OFormattedModel::_propertyChanged( const com::sun::star::beans::PropertyChangeEvent& evt ) throw(RuntimeException)
+{
+ // TODO: check how this works with external bindings
+
+ OSL_ENSURE( evt.Source == m_xAggregateSet, "OFormattedModel::_propertyChanged: where did this come from?" );
+ if ( evt.Source == m_xAggregateSet )
+ {
+ Reference< XPropertySet > xSourceSet( evt.Source, UNO_QUERY );
+ if ( evt.PropertyName.equals( PROPERTY_FORMATKEY ) )
+ {
+ if ( evt.NewValue.getValueType().getTypeClass() == TypeClass_LONG )
+ {
+ try
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ Reference<XNumberFormatsSupplier> xSupplier( calcFormatsSupplier() );
+ m_nKeyType = getNumberFormatType(xSupplier->getNumberFormats(), getINT32( evt.NewValue ) );
+
+ // as m_aSaveValue (which is used by commitControlValueToDbColumn) is format dependent we have
+ // to recalc it, which is done by translateDbColumnToControlValue
+ if ( m_xColumn.is() && m_xAggregateFastSet.is() && !m_xCursor->isBeforeFirst() && !m_xCursor->isAfterLast())
+ {
+ setControlValue( translateDbColumnToControlValue(), eOther );
+ }
+
+ // if we're connected to an external value binding, then re-calculate the type
+ // used to exchange the value - it depends on the format, too
+ if ( hasExternalValueBinding() )
+ {
+ calculateExternalValueType();
+ }
+ }
+ catch(Exception&)
+ {
+ }
+ }
+ return;
+ }
+
+ if ( evt.PropertyName.equals( PROPERTY_FORMATSSUPPLIER ) )
+ {
+ updateFormatterNullDate();
+ return;
+ }
+
+ OBoundControlModel::_propertyChanged( evt );
+ }
+}
+
+//------------------------------------------------------------------------------
+void OFormattedModel::updateFormatterNullDate()
+{
+ // calc the current NULL date
+ Reference< XNumberFormatsSupplier > xSupplier( calcFormatsSupplier() );
+ if ( xSupplier.is() )
+ xSupplier->getNumberFormatSettings()->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NullDate" ) ) ) >>= m_aNullDate;
+}
+
+//------------------------------------------------------------------------------
+Reference< XNumberFormatsSupplier > OFormattedModel::calcFormatsSupplier() const
+{
+ Reference<XNumberFormatsSupplier> xSupplier;
+
+ DBG_ASSERT(m_xAggregateSet.is(), "OFormattedModel::calcFormatsSupplier : have no aggregate !");
+ // hat mein aggregiertes Model einen FormatSupplier ?
+ if( m_xAggregateSet.is() )
+ m_xAggregateSet->getPropertyValue(PROPERTY_FORMATSSUPPLIER) >>= xSupplier;
+
+ if (!xSupplier.is())
+ // check if my parent form has a supplier
+ xSupplier = calcFormFormatsSupplier();
+
+ if (!xSupplier.is())
+ xSupplier = calcDefaultFormatsSupplier();
+
+ DBG_ASSERT(xSupplier.is(), "OFormattedModel::calcFormatsSupplier : no supplier !");
+ // jetzt sollte aber einer da sein
+ return xSupplier;
+}
+
+//------------------------------------------------------------------------------
+Reference<XNumberFormatsSupplier> OFormattedModel::calcFormFormatsSupplier() const
+{
+ Reference<XChild> xMe;
+ query_interface(static_cast<XWeak*>(const_cast<OFormattedModel*>(this)), xMe);
+ // 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)
+ Reference<XChild> xParent(xMe->getParent(), UNO_QUERY);
+ Reference<XForm> xNextParentForm(xParent, UNO_QUERY);
+ while (!xNextParentForm.is() && xParent.is())
+ {
+ xParent = xParent.query( xParent->getParent() );
+ xNextParentForm = xNextParentForm.query( xParent );
+ }
+
+ if (!xNextParentForm.is())
+ {
+ OSL_FAIL("OFormattedModel::calcFormFormatsSupplier : have no ancestor which is a form !");
+ return NULL;
+ }
+
+ // den FormatSupplier von meinem Vorfahren (falls der einen hat)
+ Reference< XRowSet > xRowSet( xNextParentForm, UNO_QUERY );
+ Reference< XNumberFormatsSupplier > xSupplier;
+ if (xRowSet.is())
+ xSupplier = getNumberFormats( getConnection(xRowSet), sal_True, getContext().getLegacyServiceFactory() );
+ return xSupplier;
+}
+
+//------------------------------------------------------------------------------
+Reference< XNumberFormatsSupplier > OFormattedModel::calcDefaultFormatsSupplier() const
+{
+ return StandardFormatsSupplier::get( getContext().getLegacyServiceFactory() );
+}
+
+// XBoundComponent
+//------------------------------------------------------------------------------
+void OFormattedModel::loaded(const EventObject& rEvent) throw ( ::com::sun::star::uno::RuntimeException)
+{
+ // HACK : our onConnectedDbColumn 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.
+
+ SolarMutexGuard aGuard;
+ OEditBaseModel::loaded(rEvent);
+}
+
+//------------------------------------------------------------------------------
+void OFormattedModel::onConnectedDbColumn( const Reference< XInterface >& _rxForm )
+{
+ m_xOriginalFormatter = NULL;
+
+ // get some properties of the field
+ m_nFieldType = DataType::OTHER;
+ Reference<XPropertySet> xField = getField();
+ if ( xField.is() )
+ xField->getPropertyValue( PROPERTY_FIELDTYPE ) >>= m_nFieldType;
+
+ sal_Int32 nFormatKey = 0;
+
+ DBG_ASSERT(m_xAggregateSet.is(), "OFormattedModel::onConnectedDbColumn : have no aggregate !");
+ if (m_xAggregateSet.is())
+ { // all the following doesn't make any sense if we have no aggregate ...
+ Any aSupplier = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATSSUPPLIER);
+ DBG_ASSERT( aSupplier.hasValue(), "OFormattedModel::onConnectedDbColumn : invalid property value !" );
+ // das sollte im Constructor oder im read auf was richtiges gesetzt worden sein
+
+ Any aFmtKey = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATKEY);
+ if ( !(aFmtKey >>= nFormatKey ) )
+ { // nobody gave us a format to use. So we examine the field we're bound to for a
+ // format key, and use it ourself, too
+ sal_Int32 nType = DataType::VARCHAR;
+ if (xField.is())
+ {
+ aFmtKey = xField->getPropertyValue(PROPERTY_FORMATKEY);
+ xField->getPropertyValue(PROPERTY_FIELDTYPE) >>= nType ;
+ }
+
+ Reference<XNumberFormatsSupplier> xSupplier = calcFormFormatsSupplier();
+ DBG_ASSERT(xSupplier.is(), "OFormattedModel::onConnectedDbColumn : bound to a field but no parent with a formatter ? how this ?");
+ if (xSupplier.is())
+ {
+ m_bOriginalNumeric = getBOOL(getPropertyValue(PROPERTY_TREATASNUMERIC));
+
+ 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);
+ if (xTypes.is())
+ {
+ Locale aApplicationLocale = Application::GetSettings().GetUILocale();
+
+ if (m_bOriginalNumeric)
+ aFmtKey <<= (sal_Int32)xTypes->getStandardFormat(NumberFormat::NUMBER, aApplicationLocale);
+ else
+ aFmtKey <<= (sal_Int32)xTypes->getStandardFormat(NumberFormat::TEXT, aApplicationLocale);
+ }
+ }
+
+ aSupplier >>= m_xOriginalFormatter;
+ m_xAggregateSet->setPropertyValue(PROPERTY_FORMATSSUPPLIER, makeAny(xSupplier));
+ m_xAggregateSet->setPropertyValue(PROPERTY_FORMATKEY, aFmtKey);
+
+ // das Numeric-Flag an mein gebundenes Feld anpassen
+ if (xField.is())
+ {
+ m_bNumeric = sal_False;
+ switch (nType)
+ {
+ case DataType::BIT:
+ case DataType::BOOLEAN:
+ 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;
+ }
+ }
+ else
+ m_bNumeric = m_bOriginalNumeric;
+
+ setPropertyValue(PROPERTY_TREATASNUMERIC, makeAny((sal_Bool)m_bNumeric));
+
+ OSL_VERIFY( aFmtKey >>= nFormatKey );
+ }
+ }
+ }
+
+ Reference<XNumberFormatsSupplier> xSupplier = calcFormatsSupplier();
+ m_bNumeric = getBOOL( getPropertyValue( PROPERTY_TREATASNUMERIC ) );
+ m_nKeyType = getNumberFormatType( xSupplier->getNumberFormats(), nFormatKey );
+ xSupplier->getNumberFormatSettings()->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NullDate") ) ) >>= m_aNullDate;
+
+ OEditBaseModel::onConnectedDbColumn( _rxForm );
+}
+
+//------------------------------------------------------------------------------
+void OFormattedModel::onDisconnectedDbColumn()
+{
+ OEditBaseModel::onDisconnectedDbColumn();
+ 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));
+ m_xOriginalFormatter = NULL;
+ }
+
+ m_nFieldType = DataType::OTHER;
+ m_nKeyType = NumberFormat::UNDEFINED;
+ m_aNullDate = DBTypeConversion::getStandardDate();
+}
+
+//------------------------------------------------------------------------------
+void OFormattedModel::write(const Reference<XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
+{
+ 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 ;)
+
+ Reference<XNumberFormatsSupplier> xSupplier;
+ Any aFmtKey;
+ sal_Bool bVoidKey = sal_True;
+ if (m_xAggregateSet.is())
+ {
+ Any aSupplier = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATSSUPPLIER);
+ if (aSupplier.getValueType().getTypeClass() != TypeClass_VOID)
+ {
+ OSL_VERIFY( aSupplier >>= xSupplier );
+ }
+
+ aFmtKey = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATKEY);
+ bVoidKey = (!xSupplier.is() || !aFmtKey.hasValue()) || (isLoaded() && 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
+
+ Any aKey = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATKEY);
+ sal_Int32 nKey = aKey.hasValue() ? getINT32(aKey) : 0;
+
+ Reference<XNumberFormats> xFormats = xSupplier->getNumberFormats();
+
+ ::rtl::OUString sFormatDescription;
+ LanguageType eFormatLanguage = LANGUAGE_DONTKNOW;
+
+ static const ::rtl::OUString s_aLocaleProp (RTL_CONSTASCII_USTRINGPARAM("Locale") );
+ Reference<com::sun::star::beans::XPropertySet> xFormat = xFormats->getByKey(nKey);
+ if (hasProperty(s_aLocaleProp, xFormat))
+ {
+ 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)))
+ {
+ Locale* pLocale = (Locale*)aLocale.getValue();
+ eFormatLanguage = MsLangId::convertLocaleToLanguage( *pLocale );
+ }
+ }
+
+ static const ::rtl::OUString s_aFormatStringProp (RTL_CONSTASCII_USTRINGPARAM("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
+ {
+ Reference< XDataOutputStream > xOut(_rxOutStream, UNO_QUERY);
+ OStreamSection aDownCompat(xOut);
+
+ // a sub version within the skippable block
+ _rxOutStream->writeShort(0x0000);
+
+ // version 0: the effective value of the aggregate
+ Any aEffectiveValue;
+ if (m_xAggregateSet.is())
+ {
+ try { aEffectiveValue = m_xAggregateSet->getPropertyValue(PROPERTY_EFFECTIVE_VALUE); } catch(Exception&) { }
+ }
+
+ {
+ OStreamSection aDownCompat2(xOut);
+ switch (aEffectiveValue.getValueType().getTypeClass())
+ {
+ case TypeClass_STRING:
+ _rxOutStream->writeShort(0x0000);
+ _rxOutStream->writeUTF(::comphelper::getString(aEffectiveValue));
+ break;
+ case TypeClass_DOUBLE:
+ _rxOutStream->writeShort(0x0001);
+ _rxOutStream->writeDouble(::comphelper::getDouble(aEffectiveValue));
+ break;
+ default: // void and all unknown states
+ DBG_ASSERT(!aEffectiveValue.hasValue(), "FmXFormattedModel::write : unknown property value type !");
+ _rxOutStream->writeShort(0x0002);
+ break;
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void OFormattedModel::read(const Reference<XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
+{
+ OEditBaseModel::read(_rxInStream);
+ sal_uInt16 nVersion = _rxInStream->readShort();
+
+ Reference<XNumberFormatsSupplier> xSupplier;
+ sal_Int32 nKey = -1;
+ switch (nVersion)
+ {
+ case 0x0001 :
+ case 0x0002 :
+ case 0x0003 :
+ {
+ sal_Bool bNonVoidKey = _rxInStream->readBoolean();
+ if (bNonVoidKey)
+ {
+ // den String und die Language lesen ....
+ ::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 ....
+ Reference<XNumberFormats> xFormats = xSupplier->getNumberFormats();
+
+ if (xFormats.is())
+ {
+ Locale aDescriptionLanguage( MsLangId::convertLanguageToLocale(eDescriptionLanguage));
+
+ 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
+ Reference< XDataInputStream > xIn(_rxInStream, UNO_QUERY);
+ OStreamSection aDownCompat(xIn);
+
+ sal_Int16 nSubVersion = _rxInStream->readShort();
+ (void)nSubVersion;
+
+ // version 0 and higher : the "effective value" property
+ Any aEffectiveValue;
+ {
+ OStreamSection 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:
+ OSL_FAIL("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() && ( getControlSource().getLength() == 0 ) )
+ {
+ try
+ {
+ m_xAggregateSet->setPropertyValue(PROPERTY_EFFECTIVE_VALUE, aEffectiveValue);
+ }
+ catch(Exception&)
+ {
+ }
+ }
+ }
+ }
+ break;
+ default :
+ OSL_FAIL("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())
+ {
+ m_xAggregateSet->setPropertyValue(PROPERTY_FORMATSSUPPLIER, makeAny(xSupplier));
+ m_xAggregateSet->setPropertyValue(PROPERTY_FORMATKEY, makeAny((sal_Int32)nKey));
+ }
+ else
+ {
+ setPropertyToDefault(PROPERTY_FORMATSSUPPLIER);
+ setPropertyToDefault(PROPERTY_FORMATKEY);
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_uInt16 OFormattedModel::getPersistenceFlags() const
+{
+ return (OEditBaseModel::getPersistenceFlags() & ~PF_HANDLE_COMMON_PROPS);
+ // a) we do our own call to writeCommonEditProperties
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OFormattedModel::commitControlValueToDbColumn( bool /*_bPostReset*/ )
+{
+ Any aControlValue( m_xAggregateFastSet->getFastPropertyValue( getValuePropertyAggHandle() ) );
+ if ( aControlValue != m_aSaveValue )
+ {
+ // Leerstring + EmptyIsNull = void
+ if ( !aControlValue.hasValue()
+ || ( ( aControlValue.getValueType().getTypeClass() == TypeClass_STRING )
+ && ( getString( aControlValue ).getLength() == 0 )
+ && m_bEmptyIsNull
+ )
+ )
+ m_xColumnUpdate->updateNull();
+ else
+ {
+ // als Value koennen nur double, string oder void auftreten
+ try
+ {
+ if ( aControlValue.getValueType().getTypeClass() == TypeClass_DOUBLE )
+ {
+ DBTypeConversion::setValue( m_xColumnUpdate, m_aNullDate, getDouble( aControlValue ), m_nKeyType );
+ }
+ else
+ {
+ DBG_ASSERT( aControlValue.getValueType().getTypeClass() == TypeClass_STRING, "OFormattedModel::commitControlValueToDbColumn: invalud value type !" );
+ m_xColumnUpdate->updateString( getString( aControlValue ) );
+ }
+ }
+ catch(Exception&)
+ {
+ return sal_False;
+ }
+ }
+ m_aSaveValue = aControlValue;
+ }
+ return sal_True;
+}
+
+//------------------------------------------------------------------------------
+void OFormattedModel::onConnectedExternalValue( )
+{
+ OEditBaseModel::onConnectedExternalValue();
+ updateFormatterNullDate();
+}
+
+//------------------------------------------------------------------------------
+Any OFormattedModel::translateExternalValueToControlValue( const Any& _rExternalValue ) const
+{
+ Any aControlValue;
+ switch( _rExternalValue.getValueTypeClass() )
+ {
+ case TypeClass_VOID:
+ break;
+
+ case TypeClass_STRING:
+ aControlValue = _rExternalValue;
+ break;
+
+ case TypeClass_BOOLEAN:
+ {
+ sal_Bool bExternalValue = sal_False;
+ _rExternalValue >>= bExternalValue;
+ aControlValue <<= (double)( bExternalValue ? 1 : 0 );
+ }
+ break;
+
+ default:
+ {
+ if ( _rExternalValue.getValueType().equals( ::getCppuType( static_cast< UNODate* >( NULL ) ) ) )
+ {
+ UNODate aDate;
+ _rExternalValue >>= aDate;
+ aControlValue <<= DBTypeConversion::toDouble( aDate, m_aNullDate );
+ }
+ else if ( _rExternalValue.getValueType().equals( ::getCppuType( static_cast< UNOTime* >( NULL ) ) ) )
+ {
+ UNOTime aTime;
+ _rExternalValue >>= aTime;
+ aControlValue <<= DBTypeConversion::toDouble( aTime );
+ }
+ else if ( _rExternalValue.getValueType().equals( ::getCppuType( static_cast< UNODateTime* >( NULL ) ) ) )
+ {
+ UNODateTime aDateTime;
+ _rExternalValue >>= aDateTime;
+ aControlValue <<= DBTypeConversion::toDouble( aDateTime, m_aNullDate );
+ }
+ else
+ {
+ OSL_ENSURE( _rExternalValue.getValueTypeClass() == TypeClass_DOUBLE,
+ "OFormattedModel::translateExternalValueToControlValue: don't know how to translate this type!" );
+ double fValue = 0;
+ OSL_VERIFY( _rExternalValue >>= fValue );
+ aControlValue <<= fValue;
+ }
+ }
+ }
+
+ return aControlValue;
+}
+
+//------------------------------------------------------------------------------
+Any OFormattedModel::translateControlValueToExternalValue( ) const
+{
+ OSL_PRECOND( hasExternalValueBinding(),
+ "OFormattedModel::translateControlValueToExternalValue: precondition not met!" );
+
+ Any aControlValue( getControlValue() );
+ if ( !aControlValue.hasValue() )
+ return aControlValue;
+
+ Any aExternalValue;
+
+ // translate into the the external value type
+ Type aExternalValueType( getExternalValueType() );
+ switch ( aExternalValueType.getTypeClass() )
+ {
+ case TypeClass_STRING:
+ {
+ ::rtl::OUString sString;
+ if ( aControlValue >>= sString )
+ {
+ aExternalValue <<= sString;
+ break;
+ }
+ }
+ // NO break here!
+
+ case TypeClass_BOOLEAN:
+ {
+ double fValue = 0;
+ OSL_VERIFY( aControlValue >>= fValue );
+ // if this asserts ... well, the somebody set the TreatAsNumeric property to false,
+ // and the control value is a string. This implies some weird misconfiguration
+ // of the FormattedModel, so we won't care for it for the moment.
+ aExternalValue <<= (sal_Bool)( fValue ? sal_True : sal_False );
+ }
+ break;
+
+ default:
+ {
+ double fValue = 0;
+ OSL_VERIFY( aControlValue >>= fValue );
+ // if this asserts ... well, the somebody set the TreatAsNumeric property to false,
+ // and the control value is a string. This implies some weird misconfiguration
+ // of the FormattedModel, so we won't care for it for the moment.
+
+ if ( aExternalValueType.equals( ::getCppuType( static_cast< UNODate* >( NULL ) ) ) )
+ {
+ aExternalValue <<= DBTypeConversion::toDate( fValue, m_aNullDate );
+ }
+ else if ( aExternalValueType.equals( ::getCppuType( static_cast< UNOTime* >( NULL ) ) ) )
+ {
+ aExternalValue <<= DBTypeConversion::toTime( fValue );
+ }
+ else if ( aExternalValueType.equals( ::getCppuType( static_cast< UNODateTime* >( NULL ) ) ) )
+ {
+ aExternalValue <<= DBTypeConversion::toDateTime( fValue, m_aNullDate );
+ }
+ else
+ {
+ OSL_ENSURE( aExternalValueType.equals( ::getCppuType( static_cast< double* >( NULL ) ) ),
+ "OFormattedModel::translateControlValueToExternalValue: don't know how to translate this type!" );
+ aExternalValue <<= fValue;
+ }
+ }
+ break;
+ }
+ return aExternalValue;
+}
+
+//------------------------------------------------------------------------------
+Any OFormattedModel::translateDbColumnToControlValue()
+{
+ if ( m_bNumeric )
+ m_aSaveValue <<= DBTypeConversion::getValue( m_xColumn, m_aNullDate ); // #100056# OJ
+ else
+ m_aSaveValue <<= m_xColumn->getString();
+
+ if ( m_xColumn->wasNull() )
+ m_aSaveValue.clear();
+
+ return m_aSaveValue;
+}
+
+// -----------------------------------------------------------------------------
+Sequence< Type > OFormattedModel::getSupportedBindingTypes()
+{
+ ::std::list< Type > aTypes;
+ aTypes.push_back( ::getCppuType( static_cast< double* >( NULL ) ) );
+
+ switch ( m_nKeyType & ~NumberFormat::DEFINED )
+ {
+ case NumberFormat::DATE:
+ aTypes.push_front(::getCppuType( static_cast< UNODate* >( NULL ) ) );
+ break;
+ case NumberFormat::TIME:
+ aTypes.push_front(::getCppuType( static_cast< UNOTime* >( NULL ) ) );
+ break;
+ case NumberFormat::DATETIME:
+ aTypes.push_front(::getCppuType( static_cast< UNODateTime* >( NULL ) ) );
+ break;
+ case NumberFormat::TEXT:
+ aTypes.push_front(::getCppuType( static_cast< ::rtl::OUString* >( NULL ) ) );
+ break;
+ case NumberFormat::LOGICAL:
+ aTypes.push_front(::getCppuType( static_cast< sal_Bool* >( NULL ) ) );
+ break;
+ }
+
+ Sequence< Type > aTypesRet( aTypes.size() );
+ ::std::copy( aTypes.begin(), aTypes.end(), aTypesRet.getArray() );
+ return aTypesRet;
+}
+
+//------------------------------------------------------------------------------
+Any OFormattedModel::getDefaultForReset() const
+{
+ return m_xAggregateSet->getPropertyValue( PROPERTY_EFFECTIVE_DEFAULT );
+}
+
+//------------------------------------------------------------------------------
+void OFormattedModel::resetNoBroadcast()
+{
+ OEditBaseModel::resetNoBroadcast();
+ m_aSaveValue.clear();
+}
+
+//.........................................................................
+}
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/FormattedField.hxx b/forms/source/component/FormattedField.hxx
new file mode 100644
index 000000000000..9891a71bf654
--- /dev/null
+++ b/forms/source/component/FormattedField.hxx
@@ -0,0 +1,200 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FORMS_FORMATTEDFIELD_HXX_
+#define _FORMS_FORMATTEDFIELD_HXX_
+
+#include "EditBase.hxx"
+#include <comphelper/propmultiplex.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include "errorbroadcaster.hxx"
+
+//.........................................................................
+namespace frm
+{
+
+ //==================================================================
+ //= OFormattedModel
+ //==================================================================
+
+ class OFormattedModel
+ :public OEditBaseModel
+ ,public OErrorBroadcaster
+ {
+ // das Original, falls ich die Format-Properties meines aggregierten Models gefaket, d.h. von dem Feld, an das
+ // ich gebunden bin, weitergereicht habe (nur gueltig wenn loaded)
+ ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier> m_xOriginalFormatter;
+ ::com::sun::star::util::Date m_aNullDate;
+ ::com::sun::star::uno::Any m_aSaveValue;
+
+ sal_Int32 m_nFieldType;
+ sal_Int16 m_nKeyType;
+ sal_Bool m_bOriginalNumeric : 1,
+ m_bNumeric : 1; // analog fuer TreatAsNumeric-Property
+
+ protected:
+ ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier> calcDefaultFormatsSupplier() const;
+ ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier> calcFormFormatsSupplier() const;
+ ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier> calcFormatsSupplier() const;
+
+ DECLARE_DEFAULT_LEAF_XTOR( OFormattedModel );
+
+ friend class OFormattedFieldWrapper;
+
+ protected:
+ // XInterface
+ DECLARE_UNO3_AGG_DEFAULTS( OFormattedModel, OEditBaseModel );
+
+ // XTypeProvider
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();
+
+ // XAggregation
+ virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation(const ::com::sun::star::uno::Type& _rType) throw(::com::sun::star::uno::RuntimeException);
+
+ // OComponentHelper
+ virtual void SAL_CALL disposing();
+
+ // XServiceInfo
+ IMPLEMENTATION_NAME(OFormattedModel);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw();
+
+ // XPersistObject
+ virtual void SAL_CALL write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getServiceName() throw ( ::com::sun::star::uno::RuntimeException);
+
+ // XPropertySet
+ virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle ) const;
+ virtual sal_Bool SAL_CALL convertFastPropertyValue(::com::sun::star::uno::Any& rConvertedValue, ::com::sun::star::uno::Any& rOldValue,
+ sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
+ throw(::com::sun::star::lang::IllegalArgumentException);
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue) throw ( ::com::sun::star::uno::Exception);
+
+ // XLoadListener
+ virtual void SAL_CALL loaded(const ::com::sun::star::lang::EventObject& rEvent) throw ( ::com::sun::star::uno::RuntimeException);
+
+ // XPropertyState
+ void setPropertyToDefaultByHandle(sal_Int32 nHandle);
+ ::com::sun::star::uno::Any getPropertyDefaultByHandle(sal_Int32 nHandle) const;
+
+ void SAL_CALL setPropertyToDefault(const ::rtl::OUString& aPropertyName) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Any SAL_CALL getPropertyDefault( const ::rtl::OUString& aPropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
+
+ // OControlModel's property handling
+ virtual void describeFixedProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps
+ ) const;
+ virtual void describeAggregateProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rAggregateProps
+ ) const;
+
+ // XPropertyChangeListener
+ virtual void _propertyChanged(const ::com::sun::star::beans::PropertyChangeEvent& evt) throw(::com::sun::star::uno::RuntimeException);
+
+ // prevent method hiding
+ using OEditBaseModel::disposing;
+ using OEditBaseModel::getFastPropertyValue;
+
+ protected:
+ virtual sal_uInt16 getPersistenceFlags() const;
+ // as we have an own version handling for persistence
+
+ // OBoundControlModel overridables
+ virtual ::com::sun::star::uno::Any
+ translateDbColumnToControlValue( );
+ virtual sal_Bool commitControlValueToDbColumn( bool _bPostReset );
+
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type >
+ getSupportedBindingTypes();
+ virtual ::com::sun::star::uno::Any
+ translateExternalValueToControlValue( const ::com::sun::star::uno::Any& _rExternalValue ) const;
+ virtual ::com::sun::star::uno::Any
+ translateControlValueToExternalValue( ) const;
+ virtual void onConnectedExternalValue( );
+
+ virtual ::com::sun::star::uno::Any
+ getDefaultForReset() const;
+ virtual void resetNoBroadcast();
+
+ virtual void onConnectedDbColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxForm );
+ virtual void onDisconnectedDbColumn();
+
+ private:
+ DECLARE_XCLONEABLE();
+
+ void implConstruct();
+
+ void updateFormatterNullDate();
+ };
+
+ //==================================================================
+ //= OFormattedControl
+ //==================================================================
+ typedef ::cppu::ImplHelper1< ::com::sun::star::awt::XKeyListener> OFormattedControl_BASE;
+ class OFormattedControl : public OBoundControl
+ ,public OFormattedControl_BASE
+ {
+ sal_uInt32 m_nKeyEvent;
+
+ public:
+ OFormattedControl(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);
+ virtual ~OFormattedControl();
+
+ DECLARE_UNO3_AGG_DEFAULTS(OFormattedControl, OBoundControl);
+ virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation(const ::com::sun::star::uno::Type& _rType) throw(::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();
+
+ // ::com::sun::star::lang::XServiceInfo
+ IMPLEMENTATION_NAME(OFormattedControl);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw();
+
+ // ::com::sun::star::lang::XEventListener
+ virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& _rSource) throw(::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::awt::XKeyListener
+ virtual void SAL_CALL keyPressed(const ::com::sun::star::awt::KeyEvent& e) throw ( ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL keyReleased(const ::com::sun::star::awt::KeyEvent& e) throw ( ::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::awt::XControl
+ virtual void SAL_CALL setDesignMode(sal_Bool bOn) throw ( ::com::sun::star::uno::RuntimeException);
+
+ // disambiguation
+ using OBoundControl::disposing;
+
+ private:
+ DECL_LINK( OnKeyPressed, void* );
+ };
+
+//.........................................................................
+}
+//.........................................................................
+
+#endif // _FORMS_FORMATTEDFIELD_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/FormattedFieldWrapper.cxx b/forms/source/component/FormattedFieldWrapper.cxx
new file mode 100644
index 000000000000..118c06921ce1
--- /dev/null
+++ b/forms/source/component/FormattedFieldWrapper.cxx
@@ -0,0 +1,400 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+#include "FormattedFieldWrapper.hxx"
+#include "Edit.hxx"
+#include "FormattedField.hxx"
+#include <tools/debug.hxx>
+#include "EditBase.hxx"
+#include "services.hxx"
+#include <connectivity/dbtools.hxx>
+#include <vcl/svapp.hxx>
+
+//.........................................................................
+namespace frm
+{
+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;
+
+//==================================================================
+// OFormattedFieldWrapper
+//==================================================================
+DBG_NAME(OFormattedFieldWrapper)
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL OFormattedFieldWrapper_CreateInstance_ForceFormatted(const Reference<XMultiServiceFactory>& _rxFactory)
+{
+ return *(new OFormattedFieldWrapper(_rxFactory, sal_True));
+}
+
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL OFormattedFieldWrapper_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
+{
+ return *(new OFormattedFieldWrapper(_rxFactory, sal_False));
+}
+
+//------------------------------------------------------------------
+OFormattedFieldWrapper::OFormattedFieldWrapper(const Reference<XMultiServiceFactory>& _rxFactory, sal_Bool _bActAsFormatted)
+ :m_xServiceFactory(_rxFactory)
+ ,m_pEditPart(NULL)
+{
+ DBG_CTOR(OFormattedFieldWrapper, NULL);
+
+ if (_bActAsFormatted)
+ {
+ increment(m_refCount);
+ {
+ // instantiate an FormattedModel
+ InterfaceRef xFormattedModel;
+ // (instantiate it directly ..., as the OFormattedModel isn't registered for any service names anymore)
+ OFormattedModel* pModel = new OFormattedModel(m_xServiceFactory);
+ query_interface(static_cast<XWeak*>(pModel), xFormattedModel);
+
+ m_xAggregate = Reference<XAggregation> (xFormattedModel, UNO_QUERY);
+ DBG_ASSERT(m_xAggregate.is(), "OFormattedFieldWrapper::OFormattedFieldWrapper : the OFormattedModel didn't have an XAggregation interface !");
+
+ // _before_ setting the delegator, give it to the member references
+ query_interface(xFormattedModel, m_xFormattedPart);
+ m_pEditPart = new OEditModel(m_xServiceFactory);
+ m_pEditPart->acquire();
+ }
+ if (m_xAggregate.is())
+ { // has to be in it's own block because of the temporary variable created by *this
+ m_xAggregate->setDelegator(static_cast<XWeak*>(this));
+ }
+ decrement(m_refCount);
+ }
+}
+
+//------------------------------------------------------------------
+OFormattedFieldWrapper::OFormattedFieldWrapper( const OFormattedFieldWrapper* _pCloneSource )
+ :m_xServiceFactory( _pCloneSource->m_xServiceFactory )
+ ,m_pEditPart( NULL )
+{
+ Reference< XCloneable > xCloneAccess;
+ query_aggregation( _pCloneSource->m_xAggregate, xCloneAccess );
+
+ // clone the aggregate
+ if ( xCloneAccess.is() )
+ {
+ increment( m_refCount );
+ {
+ Reference< XCloneable > xClone = xCloneAccess->createClone();
+ m_xAggregate = Reference< XAggregation >( xClone, UNO_QUERY );
+ DBG_ASSERT(m_xAggregate.is(), "OFormattedFieldWrapper::OFormattedFieldWrapper : invalid aggregate clone!");
+
+ query_interface( Reference< XInterface >( xClone.get() ), m_xFormattedPart );
+
+ if ( _pCloneSource->m_pEditPart )
+ {
+ m_pEditPart = new OEditModel( _pCloneSource->m_pEditPart, _pCloneSource->m_xServiceFactory );
+ m_pEditPart->acquire();
+ }
+ }
+ if ( m_xAggregate.is() )
+ { // has to be in it's own block because of the temporary variable created by *this
+ m_xAggregate->setDelegator( static_cast< XWeak* >( this ) );
+ }
+ decrement( m_refCount );
+ }
+ else
+ { // the clone source does not yet have an aggregate -> we don't yet need one, too
+ }
+}
+
+//------------------------------------------------------------------
+OFormattedFieldWrapper::~OFormattedFieldWrapper()
+{
+ // release the aggregated object (if any)
+ if (m_xAggregate.is())
+ m_xAggregate->setDelegator(InterfaceRef ());
+
+ if (m_pEditPart)
+ m_pEditPart->release();
+
+ DBG_DTOR(OFormattedFieldWrapper, NULL);
+}
+
+//------------------------------------------------------------------
+Any SAL_CALL OFormattedFieldWrapper::queryAggregation(const Type& _rType) throw (RuntimeException)
+{
+ Any aReturn;
+
+ if (_rType.equals( ::getCppuType( static_cast< Reference< XTypeProvider >* >(NULL) ) ) )
+ { // a XTypeProvider interface needs a working aggregate - we don't want to give the type provider
+ // of our base class (OFormattedFieldWrapper_Base) to the caller as it supplies nearly nothing
+ ensureAggregate();
+ if (m_xAggregate.is())
+ aReturn = m_xAggregate->queryAggregation(_rType);
+ }
+
+ if (!aReturn.hasValue())
+ {
+ aReturn = OFormattedFieldWrapper_Base::queryAggregation(_rType);
+
+ if ((_rType.equals( ::getCppuType( static_cast< Reference< XServiceInfo >* >(NULL) ) ) ) && aReturn.hasValue())
+ { // somebody requested an XServiceInfo interface and our base class provided it
+ // check our aggregate if it has one, too
+ ensureAggregate();
+ }
+
+ if (!aReturn.hasValue())
+ {
+ aReturn = ::cppu::queryInterface( _rType,
+ static_cast< XPersistObject* >( this ),
+ static_cast< XCloneable* >( this )
+ );
+
+ if (!aReturn.hasValue())
+ {
+ // somebody requests an interface other than the basics (XInterface) and other than
+ // the two we can supply without an aggregate. So ensure
+ // the aggregate exists.
+ ensureAggregate();
+ if (m_xAggregate.is())
+ aReturn = m_xAggregate->queryAggregation(_rType);
+ }
+ }
+ }
+
+ return aReturn;
+}
+
+//------------------------------------------------------------------
+::rtl::OUString SAL_CALL OFormattedFieldWrapper::getServiceName() throw(RuntimeException)
+{
+ // return the old compatibility name for an EditModel
+ return FRM_COMPONENT_EDIT;
+}
+
+//------------------------------------------------------------------
+::rtl::OUString SAL_CALL OFormattedFieldWrapper::getImplementationName( ) throw (RuntimeException)
+{
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.forms.OFormattedFieldWrapper") );
+}
+
+//------------------------------------------------------------------
+sal_Bool SAL_CALL OFormattedFieldWrapper::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
+{
+ DBG_ASSERT(m_xAggregate.is(), "OFormattedFieldWrapper::supportsService: should never have made it 'til here without an aggregate!");
+ Reference< XServiceInfo > xSI;
+ m_xAggregate->queryAggregation(::getCppuType(static_cast< Reference< XServiceInfo >* >(NULL))) >>= xSI;
+ return xSI->supportsService(_rServiceName);
+}
+
+//------------------------------------------------------------------
+Sequence< ::rtl::OUString > SAL_CALL OFormattedFieldWrapper::getSupportedServiceNames( ) throw (RuntimeException)
+{
+ DBG_ASSERT(m_xAggregate.is(), "OFormattedFieldWrapper::getSupportedServiceNames: should never have made it 'til here without an aggregate!");
+ Reference< XServiceInfo > xSI;
+ m_xAggregate->queryAggregation(::getCppuType(static_cast< Reference< XServiceInfo >* >(NULL))) >>= xSI;
+ return xSI->getSupportedServiceNames();
+}
+
+//------------------------------------------------------------------
+void SAL_CALL OFormattedFieldWrapper::write(const Reference<XObjectOutputStream>& _rxOutStream) throw( IOException, RuntimeException )
+{
+ // can't write myself
+ ensureAggregate();
+
+ // if we act as real edit field, we can simple forward this write request
+ if (!m_xFormattedPart.is())
+ {
+ Reference<XPersistObject> xAggregatePersistence;
+ query_aggregation(m_xAggregate, xAggregatePersistence);
+ DBG_ASSERT(xAggregatePersistence.is(), "OFormattedFieldWrapper::write : don't know how to handle this : can't write !");
+ // oops ... We gave an XPersistObject interface to the caller but now we aren't an XPersistObject ...
+ if (xAggregatePersistence.is())
+ xAggregatePersistence->write(_rxOutStream);
+ return;
+ }
+
+ // else we have to write an edit part first
+ DBG_ASSERT(m_pEditPart, "OFormattedFieldWrapper::write : formatted part without edit part ?");
+ if ( !m_pEditPart )
+ throw RuntimeException( ::rtl::OUString(), *this );
+
+ // for this we transfer the current props of the formatted part to the edit part
+ Reference<XPropertySet> xFormatProps(m_xFormattedPart, UNO_QUERY);
+ Reference<XPropertySet> xEditProps;
+ query_interface(static_cast<XWeak*>(m_pEditPart), xEditProps);
+
+ Locale aAppLanguage = Application::GetSettings().GetUILocale();
+ dbtools::TransferFormComponentProperties(xFormatProps, xEditProps, aAppLanguage);
+
+ // then write the edit part, after switching to "fake mode"
+ m_pEditPart->enableFormattedWriteFake();
+ m_pEditPart->write(_rxOutStream);
+ m_pEditPart->disableFormattedWriteFake();
+
+ // and finally write the formatted part we're really interested in
+ m_xFormattedPart->write(_rxOutStream);
+}
+
+//------------------------------------------------------------------
+void SAL_CALL OFormattedFieldWrapper::read(const Reference<XObjectInputStream>& _rxInStream) throw( IOException, RuntimeException )
+{
+ if (m_xAggregate.is())
+ { // we alread did a decision if we're an EditModel or a FormattedModel
+
+ // if we act as formatted, we have to read the edit part first
+ if (m_xFormattedPart.is())
+ {
+ // two possible cases:
+ // a) the stuff was written by a version which didn't work with an Edit header (all intermediate
+ // versions >5.1 && <=568)
+ // b) it was written by a version using edit headers
+ // as we can distinguish a) from b) only after we have read the edit part, we need to remember the
+ // position
+ Reference<XMarkableStream> xInMarkable(_rxInStream, UNO_QUERY);
+ DBG_ASSERT(xInMarkable.is(), "OFormattedFieldWrapper::read : can only work with markable streams !");
+ sal_Int32 nBeforeEditPart = xInMarkable->createMark();
+
+ m_pEditPart->read(_rxInStream);
+ // this only works because an edit model can read the stuff written by a formatted model (maybe with
+ // some assertions) , but not vice versa
+ if (!m_pEditPart->lastReadWasFormattedFake())
+ { // case a), written with a version without the edit part fake, so seek to the start position, again
+ xInMarkable->jumpToMark(nBeforeEditPart);
+ }
+ xInMarkable->deleteMark(nBeforeEditPart);
+ }
+
+ Reference<XPersistObject> xAggregatePersistence;
+ query_aggregation(m_xAggregate, xAggregatePersistence);
+ DBG_ASSERT(xAggregatePersistence.is(), "OFormattedFieldWrapper::read : don't know how to handle this : can't read !");
+ // oops ... We gave an XPersistObject interface to the caller but now we aren't an XPersistObject ...
+
+ if (xAggregatePersistence.is())
+ xAggregatePersistence->read(_rxInStream);
+ return;
+ }
+
+ // we have to decide from the data within the stream whether we should be an EditModel or a FormattedModel
+ OEditBaseModel* pNewAggregate = NULL;
+
+ // let an OEditModel do the reading
+ OEditModel* pBasicReader = new OEditModel(m_xServiceFactory);
+ Reference< XInterface > xHoldBasicReaderAlive( *pBasicReader );
+ pBasicReader->read(_rxInStream);
+
+ // was it really an edit model ?
+ if (!pBasicReader->lastReadWasFormattedFake())
+ // yes -> all fine
+ pNewAggregate = pBasicReader;
+ else
+ { // no -> substitute it with a formatted model
+
+ // let the formmatted model do the reading
+ OFormattedModel* pFormattedReader = new OFormattedModel(m_xServiceFactory);
+ Reference< XInterface > xHoldAliveWhileRead( *pFormattedReader );
+ pFormattedReader->read(_rxInStream);
+
+ // for the next write (if any) : the FormattedModel and the EditModel parts
+ query_interface(static_cast<XWeak*>(pFormattedReader), m_xFormattedPart);
+ m_pEditPart = pBasicReader;
+ m_pEditPart->acquire();
+
+ // aggregate the formatted part below
+ pNewAggregate = pFormattedReader;
+ }
+
+ // do the aggregation
+ increment(m_refCount);
+ {
+ query_interface(static_cast<XWeak*>(pNewAggregate), m_xAggregate);
+ DBG_ASSERT(m_xAggregate.is(), "OFormattedFieldWrapper::read : the OEditModel didn't have an XAggregation interface !");
+ }
+ if (m_xAggregate.is())
+ { // has to be in it's own block because of the temporary variable created by *this
+ m_xAggregate->setDelegator(static_cast<XWeak*>(this));
+ }
+ decrement(m_refCount);
+}
+
+//------------------------------------------------------------------
+Reference< XCloneable > SAL_CALL OFormattedFieldWrapper::createClone( ) throw (RuntimeException)
+{
+ ensureAggregate();
+
+ return new OFormattedFieldWrapper( this );
+}
+
+//------------------------------------------------------------------
+void OFormattedFieldWrapper::ensureAggregate()
+{
+ if (m_xAggregate.is())
+ return;
+
+ increment(m_refCount);
+ {
+ // instantiate an EditModel (the only place where we are allowed to decide that we're an FormattedModel
+ // is in ::read)
+ InterfaceRef xEditModel = m_xServiceFactory->createInstance(FRM_SUN_COMPONENT_TEXTFIELD);
+ if (!xEditModel.is())
+ {
+ // arghhh ... instantiate it directly ... it's dirty, but we really need this aggregate
+ OEditModel* pModel = new OEditModel(m_xServiceFactory);
+ query_interface(static_cast<XWeak*>(pModel), xEditModel);
+ }
+
+ m_xAggregate = Reference<XAggregation> (xEditModel, UNO_QUERY);
+ DBG_ASSERT(m_xAggregate.is(), "OFormattedFieldWrapper::ensureAggregate : the OEditModel didn't have an XAggregation interface !");
+
+ {
+ Reference< XServiceInfo > xSI(m_xAggregate, UNO_QUERY);
+ if (!xSI.is())
+ {
+ OSL_FAIL("OFormattedFieldWrapper::ensureAggregate: the aggregate has no XServiceInfo!");
+ m_xAggregate.clear();
+ }
+ }
+ }
+ if (m_xAggregate.is())
+ { // has to be in it's own block because of the temporary variable created by *this
+ m_xAggregate->setDelegator(static_cast<XWeak*>(this));
+ }
+ decrement(m_refCount);
+}
+
+//.........................................................................
+}
+//.........................................................................
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/FormattedFieldWrapper.hxx b/forms/source/component/FormattedFieldWrapper.hxx
new file mode 100644
index 000000000000..d7726ee428fa
--- /dev/null
+++ b/forms/source/component/FormattedFieldWrapper.hxx
@@ -0,0 +1,101 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FRM_FORMATTED_FIELD_WRAPPER_HXX_
+#define _FRM_FORMATTED_FIELD_WRAPPER_HXX_
+
+#include "FormComponent.hxx"
+#include <cppuhelper/implbase3.hxx>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/util/XCloneable.hpp>
+
+//.........................................................................
+namespace frm
+{
+
+class OEditModel;
+//==================================================================
+//= OFormattedFieldWrapper
+//==================================================================
+typedef ::cppu::WeakAggImplHelper3 < ::com::sun::star::io::XPersistObject
+ , ::com::sun::star::lang::XServiceInfo
+ , ::com::sun::star::util::XCloneable
+ > OFormattedFieldWrapper_Base;
+
+class OFormattedFieldWrapper : public OFormattedFieldWrapper_Base
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory> m_xServiceFactory;
+
+protected:
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XAggregation> m_xAggregate;
+
+ OEditModel* m_pEditPart;
+ // if we act as formatted this is used to write the EditModel part
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XPersistObject> m_xFormattedPart;
+ // if we act as formatted, this is the PersistObject interface of our aggregate, used
+ // to read and write the FormattedModel part
+
+ OFormattedFieldWrapper(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory, sal_Bool _bActAsFormatted);
+ // if _bActAsFormatted is sal_False, the state is undetermined until somebody calls ::read or does
+ // anything which requires a living aggregate
+ OFormattedFieldWrapper( const OFormattedFieldWrapper* _pCloneSource );
+ virtual ~OFormattedFieldWrapper();
+
+ friend InterfaceRef SAL_CALL OFormattedFieldWrapper_CreateInstance_ForceFormatted(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);
+ friend InterfaceRef SAL_CALL OFormattedFieldWrapper_CreateInstance(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);
+
+public:
+ // UNO
+ DECLARE_UNO3_AGG_DEFAULTS(OFormattedFieldWrapper, OWeakAggObject);
+ virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation(const ::com::sun::star::uno::Type& _rType) throw(::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XPersistObject
+ virtual ::rtl::OUString SAL_CALL getServiceName() throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ // XCloneable
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL createClone( ) throw (::com::sun::star::uno::RuntimeException);
+
+protected:
+ /// ensure we're in a defined state, which means a FormattedModel _OR_ an EditModel
+ void ensureAggregate();
+};
+
+//.........................................................................
+}
+//.........................................................................
+
+#endif // _FRM_FORMATTED_FIELD_WRAPPER_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/FormsCollection.cxx b/forms/source/component/FormsCollection.cxx
new file mode 100644
index 000000000000..2b72d8e42f57
--- /dev/null
+++ b/forms/source/component/FormsCollection.cxx
@@ -0,0 +1,188 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+
+#include "FormsCollection.hxx"
+#include "services.hxx"
+#include <comphelper/sequence.hxx>
+#include <tools/debug.hxx>
+#include <com/sun/star/form/XForm.hpp>
+#include <rtl/logfile.hxx>
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::form;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::util;
+
+//------------------------------------------------------------------
+DBG_NAME(OFormsCollection)
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL OFormsCollection_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
+{
+ return *(new OFormsCollection(_rxFactory));
+}
+
+//------------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OFormsCollection::getServiceName() throw(RuntimeException)
+{
+ return FRM_SUN_FORMS_COLLECTION;
+}
+
+//------------------------------------------------------------------------------
+Sequence< sal_Int8 > SAL_CALL OFormsCollection::getImplementationId( ) throw(RuntimeException)
+{
+ return OImplementationIds::getImplementationId(getTypes());
+}
+
+//------------------------------------------------------------------------------
+Sequence<Type> SAL_CALL OFormsCollection::getTypes() throw(RuntimeException)
+{
+ return concatSequences(OInterfaceContainer::getTypes(), FormsCollectionComponentBase::getTypes(), OFormsCollection_BASE::getTypes());
+}
+
+//------------------------------------------------------------------
+OFormsCollection::OFormsCollection(const Reference<XMultiServiceFactory>& _rxFactory)
+ :FormsCollectionComponentBase( m_aMutex )
+ ,OInterfaceContainer( _rxFactory, m_aMutex, XForm::static_type() )
+ ,OFormsCollection_BASE()
+{
+ DBG_CTOR(OFormsCollection, NULL);
+}
+
+//------------------------------------------------------------------------------
+OFormsCollection::OFormsCollection( const OFormsCollection& _cloneSource )
+ :FormsCollectionComponentBase( m_aMutex )
+ ,OInterfaceContainer( m_aMutex, _cloneSource )
+ ,OFormsCollection_BASE()
+{
+ DBG_CTOR( OFormsCollection, NULL );
+}
+
+//------------------------------------------------------------------------------
+OFormsCollection::~OFormsCollection()
+{
+ DBG_DTOR(OFormsCollection, NULL);
+ if (!FormsCollectionComponentBase::rBHelper.bDisposed)
+ {
+ acquire();
+ dispose();
+ }
+}
+
+//------------------------------------------------------------------------------
+Any SAL_CALL OFormsCollection::queryAggregation(const Type& _rType) throw(RuntimeException)
+{
+ Any aReturn = OFormsCollection_BASE::queryInterface(_rType);
+ if (!aReturn.hasValue())
+ {
+ aReturn = OInterfaceContainer::queryInterface(_rType);
+
+ if (!aReturn.hasValue())
+ aReturn = FormsCollectionComponentBase::queryAggregation(_rType);
+ }
+
+ return aReturn;
+}
+
+//------------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OFormsCollection::getImplementationName() throw(RuntimeException)
+{
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.forms.OFormsCollection") );
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL OFormsCollection::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException)
+{
+ Sequence<rtl::OUString> aSupported = getSupportedServiceNames();
+ 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;
+}
+
+//------------------------------------------------------------------------------
+StringSequence SAL_CALL OFormsCollection::getSupportedServiceNames() throw(RuntimeException)
+{
+ StringSequence aReturn(2);
+
+ aReturn.getArray()[0] = FRM_SUN_FORMS_COLLECTION;
+ aReturn.getArray()[1] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.form.FormComponents") );
+
+ return aReturn;
+}
+
+// XCloneable
+//------------------------------------------------------------------------------
+Reference< XCloneable > SAL_CALL OFormsCollection::createClone( ) throw (RuntimeException)
+{
+ OFormsCollection* pClone = new OFormsCollection( *this );
+ osl_incrementInterlockedCount( &pClone->m_refCount );
+ pClone->clonedFrom( *this );
+ osl_decrementInterlockedCount( &pClone->m_refCount );
+ return pClone;
+}
+
+// OComponentHelper
+//------------------------------------------------------------------------------
+void OFormsCollection::disposing()
+{
+ {
+ RTL_LOGFILE_CONTEXT( aLogger, "forms::OFormsCollection::disposing" );
+ OInterfaceContainer::disposing();
+ }
+ FormsCollectionComponentBase::disposing();
+ m_xParent = NULL;
+}
+
+//XChild
+//------------------------------------------------------------------------------
+void OFormsCollection::setParent(const InterfaceRef& Parent) throw( NoSupportException, RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ m_xParent = Parent;
+}
+
+//------------------------------------------------------------------------------
+InterfaceRef OFormsCollection::getParent() throw( RuntimeException )
+{
+ return m_xParent;
+}
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/FormsCollection.hxx b/forms/source/component/FormsCollection.hxx
new file mode 100644
index 000000000000..df547f1f6238
--- /dev/null
+++ b/forms/source/component/FormsCollection.hxx
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "InterfaceContainer.hxx"
+#include "ids.hxx"
+#include <cppuhelper/component.hxx>
+#include <cppuhelper/implbase2.hxx>
+#include <comphelper/uno3.hxx>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+//==================================================================
+// OFormsCollection
+// Implementiert den UNO-Container fuer Formulare
+// enthaelt alle zugeordneten Forms
+// dieses Container kann selbst den Context fuer Formulare darstellen
+// oder aussen einen Context uebergeben bekommen
+//==================================================================
+typedef ::cppu::OComponentHelper FormsCollectionComponentBase;
+typedef ::cppu::ImplHelper2< ::com::sun::star::container::XChild
+ ,::com::sun::star::lang::XServiceInfo > OFormsCollection_BASE;
+
+ // else MSVC kills itself on some statements
+class OFormsCollection
+ :public FormsCollectionComponentBase
+ ,public OInterfaceContainer
+ ,public OFormsCollection_BASE
+{
+ ::osl::Mutex m_aMutex;
+ OImplementationIdsRef m_aHoldIdHelper;
+ ::comphelper::InterfaceRef m_xParent; // Parent
+
+public:
+ OFormsCollection(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);
+ OFormsCollection( const OFormsCollection& _cloneSource );
+ virtual ~OFormsCollection();
+
+public:
+ DECLARE_UNO3_AGG_DEFAULTS(OFormsCollection, FormsCollectionComponentBase);
+
+ virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation(const ::com::sun::star::uno::Type& _rType) throw(::com::sun::star::uno::RuntimeException);
+
+ // XTypeProvider
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // XPersistObject
+ virtual ::rtl::OUString SAL_CALL getServiceName() throw(::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException);
+ virtual StringSequence SAL_CALL getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // XCloneable
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL createClone( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // OComponentHelper
+ virtual void SAL_CALL disposing();
+
+ // ::com::sun::star::container::XChild
+ virtual ::comphelper::InterfaceRef SAL_CALL getParent() throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setParent(const ::comphelper::InterfaceRef& Parent) throw(::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException);
+
+ // prevent method hiding
+ using OInterfaceContainer::disposing;
+};
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/Grid.cxx b/forms/source/component/Grid.cxx
new file mode 100644
index 000000000000..274e77fbd407
--- /dev/null
+++ b/forms/source/component/Grid.cxx
@@ -0,0 +1,1165 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+
+#include "Columns.hxx"
+#include "findpos.hxx"
+#include "Grid.hxx"
+#include "property.hrc"
+#include "property.hxx"
+#include "services.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/form/FormComponentType.hpp>
+#include <com/sun/star/form/XForm.hpp>
+#include <com/sun/star/form/XLoadable.hpp>
+#include <com/sun/star/text/WritingMode2.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/basicio.hxx>
+#include <comphelper/container.hxx>
+#include <comphelper/extract.hxx>
+#include <cppuhelper/queryinterface.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <vcl/svapp.hxx>
+
+using namespace ::com::sun::star::uno;
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::form;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::view;
+
+namespace WritingMode2 = ::com::sun::star::text::WritingMode2;
+
+const sal_uInt16 ROWHEIGHT = 0x0001;
+const sal_uInt16 FONTTYPE = 0x0002;
+const sal_uInt16 FONTSIZE = 0x0004;
+const sal_uInt16 FONTATTRIBS = 0x0008;
+const sal_uInt16 TABSTOP = 0x0010;
+const sal_uInt16 TEXTCOLOR = 0x0020;
+const sal_uInt16 FONTDESCRIPTOR = 0x0040;
+const sal_uInt16 RECORDMARKER = 0x0080;
+const sal_uInt16 BACKGROUNDCOLOR = 0x0100;
+
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL OGridControlModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
+{
+ return *(new OGridControlModel(_rxFactory));
+}
+
+DBG_NAME(OGridControlModel);
+//------------------------------------------------------------------
+OGridControlModel::OGridControlModel(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OControlModel(_rxFactory, ::rtl::OUString())
+ ,OInterfaceContainer(_rxFactory, m_aMutex, ::getCppuType(static_cast<Reference<XPropertySet>*>(NULL)))
+ ,OErrorBroadcaster( OComponentHelper::rBHelper )
+ ,FontControlModel( false )
+ ,m_aSelectListeners(m_aMutex)
+ ,m_aResetListeners(m_aMutex)
+ ,m_aRowSetChangeListeners(m_aMutex)
+ ,m_aDefaultControl( FRM_SUN_CONTROL_GRIDCONTROL )
+ ,m_nBorder(1)
+ ,m_nWritingMode( WritingMode2::CONTEXT )
+ ,m_nContextWritingMode( WritingMode2::CONTEXT )
+ ,m_bEnableVisible(sal_True)
+ ,m_bEnable(sal_True)
+ ,m_bNavigation(sal_True)
+ ,m_bRecordMarker(sal_True)
+ ,m_bPrintable(sal_True)
+ ,m_bAlwaysShowCursor(sal_False)
+ ,m_bDisplaySynchron(sal_True)
+{
+ DBG_CTOR(OGridControlModel,NULL);
+
+ m_nClassId = FormComponentType::GRIDCONTROL;
+}
+
+//------------------------------------------------------------------
+OGridControlModel::OGridControlModel( const OGridControlModel* _pOriginal, const Reference< XMultiServiceFactory >& _rxFactory )
+ :OControlModel( _pOriginal, _rxFactory )
+ ,OInterfaceContainer( _rxFactory, m_aMutex, ::getCppuType( static_cast<Reference<XPropertySet>*>( NULL ) ) )
+ ,OErrorBroadcaster( OComponentHelper::rBHelper )
+ ,FontControlModel( _pOriginal )
+ ,m_aSelectListeners( m_aMutex )
+ ,m_aResetListeners( m_aMutex )
+ ,m_aRowSetChangeListeners( m_aMutex )
+{
+ DBG_CTOR(OGridControlModel,NULL);
+
+ m_aDefaultControl = _pOriginal->m_aDefaultControl;
+ m_bEnable = _pOriginal->m_bEnable;
+ m_bEnableVisible = _pOriginal->m_bEnableVisible;
+ m_bNavigation = _pOriginal->m_bNavigation;
+ m_nBorder = _pOriginal->m_nBorder;
+ m_nWritingMode = _pOriginal->m_nWritingMode;
+ m_nContextWritingMode = _pOriginal->m_nContextWritingMode;
+ m_bRecordMarker = _pOriginal->m_bRecordMarker;
+ m_bPrintable = _pOriginal->m_bPrintable;
+ m_bAlwaysShowCursor = _pOriginal->m_bAlwaysShowCursor;
+ m_bDisplaySynchron = _pOriginal->m_bDisplaySynchron;
+
+ // clone the columns
+ cloneColumns( _pOriginal );
+
+ // TODO: clone the events?
+}
+
+//------------------------------------------------------------------
+OGridControlModel::~OGridControlModel()
+{
+ if (!OComponentHelper::rBHelper.bDisposed)
+ {
+ acquire();
+ dispose();
+ }
+
+ DBG_DTOR(OGridControlModel,NULL);
+}
+
+// XCloneable
+//------------------------------------------------------------------------------
+Reference< XCloneable > SAL_CALL OGridControlModel::createClone( ) throw (RuntimeException)
+{
+ OGridControlModel* pClone = new OGridControlModel( this, getContext().getLegacyServiceFactory() );
+ osl_incrementInterlockedCount( &pClone->m_refCount );
+ pClone->OControlModel::clonedFrom( this );
+ // do not call OInterfaceContainer::clonedFrom, it would clone the elements aka columns, which is
+ // already done in the ctor
+ //pClone->OInterfaceContainer::clonedFrom( *this );
+ osl_decrementInterlockedCount( &pClone->m_refCount );
+ return static_cast< XCloneable* >( static_cast< OControlModel* >( pClone ) );
+}
+
+//------------------------------------------------------------------------------
+void OGridControlModel::cloneColumns( const OGridControlModel* _pOriginalContainer )
+{
+ try
+ {
+ Reference< XCloneable > xColCloneable;
+
+ const OInterfaceArray::const_iterator pColumnStart = _pOriginalContainer->m_aItems.begin();
+ const OInterfaceArray::const_iterator pColumnEnd = _pOriginalContainer->m_aItems.end();
+ for ( OInterfaceArray::const_iterator pColumn = pColumnStart; pColumn != pColumnEnd; ++pColumn )
+ {
+ // ask the col for a factory for the clone
+ xColCloneable = xColCloneable.query( *pColumn );
+ DBG_ASSERT( xColCloneable.is(), "OGridControlModel::cloneColumns: column is not cloneable!" );
+
+ if ( xColCloneable.is() )
+ {
+ // create a clone of the column
+ Reference< XCloneable > xColClone( xColCloneable->createClone() );
+ DBG_ASSERT( xColClone.is(), "OGridControlModel::cloneColumns: invalid column clone!" );
+
+ if ( xColClone.is() )
+ {
+ // insert this clone into our own container
+ insertByIndex( pColumn - pColumnStart, xColClone->queryInterface( m_aElementType ) );
+ }
+
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ OSL_FAIL( "OGridControlModel::cloneColumns: caught an exception while cloning the columns!" );
+ }
+}
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+StringSequence OGridControlModel::getSupportedServiceNames() throw(RuntimeException)
+{
+ StringSequence aSupported = OControlModel::getSupportedServiceNames();
+ aSupported.realloc(aSupported.getLength() + 2);
+
+ ::rtl::OUString*pArray = aSupported.getArray();
+ pArray[aSupported.getLength()-2] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.UnoControlModel"));
+ pArray[aSupported.getLength()-1] = FRM_SUN_COMPONENT_GRIDCONTROL;
+ return aSupported;
+}
+
+//------------------------------------------------------------------------------
+Any SAL_CALL OGridControlModel::queryAggregation( const Type& _rType ) throw (RuntimeException)
+{
+ Any aReturn = OGridControlModel_BASE::queryInterface(_rType);
+
+ if ( !aReturn.hasValue() )
+ {
+ aReturn = OControlModel::queryAggregation( _rType );
+ if ( !aReturn.hasValue() )
+ {
+ aReturn = OInterfaceContainer::queryInterface( _rType );
+ if ( !aReturn.hasValue() )
+ aReturn = OErrorBroadcaster::queryInterface( _rType );
+ }
+ }
+ return aReturn;
+}
+
+// XSQLErrorListener
+//------------------------------------------------------------------------------
+void SAL_CALL OGridControlModel::errorOccured( const SQLErrorEvent& _rEvent ) throw (RuntimeException)
+{
+ // forward the errors which happened to my columns to my own listeners
+ onError( _rEvent );
+}
+
+// XRowSetSupplier
+//------------------------------------------------------------------------------
+Reference< XRowSet > SAL_CALL OGridControlModel::getRowSet( ) throw (RuntimeException)
+{
+ return Reference< XRowSet >( getParent(), UNO_QUERY );
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OGridControlModel::setRowSet( const Reference< XRowSet >& /*_rxDataSource*/ ) throw (RuntimeException)
+{
+ OSL_FAIL( "OGridControlModel::setRowSet: not supported!" );
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL OGridControlModel::addRowSetChangeListener( const Reference< XRowSetChangeListener >& i_Listener ) throw (RuntimeException)
+{
+ if ( i_Listener.is() )
+ m_aRowSetChangeListeners.addInterface( i_Listener );
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL OGridControlModel::removeRowSetChangeListener( const Reference< XRowSetChangeListener >& i_Listener ) throw (RuntimeException)
+{
+ m_aRowSetChangeListeners.removeInterface( i_Listener );
+}
+
+// XChild
+//------------------------------------------------------------------------------
+void SAL_CALL OGridControlModel::setParent( const InterfaceRef& i_Parent ) throw(NoSupportException, RuntimeException)
+{
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+ if ( i_Parent == getParent() )
+ return;
+
+ OControlModel::setParent( i_Parent );
+
+ EventObject aEvent( *this );
+ aGuard.clear();
+ m_aRowSetChangeListeners.notifyEach( &XRowSetChangeListener::onRowSetChanged, aEvent );
+}
+
+//------------------------------------------------------------------------------
+Sequence< Type > SAL_CALL OGridControlModel::getTypes( ) throw(RuntimeException)
+{
+ return concatSequences(
+ concatSequences(
+ OControlModel::getTypes(),
+ OInterfaceContainer::getTypes(),
+ OErrorBroadcaster::getTypes()
+ ),
+ OGridControlModel_BASE::getTypes()
+ );
+}
+
+// OComponentHelper
+//------------------------------------------------------------------------------
+void OGridControlModel::disposing()
+{
+ OControlModel::disposing();
+ OErrorBroadcaster::disposing();
+ OInterfaceContainer::disposing();
+
+ setParent(NULL);
+
+ EventObject aEvt(static_cast<XWeak*>(this));
+ m_aSelectListeners.disposeAndClear(aEvt);
+ m_aResetListeners.disposeAndClear(aEvt);
+ m_aRowSetChangeListeners.disposeAndClear(aEvt);
+}
+
+// XEventListener
+//------------------------------------------------------------------------------
+void OGridControlModel::disposing(const EventObject& _rEvent) throw( RuntimeException )
+{
+ OControlModel::disposing( _rEvent );
+ OInterfaceContainer::disposing( _rEvent );
+}
+
+// XSelectionSupplier
+//-----------------------------------------------------------------------------
+sal_Bool SAL_CALL OGridControlModel::select(const Any& rElement) throw(IllegalArgumentException, RuntimeException)
+{
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+
+ Reference<XPropertySet> xSel;
+ if (rElement.hasValue() && !::cppu::extractInterface(xSel, rElement))
+ {
+ throw IllegalArgumentException();
+ }
+ InterfaceRef xMe = static_cast<XWeak*>(this);
+
+ if (xSel.is())
+ {
+ Reference<XChild> xAsChild(xSel, UNO_QUERY);
+ if (!xAsChild.is() || (xAsChild->getParent() != xMe))
+ {
+ throw IllegalArgumentException();
+ }
+ }
+
+ if ( xSel != m_xSelection )
+ {
+ m_xSelection = xSel;
+ aGuard.clear();
+ m_aSelectListeners.notifyEach( &XSelectionChangeListener::selectionChanged, EventObject( *this ) );
+ return sal_True;
+ }
+ return sal_False;
+}
+
+//-----------------------------------------------------------------------------
+Any SAL_CALL OGridControlModel::getSelection() throw(RuntimeException)
+{
+ return makeAny(m_xSelection);
+}
+
+//-----------------------------------------------------------------------------
+void OGridControlModel::addSelectionChangeListener(const Reference< XSelectionChangeListener >& _rxListener) throw( RuntimeException )
+{
+ m_aSelectListeners.addInterface(_rxListener);
+}
+
+//-----------------------------------------------------------------------------
+void OGridControlModel::removeSelectionChangeListener(const Reference< XSelectionChangeListener >& _rxListener) throw( RuntimeException )
+{
+ m_aSelectListeners.removeInterface(_rxListener);
+}
+
+// XGridColumnFactory
+//------------------------------------------------------------------------------
+Reference<XPropertySet> SAL_CALL OGridControlModel::createColumn(const ::rtl::OUString& ColumnType) throw ( :: com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+{
+ const Sequence< ::rtl::OUString >& rColumnTypes = frm::getColumnTypes();
+ return createColumn( detail::findPos( ColumnType, rColumnTypes ) );
+}
+
+//------------------------------------------------------------------------------
+Reference<XPropertySet> OGridControlModel::createColumn(sal_Int32 nTypeId) const
+{
+ Reference<XPropertySet> xReturn;
+ switch (nTypeId)
+ {
+ case TYPE_CHECKBOX: xReturn = new CheckBoxColumn( getContext() ); break;
+ case TYPE_COMBOBOX: xReturn = new ComboBoxColumn( getContext() ); break;
+ case TYPE_CURRENCYFIELD: xReturn = new CurrencyFieldColumn( getContext() ); break;
+ case TYPE_DATEFIELD: xReturn = new DateFieldColumn( getContext() ); break;
+ case TYPE_LISTBOX: xReturn = new ListBoxColumn( getContext() ); break;
+ case TYPE_NUMERICFIELD: xReturn = new NumericFieldColumn( getContext() ); break;
+ case TYPE_PATTERNFIELD: xReturn = new PatternFieldColumn( getContext() ); break;
+ case TYPE_TEXTFIELD: xReturn = new TextFieldColumn( getContext() ); break;
+ case TYPE_TIMEFIELD: xReturn = new TimeFieldColumn( getContext() ); break;
+ case TYPE_FORMATTEDFIELD: xReturn = new FormattedFieldColumn( getContext() ); break;
+ default:
+ OSL_FAIL("OGridControlModel::createColumn: Unknown Column");
+ break;
+ }
+ return xReturn;
+}
+
+//------------------------------------------------------------------------------
+StringSequence SAL_CALL OGridControlModel::getColumnTypes() throw ( ::com::sun::star::uno::RuntimeException)
+{
+ return frm::getColumnTypes();
+}
+
+// XReset
+//-----------------------------------------------------------------------------
+void SAL_CALL OGridControlModel::reset() throw ( ::com::sun::star::uno::RuntimeException)
+{
+ ::cppu::OInterfaceIteratorHelper aIter(m_aResetListeners);
+ EventObject aEvt(static_cast<XWeak*>(this));
+ sal_Bool bContinue = sal_True;
+ while (aIter.hasMoreElements() && bContinue)
+ bContinue =((XResetListener*)aIter.next())->approveReset(aEvt);
+
+ if (bContinue)
+ {
+ _reset();
+ m_aResetListeners.notifyEach( &XResetListener::resetted, aEvt );
+ }
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL OGridControlModel::addResetListener(const Reference<XResetListener>& _rxListener) throw ( ::com::sun::star::uno::RuntimeException)
+{
+ m_aResetListeners.addInterface(_rxListener);
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL OGridControlModel::removeResetListener(const Reference<XResetListener>& _rxListener) throw ( ::com::sun::star::uno::RuntimeException)
+{
+ m_aResetListeners.removeInterface(_rxListener);
+}
+
+//-----------------------------------------------------------------------------
+void OGridControlModel::_reset()
+{
+ Reference<XReset> xReset;
+ sal_Int32 nCount = getCount();
+ for (sal_Int32 nIndex=0; nIndex < nCount; nIndex++)
+ {
+ getByIndex( nIndex ) >>= xReset;
+ if (xReset.is())
+ xReset->reset();
+ }
+}
+
+// XPropertySet
+//------------------------------------------------------------------------------
+void OGridControlModel::describeFixedProperties( Sequence< Property >& _rProps ) const
+{
+ BEGIN_DESCRIBE_BASE_PROPERTIES( 37 )
+ DECL_PROP1(NAME, ::rtl::OUString, BOUND);
+ DECL_PROP2(CLASSID, sal_Int16, READONLY, TRANSIENT);
+ DECL_PROP1(TAG, ::rtl::OUString, BOUND);
+ DECL_PROP1(TABINDEX, sal_Int16, BOUND);
+ DECL_PROP3(TABSTOP, sal_Bool, BOUND, MAYBEDEFAULT, MAYBEVOID);
+ DECL_PROP2(HASNAVIGATION, sal_Bool, BOUND, MAYBEDEFAULT);
+ DECL_PROP1(ENABLED, sal_Bool, BOUND);
+ DECL_PROP2(ENABLEVISIBLE, sal_Bool, BOUND, MAYBEDEFAULT);
+ DECL_PROP1(BORDER, sal_Int16, BOUND);
+ DECL_PROP2(BORDERCOLOR, sal_Int16, BOUND, MAYBEVOID);
+ DECL_PROP1(DEFAULTCONTROL, ::rtl::OUString, BOUND);
+ DECL_PROP3(TEXTCOLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID);
+ DECL_PROP3(BACKGROUNDCOLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID);
+ DECL_PROP2(FONT, FontDescriptor, BOUND, MAYBEDEFAULT);
+ DECL_PROP3(ROWHEIGHT, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID);
+ DECL_PROP1(HELPTEXT, ::rtl::OUString, BOUND);
+ DECL_PROP1(FONT_NAME, ::rtl::OUString, MAYBEDEFAULT);
+ DECL_PROP1(FONT_STYLENAME, ::rtl::OUString, MAYBEDEFAULT);
+ DECL_PROP1(FONT_FAMILY, sal_Int16, MAYBEDEFAULT);
+ DECL_PROP1(FONT_CHARSET, sal_Int16, MAYBEDEFAULT);
+ DECL_PROP1(FONT_HEIGHT, float, MAYBEDEFAULT);
+ DECL_PROP1(FONT_WEIGHT, float, MAYBEDEFAULT);
+ DECL_PROP1(FONT_SLANT, sal_Int16, MAYBEDEFAULT);
+ DECL_PROP1(FONT_UNDERLINE, sal_Int16, MAYBEDEFAULT);
+ DECL_BOOL_PROP1(FONT_WORDLINEMODE, MAYBEDEFAULT);
+ DECL_PROP3(TEXTLINECOLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID);
+ DECL_PROP2(FONTEMPHASISMARK, sal_Int16, BOUND, MAYBEDEFAULT);
+ DECL_PROP2(FONTRELIEF, sal_Int16, BOUND, MAYBEDEFAULT);
+ DECL_PROP1(FONT_STRIKEOUT, sal_Int16, MAYBEDEFAULT);
+ DECL_PROP2(RECORDMARKER, sal_Bool, BOUND, MAYBEDEFAULT );
+ DECL_PROP2(PRINTABLE, sal_Bool, BOUND, MAYBEDEFAULT );
+ DECL_PROP4(CURSORCOLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID , TRANSIENT);
+ DECL_PROP3(ALWAYSSHOWCURSOR, sal_Bool, BOUND, MAYBEDEFAULT, TRANSIENT);
+ DECL_PROP3(DISPLAYSYNCHRON, sal_Bool, BOUND, MAYBEDEFAULT, TRANSIENT);
+ DECL_PROP2(HELPURL, ::rtl::OUString, BOUND, MAYBEDEFAULT);
+ DECL_PROP2(WRITING_MODE, sal_Int16, BOUND, MAYBEDEFAULT);
+ DECL_PROP3(CONTEXT_WRITING_MODE,sal_Int16, BOUND, MAYBEDEFAULT, TRANSIENT);
+ END_DESCRIBE_PROPERTIES();
+}
+
+//------------------------------------------------------------------------------
+void OGridControlModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle ) const
+{
+ switch (nHandle)
+ {
+ case PROPERTY_ID_CONTEXT_WRITING_MODE:
+ rValue <<= m_nContextWritingMode;
+ break;
+ case PROPERTY_ID_WRITING_MODE:
+ rValue <<= m_nWritingMode;
+ break;
+ case PROPERTY_ID_HELPTEXT:
+ rValue <<= m_sHelpText;
+ break;
+ case PROPERTY_ID_HELPURL:
+ rValue <<= m_sHelpURL;
+ break;
+ case PROPERTY_ID_DISPLAYSYNCHRON:
+ setBOOL(rValue, m_bDisplaySynchron);
+ break;
+ case PROPERTY_ID_ALWAYSSHOWCURSOR:
+ setBOOL(rValue, m_bAlwaysShowCursor);
+ break;
+ case PROPERTY_ID_CURSORCOLOR:
+ rValue = m_aCursorColor;
+ break;
+ case PROPERTY_ID_PRINTABLE:
+ setBOOL(rValue, m_bPrintable);
+ break;
+ case PROPERTY_ID_TABSTOP:
+ rValue = m_aTabStop;
+ break;
+ case PROPERTY_ID_HASNAVIGATION:
+ setBOOL(rValue, m_bNavigation);
+ break;
+ case PROPERTY_ID_RECORDMARKER:
+ setBOOL(rValue, m_bRecordMarker);
+ break;
+ case PROPERTY_ID_ENABLED:
+ setBOOL(rValue, m_bEnable);
+ break;
+ case PROPERTY_ID_ENABLEVISIBLE:
+ setBOOL(rValue, m_bEnableVisible);
+ break;
+ case PROPERTY_ID_BORDER:
+ rValue <<= (sal_Int16)m_nBorder;
+ break;
+ case PROPERTY_ID_BORDERCOLOR:
+ rValue <<= m_aBorderColor;
+ break;
+ case PROPERTY_ID_DEFAULTCONTROL:
+ rValue <<= m_aDefaultControl;
+ break;
+ case PROPERTY_ID_BACKGROUNDCOLOR:
+ rValue = m_aBackgroundColor;
+ break;
+ case PROPERTY_ID_ROWHEIGHT:
+ rValue = m_aRowHeight;
+ break;
+
+ default:
+ if ( isFontRelatedProperty( nHandle ) )
+ FontControlModel::getFastPropertyValue( rValue, nHandle );
+ else
+ OControlModel::getFastPropertyValue( rValue, nHandle );
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OGridControlModel::convertFastPropertyValue( Any& rConvertedValue, Any& rOldValue,
+ sal_Int32 nHandle, const Any& rValue )throw( IllegalArgumentException )
+{
+ sal_Bool bModified(sal_False);
+ switch (nHandle)
+ {
+ case PROPERTY_ID_CONTEXT_WRITING_MODE:
+ bModified = tryPropertyValue( rConvertedValue, rOldValue, rValue, m_nContextWritingMode );
+ break;
+ case PROPERTY_ID_WRITING_MODE:
+ bModified = tryPropertyValue( rConvertedValue, rOldValue, rValue, m_nWritingMode );
+ break;
+ case PROPERTY_ID_HELPTEXT:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_sHelpText);
+ break;
+ case PROPERTY_ID_HELPURL:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_sHelpURL);
+ break;
+ case PROPERTY_ID_DISPLAYSYNCHRON:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bDisplaySynchron);
+ break;
+ case PROPERTY_ID_ALWAYSSHOWCURSOR:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bAlwaysShowCursor);
+ break;
+ case PROPERTY_ID_CURSORCOLOR:
+ if (!rValue.hasValue() || !m_aCursorColor.hasValue())
+ {
+ if (rValue.hasValue() && (TypeClass_LONG != rValue.getValueType().getTypeClass()))
+ {
+ throw IllegalArgumentException();
+ }
+ rOldValue = m_aCursorColor;
+ rConvertedValue = rValue;
+ bModified = (rOldValue.getValue() != rConvertedValue.getValue());
+ }
+ else
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, getINT32(m_aCursorColor));
+ break;
+ case PROPERTY_ID_PRINTABLE:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bPrintable);
+ break;
+ case PROPERTY_ID_TABSTOP:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aTabStop, ::getBooleanCppuType());
+ break;
+ case PROPERTY_ID_HASNAVIGATION:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bNavigation);
+ break;
+ case PROPERTY_ID_RECORDMARKER:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bRecordMarker);
+ break;
+ case PROPERTY_ID_ENABLED:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bEnable);
+ break;
+ case PROPERTY_ID_ENABLEVISIBLE:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bEnableVisible);
+ break;
+ case PROPERTY_ID_BORDER:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_nBorder);
+ break;
+ case PROPERTY_ID_BORDERCOLOR:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aBorderColor, ::getCppuType((const sal_Int32*)NULL));
+ break;
+ case PROPERTY_ID_DEFAULTCONTROL:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aDefaultControl);
+ break;
+ case PROPERTY_ID_BACKGROUNDCOLOR:
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aBackgroundColor, ::getCppuType((const sal_Int32*)NULL));
+ break;
+ case PROPERTY_ID_ROWHEIGHT:
+ {
+ bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aRowHeight, ::getCppuType((const sal_Int32*)NULL));
+
+ sal_Int32 nNewVal( 0 );
+ if ( ( rConvertedValue >>= nNewVal ) && ( nNewVal <= 0 ) )
+ {
+ rConvertedValue.clear();
+ bModified = m_aRowHeight.hasValue();
+ }
+ }
+ break;
+ default:
+ if ( isFontRelatedProperty( nHandle ) )
+ bModified = FontControlModel::convertFastPropertyValue( rConvertedValue, rOldValue, nHandle, rValue );
+ else
+ bModified = OControlModel::convertFastPropertyValue( rConvertedValue, rOldValue, nHandle, rValue);
+ }
+ return bModified;
+}
+
+//------------------------------------------------------------------------------
+void OGridControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw ( ::com::sun::star::uno::Exception)
+{
+ switch (nHandle)
+ {
+ case PROPERTY_ID_CONTEXT_WRITING_MODE:
+ rValue >>= m_nContextWritingMode;
+ break;
+ case PROPERTY_ID_WRITING_MODE:
+ rValue >>= m_nWritingMode;
+ break;
+ case PROPERTY_ID_HELPTEXT:
+ rValue >>= m_sHelpText;
+ break;
+ case PROPERTY_ID_HELPURL:
+ rValue >>= m_sHelpURL;
+ break;
+ case PROPERTY_ID_DISPLAYSYNCHRON:
+ m_bDisplaySynchron = getBOOL(rValue);
+ break;
+ case PROPERTY_ID_ALWAYSSHOWCURSOR:
+ m_bAlwaysShowCursor = getBOOL(rValue);
+ break;
+ case PROPERTY_ID_CURSORCOLOR:
+ m_aCursorColor = rValue;
+ break;
+ case PROPERTY_ID_PRINTABLE:
+ m_bPrintable = getBOOL(rValue);
+ break;
+ case PROPERTY_ID_TABSTOP:
+ m_aTabStop = rValue;
+ break;
+ case PROPERTY_ID_HASNAVIGATION:
+ m_bNavigation = getBOOL(rValue);
+ break;
+ case PROPERTY_ID_ENABLED:
+ m_bEnable = getBOOL(rValue);
+ break;
+ case PROPERTY_ID_ENABLEVISIBLE:
+ m_bEnableVisible = getBOOL(rValue);
+ break;
+ case PROPERTY_ID_RECORDMARKER:
+ m_bRecordMarker = getBOOL(rValue);
+ break;
+ case PROPERTY_ID_BORDER:
+ rValue >>= m_nBorder;
+ break;
+ case PROPERTY_ID_BORDERCOLOR:
+ m_aBorderColor = rValue;
+ break;
+ case PROPERTY_ID_DEFAULTCONTROL:
+ rValue >>= m_aDefaultControl;
+ break;
+ case PROPERTY_ID_BACKGROUNDCOLOR:
+ m_aBackgroundColor = rValue;
+ break;
+ case PROPERTY_ID_ROWHEIGHT:
+ m_aRowHeight = rValue;
+ break;
+
+ default:
+ if ( isFontRelatedProperty( nHandle ) )
+ {
+ FontDescriptor aOldFont( getFont() );
+
+ FontControlModel::setFastPropertyValue_NoBroadcast( nHandle, rValue );
+
+ if ( isFontAggregateProperty( nHandle ) )
+ firePropertyChange( PROPERTY_ID_FONT, makeAny( getFont() ), makeAny( aOldFont ) );
+ }
+ else
+ OControlModel::setFastPropertyValue_NoBroadcast( nHandle, rValue );
+ }
+
+}
+
+//XPropertyState
+
+//------------------------------------------------------------------------------
+Any OGridControlModel::getPropertyDefaultByHandle( sal_Int32 nHandle ) const
+{
+ Any aReturn;
+ switch (nHandle)
+ {
+ case PROPERTY_ID_CONTEXT_WRITING_MODE:
+ case PROPERTY_ID_WRITING_MODE:
+ aReturn <<= WritingMode2::CONTEXT;
+ break;
+
+ case PROPERTY_ID_DEFAULTCONTROL:
+ aReturn <<= ::rtl::OUString( STARDIV_ONE_FORM_CONTROL_GRID );
+ break;
+
+ case PROPERTY_ID_PRINTABLE:
+ case PROPERTY_ID_HASNAVIGATION:
+ case PROPERTY_ID_RECORDMARKER:
+ case PROPERTY_ID_DISPLAYSYNCHRON:
+ case PROPERTY_ID_ENABLED:
+ case PROPERTY_ID_ENABLEVISIBLE:
+ aReturn = makeBoolAny(sal_True);
+ break;
+
+ case PROPERTY_ID_ALWAYSSHOWCURSOR:
+ aReturn = makeBoolAny(sal_False);
+ break;
+
+ case PROPERTY_ID_HELPURL:
+ case PROPERTY_ID_HELPTEXT:
+ aReturn <<= ::rtl::OUString();
+ break;
+
+ case PROPERTY_ID_BORDER:
+ aReturn <<= (sal_Int16)1;
+ break;
+
+ case PROPERTY_ID_BORDERCOLOR:
+ case PROPERTY_ID_TABSTOP:
+ case PROPERTY_ID_BACKGROUNDCOLOR:
+ case PROPERTY_ID_ROWHEIGHT:
+ case PROPERTY_ID_CURSORCOLOR:
+ // void
+ break;
+
+ default:
+ if ( isFontRelatedProperty( nHandle ) )
+ aReturn = FontControlModel::getPropertyDefaultByHandle( nHandle );
+ else
+ aReturn = OControlModel::getPropertyDefaultByHandle(nHandle);
+ }
+ return aReturn;
+}
+
+//------------------------------------------------------------------------------
+OGridColumn* OGridControlModel::getColumnImplementation(const InterfaceRef& _rxIFace) const
+{
+ OGridColumn* pImplementation = NULL;
+ Reference< XUnoTunnel > xUnoTunnel( _rxIFace, UNO_QUERY );
+ if ( xUnoTunnel.is() )
+ pImplementation = reinterpret_cast<OGridColumn*>(xUnoTunnel->getSomething(OGridColumn::getUnoTunnelImplementationId()));
+
+ return pImplementation;
+}
+
+//------------------------------------------------------------------------------
+void OGridControlModel::gotColumn( const Reference< XInterface >& _rxColumn )
+{
+ Reference< XSQLErrorBroadcaster > xBroadcaster( _rxColumn, UNO_QUERY );
+ if ( xBroadcaster.is() )
+ xBroadcaster->addSQLErrorListener( this );
+}
+
+//------------------------------------------------------------------------------
+void OGridControlModel::lostColumn(const Reference< XInterface >& _rxColumn)
+{
+ if ( m_xSelection == _rxColumn )
+ { // the currently selected element was replaced
+ m_xSelection.clear();
+ EventObject aEvt( static_cast< XWeak* >( this ) );
+ m_aSelectListeners.notifyEach( &XSelectionChangeListener::selectionChanged, aEvt );
+ }
+
+ Reference< XSQLErrorBroadcaster > xBroadcaster( _rxColumn, UNO_QUERY );
+ if ( xBroadcaster.is() )
+ xBroadcaster->removeSQLErrorListener( this );
+}
+
+//------------------------------------------------------------------------------
+void OGridControlModel::implRemoved(const InterfaceRef& _rxObject)
+{
+ OInterfaceContainer::implRemoved(_rxObject);
+ lostColumn(_rxObject);
+}
+
+//------------------------------------------------------------------------------
+void OGridControlModel::implInserted( const ElementDescription* _pElement )
+{
+ OInterfaceContainer::implInserted( _pElement );
+ gotColumn( _pElement->xInterface );
+}
+
+//------------------------------------------------------------------------------
+void OGridControlModel::impl_replacedElement( const ContainerEvent& _rEvent, ::osl::ClearableMutexGuard& _rInstanceLock )
+{
+ Reference< XInterface > xOldColumn( _rEvent.ReplacedElement, UNO_QUERY );
+ Reference< XInterface > xNewColumn( _rEvent.Element, UNO_QUERY );
+
+ bool bNewSelection = ( xOldColumn == m_xSelection );
+
+ lostColumn( xOldColumn );
+ gotColumn( xNewColumn );
+
+ if ( bNewSelection )
+ m_xSelection.set( xNewColumn, UNO_QUERY );
+
+ OInterfaceContainer::impl_replacedElement( _rEvent, _rInstanceLock );
+ // <<---- SYNCHRONIZED
+
+ if ( bNewSelection )
+ {
+ m_aSelectListeners.notifyEach( &XSelectionChangeListener::selectionChanged, EventObject( *this ) );
+ }
+}
+
+//------------------------------------------------------------------------------
+ElementDescription* OGridControlModel::createElementMetaData( )
+{
+ return new ColumnDescription;
+}
+
+//------------------------------------------------------------------------------
+void OGridControlModel::approveNewElement( const Reference< XPropertySet >& _rxObject, ElementDescription* _pElement )
+{
+ OGridColumn* pCol = getColumnImplementation( _rxObject );
+ if ( !pCol )
+ throw IllegalArgumentException();
+
+ OInterfaceContainer::approveNewElement( _rxObject, _pElement );
+
+ // if we're here, the object passed all tests
+ if ( _pElement )
+ static_cast< ColumnDescription* >( _pElement )->pColumn = pCol;
+}
+
+// XPersistObject
+//------------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OGridControlModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException)
+{
+ return FRM_COMPONENT_GRID; // old (non-sun) name for compatibility !
+}
+
+//------------------------------------------------------------------------------
+void OGridControlModel::write(const Reference<XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
+{
+ OControlModel::write(_rxOutStream);
+
+ Reference<XMarkableStream> xMark(_rxOutStream, UNO_QUERY);
+
+ // 1. Version
+ _rxOutStream->writeShort(0x0008);
+
+ // 2. Columns
+ sal_Int32 nLen = getCount();
+ _rxOutStream->writeLong(nLen);
+ OGridColumn* pCol;
+ for (sal_Int32 i = 0; i < nLen; i++)
+ {
+ // zuerst den Servicenamen fuer das darunterliegende Model
+ pCol = getColumnImplementation(m_aItems[i]);
+ DBG_ASSERT(pCol != NULL, "OGridControlModel::write : such items should never reach it into my container !");
+
+ _rxOutStream << pCol->getModelName();
+
+ // dann das Object selbst
+ sal_Int32 nMark = xMark->createMark();
+ sal_Int32 nObjLen = 0;
+ _rxOutStream->writeLong(nObjLen);
+
+ // schreiben der Col
+ pCol->write(_rxOutStream);
+
+ // feststellen der Laenge
+ nObjLen = xMark->offsetToMark(nMark) - 4;
+ xMark->jumpToMark(nMark);
+ _rxOutStream->writeLong(nObjLen);
+ xMark->jumpToFurthest();
+ xMark->deleteMark(nMark);
+ }
+
+ // 3. Events
+ writeEvents(_rxOutStream);
+
+ // 4. Attribute
+ // Maskierung fuer alle any Typen
+ sal_uInt16 nAnyMask = 0;
+ if (m_aRowHeight.getValueType().getTypeClass() == TypeClass_LONG)
+ nAnyMask |= ROWHEIGHT;
+ if ( getFont() != getDefaultFont() )
+ nAnyMask |= FONTATTRIBS | FONTSIZE | FONTTYPE | FONTDESCRIPTOR;
+ if (m_aTabStop.getValueType().getTypeClass() == TypeClass_BOOLEAN)
+ nAnyMask |= TABSTOP;
+ if ( hasTextColor() )
+ nAnyMask |= TEXTCOLOR;
+ if (m_aBackgroundColor.getValueType().getTypeClass() == TypeClass_LONG)
+ nAnyMask |= BACKGROUNDCOLOR;
+ if (!m_bRecordMarker)
+ nAnyMask |= RECORDMARKER;
+
+ _rxOutStream->writeShort(nAnyMask);
+
+ if (nAnyMask & ROWHEIGHT)
+ _rxOutStream->writeLong(getINT32(m_aRowHeight));
+
+ // old structures
+ const FontDescriptor& aFont = getFont();
+ if ( nAnyMask & FONTDESCRIPTOR )
+ {
+ // Attrib
+ _rxOutStream->writeShort( sal::static_int_cast< sal_Int16 >( VCLUnoHelper::ConvertFontWeight( aFont.Weight ) ) );
+ _rxOutStream->writeShort( sal::static_int_cast< sal_Int16 >( aFont.Slant ) );
+ _rxOutStream->writeShort( aFont.Underline );
+ _rxOutStream->writeShort( aFont.Strikeout );
+ _rxOutStream->writeShort( sal_Int16(aFont.Orientation * 10) );
+ _rxOutStream->writeBoolean( aFont.Kerning );
+ _rxOutStream->writeBoolean( aFont.WordLineMode );
+
+ // Size
+ _rxOutStream->writeLong( aFont.Width );
+ _rxOutStream->writeLong( aFont.Height );
+ _rxOutStream->writeShort( sal::static_int_cast< sal_Int16 >( VCLUnoHelper::ConvertFontWidth( aFont.CharacterWidth ) ) );
+
+ // Type
+ _rxOutStream->writeUTF( aFont.Name );
+ _rxOutStream->writeUTF( aFont.StyleName );
+ _rxOutStream->writeShort( aFont.Family );
+ _rxOutStream->writeShort( aFont.CharSet );
+ _rxOutStream->writeShort( aFont.Pitch );
+ }
+
+ _rxOutStream << m_aDefaultControl;
+
+ _rxOutStream->writeShort(m_nBorder);
+ _rxOutStream->writeBoolean(m_bEnable);
+
+ if (nAnyMask & TABSTOP)
+ _rxOutStream->writeBoolean(getBOOL(m_aTabStop));
+
+ _rxOutStream->writeBoolean(m_bNavigation);
+
+ if (nAnyMask & TEXTCOLOR)
+ _rxOutStream->writeLong( getTextColor() );
+
+ // neu ab Version 6
+ _rxOutStream << m_sHelpText;
+
+ if (nAnyMask & FONTDESCRIPTOR)
+ _rxOutStream << getFont();
+
+ if (nAnyMask & RECORDMARKER)
+ _rxOutStream->writeBoolean(m_bRecordMarker);
+
+ // neu ab Version 7
+ _rxOutStream->writeBoolean(m_bPrintable);
+
+ // new since 8
+ if (nAnyMask & BACKGROUNDCOLOR)
+ _rxOutStream->writeLong(getINT32(m_aBackgroundColor));
+}
+
+//------------------------------------------------------------------------------
+void OGridControlModel::read(const Reference<XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
+{
+ OControlModel::read(_rxInStream);
+
+ Reference<XMarkableStream> xMark(_rxInStream, UNO_QUERY);
+
+ // 1. Version
+ sal_Int16 nVersion = _rxInStream->readShort();
+
+ // 2. Einlesen der Spalten
+ sal_Int32 nLen = _rxInStream->readLong();
+ if (nLen)
+ {
+ for (sal_Int32 i = 0; i < nLen; i++)
+ {
+ // Lesen des Modelnamen
+
+ ::rtl::OUString sModelName;
+ _rxInStream >> sModelName;
+
+ Reference<XPropertySet> xCol(createColumn(getColumnTypeByModelName(sModelName)));
+ DBG_ASSERT(xCol.is(), "OGridControlModel::read : unknown column type !");
+ sal_Int32 nObjLen = _rxInStream->readLong();
+ if (nObjLen)
+ {
+ sal_Int32 nMark = xMark->createMark();
+ if (xCol.is())
+ {
+ OGridColumn* pCol = getColumnImplementation(xCol);
+ pCol->read(_rxInStream);
+ }
+ xMark->jumpToMark(nMark);
+ _rxInStream->skipBytes(nObjLen);
+ xMark->deleteMark(nMark);
+ }
+
+ if ( xCol.is() )
+ implInsert( i, xCol, sal_False, NULL, sal_False );
+ }
+ }
+
+ // In der Basisimplementierung werden die Events nur gelesen, Elemente im Container existieren
+ // da aber vor TF_ONE fuer das GridControl immer Events geschrieben wurden, muessen sie auch immer
+ // mit gelesen werden
+ sal_Int32 nObjLen = _rxInStream->readLong();
+ if (nObjLen)
+ {
+ sal_Int32 nMark = xMark->createMark();
+ Reference<XPersistObject> xObj(m_xEventAttacher, UNO_QUERY);
+ if (xObj.is())
+ xObj->read(_rxInStream);
+ xMark->jumpToMark(nMark);
+ _rxInStream->skipBytes(nObjLen);
+ xMark->deleteMark(nMark);
+ }
+
+ // Attachement lesen
+ for (sal_Int32 i = 0; i < nLen; i++)
+ {
+ InterfaceRef xIfc(m_aItems[i], UNO_QUERY);
+ Reference<XPropertySet> xSet(xIfc, UNO_QUERY);
+ Any aHelper;
+ aHelper <<= xSet;
+ m_xEventAttacher->attach( i, xIfc, aHelper );
+ }
+
+ // 4. Einlesen der Attribute
+ if (nVersion == 1)
+ return;
+
+ // Maskierung fuer any
+ sal_uInt16 nAnyMask = _rxInStream->readShort();
+
+ if (nAnyMask & ROWHEIGHT)
+ {
+ sal_Int32 nValue = _rxInStream->readLong();
+ m_aRowHeight <<= (sal_Int32)nValue;
+ }
+
+ FontDescriptor aFont( getFont() );
+ if ( nAnyMask & FONTATTRIBS )
+ {
+ aFont.Weight = (float)VCLUnoHelper::ConvertFontWeight( _rxInStream->readShort() );
+
+ aFont.Slant = (FontSlant)_rxInStream->readShort();
+ aFont.Underline = _rxInStream->readShort();
+ aFont.Strikeout = _rxInStream->readShort();
+ aFont.Orientation = ( (float)_rxInStream->readShort() ) / 10;
+ aFont.Kerning = _rxInStream->readBoolean();
+ aFont.WordLineMode = _rxInStream->readBoolean();
+ }
+ if ( nAnyMask & FONTSIZE )
+ {
+ aFont.Width = (sal_Int16)_rxInStream->readLong();
+ aFont.Height = (sal_Int16)_rxInStream->readLong();
+ aFont.CharacterWidth = (float)VCLUnoHelper::ConvertFontWidth( _rxInStream->readShort() );
+ }
+ if ( nAnyMask & FONTTYPE )
+ {
+ aFont.Name = _rxInStream->readUTF();
+ aFont.StyleName = _rxInStream->readUTF();
+ aFont.Family = _rxInStream->readShort();
+ aFont.CharSet = _rxInStream->readShort();
+ aFont.Pitch = _rxInStream->readShort();
+ }
+
+ if ( nAnyMask & ( FONTATTRIBS | FONTSIZE | FONTTYPE ) )
+ setFont( aFont );
+
+ // Name
+ _rxInStream >> m_aDefaultControl;
+ m_nBorder = _rxInStream->readShort();
+ m_bEnable = _rxInStream->readBoolean();
+
+ if (nAnyMask & TABSTOP)
+ {
+ m_aTabStop = makeBoolAny(_rxInStream->readBoolean());
+ }
+
+ if (nVersion > 3)
+ m_bNavigation = _rxInStream->readBoolean();
+
+ if (nAnyMask & TEXTCOLOR)
+ {
+ sal_Int32 nValue = _rxInStream->readLong();
+ setTextColor( (sal_Int32)nValue );
+ }
+
+ // neu ab Version 6
+ if (nVersion > 5)
+ _rxInStream >> m_sHelpText;
+
+ if (nAnyMask & FONTDESCRIPTOR)
+ {
+ FontDescriptor aUNOFont;
+ _rxInStream >> aUNOFont;
+ setFont( aFont );
+ }
+
+ if (nAnyMask & RECORDMARKER)
+ m_bRecordMarker = _rxInStream->readBoolean();
+
+ // neu ab Version 7
+ if (nVersion > 6)
+ m_bPrintable = _rxInStream->readBoolean();
+
+ if (nAnyMask & BACKGROUNDCOLOR)
+ {
+ sal_Int32 nValue = _rxInStream->readLong();
+ m_aBackgroundColor <<= (sal_Int32)nValue;
+ }
+}
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/Grid.hxx b/forms/source/component/Grid.hxx
new file mode 100644
index 000000000000..5b4b645d77f0
--- /dev/null
+++ b/forms/source/component/Grid.hxx
@@ -0,0 +1,221 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "errorbroadcaster.hxx"
+#include "FormComponent.hxx"
+#include "formcontrolfont.hxx"
+#include "InterfaceContainer.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/form/XGridColumnFactory.hpp>
+#include <com/sun/star/form/XLoadable.hpp>
+#include <com/sun/star/sdb/XRowSetSupplier.hpp>
+#include <com/sun/star/sdb/XRowSetChangeBroadcaster.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/proparrhlp.hxx>
+#include <cppuhelper/implbase7.hxx>
+#include <tools/link.hxx>
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+class OGridColumn;
+
+//==================================================================
+// ColumnDescription
+//==================================================================
+
+ struct ColumnDescription : public ElementDescription
+ {
+ public:
+ OGridColumn* pColumn; // not owned by this instance! only to prevent duplicate XUnoTunnel usage
+ };
+
+//==================================================================
+// OGridControlModel
+//==================================================================
+typedef ::cppu::ImplHelper7 < ::com::sun::star::awt::XControlModel
+ , ::com::sun::star::form::XGridColumnFactory
+ , ::com::sun::star::form::XReset
+ , ::com::sun::star::view::XSelectionSupplier
+ , ::com::sun::star::sdb::XSQLErrorListener
+ , ::com::sun::star::sdb::XRowSetSupplier
+ , ::com::sun::star::sdb::XRowSetChangeBroadcaster
+ > OGridControlModel_BASE;
+
+class OGridControlModel :public OControlModel
+ ,public OInterfaceContainer
+ ,public OErrorBroadcaster
+ ,public FontControlModel
+ ,public OGridControlModel_BASE
+{
+ ::cppu::OInterfaceContainerHelper m_aSelectListeners,
+ m_aResetListeners,
+ m_aRowSetChangeListeners;
+
+// [properties]
+ ::com::sun::star::uno::Any m_aRowHeight; // Zeilenhoehe
+ ::com::sun::star::uno::Any m_aTabStop;
+ ::com::sun::star::uno::Any m_aBackgroundColor;
+ ::com::sun::star::uno::Any m_aCursorColor; // transient
+ ::com::sun::star::uno::Any m_aBorderColor;
+ ::rtl::OUString m_aDefaultControl;
+ ::rtl::OUString m_sHelpText;
+// [properties]
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > m_xSelection;
+
+// [properties]
+ ::rtl::OUString m_sHelpURL; // URL
+ sal_Int16 m_nBorder;
+ sal_Int16 m_nWritingMode;
+ sal_Int16 m_nContextWritingMode;
+ sal_Bool m_bEnableVisible : 1;
+ sal_Bool m_bEnable : 1;
+ sal_Bool m_bNavigation : 1;
+ sal_Bool m_bRecordMarker : 1;
+ sal_Bool m_bPrintable : 1;
+ sal_Bool m_bAlwaysShowCursor : 1; // transient
+ sal_Bool m_bDisplaySynchron : 1; // transient
+// [properties]
+
+protected:
+ void _reset();
+
+public:
+ DECLARE_DEFAULT_LEAF_XTOR( OGridControlModel );
+
+ // UNO Anbindung
+ DECLARE_UNO3_AGG_DEFAULTS(OGridControlModel, OControlModel);
+ virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XChild
+ virtual void SAL_CALL setParent(const InterfaceRef& Parent) throw(::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ IMPLEMENTATION_NAME(OGridControlModel);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
+
+ // XTypeProvider
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // OComponentHelper
+ virtual void SAL_CALL disposing();
+
+ // XEventListener
+ virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& _rSource) throw(::com::sun::star::uno::RuntimeException);
+
+ // XReset
+ virtual void SAL_CALL reset() throw ( ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addResetListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XResetListener>& _rxListener) throw ( ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeResetListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XResetListener>& _rxListener) throw ( ::com::sun::star::uno::RuntimeException);
+
+ // XSelectionSupplier
+ virtual sal_Bool SAL_CALL select(const ::com::sun::star::uno::Any& aElement) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Any SAL_CALL getSelection() throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addSelectionChangeListener(const ::com::sun::star::uno::Reference< ::com::sun::star::view::XSelectionChangeListener >& xListener) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeSelectionChangeListener(const ::com::sun::star::uno::Reference< ::com::sun::star::view::XSelectionChangeListener >& xListener) throw(::com::sun::star::uno::RuntimeException);
+
+ // XGridColumnFactory
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet> SAL_CALL createColumn(const ::rtl::OUString& ColumnType) throw ( :: com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual StringSequence SAL_CALL getColumnTypes() throw ( ::com::sun::star::uno::RuntimeException);
+
+ // XPersistObject
+ virtual ::rtl::OUString SAL_CALL getServiceName() throw ( ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ // XPropertySet
+ virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle ) const;
+ virtual sal_Bool SAL_CALL convertFastPropertyValue(::com::sun::star::uno::Any& rConvertedValue, ::com::sun::star::uno::Any& rOldValue,
+ sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
+ throw(::com::sun::star::lang::IllegalArgumentException);
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue) throw ( ::com::sun::star::uno::Exception);
+
+ // XPropertyState
+ virtual ::com::sun::star::uno::Any getPropertyDefaultByHandle( sal_Int32 nHandle ) const;
+
+ // XSQLErrorListener
+ virtual void SAL_CALL errorOccured( const ::com::sun::star::sdb::SQLErrorEvent& _rEvent ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XRowSetSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSet > SAL_CALL getRowSet( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setRowSet( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSet >& xDataSource ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XRowSetChangeBroadcaster
+ virtual void SAL_CALL addRowSetChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XRowSetChangeListener >& i_Listener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeRowSetChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XRowSetChangeListener >& i_Listener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // OControlModel's property handling
+ virtual void describeFixedProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps
+ ) const;
+
+ // prevent method hiding
+ using OControlModel::disposing;
+ using OControlModel::getFastPropertyValue;
+
+protected:
+ DECLARE_XCLONEABLE();
+
+protected:
+ virtual void approveNewElement(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxObject,
+ ElementDescription* _pElement
+ );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet> createColumn(sal_Int32 nTypeId) const;
+
+ OGridColumn* getColumnImplementation(const InterfaceRef& _rxIFace) const;
+
+ virtual ElementDescription* createElementMetaData( );
+
+protected:
+ virtual void implRemoved(const InterfaceRef& _rxObject);
+ virtual void implInserted( const ElementDescription* _pElement );
+ virtual void impl_replacedElement(
+ const ::com::sun::star::container::ContainerEvent& _rEvent,
+ ::osl::ClearableMutexGuard& _rInstanceLock
+ );
+
+ void gotColumn(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxColumn);
+ void lostColumn(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxColumn);
+
+ void cloneColumns( const OGridControlModel* _pOriginalContainer );
+};
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/GroupBox.cxx b/forms/source/component/GroupBox.cxx
new file mode 100644
index 000000000000..ccb45d2f8a48
--- /dev/null
+++ b/forms/source/component/GroupBox.cxx
@@ -0,0 +1,175 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+#include "GroupBox.hxx"
+#include "property.hxx"
+#include "property.hrc"
+#include "services.hxx"
+#include <tools/debug.hxx>
+
+//.........................................................................
+namespace frm
+{
+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;
+
+//==================================================================
+// OGroupBoxModel
+//==================================================================
+
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL OGroupBoxModel_CreateInstance(const Reference<starlang::XMultiServiceFactory>& _rxFactory) throw (RuntimeException)
+{
+ return *(new OGroupBoxModel(_rxFactory));
+}
+
+//------------------------------------------------------------------
+DBG_NAME( OGroupBoxModel )
+//------------------------------------------------------------------
+OGroupBoxModel::OGroupBoxModel(const Reference<starlang::XMultiServiceFactory>& _rxFactory)
+ :OControlModel(_rxFactory, VCL_CONTROLMODEL_GROUPBOX, VCL_CONTROL_GROUPBOX)
+{
+ DBG_CTOR( OGroupBoxModel, NULL );
+ m_nClassId = FormComponentType::GROUPBOX;
+}
+
+//------------------------------------------------------------------
+OGroupBoxModel::OGroupBoxModel( const OGroupBoxModel* _pOriginal, const Reference<starlang::XMultiServiceFactory>& _rxFactory )
+ :OControlModel( _pOriginal, _rxFactory )
+{
+ DBG_CTOR( OGroupBoxModel, NULL );
+}
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+StringSequence SAL_CALL OGroupBoxModel::getSupportedServiceNames() throw(RuntimeException)
+{
+ StringSequence aSupported = OControlModel::getSupportedServiceNames();
+ aSupported.realloc(aSupported.getLength() + 1);
+
+ ::rtl::OUString* pArray = aSupported.getArray();
+ pArray[aSupported.getLength()-1] = FRM_SUN_COMPONENT_GROUPBOX;
+ return aSupported;
+}
+
+//------------------------------------------------------------------
+OGroupBoxModel::~OGroupBoxModel()
+{
+ DBG_DTOR( OGroupBoxModel, NULL );
+}
+
+//------------------------------------------------------------------------------
+IMPLEMENT_DEFAULT_CLONING( OGroupBoxModel )
+
+//------------------------------------------------------------------------------
+void OGroupBoxModel::describeAggregateProperties( Sequence< Property >& _rAggregateProps ) const
+{
+ OControlModel::describeAggregateProperties( _rAggregateProps );
+ // don't want to have the TabStop property
+ RemoveProperty(_rAggregateProps, PROPERTY_TABSTOP);
+}
+
+//------------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OGroupBoxModel::getServiceName() throw(RuntimeException)
+{
+ return FRM_COMPONENT_GROUPBOX; // old (non-sun) name for compatibility !
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OGroupBoxModel::write(const Reference< XObjectOutputStream>& _rxOutStream)
+ throw(IOException, RuntimeException)
+{
+ OControlModel::write(_rxOutStream);
+
+ // Version
+ _rxOutStream->writeShort(0x0002);
+ writeHelpTextCompatibly(_rxOutStream);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OGroupBoxModel::read(const Reference< XObjectInputStream>& _rxInStream) throw(IOException, RuntimeException)
+{
+ OControlModel::read( _rxInStream );
+
+ // Version
+ sal_uInt16 nVersion = _rxInStream->readShort();
+ DBG_ASSERT(nVersion > 0, "OGroupBoxModel::read : version 0 ? this should never have been written !");
+ // ups, ist das Englisch richtig ? ;)
+
+ if (nVersion == 2)
+ readHelpTextCompatibly(_rxInStream);
+
+ if (nVersion > 0x0002)
+ {
+ OSL_FAIL("OGroupBoxModel::read : unknown version !");
+ }
+};
+
+//==================================================================
+// OGroupBoxControl
+//==================================================================
+
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL OGroupBoxControl_CreateInstance(const Reference<starlang::XMultiServiceFactory>& _rxFactory) throw (RuntimeException)
+{
+ return *(new OGroupBoxControl(_rxFactory));
+}
+
+//------------------------------------------------------------------------------
+OGroupBoxControl::OGroupBoxControl(const Reference<starlang::XMultiServiceFactory>& _rxFactory)
+ :OControl(_rxFactory, VCL_CONTROL_GROUPBOX)
+{
+}
+
+//------------------------------------------------------------------------------
+StringSequence SAL_CALL OGroupBoxControl::getSupportedServiceNames() throw(RuntimeException)
+{
+ StringSequence aSupported = OControl::getSupportedServiceNames();
+ aSupported.realloc(aSupported.getLength() + 1);
+
+ ::rtl::OUString* pArray = aSupported.getArray();
+ pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_GROUPBOX;
+ return aSupported;
+}
+
+//.........................................................................
+}
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/GroupBox.hxx b/forms/source/component/GroupBox.hxx
new file mode 100644
index 000000000000..a7b0411af451
--- /dev/null
+++ b/forms/source/component/GroupBox.hxx
@@ -0,0 +1,86 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FORMS_GROUPBOX_HXX_
+#define _FORMS_GROUPBOX_HXX_
+
+#include "FormComponent.hxx"
+
+//.........................................................................
+namespace frm
+{
+
+//==================================================================
+// OGroupBoxModel
+//==================================================================
+class OGroupBoxModel
+ :public OControlModel
+{
+public:
+ DECLARE_DEFAULT_LEAF_XTOR( OGroupBoxModel );
+
+ // XServiceInfo
+ IMPLEMENTATION_NAME(OGroupBoxModel);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
+
+ // XPersistObject
+ virtual ::rtl::OUString SAL_CALL getServiceName() throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL
+ write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL
+ read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ // OControlModel's property handling
+ virtual void describeAggregateProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rAggregateProps
+ ) const;
+
+protected:
+ DECLARE_XCLONEABLE();
+};
+
+//==================================================================
+// OGroupBoxControl (nur aus Kompatibilitaet zur 5.0)
+//==================================================================
+class OGroupBoxControl : public OControl
+{
+public:
+ OGroupBoxControl(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);
+
+ // XServiceInfo
+ IMPLEMENTATION_NAME(OGroupBoxControl);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
+};
+
+//.........................................................................
+}
+//.........................................................................
+
+#endif // _FORMS_GROUPBOX_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/GroupManager.cxx b/forms/source/component/GroupManager.cxx
new file mode 100644
index 000000000000..1268bcb5828b
--- /dev/null
+++ b/forms/source/component/GroupManager.cxx
@@ -0,0 +1,533 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+#include "GroupManager.hxx"
+#include <com/sun/star/beans/XFastPropertySet.hpp>
+#include <com/sun/star/form/FormComponentType.hpp>
+#include <comphelper/property.hxx>
+#include <comphelper/uno3.hxx>
+#include <tools/solar.h>
+#include <tools/debug.hxx>
+
+#include "property.hrc"
+
+#include <algorithm>
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::sdbc;
+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::lang;
+using namespace ::com::sun::star::form;
+
+namespace
+{
+ bool isRadioButton( const Reference< XPropertySet >& _rxComponent )
+ {
+ bool bIs = false;
+ if ( hasProperty( PROPERTY_CLASSID, _rxComponent ) )
+ {
+ sal_Int16 nClassId = FormComponentType::CONTROL;
+ _rxComponent->getPropertyValue( PROPERTY_CLASSID ) >>= nClassId;
+ if ( nClassId == FormComponentType::RADIOBUTTON )
+ bIs = true;
+ }
+ return bIs;
+ }
+}
+
+//========================================================================
+// class OGroupCompAcc
+//========================================================================
+//------------------------------------------------------------------
+OGroupCompAcc::OGroupCompAcc(const Reference<XPropertySet>& rxElement, const OGroupComp& _rGroupComp )
+ :m_xComponent( rxElement )
+ ,m_aGroupComp( _rGroupComp )
+{
+}
+
+//------------------------------------------------------------------
+sal_Bool OGroupCompAcc::operator==( const OGroupCompAcc& rCompAcc ) const
+{
+ return (m_xComponent == rCompAcc.GetComponent());
+}
+
+//------------------------------------------------------------------
+class OGroupCompAccLess : public ::std::binary_function<OGroupCompAcc, OGroupCompAcc, sal_Bool>
+{
+public:
+ sal_Bool operator() (const OGroupCompAcc& lhs, const OGroupCompAcc& rhs) const
+ {
+ return
+ reinterpret_cast<sal_Int64>(lhs.m_xComponent.get())
+ < reinterpret_cast<sal_Int64>(rhs.m_xComponent.get());
+ }
+};
+
+//========================================================================
+// class OGroupComp
+//========================================================================
+
+//------------------------------------------------------------------
+OGroupComp::OGroupComp()
+ :m_nPos( -1 )
+ ,m_nTabIndex( 0 )
+{
+}
+
+//------------------------------------------------------------------
+OGroupComp::OGroupComp(const OGroupComp& _rSource)
+ :m_aName( _rSource.m_aName )
+ ,m_xComponent( _rSource.m_xComponent )
+ ,m_xControlModel(_rSource.m_xControlModel)
+ ,m_nPos( _rSource.m_nPos )
+ ,m_nTabIndex( _rSource.m_nTabIndex )
+{
+}
+
+//------------------------------------------------------------------
+OGroupComp::OGroupComp(const Reference<XPropertySet>& rxSet, sal_Int32 nInsertPos )
+ : m_aName( OGroupManager::GetGroupName( rxSet ) )
+ , m_xComponent( rxSet )
+ , m_xControlModel(rxSet,UNO_QUERY)
+ , m_nPos( nInsertPos )
+ , m_nTabIndex(0)
+{
+ if (m_xComponent.is())
+ {
+ if (hasProperty( PROPERTY_TABINDEX, m_xComponent ) )
+ // Indices kleiner 0 werden wie 0 behandelt
+ m_nTabIndex = Max(getINT16(m_xComponent->getPropertyValue( PROPERTY_TABINDEX )) , sal_Int16(0));
+ }
+}
+
+//------------------------------------------------------------------
+sal_Bool OGroupComp::operator==( const OGroupComp& rComp ) const
+{
+ return m_nTabIndex == rComp.GetTabIndex() && m_nPos == rComp.GetPos();
+}
+
+//------------------------------------------------------------------
+class OGroupCompLess : public ::std::binary_function<OGroupComp, OGroupComp, sal_Bool>
+{
+public:
+ sal_Bool operator() (const OGroupComp& lhs, const OGroupComp& rhs) const
+ {
+ sal_Bool bResult;
+ // TabIndex von 0 wird hinten einsortiert
+ if (lhs.m_nTabIndex == rhs.GetTabIndex())
+ bResult = lhs.m_nPos < rhs.GetPos();
+ else if (lhs.m_nTabIndex && rhs.GetTabIndex())
+ bResult = lhs.m_nTabIndex < rhs.GetTabIndex();
+ else
+ bResult = lhs.m_nTabIndex != 0;
+ return bResult;
+ }
+};
+
+//========================================================================
+// class OGroup
+//========================================================================
+
+DBG_NAME(OGroup)
+//------------------------------------------------------------------
+OGroup::OGroup( const ::rtl::OUString& rGroupName )
+ :m_aGroupName( rGroupName )
+ ,m_nInsertPos(0)
+{
+ DBG_CTOR(OGroup,NULL);
+}
+
+#ifdef DBG_UTIL
+//------------------------------------------------------------------
+OGroup::OGroup( const OGroup& _rSource )
+:m_aCompArray(_rSource.m_aCompArray)
+ ,m_aCompAccArray(_rSource.m_aCompAccArray)
+ ,m_aGroupName(_rSource.m_aGroupName)
+ ,m_nInsertPos(_rSource.m_nInsertPos)
+{
+ DBG_CTOR(OGroup,NULL);
+}
+#endif
+
+//------------------------------------------------------------------
+OGroup::~OGroup()
+{
+ DBG_DTOR(OGroup,NULL);
+}
+
+//------------------------------------------------------------------
+void OGroup::InsertComponent( const Reference<XPropertySet>& xSet )
+{
+ OGroupComp aNewGroupComp( xSet, m_nInsertPos );
+ sal_Int32 nPosInserted = insert_sorted(m_aCompArray, aNewGroupComp, OGroupCompLess());
+
+ OGroupCompAcc aNewGroupCompAcc( xSet, m_aCompArray[nPosInserted] );
+ insert_sorted(m_aCompAccArray, aNewGroupCompAcc, OGroupCompAccLess());
+ m_nInsertPos++;
+}
+
+//------------------------------------------------------------------
+void OGroup::RemoveComponent( const Reference<XPropertySet>& rxElement )
+{
+ sal_Int32 nGroupCompAccPos;
+ OGroupCompAcc aSearchCompAcc( rxElement, OGroupComp() );
+ if ( seek_entry(m_aCompAccArray, aSearchCompAcc, nGroupCompAccPos, OGroupCompAccLess()) )
+ {
+ OGroupCompAcc& aGroupCompAcc = m_aCompAccArray[nGroupCompAccPos];
+ const OGroupComp& aGroupComp = aGroupCompAcc.GetGroupComponent();
+
+ sal_Int32 nGroupCompPos;
+ if ( seek_entry(m_aCompArray, aGroupComp, nGroupCompPos, OGroupCompLess()) )
+ {
+ m_aCompAccArray.erase( m_aCompAccArray.begin() + nGroupCompAccPos );
+ m_aCompArray.erase( m_aCompArray.begin() + nGroupCompPos );
+
+ /*============================================================
+ Durch das Entfernen der GroupComp ist die Einfuegeposition
+ ungueltig geworden. Sie braucht hier aber nicht angepasst werden,
+ da sie fortlaufend vergeben wird und damit immer
+ aufsteigend eindeutig ist.
+ ============================================================*/
+ }
+ else
+ {
+ OSL_FAIL( "OGroup::RemoveComponent: Component nicht in Gruppe" );
+ }
+ }
+ else
+ {
+ OSL_FAIL( "OGroup::RemoveComponent: Component nicht in Gruppe" );
+ }
+}
+
+//------------------------------------------------------------------
+sal_Bool OGroup::operator==( const OGroup& rGroup ) const
+{
+ return m_aGroupName.equals(rGroup.GetGroupName());
+}
+
+//------------------------------------------------------------------
+class OGroupLess : public ::std::binary_function<OGroup, OGroup, sal_Bool>
+{
+public:
+ sal_Bool operator() (const OGroup& lhs, const OGroup& rhs) const
+ {
+ return lhs.m_aGroupName < rhs.m_aGroupName;
+ }
+};
+
+//------------------------------------------------------------------
+Sequence< Reference<XControlModel> > OGroup::GetControlModels() const
+{
+ sal_Int32 nLen = m_aCompArray.size();
+ Sequence<Reference<XControlModel> > aControlModelSeq( nLen );
+ Reference<XControlModel>* pModels = aControlModelSeq.getArray();
+
+ ConstOGroupCompArrIterator aGroupComps = m_aCompArray.begin();
+ for (sal_Int32 i = 0; i < nLen; ++i, ++pModels, ++aGroupComps)
+ {
+ *pModels = aGroupComps->GetControlModel();
+ }
+ return aControlModelSeq;
+}
+
+DBG_NAME(OGroupManager);
+//------------------------------------------------------------------
+OGroupManager::OGroupManager(const Reference< XContainer >& _rxContainer)
+ :m_pCompGroup( new OGroup( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AllComponentGroup") ) ) )
+ ,m_xContainer(_rxContainer)
+{
+ DBG_CTOR(OGroupManager,NULL);
+
+ increment(m_refCount);
+ {
+ _rxContainer->addContainerListener(this);
+ }
+ decrement(m_refCount);
+}
+
+//------------------------------------------------------------------
+OGroupManager::~OGroupManager()
+{
+ DBG_DTOR(OGroupManager,NULL);
+ // Alle Components und CompGroup loeschen
+ delete m_pCompGroup;
+}
+
+// XPropertyChangeListener
+//------------------------------------------------------------------
+void OGroupManager::disposing(const EventObject& evt) throw( RuntimeException )
+{
+ Reference<XContainer> xContainer(evt.Source, UNO_QUERY);
+ if (xContainer.get() == m_xContainer.get())
+ {
+ DELETEZ(m_pCompGroup);
+
+ ////////////////////////////////////////////////////////////////
+ // Gruppen loeschen
+ m_aGroupArr.clear();
+ m_xContainer.clear();
+ }
+}
+// -----------------------------------------------------------------------------
+void OGroupManager::removeFromGroupMap(const ::rtl::OUString& _sGroupName,const Reference<XPropertySet>& _xSet)
+{
+ // Component aus CompGroup entfernen
+ m_pCompGroup->RemoveComponent( _xSet );
+
+ OGroupArr::iterator aFind = m_aGroupArr.find(_sGroupName);
+
+ if ( aFind != m_aGroupArr.end() )
+ {
+ // Gruppe vorhanden
+ aFind->second.RemoveComponent( _xSet );
+
+ // Wenn Anzahl der Gruppenelemente == 1 ist, Gruppe deaktivieren
+ sal_Int32 nCount = aFind->second.Count();
+ if ( nCount == 1 || nCount == 0 )
+ {
+ OActiveGroups::iterator aActiveFind = ::std::find(
+ m_aActiveGroupMap.begin(),
+ m_aActiveGroupMap.end(),
+ aFind
+ );
+ if ( aActiveFind != m_aActiveGroupMap.end() )
+ {
+ // the group is active. Deactivate it if the remaining component
+ // is *no* radio button
+ if ( nCount == 0 || !isRadioButton( aFind->second.GetObject( 0 ) ) )
+ m_aActiveGroupMap.erase( aActiveFind );
+ }
+ }
+ }
+
+
+ // Bei Component als PropertyChangeListener abmelden
+ _xSet->removePropertyChangeListener( PROPERTY_NAME, this );
+ if (hasProperty(PROPERTY_GROUP_NAME, _xSet))
+ _xSet->removePropertyChangeListener( PROPERTY_GROUP_NAME, this );
+ if (hasProperty(PROPERTY_TABINDEX, _xSet))
+ _xSet->removePropertyChangeListener( PROPERTY_TABINDEX, this );
+}
+//------------------------------------------------------------------
+void SAL_CALL OGroupManager::propertyChange(const PropertyChangeEvent& evt) throw ( ::com::sun::star::uno::RuntimeException)
+{
+ Reference<XPropertySet> xSet(evt.Source, UNO_QUERY);
+
+ // Component aus Gruppe entfernen
+ ::rtl::OUString sGroupName;
+ if (hasProperty( PROPERTY_GROUP_NAME, xSet ))
+ xSet->getPropertyValue( PROPERTY_GROUP_NAME ) >>= sGroupName;
+ if (evt.PropertyName == PROPERTY_NAME) {
+ if (sGroupName.getLength() > 0)
+ return; // group hasn't changed; ignore this name change.
+ // no GroupName; use Name as GroupNme
+ evt.OldValue >>= sGroupName;
+ }
+ else if (evt.PropertyName == PROPERTY_GROUP_NAME) {
+ evt.OldValue >>= sGroupName;
+ if (sGroupName.getLength() == 0) {
+ // No prior GroupName; fallback to Nme
+ xSet->getPropertyValue( PROPERTY_NAME ) >>= sGroupName;
+ }
+ }
+ else
+ sGroupName = GetGroupName( xSet );
+
+ removeFromGroupMap(sGroupName,xSet);
+
+ // Component neu einordnen
+ InsertElement( xSet );
+}
+
+// XContainerListener
+//------------------------------------------------------------------
+void SAL_CALL OGroupManager::elementInserted(const ContainerEvent& Event) throw ( ::com::sun::star::uno::RuntimeException)
+{
+ Reference< XPropertySet > xProps;
+ Event.Element >>= xProps;
+ if ( xProps.is() )
+ InsertElement( xProps );
+}
+
+//------------------------------------------------------------------
+void SAL_CALL OGroupManager::elementRemoved(const ContainerEvent& Event) throw ( ::com::sun::star::uno::RuntimeException)
+{
+ Reference<XPropertySet> xProps;
+ Event.Element >>= xProps;
+ if ( xProps.is() )
+ RemoveElement( xProps );
+}
+
+//------------------------------------------------------------------
+void SAL_CALL OGroupManager::elementReplaced(const ContainerEvent& Event) throw ( ::com::sun::star::uno::RuntimeException)
+{
+ Reference<XPropertySet> xProps;
+ Event.ReplacedElement >>= xProps;
+ if ( xProps.is() )
+ RemoveElement( xProps );
+
+ xProps.clear();
+ Event.Element >>= xProps;
+ if ( xProps.is() )
+ InsertElement( xProps );
+}
+
+// Other functions
+//------------------------------------------------------------------
+Sequence<Reference<XControlModel> > OGroupManager::getControlModels()
+{
+ return m_pCompGroup->GetControlModels();
+}
+
+//------------------------------------------------------------------
+sal_Int32 OGroupManager::getGroupCount()
+{
+ return m_aActiveGroupMap.size();
+}
+
+//------------------------------------------------------------------
+void OGroupManager::getGroup(sal_Int32 nGroup, Sequence< Reference<XControlModel> >& _rGroup, ::rtl::OUString& _rName)
+{
+ OSL_ENSURE(nGroup >= 0 && (size_t)nGroup < m_aActiveGroupMap.size(),"OGroupManager::getGroup: Invalid group index!");
+ OGroupArr::iterator aGroupPos = m_aActiveGroupMap[nGroup];
+ _rName = aGroupPos->second.GetGroupName();
+ _rGroup = aGroupPos->second.GetControlModels();
+}
+
+//------------------------------------------------------------------
+void OGroupManager::getGroupByName(const ::rtl::OUString& _rName, Sequence< Reference<XControlModel> >& _rGroup)
+{
+ OGroupArr::iterator aFind = m_aGroupArr.find(_rName);
+ if ( aFind != m_aGroupArr.end() )
+ _rGroup = aFind->second.GetControlModels();
+}
+
+//------------------------------------------------------------------
+void OGroupManager::InsertElement( const Reference<XPropertySet>& xSet )
+{
+ // Nur ControlModels
+ Reference<XControlModel> xControl(xSet, UNO_QUERY);
+ if (!xControl.is() )
+ return;
+
+ // Component in CompGroup aufnehmen
+ m_pCompGroup->InsertComponent( xSet );
+
+ // Component in Gruppe aufnehmen
+ ::rtl::OUString sGroupName( GetGroupName( xSet ) );
+
+ OGroupArr::iterator aFind = m_aGroupArr.find(sGroupName);
+
+ if ( aFind == m_aGroupArr.end() )
+ {
+ aFind = m_aGroupArr.insert(OGroupArr::value_type(sGroupName,OGroup(sGroupName))).first;
+ }
+
+ aFind->second.InsertComponent( xSet );
+
+ // if we have at least 2 elements in the group, then this is an "active group"
+ bool bActivateGroup = aFind->second.Count() == 2;
+
+ // Additionally, if the component is a radio button, then it's group becomes active,
+ // too. With this, we ensure that in a container with n radio buttons which all are
+ // in different groups the selection still works reliably (means that all radios can be
+ // clicked independently)
+ if ( aFind->second.Count() == 1 )
+ {
+ if ( isRadioButton( xSet ) )
+ bActivateGroup = true;
+ }
+
+ if ( bActivateGroup )
+ {
+ OActiveGroups::iterator aAlreadyExistent = ::std::find(
+ m_aActiveGroupMap.begin(),
+ m_aActiveGroupMap.end(),
+ aFind
+ );
+ if ( aAlreadyExistent == m_aActiveGroupMap.end() )
+ m_aActiveGroupMap.push_back( aFind );
+ }
+
+
+ // Bei Component als PropertyChangeListener anmelden
+ xSet->addPropertyChangeListener( PROPERTY_NAME, this );
+ if (hasProperty(PROPERTY_GROUP_NAME, xSet))
+ xSet->addPropertyChangeListener( PROPERTY_GROUP_NAME, this );
+
+ // Tabindex muss nicht jeder unterstuetzen
+ if (hasProperty(PROPERTY_TABINDEX, xSet))
+ xSet->addPropertyChangeListener( PROPERTY_TABINDEX, this );
+
+}
+
+//------------------------------------------------------------------
+void OGroupManager::RemoveElement( const Reference<XPropertySet>& xSet )
+{
+ // Nur ControlModels
+ Reference<XControlModel> xControl(xSet, UNO_QUERY);
+ if (!xControl.is() )
+ return;
+
+ // Component aus Gruppe entfernen
+ ::rtl::OUString sGroupName( GetGroupName( xSet ) );
+
+ removeFromGroupMap(sGroupName,xSet);
+}
+
+::rtl::OUString OGroupManager::GetGroupName( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet> xComponent )
+{
+ if (!xComponent.is())
+ return ::rtl::OUString();
+ ::rtl::OUString sGroupName;
+ if (hasProperty( PROPERTY_GROUP_NAME, xComponent )) {
+ xComponent->getPropertyValue( PROPERTY_GROUP_NAME ) >>= sGroupName;
+ if (sGroupName.getLength() == 0)
+ xComponent->getPropertyValue( PROPERTY_NAME ) >>= sGroupName;
+ }
+ else
+ xComponent->getPropertyValue( PROPERTY_NAME ) >>= sGroupName;
+ return sGroupName;
+}
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/GroupManager.hxx b/forms/source/component/GroupManager.hxx
new file mode 100644
index 000000000000..7f6e99be8354
--- /dev/null
+++ b/forms/source/component/GroupManager.hxx
@@ -0,0 +1,234 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FRM_GROUPMANAGER_HXX_
+#define _FRM_GROUPMANAGER_HXX_
+
+#include <com/sun/star/sdbc/XRowSet.hpp>
+#include <com/sun/star/awt/XControlModel.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertyChangeListener.hpp>
+#include <com/sun/star/container/XContainerListener.hpp>
+#include <com/sun/star/container/XContainer.hpp>
+#include <cppuhelper/implbase2.hxx>
+#include <comphelper/stl_types.hxx>
+#include <comphelper/types.hxx>
+
+#include <algorithm>
+
+using namespace comphelper;
+
+/*========================================================================
+Funktionsweise GroupManager:
+
+Der GroupManager horcht an der starform, ob FormComponents eingefuegt oder entfernt
+werden. Zusaetzlich horcht er bei den FormComponents an den Properties
+"Name" und "TabIndex". Mit diesen Infos aktualisiert er seine Gruppen.
+
+Der GroupManager verwaltet eine Gruppe, in der alle Controls nach TabIndex
+geordnet sind, und ein Array von Gruppen, in dem jede FormComponent noch
+einmal einer Gruppe dem Namen nach zugeordnet wird.
+Die einzelnen Gruppen werden ueber eine Map aktiviert, wenn sie mehr als
+ein Element besitzen.
+
+Die Gruppen verwalten intern die FormComponents in zwei Arrays. In dem
+GroupCompArray werden die Components nach TabIndex und Einfuegepostion
+sortiert. Da auf dieses Array ueber die FormComponent zugegriffen
+wird, gibt es noch das GroupCompAccessArray, in dem die FormComponents
+nach ihrer Speicheradresse sortiert sind. Jedes Element des
+GroupCompAccessArrays ist mit einem Element des GroupCompArrays verpointert.
+
+========================================================================*/
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+//========================================================================
+ template <class ELEMENT, class LESS_COMPARE>
+ sal_Int32 insert_sorted(::std::vector<ELEMENT>& _rArray, const ELEMENT& _rNewElement, const LESS_COMPARE& _rCompareOp)
+ {
+ typename ::std::vector<ELEMENT>::iterator aInsertPos = ::std::lower_bound(
+ _rArray.begin(),
+ _rArray.end(),
+ _rNewElement,
+ _rCompareOp
+ );
+ aInsertPos = _rArray.insert(aInsertPos, _rNewElement);
+ return aInsertPos - _rArray.begin();
+ }
+
+ template <class ELEMENT, class LESS_COMPARE>
+ sal_Bool seek_entry(const ::std::vector<ELEMENT>& _rArray, const ELEMENT& _rNewElement, sal_Int32& nPos, const LESS_COMPARE& _rCompareOp)
+ {
+ typename ::std::vector<ELEMENT>::const_iterator aExistentPos = ::std::lower_bound(
+ _rArray.begin(),
+ _rArray.end(),
+ _rNewElement,
+ _rCompareOp
+ );
+ if ((aExistentPos != _rArray.end()) && (*aExistentPos == _rNewElement))
+ { // we have a valid "lower or equal" element and it's really "equal"
+ nPos = aExistentPos - _rArray.begin();
+ return sal_True;
+ }
+ nPos = -1;
+ return sal_False;
+ }
+
+//========================================================================
+class OGroupComp
+{
+ ::rtl::OUString m_aName;
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet> m_xComponent;
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel> m_xControlModel;
+ sal_Int32 m_nPos;
+ sal_Int16 m_nTabIndex;
+
+ friend class OGroupCompLess;
+
+public:
+ OGroupComp(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& rxElement, sal_Int32 nInsertPos );
+ OGroupComp(const OGroupComp& _rSource);
+ OGroupComp();
+
+ sal_Bool operator==( const OGroupComp& rComp ) const;
+
+ inline const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& GetComponent() const { return m_xComponent; }
+ inline const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel>& GetControlModel() const { return m_xControlModel; }
+
+ sal_Int32 GetPos() const { return m_nPos; }
+ sal_Int16 GetTabIndex() const { return m_nTabIndex; }
+ ::rtl::OUString GetName() const { return m_aName; }
+};
+
+DECLARE_STL_VECTOR(OGroupComp, OGroupCompArr);
+
+//========================================================================
+class OGroupComp;
+class OGroupCompAcc
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet> m_xComponent;
+
+ OGroupComp m_aGroupComp;
+
+ friend class OGroupCompAccLess;
+
+public:
+ OGroupCompAcc(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& rxElement, const OGroupComp& _rGroupComp );
+
+ sal_Bool operator==( const OGroupCompAcc& rCompAcc ) const;
+
+ inline const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& GetComponent() const { return m_xComponent; }
+ const OGroupComp& GetGroupComponent() const { return m_aGroupComp; }
+};
+
+DECLARE_STL_VECTOR(OGroupCompAcc, OGroupCompAccArr);
+
+//========================================================================
+class OGroup
+{
+ OGroupCompArr m_aCompArray;
+ OGroupCompAccArr m_aCompAccArray;
+
+ ::rtl::OUString m_aGroupName;
+ sal_uInt16 m_nInsertPos; // Die Einfugeposition der GroupComps wird von der Gruppe bestimmt.
+
+ friend class OGroupLess;
+
+public:
+ OGroup( const ::rtl::OUString& rGroupName );
+#ifdef DBG_UTIL
+ OGroup( const OGroup& _rSource ); // just to ensure the DBG_CTOR call
+#endif
+ virtual ~OGroup();
+
+ sal_Bool operator==( const OGroup& rGroup ) const;
+
+ ::rtl::OUString GetGroupName() const { return m_aGroupName; }
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel> > GetControlModels() const;
+
+ void InsertComponent( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& rxElement );
+ void RemoveComponent( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& rxElement );
+ sal_uInt16 Count() const { return sal::static_int_cast< sal_uInt16 >(m_aCompArray.size()); }
+ const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& GetObject( sal_uInt16 nP ) const
+ { return m_aCompArray[nP].GetComponent(); }
+};
+
+DECLARE_STL_USTRINGACCESS_MAP(OGroup, OGroupArr);
+DECLARE_STL_VECTOR(OGroupArr::iterator, OActiveGroups);
+
+//========================================================================
+class OGroupManager : public ::cppu::WeakImplHelper2< ::com::sun::star::beans::XPropertyChangeListener, ::com::sun::star::container::XContainerListener>
+{
+ OGroup* m_pCompGroup; // Alle Components nach TabIndizes sortiert
+ OGroupArr m_aGroupArr; // Alle Components nach Gruppen sortiert
+ OActiveGroups m_aActiveGroupMap; // In dieser Map werden die Indizes aller Gruppen gehalten,
+ // die mehr als 1 Element haben
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainer >
+ m_xContainer;
+
+ // Helper functions
+ void InsertElement( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& rxElement );
+ void RemoveElement( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& rxElement );
+ void removeFromGroupMap(const ::rtl::OUString& _sGroupName,const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& _xSet);
+
+public:
+ OGroupManager(const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainer >& _rxContainer);
+ virtual ~OGroupManager();
+
+// ::com::sun::star::lang::XEventListener
+ virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& _rSource) throw(::com::sun::star::uno::RuntimeException);
+
+// ::com::sun::star::beans::XPropertyChangeListener
+ virtual void SAL_CALL propertyChange(const ::com::sun::star::beans::PropertyChangeEvent& evt) throw ( ::com::sun::star::uno::RuntimeException);
+
+// ::com::sun::star::container::XContainerListener
+ virtual void SAL_CALL elementInserted(const ::com::sun::star::container::ContainerEvent& _rEvent) throw ( ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL elementRemoved(const ::com::sun::star::container::ContainerEvent& _rEvent) throw ( ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL elementReplaced(const ::com::sun::star::container::ContainerEvent& _rEvent) throw ( ::com::sun::star::uno::RuntimeException);
+
+// Other functions
+ sal_Int32 getGroupCount();
+ void getGroup(sal_Int32 nGroup, ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel> >& _rGroup, ::rtl::OUString& Name);
+ void getGroupByName(const ::rtl::OUString& Name, ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel> >& _rGroup);
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel> > getControlModels();
+
+ static ::rtl::OUString GetGroupName( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet> xComponent );
+};
+
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+#endif // _FRM_GROUPMANAGER_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/Hidden.cxx b/forms/source/component/Hidden.cxx
new file mode 100644
index 000000000000..b2813dd21d93
--- /dev/null
+++ b/forms/source/component/Hidden.cxx
@@ -0,0 +1,190 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+#include "Hidden.hxx"
+#include "property.hxx"
+#include "property.hrc"
+#include "services.hxx"
+#include <tools/debug.hxx>
+#include <comphelper/basicio.hxx>
+
+//.........................................................................
+namespace frm
+{
+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;
+
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL OHiddenModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory) throw (RuntimeException)
+{
+ return *(new OHiddenModel(_rxFactory));
+}
+
+//------------------------------------------------------------------
+DBG_NAME( OHiddenModel )
+//------------------------------------------------------------------
+OHiddenModel::OHiddenModel(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OControlModel(_rxFactory, ::rtl::OUString())
+{
+ DBG_CTOR( OHiddenModel, NULL );
+ m_nClassId = FormComponentType::HIDDENCONTROL;
+}
+
+//------------------------------------------------------------------
+OHiddenModel::OHiddenModel( const OHiddenModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
+ :OControlModel( _pOriginal, _rxFactory )
+{
+ DBG_CTOR( OHiddenModel, NULL );
+ m_sHiddenValue = _pOriginal->m_sHiddenValue;
+}
+
+//------------------------------------------------------------------------------
+OHiddenModel::~OHiddenModel( )
+{
+ DBG_CTOR( OHiddenModel, NULL );
+}
+
+//------------------------------------------------------------------------------
+IMPLEMENT_DEFAULT_CLONING( OHiddenModel )
+
+//------------------------------------------------------------------------------
+void OHiddenModel::getFastPropertyValue(Any& _rValue, sal_Int32 _nHandle) const
+{
+ switch (_nHandle)
+ {
+ case PROPERTY_ID_HIDDEN_VALUE : _rValue <<= m_sHiddenValue; break;
+ default:
+ OControlModel::getFastPropertyValue(_rValue, _nHandle);
+ }
+}
+
+//------------------------------------------------------------------------------
+void OHiddenModel::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle, const Any& _rValue) throw (com::sun::star::uno::Exception)
+{
+ switch (_nHandle)
+ {
+ case PROPERTY_ID_HIDDEN_VALUE :
+ DBG_ASSERT(_rValue.getValueType().getTypeClass() == TypeClass_STRING, "OHiddenModel::setFastPropertyValue_NoBroadcast : invalid type !" );
+ _rValue >>= m_sHiddenValue;
+ break;
+ default:
+ OControlModel::setFastPropertyValue_NoBroadcast(_nHandle, _rValue);
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OHiddenModel::convertFastPropertyValue(
+ Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue)
+ throw (IllegalArgumentException)
+{
+ sal_Bool bModified(sal_False);
+ switch (_nHandle)
+ {
+ case PROPERTY_ID_HIDDEN_VALUE :
+ bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_sHiddenValue);
+ break;
+ default:
+ bModified = OControlModel::convertFastPropertyValue(_rConvertedValue, _rOldValue, _nHandle, _rValue);
+ break;
+ }
+ return bModified;
+}
+
+//------------------------------------------------------------------------------
+void OHiddenModel::describeFixedProperties( Sequence< Property >& _rProps ) const
+{
+ BEGIN_DESCRIBE_BASE_PROPERTIES(4)
+ DECL_PROP2(CLASSID, sal_Int16, READONLY, TRANSIENT);
+ DECL_PROP1(HIDDEN_VALUE, ::rtl::OUString, BOUND);
+ DECL_PROP1(NAME, ::rtl::OUString, BOUND);
+ DECL_PROP1(TAG, ::rtl::OUString, BOUND);
+ END_DESCRIBE_PROPERTIES();
+}
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+StringSequence SAL_CALL OHiddenModel::getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException)
+{
+ StringSequence aSupported( 2 );
+ aSupported[ 0 ] = FRM_SUN_COMPONENT_HIDDENCONTROL;
+ aSupported[ 1 ] = FRM_SUN_FORMCOMPONENT;
+ return aSupported;
+}
+
+//------------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OHiddenModel::getServiceName() throw(RuntimeException)
+{
+ return FRM_COMPONENT_HIDDEN; // old (non-sun) name for compatibility !
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OHiddenModel::write(const Reference<XObjectOutputStream>& _rxOutStream)
+ throw(IOException, RuntimeException)
+{
+ // Version
+ _rxOutStream->writeShort(0x0002);
+
+ // Wert
+ _rxOutStream << m_sHiddenValue;
+
+ OControlModel::write(_rxOutStream);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OHiddenModel::read(const Reference<XObjectInputStream>& _rxInStream) throw(IOException, RuntimeException)
+{
+ // Version
+ sal_uInt16 nVersion = _rxInStream->readShort();
+
+ // Name
+ DBG_ASSERT(nVersion != 1, "OHiddenModel::read : this version is obsolete !");
+ switch (nVersion)
+ {
+ case 1 : { ::rtl::OUString sDummy; _rxInStream >> sDummy; _rxInStream >> m_sHiddenValue; } break;
+ case 2 : _rxInStream >> m_sHiddenValue; break;
+ default : OSL_FAIL("OHiddenModel::read : unknown version !"); m_sHiddenValue = ::rtl::OUString();
+ }
+ OControlModel::read(_rxInStream);
+}
+
+//.........................................................................
+}
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/Hidden.hxx b/forms/source/component/Hidden.hxx
new file mode 100644
index 000000000000..640b91dbd3c1
--- /dev/null
+++ b/forms/source/component/Hidden.hxx
@@ -0,0 +1,86 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FORMS_HIDDEN_HXX_
+#define _FORMS_HIDDEN_HXX_
+
+#include "FormComponent.hxx"
+
+//.........................................................................
+namespace frm
+{
+
+//==================================================================
+// OHiddenModel
+//==================================================================
+class OHiddenModel
+ :public OControlModel
+{
+ ::rtl::OUString m_sHiddenValue;
+
+public:
+ DECLARE_DEFAULT_LEAF_XTOR( OHiddenModel );
+
+ // OPropertySetHelper
+ virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const;
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
+ throw (::com::sun::star::uno::Exception);
+ virtual sal_Bool SAL_CALL convertFastPropertyValue(
+ ::com::sun::star::uno::Any& _rConvertedValue, ::com::sun::star::uno::Any& _rOldValue, sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue )
+ throw (::com::sun::star::lang::IllegalArgumentException);
+
+ // XServiceInfo
+ IMPLEMENTATION_NAME(OHiddenModel);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
+
+ // XPersistObject
+ virtual ::rtl::OUString SAL_CALL getServiceName() throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL
+ write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL
+ read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ // OControlModel's property handling
+ virtual void describeFixedProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps
+ ) const;
+
+ // prevent method hiding
+ using OControlModel::getFastPropertyValue;
+
+protected:
+ DECLARE_XCLONEABLE( );
+};
+
+#endif // _FORMS_HIDDEN_HXX_
+
+//.........................................................................
+}
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/ImageButton.cxx b/forms/source/component/ImageButton.cxx
new file mode 100644
index 000000000000..c65fea102a12
--- /dev/null
+++ b/forms/source/component/ImageButton.cxx
@@ -0,0 +1,275 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+#include "ImageButton.hxx"
+#include <tools/debug.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/svapp.hxx>
+#include <osl/mutex.hxx>
+#include <comphelper/basicio.hxx>
+#include <com/sun/star/awt/MouseButton.hpp>
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+using namespace ::com::sun::star;
+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::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::util;
+
+//==================================================================
+//= OImageButtonModel
+//==================================================================
+DBG_NAME(OImageButtonModel)
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL OImageButtonModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
+{
+ return *(new OImageButtonModel(_rxFactory));
+}
+
+//------------------------------------------------------------------
+OImageButtonModel::OImageButtonModel(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OClickableImageBaseModel( _rxFactory, VCL_CONTROLMODEL_IMAGEBUTTON, FRM_SUN_CONTROL_IMAGEBUTTON )
+ // use the old control name for compytibility reasons
+{
+ DBG_CTOR(OImageButtonModel, NULL);
+ m_nClassId = FormComponentType::IMAGEBUTTON;
+}
+
+//------------------------------------------------------------------
+OImageButtonModel::OImageButtonModel( const OImageButtonModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory)
+ :OClickableImageBaseModel( _pOriginal, _rxFactory )
+{
+ DBG_CTOR(OImageButtonModel, NULL);
+ implInitializeImageURL();
+}
+
+//------------------------------------------------------------------------------
+IMPLEMENT_DEFAULT_CLONING( OImageButtonModel )
+
+//------------------------------------------------------------------------------
+OImageButtonModel::~OImageButtonModel()
+{
+ DBG_DTOR(OImageButtonModel, NULL);
+}
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+StringSequence OImageButtonModel::getSupportedServiceNames() throw()
+{
+ StringSequence aSupported = OClickableImageBaseModel::getSupportedServiceNames();
+ aSupported.realloc(aSupported.getLength() + 1);
+
+ ::rtl::OUString*pArray = aSupported.getArray();
+ pArray[aSupported.getLength()-1] = FRM_SUN_COMPONENT_IMAGEBUTTON;
+ return aSupported;
+}
+
+//------------------------------------------------------------------------------
+void OImageButtonModel::describeFixedProperties( Sequence< Property >& _rProps ) const
+{
+ BEGIN_DESCRIBE_PROPERTIES( 5, OClickableImageBaseModel )
+ DECL_PROP1(BUTTONTYPE, FormButtonType, BOUND);
+ DECL_PROP1(DISPATCHURLINTERNAL, sal_Bool, BOUND);
+ DECL_PROP1(TARGET_URL, ::rtl::OUString, BOUND);
+ DECL_PROP1(TARGET_FRAME, ::rtl::OUString, BOUND);
+ DECL_PROP1(TABINDEX, sal_Int16, BOUND);
+ END_DESCRIBE_PROPERTIES();
+}
+
+//------------------------------------------------------------------------------
+::rtl::OUString OImageButtonModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException)
+{
+ return FRM_COMPONENT_IMAGEBUTTON; // old (non-sun) name for compatibility !
+}
+
+//------------------------------------------------------------------------------
+void OImageButtonModel::write(const Reference<XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
+{
+ OControlModel::write(_rxOutStream);
+
+ // Version
+ _rxOutStream->writeShort(0x0003);
+ _rxOutStream->writeShort((sal_uInt16)m_eButtonType);
+
+ ::rtl::OUString sTmp(INetURLObject::decode( m_sTargetURL, '%', INetURLObject::DECODE_UNAMBIGUOUS));
+ _rxOutStream << sTmp;
+ _rxOutStream << m_sTargetFrame;
+ writeHelpTextCompatibly(_rxOutStream);
+}
+
+//------------------------------------------------------------------------------
+void OImageButtonModel::read(const Reference<XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
+{
+ OControlModel::read(_rxInStream);
+
+ // Version
+ sal_uInt16 nVersion = _rxInStream->readShort();
+
+ switch (nVersion)
+ {
+ case 0x0001:
+ {
+ m_eButtonType = (FormButtonType)_rxInStream->readShort();
+ }
+ break;
+ case 0x0002:
+ {
+ m_eButtonType = (FormButtonType)_rxInStream->readShort();
+ _rxInStream >> m_sTargetURL;
+ _rxInStream >> m_sTargetFrame;
+ }
+ break;
+ case 0x0003:
+ {
+ m_eButtonType = (FormButtonType)_rxInStream->readShort();
+ _rxInStream >> m_sTargetURL;
+ _rxInStream >> m_sTargetFrame;
+ readHelpTextCompatibly(_rxInStream);
+ }
+ break;
+
+ default :
+ OSL_FAIL("OImageButtonModel::read : unknown version !");
+ m_eButtonType = FormButtonType_PUSH;
+ m_sTargetURL = ::rtl::OUString();
+ m_sTargetFrame = ::rtl::OUString();
+ break;
+ }
+}
+
+//==================================================================
+// OImageButtonControl
+//==================================================================
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL OImageButtonControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
+{
+ return *(new OImageButtonControl(_rxFactory));
+}
+
+//------------------------------------------------------------------------------
+Sequence<Type> OImageButtonControl::_getTypes()
+{
+ static Sequence<Type> aTypes;
+ if (!aTypes.getLength())
+ aTypes = concatSequences(OClickableImageBaseControl::_getTypes(), OImageButtonControl_BASE::getTypes());
+ return aTypes;
+}
+
+//------------------------------------------------------------------------------
+StringSequence OImageButtonControl::getSupportedServiceNames() throw()
+{
+ StringSequence aSupported = OClickableImageBaseControl::getSupportedServiceNames();
+ aSupported.realloc(aSupported.getLength() + 1);
+
+ ::rtl::OUString*pArray = aSupported.getArray();
+ pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_IMAGEBUTTON;
+ return aSupported;
+}
+
+//------------------------------------------------------------------------------
+OImageButtonControl::OImageButtonControl(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OClickableImageBaseControl(_rxFactory, VCL_CONTROL_IMAGEBUTTON)
+{
+ increment(m_refCount);
+ {
+ // als MouseListener anmelden
+ Reference< awt::XWindow > xComp;
+ query_aggregation( m_xAggregate, xComp);
+ if (xComp.is())
+ xComp->addMouseListener( static_cast< awt::XMouseListener* >( this ) );
+ }
+ decrement(m_refCount);
+}
+
+// UNO Anbindung
+//------------------------------------------------------------------------------
+Any SAL_CALL OImageButtonControl::queryAggregation(const Type& _rType) throw (RuntimeException)
+{
+ Any aReturn = OClickableImageBaseControl::queryAggregation(_rType);
+ if (!aReturn.hasValue())
+ aReturn = OImageButtonControl_BASE::queryInterface(_rType);
+
+ return aReturn;
+}
+
+//------------------------------------------------------------------------------
+void OImageButtonControl::mousePressed(const awt::MouseEvent& e) throw ( ::com::sun::star::uno::RuntimeException)
+{
+ SolarMutexGuard aSolarGuard;
+
+ if (e.Buttons != awt::MouseButton::LEFT)
+ return;
+
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+ if( m_aApproveActionListeners.getLength() )
+ {
+ // if there are listeners, start the action in an own thread, to not allow
+ // them to block us here (we're in the application's main thread)
+ getImageProducerThread()->OComponentEventThread::addEvent( &e );
+ }
+ else
+ {
+ // Sonst nicht. Dann darf man aber auf keinen Fal die Listener
+ // benachrichtigen, auch dann nicht, wenn er spaeter hinzukommt.
+ aGuard.clear();
+ actionPerformed_Impl( sal_False, e );
+ }
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OImageButtonControl::mouseReleased(const awt::MouseEvent& /*e*/) throw ( RuntimeException)
+{
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OImageButtonControl::mouseEntered(const awt::MouseEvent& /*e*/) throw ( RuntimeException)
+{
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OImageButtonControl::mouseExited(const awt::MouseEvent& /*e*/) throw ( RuntimeException)
+{
+}
+
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/ImageButton.hxx b/forms/source/component/ImageButton.hxx
new file mode 100644
index 000000000000..cd5e4f7758a1
--- /dev/null
+++ b/forms/source/component/ImageButton.hxx
@@ -0,0 +1,109 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FRM_IMAGE_BUTTON_HXX_
+#define _FRM_IMAGE_BUTTON_HXX_
+
+#include "clickableimage.hxx"
+#include <com/sun/star/awt/XMouseListener.hpp>
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+//==================================================================
+// OImageButtonModel
+//==================================================================
+class OImageButtonModel
+ :public OClickableImageBaseModel
+{
+public:
+ DECLARE_DEFAULT_LEAF_XTOR( OImageButtonModel );
+
+// ::com::sun::star::lang::XServiceInfo
+ IMPLEMENTATION_NAME(OImageButtonModel);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw();
+
+// ::com::sun::star::io::XPersistObject
+ virtual ::rtl::OUString SAL_CALL getServiceName() throw ( ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ // OControlModel's property handling
+ virtual void describeFixedProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps
+ ) const;
+
+protected:
+ DECLARE_XCLONEABLE();
+};
+
+//==================================================================
+// OImageButtonControl
+//==================================================================
+typedef ::cppu::ImplHelper1< ::com::sun::star::awt::XMouseListener> OImageButtonControl_BASE;
+class OImageButtonControl : public OClickableImageBaseControl,
+ public OImageButtonControl_BASE
+{
+protected:
+ // UNO Anbindung
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();
+
+public:
+ OImageButtonControl(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);
+
+ // XServiceInfo
+ IMPLEMENTATION_NAME(OImageButtonControl);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw();
+
+ // UNO Anbindung
+ DECLARE_UNO3_AGG_DEFAULTS(OImageButtonControl, OClickableImageBaseControl);
+ virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation(const ::com::sun::star::uno::Type& _rType) throw(::com::sun::star::uno::RuntimeException);
+
+ // XEventListener
+ virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& _rSource) throw(::com::sun::star::uno::RuntimeException)
+ { OControl::disposing(_rSource); }
+
+ // XMouseListener
+ virtual void SAL_CALL mousePressed(const ::com::sun::star::awt::MouseEvent& e) throw ( ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL mouseReleased(const ::com::sun::star::awt::MouseEvent& e) throw ( ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL mouseEntered(const ::com::sun::star::awt::MouseEvent& e) throw ( ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL mouseExited(const ::com::sun::star::awt::MouseEvent& e) throw ( ::com::sun::star::uno::RuntimeException);
+
+ // prevent method hiding
+ using OClickableImageBaseControl::disposing;
+};
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+#endif // _FRM_IMAGE_BUTTON_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/ImageControl.cxx b/forms/source/component/ImageControl.cxx
new file mode 100644
index 000000000000..c05e9e3f2828
--- /dev/null
+++ b/forms/source/component/ImageControl.cxx
@@ -0,0 +1,1021 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+#include "ImageControl.hxx"
+
+#include "property.hrc"
+#include "frm_resource.hrc"
+#include "frm_resource.hxx"
+#include "services.hxx"
+#include "componenttools.hxx"
+
+#include <svtools/imageresourceaccess.hxx>
+#include <unotools/ucblockbytes.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <com/sun/star/awt/XPopupMenu.hpp>
+#include <com/sun/star/awt/PopupMenuDirection.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
+#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
+#include <com/sun/star/ui/dialogs/XFilePicker.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/awt/MouseButton.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/awt/XDialog.hpp>
+#include <com/sun/star/io/XActiveDataSink.hpp>
+#include <com/sun/star/io/NotConnectedException.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/graphic/GraphicObject.hpp>
+#include <tools/urlobj.hxx>
+#include <tools/stream.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <vcl/svapp.hxx>
+#include <unotools/streamhelper.hxx>
+#include <comphelper/extract.hxx>
+#include <comphelper/guarding.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <svl/urihelper.hxx>
+
+#include <memory>
+
+#define ID_OPEN_GRAPHICS 1
+#define ID_CLEAR_GRAPHICS 2
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+using namespace ::com::sun::star;
+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::ui::dialogs;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::graphic;
+using namespace ::com::sun::star::frame;
+
+//==============================================================================
+//= OImageControlModel
+//==============================================================================
+namespace
+{
+ enum ImageStoreType
+ {
+ ImageStoreBinary,
+ ImageStoreLink,
+
+ ImageStoreInvalid
+ };
+
+ ImageStoreType lcl_getImageStoreType( const sal_Int32 _nFieldType )
+ {
+ // binary/longvarchar types could be used to store images in binary representation
+ if ( ( _nFieldType == DataType::BINARY )
+ || ( _nFieldType == DataType::VARBINARY )
+ || ( _nFieldType == DataType::LONGVARBINARY )
+ || ( _nFieldType == DataType::OTHER )
+ || ( _nFieldType == DataType::OBJECT )
+ || ( _nFieldType == DataType::BLOB )
+ || ( _nFieldType == DataType::LONGVARCHAR )
+ || ( _nFieldType == DataType::CLOB )
+ )
+ return ImageStoreBinary;
+
+ // char types could be used to store links to images
+ if ( ( _nFieldType == DataType::CHAR )
+ || ( _nFieldType == DataType::VARCHAR )
+ )
+ return ImageStoreLink;
+
+ return ImageStoreInvalid;
+ }
+}
+
+//==============================================================================
+// OImageControlModel
+//==============================================================================
+
+//------------------------------------------------------------------------------
+InterfaceRef SAL_CALL OImageControlModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
+{
+ return *(new OImageControlModel(_rxFactory));
+}
+
+//------------------------------------------------------------------------------
+Sequence<Type> OImageControlModel::_getTypes()
+{
+ return concatSequences(
+ OBoundControlModel::_getTypes(),
+ OImageControlModel_Base::getTypes()
+ );
+}
+
+DBG_NAME(OImageControlModel)
+//------------------------------------------------------------------
+OImageControlModel::OImageControlModel(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OBoundControlModel( _rxFactory, VCL_CONTROLMODEL_IMAGECONTROL, FRM_SUN_CONTROL_IMAGECONTROL, sal_False, sal_False, sal_False )
+ // use the old control name for compytibility reasons
+ ,m_pImageProducer( NULL )
+ ,m_bExternalGraphic( true )
+ ,m_bReadOnly( sal_False )
+ ,m_sImageURL()
+ ,m_xGraphicObject()
+{
+ DBG_CTOR( OImageControlModel, NULL );
+ m_nClassId = FormComponentType::IMAGECONTROL;
+ initOwnValueProperty( PROPERTY_IMAGE_URL );
+
+ implConstruct();
+}
+
+//------------------------------------------------------------------
+OImageControlModel::OImageControlModel( const OImageControlModel* _pOriginal, const Reference< XMultiServiceFactory >& _rxFactory )
+ :OBoundControlModel( _pOriginal, _rxFactory )
+ // use the old control name for compytibility reasons
+ ,m_pImageProducer( NULL )
+ ,m_bExternalGraphic( true )
+ ,m_bReadOnly( _pOriginal->m_bReadOnly )
+ ,m_sImageURL( _pOriginal->m_sImageURL )
+ ,m_xGraphicObject( _pOriginal->m_xGraphicObject )
+{
+ DBG_CTOR( OImageControlModel, NULL );
+ implConstruct();
+
+ osl_incrementInterlockedCount( &m_refCount );
+ {
+ // simulate a propertyChanged event for the ImageURL
+ ::osl::MutexGuard aGuard( m_aMutex );
+ impl_handleNewImageURL_lck( eOther );
+ }
+ osl_decrementInterlockedCount( &m_refCount );
+}
+
+//------------------------------------------------------------------
+void OImageControlModel::implConstruct()
+{
+ m_pImageProducer = new ImageProducer;
+ m_xImageProducer = m_pImageProducer;
+ m_pImageProducer->SetDoneHdl( LINK( this, OImageControlModel, OnImageImportDone ) );
+}
+
+//------------------------------------------------------------------
+OImageControlModel::~OImageControlModel()
+{
+ if (!OComponentHelper::rBHelper.bDisposed)
+ {
+ acquire();
+ dispose();
+ }
+
+ DBG_DTOR(OImageControlModel,NULL);
+}
+
+// XCloneable
+//------------------------------------------------------------------------------
+IMPLEMENT_DEFAULT_CLONING( OImageControlModel )
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+StringSequence OImageControlModel::getSupportedServiceNames() throw()
+{
+ StringSequence aSupported = OBoundControlModel::getSupportedServiceNames();
+ aSupported.realloc(aSupported.getLength() + 1);
+
+ ::rtl::OUString*pArray = aSupported.getArray();
+ pArray[aSupported.getLength()-1] = FRM_SUN_COMPONENT_IMAGECONTROL;
+ return aSupported;
+}
+
+//------------------------------------------------------------------------------
+Any SAL_CALL OImageControlModel::queryAggregation(const Type& _rType) throw (RuntimeException)
+{
+ // oder matters: we want to "override" the XImageProducer interface of the aggreate with out
+ // own XImageProducer interface, thus we need to query OImageControlModel_Base first
+ Any aReturn = OImageControlModel_Base::queryInterface( _rType );
+
+ // BUT: _don't_ let it feel responsible for the XTypeProvider interface
+ // (as this is implemented by our base class in the proper way)
+ if ( _rType.equals( ::getCppuType( static_cast< Reference< XTypeProvider >* >( NULL ) ) )
+ || !aReturn.hasValue()
+ )
+ aReturn = OBoundControlModel::queryAggregation( _rType );
+
+ return aReturn;
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OImageControlModel::approveDbColumnType( sal_Int32 _nColumnType )
+{
+ return ImageStoreInvalid != lcl_getImageStoreType( _nColumnType );
+}
+
+//------------------------------------------------------------------------------
+void OImageControlModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle) const
+{
+ switch (nHandle)
+ {
+ case PROPERTY_ID_READONLY:
+ rValue <<= (sal_Bool)m_bReadOnly;
+ break;
+ case PROPERTY_ID_IMAGE_URL:
+ rValue <<= m_sImageURL;
+ break;
+ case PROPERTY_ID_GRAPHIC:
+ rValue <<= m_xGraphicObject.is() ? m_xGraphicObject->getGraphic() : Reference< XGraphic >();
+ break;
+ default:
+ OBoundControlModel::getFastPropertyValue(rValue, nHandle);
+ }
+}
+
+//------------------------------------------------------------------------------
+void OImageControlModel::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const Any& rValue) throw ( ::com::sun::star::uno::Exception)
+{
+ switch (nHandle)
+ {
+ case PROPERTY_ID_READONLY :
+ DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_BOOLEAN, "OImageControlModel::setFastPropertyValue_NoBroadcast : invalid type !" );
+ m_bReadOnly = getBOOL(rValue);
+ break;
+
+ case PROPERTY_ID_IMAGE_URL:
+ OSL_VERIFY( rValue >>= m_sImageURL );
+ impl_handleNewImageURL_lck( eOther );
+ {
+ ControlModelLock aLock( *this );
+ // that's a fake ... onValuePropertyChange expects to receive the only lock to our instance,
+ // but we're already called with our mutex locked ...
+ onValuePropertyChange( aLock );
+ }
+ break;
+
+ case PROPERTY_ID_GRAPHIC:
+ {
+ Reference< XGraphic > xGraphic;
+ OSL_VERIFY( rValue >>= xGraphic );
+ if ( !xGraphic.is() )
+ m_xGraphicObject.clear();
+ else
+ {
+ m_xGraphicObject = GraphicObject::create( m_aContext.getUNOContext() );
+ m_xGraphicObject->setGraphic( xGraphic );
+ }
+
+ if ( m_bExternalGraphic )
+ {
+ // if that's an external graphic, i.e. one which has not been loaded by ourselves in response to a
+ // new image URL, then also adjust our ImageURL.
+ ::rtl::OUString sNewImageURL;
+ if ( m_xGraphicObject.is() )
+ {
+ sNewImageURL = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.GraphicObject:" ) );
+ sNewImageURL = sNewImageURL + m_xGraphicObject->getUniqueID();
+ }
+ m_sImageURL = sNewImageURL;
+ // TODO: speaking strictly, this would need to be notified, since ImageURL is a bound property. However,
+ // this method here is called with a locked mutex, so we cannot simply call listeners ...
+ // I think the missing notification (and thus clients which potentially cannot observe the change)
+ // is less severe than the potential deadlock ...
+ }
+ }
+ break;
+
+ default:
+ OBoundControlModel::setFastPropertyValue_NoBroadcast(nHandle, rValue);
+ break;
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OImageControlModel::convertFastPropertyValue(Any& rConvertedValue, Any& rOldValue, sal_Int32 nHandle, const Any& rValue)
+ throw( IllegalArgumentException )
+{
+ switch (nHandle)
+ {
+ case PROPERTY_ID_READONLY :
+ return tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bReadOnly);
+
+ case PROPERTY_ID_IMAGE_URL:
+ return tryPropertyValue( rConvertedValue, rOldValue, rValue, m_sImageURL );
+
+ case PROPERTY_ID_GRAPHIC:
+ {
+ const Reference< XGraphic > xGraphic( getFastPropertyValue( PROPERTY_ID_GRAPHIC ), UNO_QUERY );
+ return tryPropertyValue( rConvertedValue, rOldValue, rValue, xGraphic );
+ }
+
+ default:
+ return OBoundControlModel::convertFastPropertyValue(rConvertedValue, rOldValue, nHandle, rValue);
+ }
+}
+
+//------------------------------------------------------------------------------
+void OImageControlModel::describeFixedProperties( Sequence< Property >& _rProps ) const
+{
+ BEGIN_DESCRIBE_PROPERTIES( 4, OBoundControlModel )
+ DECL_IFACE_PROP2( GRAPHIC, XGraphic, BOUND, TRANSIENT );
+ DECL_PROP1 ( IMAGE_URL, ::rtl::OUString, BOUND );
+ DECL_BOOL_PROP1 ( READONLY, BOUND );
+ DECL_PROP1 ( TABINDEX, sal_Int16, BOUND );
+ END_DESCRIBE_PROPERTIES();
+}
+
+//------------------------------------------------------------------------------
+void OImageControlModel::describeAggregateProperties( Sequence< Property >& /* [out] */ o_rAggregateProperties ) const
+{
+ OBoundControlModel::describeAggregateProperties( o_rAggregateProperties );
+ // remove ImageULR and Graphic properties, we "overload" them. This is because our aggregate synchronizes those
+ // two, but we have an own sychronization mechanism.
+ RemoveProperty( o_rAggregateProperties, PROPERTY_IMAGE_URL );
+ RemoveProperty( o_rAggregateProperties, PROPERTY_GRAPHIC );
+}
+
+//------------------------------------------------------------------------------
+::rtl::OUString OImageControlModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException)
+{
+ return FRM_COMPONENT_IMAGECONTROL; // old (non-sun) name for compatibility !
+}
+
+//------------------------------------------------------------------------------
+void OImageControlModel::write(const Reference<XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
+{
+ // Basisklasse
+ OBoundControlModel::write(_rxOutStream);
+ // Version
+ _rxOutStream->writeShort(0x0003);
+ // Name
+ _rxOutStream->writeBoolean(m_bReadOnly);
+ writeHelpTextCompatibly(_rxOutStream);
+ // from version 0x0003 : common properties
+ writeCommonProperties(_rxOutStream);
+}
+
+//------------------------------------------------------------------------------
+void OImageControlModel::read(const Reference<XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
+{
+ OBoundControlModel::read(_rxInStream);
+
+ // Version
+ sal_uInt16 nVersion = _rxInStream->readShort();
+ switch (nVersion)
+ {
+ case 0x0001:
+ m_bReadOnly = _rxInStream->readBoolean();
+ break;
+ case 0x0002:
+ m_bReadOnly = _rxInStream->readBoolean();
+ readHelpTextCompatibly(_rxInStream);
+ break;
+ case 0x0003:
+ m_bReadOnly = _rxInStream->readBoolean();
+ readHelpTextCompatibly(_rxInStream);
+ readCommonProperties(_rxInStream);
+ break;
+ default :
+ OSL_FAIL("OImageControlModel::read : unknown version !");
+ m_bReadOnly = sal_False;
+ defaultCommonProperties();
+ break;
+ }
+ // Nach dem Lesen die Defaultwerte anzeigen
+ if ( getControlSource().getLength() )
+ { // (not if we don't have a control source - the "State" property acts like it is persistent, then
+ ::osl::MutexGuard aGuard(m_aMutex); // resetNoBroadcast expects this mutex guarding
+ resetNoBroadcast();
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OImageControlModel::impl_updateStreamForURL_lck( const ::rtl::OUString& _rURL, ValueChangeInstigator _eInstigator )
+{
+ // create a stream for the image specified by the URL
+ ::std::auto_ptr< SvStream > pImageStream;
+ Reference< XInputStream > xImageStream;
+
+ if ( ::svt::GraphicAccess::isSupportedURL( _rURL ) )
+ {
+ xImageStream = ::svt::GraphicAccess::getImageXStream( getContext().getLegacyServiceFactory(), _rURL );
+ }
+ else
+ {
+ pImageStream.reset( ::utl::UcbStreamHelper::CreateStream( _rURL, STREAM_READ ) );
+ sal_Bool bSetNull = ( pImageStream.get() == NULL ) || ( ERRCODE_NONE != pImageStream->GetErrorCode() );
+
+ if ( !bSetNull )
+ {
+ // get the size of the stream
+ pImageStream->Seek(STREAM_SEEK_TO_END);
+ sal_Int32 nSize = (sal_Int32)pImageStream->Tell();
+ if (pImageStream->GetBufferSize() < 8192)
+ pImageStream->SetBufferSize(8192);
+ pImageStream->Seek(STREAM_SEEK_TO_BEGIN);
+
+ xImageStream = new ::utl::OInputStreamHelper( new SvLockBytes( pImageStream.get(), sal_False ), nSize );
+ }
+ }
+
+ if ( xImageStream.is() )
+ {
+ if ( m_xColumnUpdate.is() )
+ m_xColumnUpdate->updateBinaryStream( xImageStream, xImageStream->available() );
+ else
+ setControlValue( makeAny( xImageStream ), _eInstigator );
+ xImageStream->closeInput();
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OImageControlModel::impl_handleNewImageURL_lck( ValueChangeInstigator _eInstigator )
+{
+ switch ( lcl_getImageStoreType( getFieldType() ) )
+ {
+ case ImageStoreBinary:
+ if ( impl_updateStreamForURL_lck( m_sImageURL, _eInstigator ) )
+ return sal_True;
+ break;
+
+ case ImageStoreLink:
+ {
+ ::rtl::OUString sCommitURL( m_sImageURL );
+ if ( m_sDocumentURL.getLength() )
+ sCommitURL = URIHelper::simpleNormalizedMakeRelative( m_sDocumentURL, sCommitURL );
+ OSL_ENSURE( m_xColumnUpdate.is(), "OImageControlModel::impl_handleNewImageURL_lck: no bound field, but ImageStoreLink?!" );
+ if ( m_xColumnUpdate.is() )
+ {
+ m_xColumnUpdate->updateString( sCommitURL );
+ return sal_True;
+ }
+ }
+ break;
+
+ case ImageStoreInvalid:
+ OSL_FAIL( "OImageControlModel::impl_handleNewImageURL_lck: image storage type type!" );
+ break;
+ }
+
+ // if we're here, then the above code was unable to update our field/control from the given URL
+ // => fall back to NULL/VOID
+ if ( m_xColumnUpdate.is() )
+ m_xColumnUpdate->updateNull();
+ else
+ setControlValue( Any(), _eInstigator );
+
+ return sal_True;
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OImageControlModel::commitControlValueToDbColumn( bool _bPostReset )
+{
+ if ( _bPostReset )
+ {
+ // since this is a "commit after reset", we can simply update the column
+ // with null - this is our "default" which we were just reset to
+ if ( m_xColumnUpdate.is() )
+ m_xColumnUpdate->updateNull();
+ }
+ else
+ {
+ ::osl::MutexGuard aGuard(m_aMutex);
+ return impl_handleNewImageURL_lck( eDbColumnBinding );
+ }
+
+ return sal_True;
+}
+
+//------------------------------------------------------------------------------
+namespace
+{
+ bool lcl_isValidDocumentURL( const ::rtl::OUString& _rDocURL )
+ {
+ return ( _rDocURL.getLength() && !_rDocURL.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "private:object" ) ) );
+ }
+}
+
+//------------------------------------------------------------------------------
+void OImageControlModel::onConnectedDbColumn( const Reference< XInterface >& _rxForm )
+{
+ OBoundControlModel::onConnectedDbColumn( _rxForm );
+
+ try
+ {
+ Reference< XModel > xDocument( getXModel( *this ) );
+ if ( xDocument.is() )
+ {
+ m_sDocumentURL = xDocument->getURL();
+ if ( !lcl_isValidDocumentURL( m_sDocumentURL ) )
+ {
+ Reference< XChild > xAsChild( xDocument, UNO_QUERY );
+ while ( xAsChild.is() && !lcl_isValidDocumentURL( m_sDocumentURL ) )
+ {
+ xDocument.set( xAsChild->getParent(), UNO_QUERY );
+ if ( xDocument.is() )
+ m_sDocumentURL = xDocument->getURL();
+ xAsChild.set( xDocument, UNO_QUERY );
+ }
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+
+//------------------------------------------------------------------------------
+void OImageControlModel::onDisconnectedDbColumn()
+{
+ OBoundControlModel::onDisconnectedDbColumn();
+
+ m_sDocumentURL = ::rtl::OUString();
+}
+
+//------------------------------------------------------------------------------
+Any OImageControlModel::translateDbColumnToControlValue()
+{
+ switch ( lcl_getImageStoreType( getFieldType() ) )
+ {
+ case ImageStoreBinary:
+ {
+ Reference< XInputStream > xImageStream( m_xColumn->getBinaryStream() );
+ if ( m_xColumn->wasNull() )
+ xImageStream.clear();
+ return makeAny( xImageStream );
+ }
+ case ImageStoreLink:
+ {
+ ::rtl::OUString sImageLink( m_xColumn->getString() );
+ if ( m_sDocumentURL.getLength() )
+ sImageLink = INetURLObject::GetAbsURL( m_sDocumentURL, sImageLink );
+ return makeAny( sImageLink );
+ }
+ case ImageStoreInvalid:
+ OSL_FAIL( "OImageControlModel::translateDbColumnToControlValue: invalid field type!" );
+ break;
+ }
+ return Any();
+}
+
+//------------------------------------------------------------------------------
+Any OImageControlModel::getControlValue( ) const
+{
+ return makeAny( m_sImageURL );
+}
+
+//------------------------------------------------------------------------------
+void OImageControlModel::doSetControlValue( const Any& _rValue )
+{
+ DBG_ASSERT( GetImageProducer() && m_xImageProducer.is(), "OImageControlModel::doSetControlValue: no image producer!" );
+ if ( !GetImageProducer() || !m_xImageProducer.is() )
+ return;
+
+ bool bStartProduction = false;
+ switch ( lcl_getImageStoreType( getFieldType() ) )
+ {
+ case ImageStoreBinary:
+ {
+ // give the image producer the stream
+ Reference< XInputStream > xInStream;
+ _rValue >>= xInStream;
+ GetImageProducer()->setImage( xInStream );
+ bStartProduction = true;
+ }
+ break;
+
+ case ImageStoreLink:
+ {
+ ::rtl::OUString sImageURL;
+ _rValue >>= sImageURL;
+ GetImageProducer()->SetImage( sImageURL );
+ bStartProduction = true;
+ }
+ break;
+
+ case ImageStoreInvalid:
+ OSL_FAIL( "OImageControlModel::doSetControlValue: invalid field type!" );
+ break;
+
+ } // switch ( lcl_getImageStoreType( getFieldType() ) )
+
+ if ( bStartProduction )
+ {
+ // start production
+ Reference< XImageProducer > xProducer = m_xImageProducer;
+ {
+ // release our mutex once (it's acquired in the calling method!), as starting the image production may
+ // result in the locking of the solar mutex (unfortunally the default implementation of our aggregate,
+ // VCLXImageControl, does this locking)
+ MutexRelease aRelease(m_aMutex);
+ xProducer->startProduction();
+ }
+ }
+}
+
+// OComponentHelper
+//------------------------------------------------------------------
+void SAL_CALL OImageControlModel::disposing()
+{
+ OBoundControlModel::disposing();
+}
+
+//------------------------------------------------------------------------------
+void OImageControlModel::resetNoBroadcast()
+{
+ if ( hasField() ) // only reset when we are connected to a column
+ OBoundControlModel::resetNoBroadcast( );
+}
+
+//--------------------------------------------------------------------
+Reference< XImageProducer > SAL_CALL OImageControlModel::getImageProducer() throw ( RuntimeException)
+{
+ return this;
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL OImageControlModel::addConsumer( const Reference< XImageConsumer >& _rxConsumer ) throw (RuntimeException)
+{
+ GetImageProducer()->addConsumer( _rxConsumer );
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL OImageControlModel::removeConsumer( const Reference< XImageConsumer >& _rxConsumer ) throw (RuntimeException)
+{
+ GetImageProducer()->removeConsumer( _rxConsumer );
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL OImageControlModel::startProduction( ) throw (RuntimeException)
+{
+ GetImageProducer()->startProduction();
+}
+
+//------------------------------------------------------------------------------
+IMPL_LINK( OImageControlModel, OnImageImportDone, ::Graphic*, i_pGraphic )
+{
+ const Reference< XGraphic > xGraphic( i_pGraphic != NULL ? Image( i_pGraphic->GetBitmapEx() ).GetXGraphic() : NULL );
+ m_bExternalGraphic = false;
+ try
+ {
+ setPropertyValue( PROPERTY_GRAPHIC, makeAny( xGraphic ) );
+ }
+ catch ( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ m_bExternalGraphic = true;
+ return 1L;
+}
+
+//==================================================================
+// OImageControlControl
+//==================================================================
+
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL OImageControlControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
+{
+ return *(new OImageControlControl(_rxFactory));
+}
+
+//------------------------------------------------------------------------------
+Sequence<Type> OImageControlControl::_getTypes()
+{
+ return concatSequences(
+ OBoundControl::_getTypes(),
+ OImageControlControl_Base::getTypes()
+ );
+}
+
+//------------------------------------------------------------------------------
+OImageControlControl::OImageControlControl(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OBoundControl(_rxFactory, VCL_CONTROL_IMAGECONTROL)
+ ,m_aModifyListeners( m_aMutex )
+{
+ increment(m_refCount);
+ {
+ // als Focus- und MouseListener anmelden
+ Reference< XWindow > xComp;
+ query_aggregation( m_xAggregate, xComp );
+ if ( xComp.is() )
+ xComp->addMouseListener( this );
+ }
+ decrement(m_refCount);
+}
+
+//------------------------------------------------------------------------------
+Any SAL_CALL OImageControlControl::queryAggregation(const Type& _rType) throw (RuntimeException)
+{
+ Any aReturn = OBoundControl::queryAggregation( _rType );
+ if ( !aReturn.hasValue() )
+ aReturn = ::cppu::queryInterface(
+ _rType,
+ static_cast< XMouseListener* >( this ),
+ static_cast< XModifyBroadcaster* >( this )
+ );
+
+ return aReturn;
+}
+
+//------------------------------------------------------------------------------
+StringSequence OImageControlControl::getSupportedServiceNames() throw()
+{
+ StringSequence aSupported = OBoundControl::getSupportedServiceNames();
+ aSupported.realloc(aSupported.getLength() + 1);
+
+ ::rtl::OUString*pArray = aSupported.getArray();
+ pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_IMAGECONTROL;
+ return aSupported;
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OImageControlControl::addModifyListener( const Reference< XModifyListener >& _Listener ) throw (RuntimeException)
+{
+ m_aModifyListeners.addInterface( _Listener );
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OImageControlControl::removeModifyListener( const Reference< XModifyListener >& _Listener ) throw (RuntimeException)
+{
+ m_aModifyListeners.removeInterface( _Listener );
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OImageControlControl::disposing()
+{
+ EventObject aEvent( *this );
+ m_aModifyListeners.disposeAndClear( aEvent );
+
+ OBoundControl::disposing();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OImageControlControl::disposing( const EventObject& _Event ) throw(RuntimeException)
+{
+ OBoundControl::disposing( _Event );
+}
+
+//------------------------------------------------------------------------------
+void OImageControlControl::implClearGraphics( sal_Bool _bForce )
+{
+ Reference< XPropertySet > xSet( getModel(), UNO_QUERY );
+ if ( xSet.is() )
+ {
+ if ( _bForce )
+ {
+ ::rtl::OUString sOldImageURL;
+ xSet->getPropertyValue( PROPERTY_IMAGE_URL ) >>= sOldImageURL;
+
+ if ( !sOldImageURL.getLength() )
+ // the ImageURL is already empty, so simply setting a new empty one would not suffice
+ // (since it would be ignored)
+ xSet->setPropertyValue( PROPERTY_IMAGE_URL, makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:emptyImage" ) ) ) );
+ // (the concrete URL we're passing here doens't matter. It's important that
+ // the model cannot resolve it to a a valid resource describing an image stream
+ }
+
+ xSet->setPropertyValue( PROPERTY_IMAGE_URL, makeAny( ::rtl::OUString() ) );
+ }
+}
+
+//------------------------------------------------------------------------------
+bool OImageControlControl::implInsertGraphics()
+{
+ Reference< XPropertySet > xSet( getModel(), UNO_QUERY );
+ if ( !xSet.is() )
+ return false;
+
+ ::rtl::OUString sTitle = FRM_RES_STRING(RID_STR_IMPORT_GRAPHIC);
+ // build some arguments for the upcoming dialog
+ try
+ {
+ ::sfx2::FileDialogHelper aDialog( TemplateDescription::FILEOPEN_LINK_PREVIEW, SFXWB_GRAPHIC );
+ aDialog.SetTitle( sTitle );
+
+ Reference< XFilePickerControlAccess > xController( aDialog.GetFilePicker(), UNO_QUERY_THROW );
+ xController->setValue(ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0, ::cppu::bool2any(sal_True));
+
+ Reference<XPropertySet> xBoundField;
+ if ( hasProperty( PROPERTY_BOUNDFIELD, xSet ) )
+ xSet->getPropertyValue( PROPERTY_BOUNDFIELD ) >>= xBoundField;
+ sal_Bool bHasField = xBoundField.is();
+
+ // if the control is bound to a DB field, then it's not possible to decide whether or not to link
+ xController->enableControl(ExtendedFilePickerElementIds::CHECKBOX_LINK, !bHasField );
+
+ // if the control is bound to a DB field, then linking of the image depends on the type of the field
+ sal_Bool bImageIsLinked = sal_True;
+ if ( bHasField )
+ {
+ sal_Int32 nFieldType = DataType::OTHER;
+ OSL_VERIFY( xBoundField->getPropertyValue( PROPERTY_FIELDTYPE ) >>= nFieldType );
+ bImageIsLinked = ( lcl_getImageStoreType( nFieldType ) == ImageStoreLink );
+ }
+ xController->setValue(ExtendedFilePickerElementIds::CHECKBOX_LINK, 0, makeAny( bImageIsLinked ) );
+
+ if ( ERRCODE_NONE == aDialog.Execute() )
+ {
+ // reset the url property in case it already has the value we're about to set - in this case
+ // our propertyChanged would not get called without this.
+ implClearGraphics( sal_False );
+ sal_Bool bIsLink = sal_False;
+ xController->getValue(ExtendedFilePickerElementIds::CHECKBOX_LINK, 0) >>= bIsLink;
+ // Force bIsLink to be sal_True if we're bound to a field. Though we initialized the file picker with IsLink=TRUE
+ // in this case, and disabled the respective control, there might be picker implementations which do not
+ // respect this, and return IsLink=FALSE here. In this case, "normalize" the flag.
+ // #i112659#
+ bIsLink |= bHasField;
+ if ( !bIsLink )
+ {
+ Graphic aGraphic;
+ aDialog.GetGraphic( aGraphic );
+ xSet->setPropertyValue( PROPERTY_GRAPHIC, makeAny( aGraphic.GetXGraphic() ) );
+ }
+ else
+ xSet->setPropertyValue( PROPERTY_IMAGE_URL, makeAny( ::rtl::OUString( aDialog.GetPath() ) ) );
+
+ return true;
+ }
+ }
+ catch(Exception&)
+ {
+ OSL_FAIL("OImageControlControl::implInsertGraphics: caught an exception while attempting to execute the FilePicker!");
+ }
+ return false;
+}
+
+//------------------------------------------------------------------------------
+bool OImageControlControl::impl_isEmptyGraphics_nothrow() const
+{
+ bool bIsEmpty = true;
+
+ try
+ {
+ Reference< XPropertySet > xModelProps( const_cast< OImageControlControl* >( this )->getModel(), UNO_QUERY_THROW );
+ Reference< XGraphic > xGraphic;
+ OSL_VERIFY( xModelProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Graphic" ) ) ) >>= xGraphic );
+ bIsEmpty = !xGraphic.is();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ return bIsEmpty;
+}
+
+// MouseListener
+//------------------------------------------------------------------------------
+void OImageControlControl::mousePressed(const ::com::sun::star::awt::MouseEvent& e) throw ( ::com::sun::star::uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+
+ if (e.Buttons != MouseButton::LEFT)
+ return;
+
+ bool bModified = false;
+ // is this a request for a context menu?
+ if ( e.PopupTrigger )
+ {
+ Reference< XPopupMenu > xMenu( m_aContext.createComponent( "com.sun.star.awt.PopupMenu" ), UNO_QUERY );
+ DBG_ASSERT( xMenu.is(), "OImageControlControl::mousePressed: could not create a popup menu!" );
+
+ Reference< XWindowPeer > xWindowPeer = getPeer();
+ DBG_ASSERT( xWindowPeer.is(), "OImageControlControl::mousePressed: no window!" );
+
+ if ( xMenu.is() && xWindowPeer.is() )
+ {
+ xMenu->insertItem( ID_OPEN_GRAPHICS, FRM_RES_STRING( RID_STR_OPEN_GRAPHICS ), 0, 0 );
+ xMenu->insertItem( ID_CLEAR_GRAPHICS, FRM_RES_STRING( RID_STR_CLEAR_GRAPHICS ), 0, 1 );
+
+ // check if the ImageURL is empty
+ if ( impl_isEmptyGraphics_nothrow() )
+ xMenu->enableItem( ID_CLEAR_GRAPHICS, sal_False );
+
+ awt::Rectangle aRect( e.X, e.Y, 0, 0 );
+ if ( ( e.X < 0 ) || ( e.Y < 0 ) )
+ { // context menu triggered by keyboard
+ // position it in the center of the control
+ Reference< XWindow > xWindow( static_cast< ::cppu::OWeakObject* >( this ), UNO_QUERY );
+ OSL_ENSURE( xWindow.is(), "OImageControlControl::mousePressed: me not a window? How this?" );
+ if ( xWindow.is() )
+ {
+ awt::Rectangle aPosSize = xWindow->getPosSize();
+ aRect.X = aPosSize.Width / 2;
+ aRect.Y = aPosSize.Height / 2;
+ }
+ }
+
+ const sal_Int16 nResult = xMenu->execute( xWindowPeer, aRect, PopupMenuDirection::EXECUTE_DEFAULT );
+
+ switch ( nResult )
+ {
+ case ID_OPEN_GRAPHICS:
+ implInsertGraphics();
+ bModified = true;
+ break;
+
+ case ID_CLEAR_GRAPHICS:
+ implClearGraphics( sal_True );
+ bModified = true;
+ break;
+ }
+ }
+ }
+ else
+ {
+ //////////////////////////////////////////////////////////////////////
+ // Doppelclick
+ if (e.ClickCount == 2)
+ {
+
+ Reference<XPropertySet> xSet(getModel(), UNO_QUERY);
+ if (!xSet.is())
+ return;
+
+ // wenn Control nicht gebunden ist, kein Dialog (da die zu schickende URL hinterher sowieso
+ // versanden wuerde)
+ Reference<XPropertySet> xBoundField;
+ if (hasProperty(PROPERTY_BOUNDFIELD, xSet))
+ ::cppu::extractInterface(xBoundField, xSet->getPropertyValue(PROPERTY_BOUNDFIELD));
+ if (!xBoundField.is())
+ {
+ // but only if our IMAGE_URL property is handled as if it is transient, which is equivalent to
+ // an empty control source
+ if (!hasProperty(PROPERTY_CONTROLSOURCE, xSet) || (::comphelper::getString(xSet->getPropertyValue(PROPERTY_CONTROLSOURCE)).getLength() != 0))
+ return;
+ }
+
+ sal_Bool bReadOnly = false;
+ xSet->getPropertyValue(PROPERTY_READONLY) >>= bReadOnly;
+ if (bReadOnly)
+ return;
+
+ if ( implInsertGraphics() )
+ bModified = true;
+ }
+ }
+
+ if ( bModified )
+ {
+ EventObject aEvent( *this );
+ m_aModifyListeners.notifyEach( &XModifyListener::modified, aEvent );
+ }
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OImageControlControl::mouseReleased(const awt::MouseEvent& /*e*/) throw ( RuntimeException )
+{
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OImageControlControl::mouseEntered(const awt::MouseEvent& /*e*/) throw ( RuntimeException )
+{
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OImageControlControl::mouseExited(const awt::MouseEvent& /*e*/) throw ( RuntimeException )
+{
+}
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/ImageControl.hxx b/forms/source/component/ImageControl.hxx
new file mode 100644
index 000000000000..65c3f0dc872e
--- /dev/null
+++ b/forms/source/component/ImageControl.hxx
@@ -0,0 +1,212 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FRM_IMAGE_CONTROL_HXX_
+#define _FRM_IMAGE_CONTROL_HXX_
+
+#include "FormComponent.hxx"
+#include "imgprod.hxx"
+#include <com/sun/star/form/XImageProducerSupplier.hpp>
+#include <com/sun/star/awt/XMouseListener.hpp>
+#include <com/sun/star/util/XModifyBroadcaster.hpp>
+#include <com/sun/star/graphic/XGraphicObject.hpp>
+#include <comphelper/propmultiplex.hxx>
+#include <comphelper/implementationreference.hxx>
+#include <cppuhelper/implbase2.hxx>
+
+using namespace comphelper;
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+//==================================================================
+// OImageControlModel
+//==================================================================
+typedef ::cppu::ImplHelper2 < ::com::sun::star::form::XImageProducerSupplier
+ , ::com::sun::star::awt::XImageProducer
+ > OImageControlModel_Base;
+
+class OImageControlModel
+ :public OImageControlModel_Base
+ ,public OBoundControlModel
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageProducer> m_xImageProducer;
+ ImageProducer* m_pImageProducer;
+ bool m_bExternalGraphic;
+ sal_Bool m_bReadOnly;
+ ::rtl::OUString m_sImageURL;
+ ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphicObject >
+ m_xGraphicObject;
+ ::rtl::OUString m_sDocumentURL;
+
+protected:
+ // UNO Anbindung
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();
+
+ inline ImageProducer* GetImageProducer() { return m_pImageProducer; }
+
+public:
+ DECLARE_DEFAULT_LEAF_XTOR( OImageControlModel );
+
+ virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle ) const;
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue) throw ( ::com::sun::star::uno::Exception);
+
+ virtual sal_Bool SAL_CALL convertFastPropertyValue(::com::sun::star::uno::Any& rConvertedValue, ::com::sun::star::uno::Any& rOldValue, sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
+ throw(::com::sun::star::lang::IllegalArgumentException);
+
+ // UNO Anbindung
+ DECLARE_UNO3_AGG_DEFAULTS(OImageControlModel, OBoundControlModel);
+ virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation(const ::com::sun::star::uno::Type& _rType) throw(::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ IMPLEMENTATION_NAME(OImageControlModel);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw();
+
+ // OComponentHelper
+ virtual void SAL_CALL disposing();
+
+ // XPersistObject
+ virtual ::rtl::OUString SAL_CALL getServiceName() throw ( ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ // XImageProducerSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageProducer> SAL_CALL getImageProducer() throw ( ::com::sun::star::uno::RuntimeException);
+
+ // XImageProducer
+ virtual void SAL_CALL addConsumer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer >& xConsumer ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeConsumer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer >& xConsumer ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL startProduction( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // OControlModel's property handling
+ virtual void describeAggregateProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rAggregateProps
+ ) const;
+ virtual void describeFixedProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps
+ ) const;
+
+ // prevent method hiding
+ using OBoundControlModel::disposing;
+ using OBoundControlModel::getFastPropertyValue;
+
+protected:
+ // OBoundControlModel overridables
+ virtual void onConnectedDbColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxForm );
+ virtual void onDisconnectedDbColumn();
+ virtual ::com::sun::star::uno::Any
+ translateDbColumnToControlValue( );
+ virtual sal_Bool commitControlValueToDbColumn( bool _bPostReset );
+
+ virtual ::com::sun::star::uno::Any
+ getControlValue( ) const;
+ virtual void doSetControlValue( const ::com::sun::star::uno::Any& _rValue );
+
+ virtual sal_Bool approveDbColumnType(sal_Int32 _nColumnType);
+
+ virtual void resetNoBroadcast();
+
+protected:
+ DECLARE_XCLONEABLE();
+
+ void implConstruct();
+
+ /** displays the image described by the given URL
+ @precond
+ our own mutex is locked
+ */
+ sal_Bool impl_handleNewImageURL_lck( ValueChangeInstigator _eInstigator );
+
+ /** updates the binary stream, created from loading the file which the given URL points to, into our
+ bound field, or the control itself if there is no bound field
+ */
+ sal_Bool impl_updateStreamForURL_lck( const ::rtl::OUString& _rURL, ValueChangeInstigator _eInstigator );
+
+ DECL_LINK( OnImageImportDone, ::Graphic* );
+};
+
+//==================================================================
+//= OImageControlControl
+//==================================================================
+typedef ::cppu::ImplHelper2 < ::com::sun::star::awt::XMouseListener
+ , ::com::sun::star::util::XModifyBroadcaster
+ > OImageControlControl_Base;
+class OImageControlControl : public OBoundControl
+ , public OImageControlControl_Base
+{
+private:
+ ::cppu::OInterfaceContainerHelper m_aModifyListeners;
+
+ // XTypeProvider
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();
+
+public:
+ OImageControlControl(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);
+
+ // UNO
+ DECLARE_UNO3_AGG_DEFAULTS( OImageControlControl, OBoundControl );
+ virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw(::com::sun::star::uno::RuntimeException);
+
+ // XEventListener
+ virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& _rSource) throw(::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ IMPLEMENTATION_NAME(OImageControlControl);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw();
+
+ // XMouseListener
+ virtual void SAL_CALL mousePressed(const ::com::sun::star::awt::MouseEvent& e) throw ( ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL mouseReleased(const ::com::sun::star::awt::MouseEvent& e) throw ( ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL mouseEntered(const ::com::sun::star::awt::MouseEvent& e) throw ( ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL mouseExited(const ::com::sun::star::awt::MouseEvent& e) throw ( ::com::sun::star::uno::RuntimeException);
+
+ // XModifyBroadcaster
+ virtual void SAL_CALL addModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // OComponentHelper
+ virtual void SAL_CALL disposing();
+
+private:
+ void implClearGraphics( sal_Bool _bForce );
+ bool implInsertGraphics();
+
+ /** determines whether the control does currently have an empty grahic set
+ */
+ bool impl_isEmptyGraphics_nothrow() const;
+};
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+#endif // _FRM_IMAGE_CONTROL_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/ListBox.cxx b/forms/source/component/ListBox.cxx
new file mode 100644
index 000000000000..a54377c73f27
--- /dev/null
+++ b/forms/source/component/ListBox.cxx
@@ -0,0 +1,1862 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+
+#include "ListBox.hxx"
+#include "property.hxx"
+#include "property.hrc"
+#include "services.hxx"
+#include "frm_resource.hxx"
+#include "frm_resource.hrc"
+#include "BaseListBox.hxx"
+#include "listenercontainers.hxx"
+#include "componenttools.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#include <com/sun/star/sdbc/XRowSet.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/sdb/XSQLQueryComposerFactory.hpp>
+#include <com/sun/star/sdb/XQueriesSupplier.hpp>
+#include <com/sun/star/util/NumberFormat.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/sdb/CommandType.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/basicio.hxx>
+#include <comphelper/container.hxx>
+#include <comphelper/numbers.hxx>
+#include <comphelper/listenernotification.hxx>
+#include <connectivity/dbtools.hxx>
+#include <connectivity/formattedcolumnvalue.hxx>
+#include <connectivity/dbconversion.hxx>
+#include <cppuhelper/queryinterface.hxx>
+#include <rtl/logfile.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <unotools/sharedunocomponent.hxx>
+#include <vcl/svapp.hxx>
+
+#include <boost/optional.hpp>
+
+#include <algorithm>
+#include <functional>
+
+
+//.........................................................................
+namespace frm
+{
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::sdb;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::sdbcx;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::container;
+ using namespace ::com::sun::star::form;
+ using namespace ::com::sun::star::awt;
+ using namespace ::com::sun::star::io;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::util;
+ using namespace ::com::sun::star::form::binding;
+ using namespace ::dbtools;
+
+ using ::connectivity::ORowSetValue;
+
+ //==============================================================================
+ //= helper
+ //==============================================================================
+ namespace
+ {
+ //--------------------------------------------------------------------------
+ struct RowSetValueToString : public ::std::unary_function< ORowSetValue, ::rtl::OUString >
+ {
+ ::rtl::OUString operator()( const ORowSetValue& _value ) const
+ {
+ return _value.getString();
+ }
+ };
+
+ //--------------------------------------------------------------------------
+ struct AppendRowSetValueString : public ::std::unary_function< ::rtl::OUString, void >
+ {
+ AppendRowSetValueString( ::rtl::OUString& _string )
+ :m_string( _string )
+ {
+ }
+
+ void operator()( const ::rtl::OUString _append )
+ {
+ m_string += _append;
+ }
+
+ private:
+ ::rtl::OUString& m_string;
+ };
+
+ //--------------------------------------------------------------------------
+ Sequence< ::rtl::OUString > lcl_convertToStringSequence( const ValueList& _values )
+ {
+ Sequence< ::rtl::OUString > aStrings( _values.size() );
+ ::std::transform(
+ _values.begin(),
+ _values.end(),
+ aStrings.getArray(),
+ RowSetValueToString()
+ );
+ return aStrings;
+ }
+ }
+
+ //==============================================================================
+ //= ItemEventDescription
+ //==============================================================================
+ typedef ::comphelper::EventHolder< ItemEvent > ItemEventDescription;
+
+ //==============================================================================
+ //= OListBoxModel
+ //==============================================================================
+ //------------------------------------------------------------------
+ InterfaceRef SAL_CALL OListBoxModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory) throw (RuntimeException)
+ {
+ return *(new OListBoxModel(_rxFactory));
+ }
+
+ //------------------------------------------------------------------------------
+ Sequence< Type> OListBoxModel::_getTypes()
+ {
+ return TypeBag(
+ OBoundControlModel::_getTypes(),
+ OEntryListHelper::getTypes(),
+ OErrorBroadcaster::getTypes()
+ ).getTypes();
+ }
+
+
+ DBG_NAME(OListBoxModel);
+ //------------------------------------------------------------------
+ OListBoxModel::OListBoxModel(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OBoundControlModel( _rxFactory, VCL_CONTROLMODEL_LISTBOX, FRM_SUN_CONTROL_LISTBOX, sal_True, sal_True, sal_True )
+ // use the old control name for compytibility reasons
+ ,OEntryListHelper( (OControlModel&)*this )
+ ,OErrorBroadcaster( OComponentHelper::rBHelper )
+ ,m_aListRowSet( getContext() )
+ ,m_nNULLPos(-1)
+ ,m_nBoundColumnType( DataType::SQLNULL )
+ {
+ DBG_CTOR(OListBoxModel,NULL);
+
+ m_nClassId = FormComponentType::LISTBOX;
+ m_eListSourceType = ListSourceType_VALUELIST;
+ m_aBoundColumn <<= (sal_Int16)1;
+ initValueProperty( PROPERTY_SELECT_SEQ, PROPERTY_ID_SELECT_SEQ);
+
+ startAggregatePropertyListening( PROPERTY_STRINGITEMLIST );
+ }
+
+ //------------------------------------------------------------------
+ OListBoxModel::OListBoxModel( const OListBoxModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
+ :OBoundControlModel( _pOriginal, _rxFactory )
+ ,OEntryListHelper( *_pOriginal, (OControlModel&)*this )
+ ,OErrorBroadcaster( OComponentHelper::rBHelper )
+ ,m_aListRowSet( getContext() )
+ ,m_eListSourceType( _pOriginal->m_eListSourceType )
+ ,m_aBoundColumn( _pOriginal->m_aBoundColumn )
+ ,m_aListSourceValues( _pOriginal->m_aListSourceValues )
+ ,m_aBoundValues( _pOriginal->m_aBoundValues )
+ ,m_aDefaultSelectSeq( _pOriginal->m_aDefaultSelectSeq )
+ ,m_nNULLPos(-1)
+ ,m_nBoundColumnType( DataType::SQLNULL )
+ {
+ DBG_CTOR(OListBoxModel,NULL);
+
+ startAggregatePropertyListening( PROPERTY_STRINGITEMLIST );
+ }
+
+ //------------------------------------------------------------------
+ OListBoxModel::~OListBoxModel()
+ {
+ if (!OComponentHelper::rBHelper.bDisposed)
+ {
+ acquire();
+ dispose();
+ }
+
+ DBG_DTOR(OListBoxModel,NULL);
+ }
+
+ // XCloneable
+ //------------------------------------------------------------------------------
+ IMPLEMENT_DEFAULT_CLONING( OListBoxModel )
+
+ // XServiceInfo
+ //------------------------------------------------------------------------------
+ StringSequence SAL_CALL OListBoxModel::getSupportedServiceNames() throw(RuntimeException)
+ {
+ StringSequence aSupported = OBoundControlModel::getSupportedServiceNames();
+
+ sal_Int32 nOldLen = aSupported.getLength();
+ aSupported.realloc( nOldLen + 8 );
+ ::rtl::OUString* pStoreTo = aSupported.getArray() + nOldLen;
+
+ *pStoreTo++ = BINDABLE_CONTROL_MODEL;
+ *pStoreTo++ = DATA_AWARE_CONTROL_MODEL;
+ *pStoreTo++ = VALIDATABLE_CONTROL_MODEL;
+
+ *pStoreTo++ = BINDABLE_DATA_AWARE_CONTROL_MODEL;
+ *pStoreTo++ = VALIDATABLE_BINDABLE_CONTROL_MODEL;
+
+ *pStoreTo++ = FRM_SUN_COMPONENT_LISTBOX;
+ *pStoreTo++ = FRM_SUN_COMPONENT_DATABASE_LISTBOX;
+ *pStoreTo++ = BINDABLE_DATABASE_LIST_BOX;
+
+ return aSupported;
+ }
+
+ //------------------------------------------------------------------------------
+ Any SAL_CALL OListBoxModel::queryAggregation(const Type& _rType) throw (RuntimeException)
+ {
+ Any aReturn = OBoundControlModel::queryAggregation( _rType );
+ if ( !aReturn.hasValue() )
+ aReturn = OEntryListHelper::queryInterface( _rType );
+ if ( !aReturn.hasValue() )
+ aReturn = OErrorBroadcaster::queryInterface( _rType );
+ return aReturn;
+ }
+
+ // OComponentHelper
+ //------------------------------------------------------------------------------
+ void OListBoxModel::disposing()
+ {
+ OBoundControlModel::disposing();
+ OEntryListHelper::disposing();
+ OErrorBroadcaster::disposing();
+ }
+
+ //------------------------------------------------------------------------------
+ void OListBoxModel::getFastPropertyValue(Any& _rValue, sal_Int32 _nHandle) const
+ {
+ switch (_nHandle)
+ {
+ case PROPERTY_ID_BOUNDCOLUMN:
+ _rValue <<= m_aBoundColumn;
+ break;
+
+ case PROPERTY_ID_LISTSOURCETYPE:
+ _rValue <<= m_eListSourceType;
+ break;
+
+ case PROPERTY_ID_LISTSOURCE:
+ _rValue <<= lcl_convertToStringSequence( m_aListSourceValues );
+ break;
+
+ case PROPERTY_ID_VALUE_SEQ:
+ _rValue <<= lcl_convertToStringSequence( m_aBoundValues );
+ break;
+
+ case PROPERTY_ID_DEFAULT_SELECT_SEQ:
+ _rValue <<= m_aDefaultSelectSeq;
+ break;
+
+ case PROPERTY_ID_STRINGITEMLIST:
+ _rValue <<= getStringItemList();
+ break;
+
+ default:
+ OBoundControlModel::getFastPropertyValue(_rValue, _nHandle);
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ void OListBoxModel::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle, const Any& _rValue) throw (com::sun::star::uno::Exception)
+ {
+ switch (_nHandle)
+ {
+ case PROPERTY_ID_BOUNDCOLUMN :
+ DBG_ASSERT((_rValue.getValueType().getTypeClass() == TypeClass_SHORT) || (_rValue.getValueType().getTypeClass() == TypeClass_VOID),
+ "OListBoxModel::setFastPropertyValue_NoBroadcast : invalid type !" );
+ m_aBoundColumn = _rValue;
+ break;
+
+ case PROPERTY_ID_LISTSOURCETYPE :
+ DBG_ASSERT(_rValue.getValueType().equals(::getCppuType(reinterpret_cast<ListSourceType*>(NULL))),
+ "OComboBoxModel::setFastPropertyValue_NoBroadcast : invalid type !" );
+ _rValue >>= m_eListSourceType;
+ break;
+
+ case PROPERTY_ID_LISTSOURCE:
+ {
+ // extract
+ Sequence< ::rtl::OUString > aListSource;
+ OSL_VERIFY( _rValue >>= aListSource );
+
+ // copy to member
+ ValueList().swap(m_aListSourceValues);
+ ::std::copy(
+ aListSource.getConstArray(),
+ aListSource.getConstArray() + aListSource.getLength(),
+ ::std::insert_iterator< ValueList >( m_aListSourceValues, m_aListSourceValues.end() )
+ );
+
+ // propagate
+ if ( m_eListSourceType == ListSourceType_VALUELIST )
+ {
+ m_aBoundValues = m_aListSourceValues;
+ }
+ else
+ {
+ if ( m_xCursor.is() && !hasField() && !hasExternalListSource() )
+ // listbox is already connected to a database, and no external list source
+ // data source changed -> refresh
+ loadData( false );
+ }
+ }
+ break;
+
+ case PROPERTY_ID_VALUE_SEQ :
+ OSL_FAIL( "ValueItemList is read-only!" );
+ throw PropertyVetoException();
+
+ case PROPERTY_ID_DEFAULT_SELECT_SEQ :
+ DBG_ASSERT(_rValue.getValueType().equals(::getCppuType(reinterpret_cast< Sequence<sal_Int16>*>(NULL))),
+ "OListBoxModel::setFastPropertyValue_NoBroadcast : invalid type !" );
+ _rValue >>= m_aDefaultSelectSeq;
+
+ DBG_ASSERT(m_xAggregateFastSet.is(), "OListBoxModel::setFastPropertyValue_NoBroadcast(DEFAULT_SELECT_SEQ) : invalid aggregate !");
+ if ( m_xAggregateFastSet.is() )
+ setControlValue( _rValue, eOther );
+ break;
+
+ case PROPERTY_ID_STRINGITEMLIST:
+ {
+ ControlModelLock aLock( *this );
+ setNewStringItemList( _rValue, aLock );
+ // TODO: this is bogus. setNewStringItemList expects a guard which has the *only*
+ // lock to the mutex, but setFastPropertyValue_NoBroadcast is already called with
+ // a lock - so we effectively has two locks here, of which setNewStringItemList can
+ // only control one.
+ }
+ resetNoBroadcast();
+ break;
+
+ default:
+ OBoundControlModel::setFastPropertyValue_NoBroadcast(_nHandle, _rValue);
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ sal_Bool OListBoxModel::convertFastPropertyValue(
+ Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue)
+ throw (IllegalArgumentException)
+ {
+ sal_Bool bModified(sal_False);
+ switch (_nHandle)
+ {
+ case PROPERTY_ID_BOUNDCOLUMN :
+ bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_aBoundColumn, ::getCppuType(reinterpret_cast<sal_Int16*>(NULL)));
+ break;
+
+ case PROPERTY_ID_LISTSOURCETYPE:
+ bModified = tryPropertyValueEnum(_rConvertedValue, _rOldValue, _rValue, m_eListSourceType);
+ break;
+
+ case PROPERTY_ID_LISTSOURCE:
+ bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, lcl_convertToStringSequence( m_aListSourceValues ) );
+ break;
+
+ case PROPERTY_ID_VALUE_SEQ :
+ OSL_FAIL( "ValueItemList is read-only!" );
+ throw PropertyVetoException();
+
+ case PROPERTY_ID_DEFAULT_SELECT_SEQ :
+ bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_aDefaultSelectSeq);
+ break;
+
+ case PROPERTY_ID_STRINGITEMLIST:
+ bModified = convertNewListSourceProperty( _rConvertedValue, _rOldValue, _rValue );
+ break;
+
+ default:
+ return OBoundControlModel::convertFastPropertyValue(_rConvertedValue, _rOldValue, _nHandle, _rValue);
+ }
+ return bModified;
+ }
+
+ //------------------------------------------------------------------------------
+ void SAL_CALL OListBoxModel::setPropertyValues( const Sequence< ::rtl::OUString >& _rPropertyNames, const Sequence< Any >& _rValues ) throw(PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
+ {
+ // if both SelectedItems and StringItemList are set, care for this
+ // #i27024#
+ const Any* pSelectSequenceValue = NULL;
+
+ const ::rtl::OUString* pStartPos = _rPropertyNames.getConstArray();
+ const ::rtl::OUString* pEndPos = _rPropertyNames.getConstArray() + _rPropertyNames.getLength();
+ const ::rtl::OUString* pSelectedItemsPos = ::std::find_if(
+ pStartPos, pEndPos,
+ ::std::bind2nd( ::std::equal_to< ::rtl::OUString >(), PROPERTY_SELECT_SEQ )
+ );
+ const ::rtl::OUString* pStringItemListPos = ::std::find_if(
+ pStartPos, pEndPos,
+ ::std::bind2nd( ::std::equal_to< ::rtl::OUString >(), PROPERTY_STRINGITEMLIST )
+ );
+ if ( ( pSelectedItemsPos != pEndPos ) && ( pStringItemListPos != pEndPos ) )
+ {
+ // both properties are present
+ // -> remember the value for the select sequence
+ pSelectSequenceValue = _rValues.getConstArray() + ( pSelectedItemsPos - pStartPos );
+ }
+
+ OBoundControlModel::setPropertyValues( _rPropertyNames, _rValues );
+
+ if ( pSelectSequenceValue )
+ {
+ setPropertyValue( PROPERTY_SELECT_SEQ, *pSelectSequenceValue );
+ // Note that this is the only reliable way, since one of the properties is implemented
+ // by ourself, and one is implemented by the aggregate, we cannot rely on any particular
+ // results when setting them both - too many undocumented behavior in all the involved
+ // classes
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ void OListBoxModel::describeFixedProperties( Sequence< Property >& _rProps ) const
+ {
+ BEGIN_DESCRIBE_PROPERTIES( 7, OBoundControlModel )
+ DECL_PROP1(TABINDEX, sal_Int16, BOUND);
+ DECL_PROP2(BOUNDCOLUMN, sal_Int16, BOUND, MAYBEVOID);
+ DECL_PROP1(LISTSOURCETYPE, ListSourceType, BOUND);
+ DECL_PROP1(LISTSOURCE, StringSequence, BOUND);
+ DECL_PROP3(VALUE_SEQ, StringSequence, BOUND, READONLY, TRANSIENT);
+ DECL_PROP1(DEFAULT_SELECT_SEQ, Sequence<sal_Int16>, BOUND);
+ DECL_PROP1(STRINGITEMLIST, Sequence< ::rtl::OUString >, BOUND);
+ END_DESCRIBE_PROPERTIES();
+ }
+
+ //------------------------------------------------------------------------------
+ void OListBoxModel::_propertyChanged( const PropertyChangeEvent& i_rEvent ) throw ( RuntimeException )
+ {
+ if ( i_rEvent.PropertyName == PROPERTY_STRINGITEMLIST )
+ {
+ ControlModelLock aLock( *this );
+ // SYNCHRONIZED ----->
+ // our aggregate internally changed its StringItemList property - reflect this in our "overridden"
+ // version of the property
+ setNewStringItemList( i_rEvent.NewValue, aLock );
+ // <----- SYNCHRONIZED
+ return;
+ }
+ OBoundControlModel::_propertyChanged( i_rEvent );
+ }
+
+ //------------------------------------------------------------------------------
+ void OListBoxModel::describeAggregateProperties( Sequence< Property >& _rAggregateProps ) const
+ {
+ OBoundControlModel::describeAggregateProperties( _rAggregateProps );
+
+ // superseded properties:
+ RemoveProperty( _rAggregateProps, PROPERTY_STRINGITEMLIST );
+ }
+
+ //------------------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL OListBoxModel::getServiceName() throw(RuntimeException)
+ {
+ return FRM_COMPONENT_LISTBOX; // old (non-sun) name for compatibility !
+ }
+
+ //------------------------------------------------------------------------------
+ void SAL_CALL OListBoxModel::write(const Reference<XObjectOutputStream>& _rxOutStream)
+ throw(IOException, RuntimeException)
+ {
+ OBoundControlModel::write(_rxOutStream);
+
+ // Dummy-Seq, um Kompatible zu bleiben, wenn SelectSeq nicht mehr gespeichert wird
+ Sequence<sal_Int16> aDummySeq;
+
+ // Version
+ // Version 0x0002: ListSource wird StringSeq
+ _rxOutStream->writeShort(0x0004);
+
+ // Maskierung fuer any
+ sal_uInt16 nAnyMask = 0;
+ if (m_aBoundColumn.getValueType().getTypeClass() != TypeClass_VOID)
+ nAnyMask |= BOUNDCOLUMN;
+
+ _rxOutStream << nAnyMask;
+
+ _rxOutStream << lcl_convertToStringSequence( m_aListSourceValues );
+ _rxOutStream << (sal_Int16)m_eListSourceType;
+ _rxOutStream << aDummySeq;
+ _rxOutStream << m_aDefaultSelectSeq;
+
+ if ((nAnyMask & BOUNDCOLUMN) == BOUNDCOLUMN)
+ {
+ sal_Int16 nBoundColumn = 0;
+ m_aBoundColumn >>= nBoundColumn;
+ _rxOutStream << nBoundColumn;
+ }
+ writeHelpTextCompatibly(_rxOutStream);
+
+ // from version 0x0004 : common properties
+ writeCommonProperties(_rxOutStream);
+ }
+
+ //------------------------------------------------------------------------------
+ void SAL_CALL OListBoxModel::read(const Reference<XObjectInputStream>& _rxInStream) throw(IOException, RuntimeException)
+ {
+ // Bei manchen Variblen muessen Abhaengigkeiten beruecksichtigt werden.
+ // Deshalb muessen sie explizit ueber setPropertyValue() gesetzt werden.
+
+ OBoundControlModel::read(_rxInStream);
+ ControlModelLock aLock( *this );
+
+ // since we are "overwriting" the StringItemList of our aggregate (means we have
+ // an own place to store the value, instead of relying on our aggregate storing it),
+ // we need to respect what the aggregate just read for the StringItemList property.
+ try
+ {
+ if ( m_xAggregateSet.is() )
+ setNewStringItemList( m_xAggregateSet->getPropertyValue( PROPERTY_STRINGITEMLIST ), aLock );
+ }
+ catch( const Exception& )
+ {
+ OSL_FAIL( "OComboBoxModel::read: caught an exception while examining the aggregate's string item list!" );
+ }
+
+ // Version
+ sal_uInt16 nVersion = _rxInStream->readShort();
+ DBG_ASSERT(nVersion > 0, "OListBoxModel::read : version 0 ? this should never have been written !");
+
+ if (nVersion > 0x0004)
+ {
+ OSL_FAIL("OListBoxModel::read : invalid (means unknown) version !");
+ ValueList().swap(m_aListSourceValues);
+ m_aBoundColumn <<= (sal_Int16)0;
+ ValueList().swap(m_aBoundValues);
+ m_eListSourceType = ListSourceType_VALUELIST;
+ m_aDefaultSelectSeq.realloc(0);
+ defaultCommonProperties();
+ return;
+ }
+
+ // Maskierung fuer any
+ sal_uInt16 nAnyMask;
+ _rxInStream >> nAnyMask;
+
+ // ListSourceSeq
+ StringSequence aListSourceSeq;
+ if (nVersion == 0x0001)
+ {
+ // ListSourceSeq aus String zusammenstellen;
+ ::rtl::OUString sListSource;
+ _rxInStream >> sListSource;
+
+ sal_Int32 nTokens = 1;
+ const sal_Unicode* pStr = sListSource.getStr();
+ while ( *pStr )
+ {
+ if ( *pStr == ';' )
+ nTokens++;
+ pStr++;
+ }
+ aListSourceSeq.realloc( nTokens );
+ for (sal_uInt16 i=0; i<nTokens; ++i)
+ {
+ sal_Int32 nTmp = 0;
+ aListSourceSeq.getArray()[i] = sListSource.getToken(i,';',nTmp);
+ }
+ }
+ else
+ _rxInStream >> aListSourceSeq;
+
+ sal_Int16 nListSourceType;
+ _rxInStream >> nListSourceType;
+ m_eListSourceType = (ListSourceType)nListSourceType;
+ Any aListSourceSeqAny;
+ aListSourceSeqAny <<= aListSourceSeq;
+
+ setFastPropertyValue(PROPERTY_ID_LISTSOURCE, aListSourceSeqAny );
+
+ // Dummy-Seq, um Kompatible zu bleiben, wenn SelectSeq nicht mehr gespeichert wird
+ Sequence<sal_Int16> aDummySeq;
+ _rxInStream >> aDummySeq;
+
+ // DefaultSelectSeq
+ Sequence<sal_Int16> aDefaultSelectSeq;
+ _rxInStream >> aDefaultSelectSeq;
+ Any aDefaultSelectSeqAny;
+ aDefaultSelectSeqAny <<= aDefaultSelectSeq;
+ setFastPropertyValue(PROPERTY_ID_DEFAULT_SELECT_SEQ, aDefaultSelectSeqAny);
+
+ // BoundColumn
+ if ((nAnyMask & BOUNDCOLUMN) == BOUNDCOLUMN)
+ {
+ sal_Int16 nValue;
+ _rxInStream >> nValue;
+ m_aBoundColumn <<= nValue;
+ }
+
+ if (nVersion > 2)
+ readHelpTextCompatibly(_rxInStream);
+
+ // if our string list is not filled from the value list, we must empty it
+ // this can be the case when somebody saves in alive mode
+ if ( ( m_eListSourceType != ListSourceType_VALUELIST )
+ && !hasExternalListSource()
+ )
+ {
+ setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, makeAny( StringSequence() ) );
+ }
+
+ if (nVersion > 3)
+ readCommonProperties(_rxInStream);
+
+ // Nach dem Lesen die Defaultwerte anzeigen
+ if ( getControlSource().getLength() )
+ // (not if we don't have a control source - the "State" property acts like it is persistent, then
+ resetNoBroadcast();
+ }
+
+ //------------------------------------------------------------------------------
+ void OListBoxModel::loadData( bool _bForce )
+ {
+ RTL_LOGFILE_CONTEXT( aLogContext, "OListBoxModel::loadData" );
+ DBG_ASSERT( m_eListSourceType != ListSourceType_VALUELIST, "OListBoxModel::loadData: cannot load value list from DB!" );
+ DBG_ASSERT( !hasExternalListSource(), "OListBoxModel::loadData: cannot load from DB when I have an external list source!" );
+
+ const sal_Int16 nNULLPosBackup( m_nNULLPos );
+ const sal_Int32 nBoundColumnTypeBackup( m_nBoundColumnType );
+ m_nNULLPos = -1;
+ m_nBoundColumnType = DataType::SQLNULL;
+
+ // pre-requisites:
+ // PRE1: connection
+ Reference< XConnection > xConnection;
+ // is the active connection of our form
+ Reference< XPropertySet > xFormProps( m_xCursor, UNO_QUERY );
+ if ( xFormProps.is() )
+ xFormProps->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ) >>= xConnection;
+
+ // PRE2: list source
+ ::rtl::OUString sListSource;
+ // if our list source type is no value list, we need to concatenate
+ // the single list source elements
+ ::std::for_each(
+ m_aListSourceValues.begin(),
+ m_aListSourceValues.end(),
+ AppendRowSetValueString( sListSource )
+ );
+
+ // outta here if we don't have all pre-requisites
+ if ( !xConnection.is() || !sListSource.getLength() )
+ {
+ ValueList().swap(m_aBoundValues);
+ return;
+ }
+
+ ::boost::optional< sal_Int16 > aBoundColumn;
+ if ( m_aBoundColumn.getValueType().getTypeClass() == TypeClass_SHORT )
+ {
+ sal_Int16 nBoundColumn( 0 );
+ m_aBoundColumn >>= nBoundColumn;
+ aBoundColumn.reset( nBoundColumn );
+ }
+
+ ::utl::SharedUNOComponent< XResultSet > xListCursor;
+ try
+ {
+ m_aListRowSet.setConnection( xConnection );
+
+ sal_Bool bExecute = sal_False;
+ switch (m_eListSourceType)
+ {
+ case ListSourceType_TABLEFIELDS:
+ // don't work with a statement here, the fields will be collected below
+ break;
+
+ case ListSourceType_TABLE:
+ {
+ Reference<XNameAccess> xFieldsByName = getTableFields(xConnection, sListSource);
+ Reference<XIndexAccess> xFieldsByIndex(xFieldsByName, UNO_QUERY);
+
+ // do we have a bound column if yes we have to select it
+ // and the displayed column is the first column othwhise we act as a combobox
+ ::rtl::OUString aFieldName;
+ ::rtl::OUString aBoundFieldName;
+
+ if ( !!aBoundColumn && ( *aBoundColumn >= 0 ) && xFieldsByIndex.is() )
+ {
+ if ( *aBoundColumn >= xFieldsByIndex->getCount() )
+ break;
+
+ Reference<XPropertySet> xFieldAsSet(xFieldsByIndex->getByIndex( *aBoundColumn ),UNO_QUERY);
+ xFieldAsSet->getPropertyValue(PROPERTY_NAME) >>= aBoundFieldName;
+ aBoundColumn.reset( 1 );
+
+ xFieldAsSet.set(xFieldsByIndex->getByIndex(0),UNO_QUERY);
+ xFieldAsSet->getPropertyValue(PROPERTY_NAME) >>= aFieldName;
+ }
+ else if (xFieldsByName.is())
+ {
+ if ( xFieldsByName->hasByName( getControlSource() ) )
+ aFieldName = getControlSource();
+ else
+ {
+ // otherwise look for the alias
+ Reference< XColumnsSupplier > xSupplyFields;
+ xFormProps->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SingleSelectQueryComposer"))) >>= xSupplyFields;
+
+ // search the field
+ DBG_ASSERT(xSupplyFields.is(), "OListBoxModel::loadData : invalid query composer !");
+
+ Reference<XNameAccess> xFieldNames = xSupplyFields->getColumns();
+ if ( xFieldNames->hasByName( getControlSource() ) )
+ {
+ Reference<XPropertySet> xComposerFieldAsSet;
+ xFieldNames->getByName( getControlSource() ) >>= xComposerFieldAsSet;
+ if (hasProperty(PROPERTY_FIELDSOURCE, xComposerFieldAsSet))
+ xComposerFieldAsSet->getPropertyValue(PROPERTY_FIELDSOURCE) >>= aFieldName;
+ }
+ }
+ }
+ if (!aFieldName.getLength())
+ break;
+
+ Reference<XDatabaseMetaData> xMeta = xConnection->getMetaData();
+ ::rtl::OUString aQuote = xMeta->getIdentifierQuoteString();
+ ::rtl::OUString aStatement(RTL_CONSTASCII_USTRINGPARAM("SELECT "));
+ if (!aBoundFieldName.getLength()) // act like a combobox
+ aStatement += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DISTINCT ") );
+
+ aStatement += quoteName(aQuote,aFieldName);
+ if (aBoundFieldName.getLength())
+ {
+ aStatement += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(", ") );
+ aStatement += quoteName(aQuote, aBoundFieldName);
+ }
+ aStatement += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" FROM ") );
+
+ ::rtl::OUString sCatalog, sSchema, sTable;
+ qualifiedNameComponents( xMeta, sListSource, sCatalog, sSchema, sTable, eInDataManipulation );
+ aStatement += composeTableNameForSelect( xConnection, sCatalog, sSchema, sTable );
+
+ m_aListRowSet.setEscapeProcessing( sal_False );
+ m_aListRowSet.setCommand( aStatement );
+ bExecute = sal_True;
+ }
+ break;
+
+ case ListSourceType_QUERY:
+ m_aListRowSet.setCommandFromQuery( sListSource );
+ bExecute = sal_True;
+ break;
+
+ default:
+ m_aListRowSet.setEscapeProcessing( ListSourceType_SQLPASSTHROUGH != m_eListSourceType );
+ m_aListRowSet.setCommand( sListSource );
+ bExecute = sal_True;
+ break;
+ }
+
+ if (bExecute)
+ {
+ if ( !_bForce && !m_aListRowSet.isDirty() )
+ {
+ // if none of the settings of the row set changed, compared to the last
+ // invocation of loadData, then don't re-fill the list. Instead, assume
+ // the list entries are the same.
+ m_nNULLPos = nNULLPosBackup;
+ m_nBoundColumnType = nBoundColumnTypeBackup;
+ return;
+ }
+ xListCursor.reset( m_aListRowSet.execute() );
+ }
+ }
+ catch(SQLException& eSQL)
+ {
+ onError(eSQL, FRM_RES_STRING(RID_BASELISTBOX_ERROR_FILLLIST));
+ return;
+ }
+ catch(const Exception& eUnknown)
+ {
+ (void)eUnknown;
+ return;
+ }
+
+ // Anzeige- und Werteliste fuellen
+ ValueList aDisplayList, aValueList;
+ sal_Bool bUseNULL = hasField() && !isRequired();
+
+ try
+ {
+ OSL_ENSURE( xListCursor.is() || ( ListSourceType_TABLEFIELDS == m_eListSourceType ),
+ "OListBoxModel::loadData: logic error!" );
+ if ( !xListCursor.is() && ( ListSourceType_TABLEFIELDS != m_eListSourceType ) )
+ return;
+
+ switch (m_eListSourceType)
+ {
+ case ListSourceType_SQL:
+ case ListSourceType_SQLPASSTHROUGH:
+ case ListSourceType_TABLE:
+ case ListSourceType_QUERY:
+ {
+ // Feld der 1. Column des ResultSets holen
+ Reference<XColumnsSupplier> xSupplyCols(xListCursor, UNO_QUERY);
+ DBG_ASSERT(xSupplyCols.is(), "OListBoxModel::loadData : cursor supports the row set service but is no column supplier?!");
+ Reference<XIndexAccess> xColumns;
+ if (xSupplyCols.is())
+ {
+ xColumns = Reference<XIndexAccess>(xSupplyCols->getColumns(), UNO_QUERY);
+ DBG_ASSERT(xColumns.is(), "OListBoxModel::loadData : no columns supplied by the row set !");
+ }
+
+ Reference< XPropertySet > xDataField;
+ if ( xColumns.is() )
+ xColumns->getByIndex(0) >>= xDataField;
+ if ( !xDataField.is() )
+ return;
+
+ ::dbtools::FormattedColumnValue aValueFormatter( getContext(), m_xCursor, xDataField );
+
+ // Feld der BoundColumn des ResultSets holen
+ m_nBoundColumnType = DataType::SQLNULL;
+ if ( !!aBoundColumn && ( *aBoundColumn >= 0 ) && m_xColumn.is() )
+ { // don't look for a bound column if we're not connected to a field
+ try
+ {
+ Reference< XPropertySet > xBoundField( xColumns->getByIndex( *aBoundColumn ), UNO_QUERY_THROW );
+ OSL_VERIFY( xBoundField->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Type") ) ) >>= m_nBoundColumnType );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ // Ist die LB an ein Feld gebunden und sind Leereintraege zulaessig
+ // dann wird die Position fuer einen Leereintrag gemerkt
+
+ RTL_LOGFILE_CONTEXT( aLogContext, "OListBoxModel::loadData: string collection" );
+ ::rtl::OUString aStr;
+ sal_Int16 entryPos = 0;
+ ORowSetValue aBoundValue;
+ Reference< XRow > xCursorRow( xListCursor, UNO_QUERY_THROW );
+ while ( xListCursor->next() && ( entryPos++ < SHRT_MAX ) ) // SHRT_MAX is the maximum number of entries
+ {
+ aStr = aValueFormatter.getFormattedValue();
+ aDisplayList.push_back( aStr );
+
+ if ( impl_hasBoundComponent() )
+ {
+ aBoundValue.fill( *aBoundColumn + 1, m_nBoundColumnType, xCursorRow );
+ aValueList.push_back( aBoundValue );
+ }
+
+ if ( bUseNULL && ( m_nNULLPos == -1 ) && !aStr.getLength() )
+ m_nNULLPos = sal_Int16( aDisplayList.size() - 1 );
+ }
+ }
+ break;
+
+ case ListSourceType_TABLEFIELDS:
+ {
+ Reference<XNameAccess> xFieldNames = getTableFields(xConnection, sListSource);
+ if (xFieldNames.is())
+ {
+ StringSequence seqNames = xFieldNames->getElementNames();
+ ::std::copy(
+ seqNames.getConstArray(),
+ seqNames.getConstArray() + seqNames.getLength(),
+ ::std::insert_iterator< ValueList >( aDisplayList, aDisplayList.end() )
+ );
+ }
+ }
+ break;
+ default:
+ OSL_FAIL( "OListBoxModel::loadData: unreachable!" );
+ break;
+ }
+ }
+ catch(SQLException& eSQL)
+ {
+ onError(eSQL, FRM_RES_STRING(RID_BASELISTBOX_ERROR_FILLLIST));
+ return;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ return;
+ }
+
+
+ // Value-Sequence erzeugen
+ // NULL eintrag hinzufuegen
+ if (bUseNULL && m_nNULLPos == -1)
+ {
+ if ( impl_hasBoundComponent() )
+ aValueList.insert( aValueList.begin(), ORowSetValue() );
+
+ aDisplayList.insert( aDisplayList.begin(), ORowSetValue( ::rtl::OUString() ) );
+ m_nNULLPos = 0;
+ }
+
+ m_aBoundValues = aValueList;
+
+ setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, makeAny( lcl_convertToStringSequence( aDisplayList ) ) );
+ }
+
+ //------------------------------------------------------------------------------
+ void OListBoxModel::onConnectedDbColumn( const Reference< XInterface >& /*_rxForm*/ )
+ {
+ // list boxes which are bound to a db column don't have multi selection
+ // - this would be unable to reflect in the db column
+ if ( hasField() )
+ {
+ setFastPropertyValue( PROPERTY_ID_MULTISELECTION, ::cppu::bool2any( ( sal_False ) ) );
+ }
+
+ if ( !hasExternalListSource() )
+ impl_refreshDbEntryList( false );
+ }
+
+ //------------------------------------------------------------------------------
+ void OListBoxModel::onDisconnectedDbColumn()
+ {
+ if ( m_eListSourceType != ListSourceType_VALUELIST )
+ {
+ ValueList().swap(m_aBoundValues);
+ m_nNULLPos = -1;
+ m_nBoundColumnType = DataType::SQLNULL;
+
+ if ( !hasExternalListSource() )
+ setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, makeAny( StringSequence() ) );
+
+ m_aListRowSet.dispose();
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ ValueList OListBoxModel::impl_getValues() const
+ {
+ if ( !m_aBoundValues.empty() )
+ return m_aBoundValues;
+
+ Sequence< ::rtl::OUString > aStringItems( getStringItemList() );
+ ValueList aValues( aStringItems.getLength() );
+ ::std::copy(
+ aStringItems.getConstArray(),
+ aStringItems.getConstArray() + aStringItems.getLength(),
+ aValues.begin()
+ );
+
+ return aValues;
+ }
+ //------------------------------------------------------------------------------
+ ORowSetValue OListBoxModel::getFirstSelectedValue() const
+ {
+ static const ORowSetValue s_aEmptyVaue;
+
+ DBG_ASSERT( m_xAggregateFastSet.is(), "OListBoxModel::getFirstSelectedValue: invalid aggregate!" );
+ if ( !m_xAggregateFastSet.is() )
+ return s_aEmptyVaue;
+
+ Sequence< sal_Int16 > aSelectedIndices;
+ OSL_VERIFY( m_xAggregateFastSet->getFastPropertyValue( getValuePropertyAggHandle() ) >>= aSelectedIndices );
+ if ( !aSelectedIndices.getLength() )
+ // nothing selected at all
+ return s_aEmptyVaue;
+
+ if ( ( m_nNULLPos != -1 ) && ( aSelectedIndices[0] == m_nNULLPos ) )
+ // the dedicated "NULL" entry is selected
+ return s_aEmptyVaue;
+
+ ValueList aValues( impl_getValues() );
+
+ size_t selectedValue = aSelectedIndices[0];
+ if ( selectedValue >= aValues.size() )
+ {
+ OSL_FAIL( "OListBoxModel::getFirstSelectedValue: inconsistent selection/valuelist!" );
+ return s_aEmptyVaue;
+ }
+
+ return aValues[ selectedValue ];
+ }
+
+ //------------------------------------------------------------------------------
+ sal_Bool OListBoxModel::commitControlValueToDbColumn( bool /*_bPostReset*/ )
+ {
+ // current selektion list
+ const ORowSetValue aCurrentValue( getFirstSelectedValue() );
+ if ( aCurrentValue != m_aSaveValue )
+ {
+ if ( aCurrentValue.isNull() )
+ m_xColumnUpdate->updateNull();
+ else
+ {
+ try
+ {
+ m_xColumnUpdate->updateObject( aCurrentValue.makeAny() );
+ }
+ catch ( const Exception& )
+ {
+ return sal_False;
+ }
+ }
+ m_aSaveValue = aCurrentValue;
+ }
+ return sal_True;
+ }
+
+ // XPropertiesChangeListener
+ //------------------------------------------------------------------------------
+ Any OListBoxModel::translateDbColumnToControlValue()
+ {
+ Reference< XPropertySet > xBoundField( getField() );
+ if ( !xBoundField.is() )
+ {
+ OSL_FAIL( "OListBoxModel::translateDbColumnToControlValue: no field? How could that happen?!" );
+ return Any();
+ }
+
+ Sequence< sal_Int16 > aSelectionIndicies;
+
+ ORowSetValue aCurrentValue;
+ aCurrentValue.fill( impl_hasBoundComponent() ? m_nBoundColumnType : getFieldType(), m_xColumn );
+
+ // reset selection for NULL values
+ if ( aCurrentValue.isNull() )
+ {
+ if ( m_nNULLPos != -1 )
+ {
+ aSelectionIndicies.realloc(1);
+ aSelectionIndicies[0] = m_nNULLPos;
+ }
+ }
+ else
+ {
+ ValueList aValues( impl_getValues() );
+ ValueList::const_iterator curValuePos = ::std::find( aValues.begin(), aValues.end(), aCurrentValue );
+ if ( curValuePos != aValues.end() )
+ {
+ aSelectionIndicies.realloc( 1 );
+ aSelectionIndicies[0] = curValuePos - aValues.begin();
+ }
+ }
+
+ m_aSaveValue = aCurrentValue;
+
+ return makeAny( aSelectionIndicies );
+ }
+
+ // XReset
+ //------------------------------------------------------------------------------
+ Any OListBoxModel::getDefaultForReset() const
+ {
+ Any aValue;
+ if (m_aDefaultSelectSeq.getLength())
+ aValue <<= m_aDefaultSelectSeq;
+ else if (m_nNULLPos != -1) // gebundene Listbox
+ {
+ Sequence<sal_Int16> aSeq(1);
+ aSeq.getArray()[0] = m_nNULLPos;
+ aValue <<= aSeq;
+ }
+ else
+ {
+ Sequence<sal_Int16> aSeq;
+ aValue <<= aSeq;
+ }
+
+ return aValue;
+ }
+
+ //--------------------------------------------------------------------
+ void OListBoxModel::resetNoBroadcast()
+ {
+ OBoundControlModel::resetNoBroadcast();
+ m_aSaveValue.setNull();
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OListBoxModel::disposing( const EventObject& _rSource ) throw ( RuntimeException )
+ {
+ if ( !OEntryListHelper::handleDisposing( _rSource ) )
+ OBoundControlModel::disposing( _rSource );
+ }
+
+ //--------------------------------------------------------------------
+ namespace
+ {
+ /** type how we should transfer our selection to external value bindings
+ */
+ enum ExchangeType
+ {
+ eIndexList, /// as list of indexes of selected entries
+ eIndex, /// as index of the selected entry
+ eEntryList, /// as list of string representations of selected entries
+ eEntry /// as string representation of the selected entry
+ };
+
+ //--------------------------------------------------------------------
+ ExchangeType lcl_getCurrentExchangeType( const Type& _rExchangeType )
+ {
+ switch ( _rExchangeType.getTypeClass() )
+ {
+ case TypeClass_STRING:
+ return eEntry;
+ case TypeClass_LONG:
+ return eIndex;
+ case TypeClass_SEQUENCE:
+ {
+ Type aElementType = ::comphelper::getSequenceElementType( _rExchangeType );
+ switch ( aElementType.getTypeClass() )
+ {
+ case TypeClass_STRING:
+ return eEntryList;
+ case TypeClass_LONG:
+ return eIndexList;
+ default:
+ break;
+ }
+ }
+ default:
+ break;
+ }
+ OSL_FAIL( "lcl_getCurrentExchangeType: unsupported (unexpected) exchange type!" );
+ return eEntry;
+ }
+ }
+
+ //--------------------------------------------------------------------
+ Any OListBoxModel::translateExternalValueToControlValue( const Any& _rExternalValue ) const
+ {
+ Sequence< sal_Int16 > aSelectIndexes;
+
+ switch ( lcl_getCurrentExchangeType( getExternalValueType() ) )
+ {
+ case eIndexList:
+ {
+ // unfortunately, our select sequence is a sequence<short>, while the external binding
+ // supplies sequence<int> only -> transform this
+ Sequence< sal_Int32 > aSelectIndexesPure;
+ OSL_VERIFY( _rExternalValue >>= aSelectIndexesPure );
+ aSelectIndexes.realloc( aSelectIndexesPure.getLength() );
+ ::std::copy(
+ aSelectIndexesPure.getConstArray(),
+ aSelectIndexesPure.getConstArray() + aSelectIndexesPure.getLength(),
+ aSelectIndexes.getArray()
+ );
+ }
+ break;
+
+ case eIndex:
+ {
+ sal_Int32 nSelectIndex = -1;
+ OSL_VERIFY( _rExternalValue >>= nSelectIndex );
+ if ( ( nSelectIndex >= 0 ) && ( nSelectIndex < getStringItemList().getLength() ) )
+ {
+ aSelectIndexes.realloc( 1 );
+ aSelectIndexes[ 0 ] = static_cast< sal_Int16 >( nSelectIndex );
+ }
+ }
+ break;
+
+ case eEntryList:
+ {
+ // we can retrieve a string list from the binding for multiple selection
+ Sequence< ::rtl::OUString > aSelectEntries;
+ OSL_VERIFY( _rExternalValue >>= aSelectEntries );
+
+ ::std::set< sal_Int16 > aSelectionSet;
+
+ // find the selection entries in our item list
+ const ::rtl::OUString* pSelectEntries = aSelectEntries.getArray();
+ const ::rtl::OUString* pSelectEntriesEnd = pSelectEntries + aSelectEntries.getLength();
+ while ( pSelectEntries != pSelectEntriesEnd )
+ {
+ // the indexes where the current string appears in our string items
+ Sequence< sal_Int16 > aThisEntryIndexes;
+ aThisEntryIndexes = findValue( getStringItemList(), *pSelectEntries++, sal_False );
+
+ // insert all the indexes of this entry into our set
+ ::std::copy(
+ aThisEntryIndexes.getConstArray(),
+ aThisEntryIndexes.getConstArray() + aThisEntryIndexes.getLength(),
+ ::std::insert_iterator< ::std::set< sal_Int16 > >( aSelectionSet, aSelectionSet.begin() )
+ );
+ }
+
+ // copy the indexes to the sequence
+ aSelectIndexes.realloc( aSelectionSet.size() );
+ ::std::copy(
+ aSelectionSet.begin(),
+ aSelectionSet.end(),
+ aSelectIndexes.getArray()
+ );
+ }
+ break;
+
+ case eEntry:
+ {
+ ::rtl::OUString sStringToSelect;
+ OSL_VERIFY( _rExternalValue >>= sStringToSelect );
+
+ aSelectIndexes = findValue( getStringItemList(), sStringToSelect, sal_False );
+ }
+ break;
+ }
+
+ return makeAny( aSelectIndexes );
+ }
+
+ //--------------------------------------------------------------------
+ namespace
+ {
+ //................................................................
+ struct ExtractStringFromSequence_Safe : public ::std::unary_function< sal_Int16, ::rtl::OUString >
+ {
+ protected:
+ const Sequence< ::rtl::OUString >& m_rList;
+
+ public:
+ ExtractStringFromSequence_Safe( const Sequence< ::rtl::OUString >& _rList ) : m_rList( _rList ) { }
+
+ ::rtl::OUString operator ()( sal_Int16 _nIndex )
+ {
+ OSL_ENSURE( _nIndex < m_rList.getLength(), "ExtractStringFromSequence_Safe: inconsistence!" );
+ if ( _nIndex < m_rList.getLength() )
+ return m_rList[ _nIndex ];
+ return ::rtl::OUString();
+ }
+ };
+
+ //................................................................
+ Any lcl_getSingleSelectedEntry( const Sequence< sal_Int16 >& _rSelectSequence, const Sequence< ::rtl::OUString >& _rStringList )
+ {
+ Any aReturn;
+
+ // by definition, multiple selected entries are transfered as NULL if the
+ // binding does not support string lists
+ if ( _rSelectSequence.getLength() <= 1 )
+ {
+ ::rtl::OUString sSelectedEntry;
+
+ if ( _rSelectSequence.getLength() == 1 )
+ sSelectedEntry = ExtractStringFromSequence_Safe( _rStringList )( _rSelectSequence[0] );
+
+ aReturn <<= sSelectedEntry;
+ }
+
+ return aReturn;
+ }
+
+ //................................................................
+ Any lcl_getMultiSelectedEntries( const Sequence< sal_Int16 >& _rSelectSequence, const Sequence< ::rtl::OUString >& _rStringList )
+ {
+ Sequence< ::rtl::OUString > aSelectedEntriesTexts( _rSelectSequence.getLength() );
+ ::std::transform(
+ _rSelectSequence.getConstArray(),
+ _rSelectSequence.getConstArray() + _rSelectSequence.getLength(),
+ aSelectedEntriesTexts.getArray(),
+ ExtractStringFromSequence_Safe( _rStringList )
+ );
+ return makeAny( aSelectedEntriesTexts );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ Any OListBoxModel::translateControlValueToExternalValue( ) const
+ {
+ OSL_PRECOND( hasExternalValueBinding(), "OListBoxModel::translateControlValueToExternalValue: no binding!" );
+
+ Sequence< sal_Int16 > aSelectSequence;
+ const_cast< OListBoxModel* >( this )->getPropertyValue( PROPERTY_SELECT_SEQ ) >>= aSelectSequence;
+
+ Any aReturn;
+ switch ( lcl_getCurrentExchangeType( getExternalValueType() ) )
+ {
+ case eIndexList:
+ {
+ // unfortunately, the select sequence is a sequence<short>, but our binding
+ // expects int's
+ Sequence< sal_Int32 > aTransformed( aSelectSequence.getLength() );
+ ::std::copy(
+ aSelectSequence.getConstArray(),
+ aSelectSequence.getConstArray() + aSelectSequence.getLength(),
+ aTransformed.getArray()
+ );
+ aReturn <<= aTransformed;
+ }
+ break;
+
+ case eIndex:
+ if ( aSelectSequence.getLength() <= 1 )
+ {
+ sal_Int32 nIndex = -1;
+
+ if ( aSelectSequence.getLength() == 1 )
+ nIndex = aSelectSequence[0];
+
+ aReturn <<= nIndex;
+ }
+ break;
+
+ case eEntryList:
+ aReturn = lcl_getMultiSelectedEntries( aSelectSequence, getStringItemList() );
+ break;
+
+ case eEntry:
+ aReturn = lcl_getSingleSelectedEntry( aSelectSequence, getStringItemList() );
+ break;
+ }
+
+ return aReturn;
+ }
+
+ //--------------------------------------------------------------------
+ Any OListBoxModel::getCurrentFormComponentValue() const
+ {
+ if ( hasValidator() )
+ return OBoundControlModel::getCurrentFormComponentValue();
+
+ Any aCurretnValue;
+
+ try
+ {
+ Sequence< sal_Int16 > aSelectSequence;
+ OSL_VERIFY( const_cast< OListBoxModel* >( this )->getPropertyValue( PROPERTY_SELECT_SEQ ) >>= aSelectSequence );
+
+ sal_Bool bMultiSelection( sal_False );
+ OSL_VERIFY( const_cast< OListBoxModel* >( this )->getPropertyValue( PROPERTY_MULTISELECTION ) >>= bMultiSelection );
+
+ if ( bMultiSelection )
+ aCurretnValue = lcl_getMultiSelectedEntries( aSelectSequence, getStringItemList() );
+ else
+ aCurretnValue = lcl_getSingleSelectedEntry( aSelectSequence, getStringItemList() );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ return aCurretnValue;
+ }
+
+ //--------------------------------------------------------------------
+ Sequence< Type > OListBoxModel::getSupportedBindingTypes()
+ {
+ Sequence< Type > aTypes(4);
+ aTypes[0] = ::getCppuType( static_cast< Sequence< sal_Int32 >* >( NULL ) );
+ aTypes[1] = ::getCppuType( static_cast< sal_Int32* >( NULL ) );
+ aTypes[2] = ::getCppuType( static_cast< Sequence< ::rtl::OUString >* >( NULL ) );
+ aTypes[3] = ::getCppuType( static_cast< ::rtl::OUString* >( NULL ) );
+ return aTypes;
+ }
+
+ //--------------------------------------------------------------------
+ void OListBoxModel::stringItemListChanged( ControlModelLock& _rInstanceLock )
+ {
+ if ( !m_xAggregateSet.is() )
+ return;
+
+ suspendValueListening();
+ try
+ {
+ m_xAggregateSet->setPropertyValue( PROPERTY_STRINGITEMLIST, makeAny( getStringItemList() ) );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ resumeValueListening();
+
+ // update the selection here
+ if ( hasExternalValueBinding( ) )
+ transferExternalValueToControl( _rInstanceLock );
+ else
+ {
+ if ( hasField() )
+ {
+ // TODO: update the selection in case we're bound to a database column
+ }
+ else
+ {
+ if ( m_aDefaultSelectSeq.getLength() )
+ setControlValue( makeAny( m_aDefaultSelectSeq ), eOther );
+ }
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void OListBoxModel::connectedExternalListSource( )
+ {
+ // TODO?
+ }
+
+ //--------------------------------------------------------------------
+ void OListBoxModel::disconnectedExternalListSource( )
+ {
+ // TODO: in case we're part of an already loaded form, we should probably simulate
+ // an onConnectedDbColumn, so our list get's filled with the data as indicated
+ // by our SQL-binding related properties
+ }
+
+ //--------------------------------------------------------------------
+ void OListBoxModel::impl_refreshDbEntryList( bool _bForce )
+ {
+ DBG_ASSERT( !hasExternalListSource(), "OListBoxModel::impl_refreshDbEntryList: invalid call!" );
+
+ if ( !hasExternalListSource( )
+ && ( m_eListSourceType != ListSourceType_VALUELIST )
+ && ( m_xCursor.is() )
+ )
+ {
+ loadData( _bForce );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void OListBoxModel::refreshInternalEntryList()
+ {
+ impl_refreshDbEntryList( true );
+ if ( hasField() && m_xCursor.is() )
+ initFromField( m_xCursor );
+ }
+
+ //==================================================================
+ // OListBoxControl
+ //==================================================================
+
+ //------------------------------------------------------------------
+ InterfaceRef SAL_CALL OListBoxControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory) throw (RuntimeException)
+ {
+ return *(new OListBoxControl(_rxFactory));
+ }
+
+ //------------------------------------------------------------------------------
+ Sequence< Type> OListBoxControl::_getTypes()
+ {
+ return TypeBag(
+ OBoundControl::_getTypes(),
+ OListBoxControl_BASE::getTypes()
+ ).getTypes();
+ }
+
+ //------------------------------------------------------------------
+ Any SAL_CALL OListBoxControl::queryAggregation(const Type& _rType) throw (RuntimeException)
+ {
+ Any aReturn = OListBoxControl_BASE::queryInterface( _rType );
+
+ if ( !aReturn.hasValue()
+ || _rType.equals( XTypeProvider::static_type() )
+ )
+ aReturn = OBoundControl::queryAggregation( _rType );
+
+ return aReturn;
+ }
+
+ DBG_NAME(OListBoxControl);
+ //------------------------------------------------------------------------------
+ OListBoxControl::OListBoxControl(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OBoundControl( _rxFactory, VCL_CONTROL_LISTBOX, sal_False )
+ ,m_aChangeListeners( m_aMutex )
+ ,m_aItemListeners( m_aMutex )
+ ,m_pItemBroadcaster( NULL )
+ {
+ DBG_CTOR(OListBoxControl,NULL);
+
+ increment(m_refCount);
+ {
+ // als FocusListener anmelden
+ Reference<XWindow> xComp;
+ if (query_aggregation(m_xAggregate, xComp))
+ xComp->addFocusListener(this);
+
+ // als ItemListener anmelden
+ if ( query_aggregation( m_xAggregate, m_xAggregateListBox ) )
+ m_xAggregateListBox->addItemListener(this);
+ }
+ // Refcount bei 2 fuer angemeldete Listener
+ decrement(m_refCount);
+
+ doSetDelegator();
+
+ m_aChangeTimer.SetTimeout(500);
+ m_aChangeTimer.SetTimeoutHdl(LINK(this,OListBoxControl,OnTimeout));
+ }
+
+ //------------------------------------------------------------------------------
+ OListBoxControl::~OListBoxControl()
+ {
+ if (!OComponentHelper::rBHelper.bDisposed)
+ {
+ acquire();
+ dispose();
+ }
+
+ doResetDelegator();
+ m_xAggregateListBox.clear();
+
+ DBG_DTOR(OListBoxControl,NULL);
+ }
+
+ //------------------------------------------------------------------------------
+ StringSequence SAL_CALL OListBoxControl::getSupportedServiceNames() throw(RuntimeException)
+ {
+ StringSequence aSupported = OBoundControl::getSupportedServiceNames();
+ aSupported.realloc(aSupported.getLength() + 1);
+
+ ::rtl::OUString* pArray = aSupported.getArray();
+ pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_LISTBOX;
+ return aSupported;
+ }
+
+
+ // XFocusListener
+ //------------------------------------------------------------------------------
+ void SAL_CALL OListBoxControl::focusGained(const FocusEvent& /*_rEvent*/) throw(RuntimeException)
+ {
+ ::osl::MutexGuard aGuard(m_aMutex);
+ if ( m_aChangeListeners.getLength() ) // only if there are listeners
+ {
+ Reference<XPropertySet> xSet(getModel(), UNO_QUERY);
+ if (xSet.is())
+ {
+ // memorize the current selection for posting the change event
+ m_aCurrentSelection = xSet->getPropertyValue(PROPERTY_SELECT_SEQ);
+ }
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ void SAL_CALL OListBoxControl::focusLost(const FocusEvent& /*_rEvent*/) throw(RuntimeException)
+ {
+ m_aCurrentSelection.clear();
+ }
+
+ // XItemListener
+ //------------------------------------------------------------------------------
+ void SAL_CALL OListBoxControl::itemStateChanged(const ItemEvent& _rEvent) throw(RuntimeException)
+ {
+ // forward this to our listeners
+ Reference< XChild > xChild( getModel(), UNO_QUERY );
+ if ( xChild.is() && xChild->getParent().is() )
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( m_aItemListeners.getLength() )
+ {
+ if ( !m_pItemBroadcaster.is() )
+ {
+ m_pItemBroadcaster.set( new ::comphelper::AsyncEventNotifier );
+ m_pItemBroadcaster->create();
+ }
+ m_pItemBroadcaster->addEvent( new ItemEventDescription( _rEvent ), this );
+ }
+ }
+ else
+ m_aItemListeners.notifyEach( &XItemListener::itemStateChanged, _rEvent );
+
+ // and do the handling for the ChangeListeners
+ ::osl::ClearableMutexGuard aGuard(m_aMutex);
+ if ( m_aChangeTimer.IsActive() )
+ {
+ Reference<XPropertySet> xSet(getModel(), UNO_QUERY);
+ m_aCurrentSelection = xSet->getPropertyValue(PROPERTY_SELECT_SEQ);
+
+ m_aChangeTimer.Stop();
+ m_aChangeTimer.Start();
+ }
+ else
+ {
+ if ( m_aChangeListeners.getLength() && m_aCurrentSelection.hasValue() )
+ {
+ Reference<XPropertySet> xSet(getModel(), UNO_QUERY);
+ if (xSet.is())
+ {
+ // Has the selection been changed?
+ sal_Bool bModified(sal_False);
+ Any aValue = xSet->getPropertyValue(PROPERTY_SELECT_SEQ);
+
+ Sequence<sal_Int16>& rSelection = *(Sequence<sal_Int16> *)aValue.getValue();
+ Sequence<sal_Int16>& rOldSelection = *(Sequence<sal_Int16> *)m_aCurrentSelection.getValue();
+ sal_Int32 nLen = rSelection.getLength();
+ if (nLen != rOldSelection.getLength())
+ bModified = sal_True;
+ else
+ {
+ const sal_Int16* pVal = rSelection.getConstArray();
+ const sal_Int16* pCompVal = rOldSelection.getConstArray();
+
+ while (nLen-- && !bModified)
+ bModified = pVal[nLen] != pCompVal[nLen];
+ }
+
+ if (bModified)
+ {
+ m_aCurrentSelection = aValue;
+ m_aChangeTimer.Start();
+ }
+ }
+ }
+ else if (m_aCurrentSelection.hasValue())
+ m_aCurrentSelection.clear();
+ }
+ }
+
+ // XEventListener
+ //------------------------------------------------------------------------------
+ void SAL_CALL OListBoxControl::disposing(const EventObject& _rSource) throw (RuntimeException)
+ {
+ OBoundControl::disposing(_rSource);
+ }
+
+ // XChangeBroadcaster
+ //------------------------------------------------------------------------------
+ void SAL_CALL OListBoxControl::addChangeListener(const Reference<XChangeListener>& _rxListener) throw(RuntimeException)
+ {
+ m_aChangeListeners.addInterface( _rxListener );
+ }
+
+ //------------------------------------------------------------------------------
+ void SAL_CALL OListBoxControl::removeChangeListener(const Reference<XChangeListener>& _rxListener) throw(RuntimeException)
+ {
+ m_aChangeListeners.removeInterface( _rxListener );
+ }
+
+ // OComponentHelper
+ //------------------------------------------------------------------------------
+ void OListBoxControl::disposing()
+ {
+ if (m_aChangeTimer.IsActive())
+ m_aChangeTimer.Stop();
+
+ EventObject aEvent( *this );
+ m_aChangeListeners.disposeAndClear( aEvent );
+ m_aItemListeners.disposeAndClear( aEvent );
+
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( m_pItemBroadcaster.is() )
+ {
+ m_pItemBroadcaster->removeEventsForProcessor( this );
+ m_pItemBroadcaster->terminate();
+ m_pItemBroadcaster = NULL;
+ }
+ }
+
+ OBoundControl::disposing();
+ }
+
+ //------------------------------------------------------------------------------
+ void OListBoxControl::processEvent( const AnyEvent& _rEvent )
+ {
+ Reference< XListBox > xKeepAlive( this );
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( OComponentHelper::rBHelper.bDisposed )
+ return;
+ }
+ const ItemEventDescription& rItemEvent = static_cast< const ItemEventDescription& >( _rEvent );
+ m_aItemListeners.notifyEach( &XItemListener::itemStateChanged, rItemEvent.getEventObject() );
+ }
+
+ //------------------------------------------------------------------------------
+ IMPL_LINK(OListBoxControl, OnTimeout, void*, /*EMPTYTAG*/)
+ {
+ m_aChangeListeners.notifyEach( &XChangeListener::changed, EventObject( *this ) );
+ return 0L;
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OListBoxControl::addItemListener( const Reference< XItemListener >& l ) throw (RuntimeException)
+ {
+ m_aItemListeners.addInterface( l );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OListBoxControl::removeItemListener( const Reference< XItemListener >& l ) throw (RuntimeException)
+ {
+ m_aItemListeners.removeInterface( l );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OListBoxControl::addActionListener( const Reference< XActionListener >& l ) throw (RuntimeException)
+ {
+ if ( m_xAggregateListBox.is() )
+ m_xAggregateListBox->addActionListener( l );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OListBoxControl::removeActionListener( const Reference< XActionListener >& l ) throw (RuntimeException)
+ {
+ if ( m_xAggregateListBox.is() )
+ m_xAggregateListBox->removeActionListener( l );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OListBoxControl::addItem( const ::rtl::OUString& aItem, ::sal_Int16 nPos ) throw (RuntimeException)
+ {
+ if ( m_xAggregateListBox.is() )
+ m_xAggregateListBox->addItem( aItem, nPos );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OListBoxControl::addItems( const Sequence< ::rtl::OUString >& aItems, ::sal_Int16 nPos ) throw (RuntimeException)
+ {
+ if ( m_xAggregateListBox.is() )
+ m_xAggregateListBox->addItems( aItems, nPos );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OListBoxControl::removeItems( ::sal_Int16 nPos, ::sal_Int16 nCount ) throw (RuntimeException)
+ {
+ if ( m_xAggregateListBox.is() )
+ m_xAggregateListBox->removeItems( nPos, nCount );
+ }
+
+ //--------------------------------------------------------------------
+ ::sal_Int16 SAL_CALL OListBoxControl::getItemCount( ) throw (RuntimeException)
+ {
+ if ( m_xAggregateListBox.is() )
+ return m_xAggregateListBox->getItemCount();
+ return 0;
+ }
+
+ //--------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL OListBoxControl::getItem( ::sal_Int16 nPos ) throw (RuntimeException)
+ {
+ if ( m_xAggregateListBox.is() )
+ return m_xAggregateListBox->getItem( nPos );
+ return ::rtl::OUString( );
+ }
+
+ //--------------------------------------------------------------------
+ Sequence< ::rtl::OUString > SAL_CALL OListBoxControl::getItems( ) throw (RuntimeException)
+ {
+ if ( m_xAggregateListBox.is() )
+ return m_xAggregateListBox->getItems();
+ return Sequence< ::rtl::OUString >( );
+ }
+
+ //--------------------------------------------------------------------
+ ::sal_Int16 SAL_CALL OListBoxControl::getSelectedItemPos( ) throw (RuntimeException)
+ {
+ if ( m_xAggregateListBox.is() )
+ return m_xAggregateListBox->getSelectedItemPos();
+ return 0;
+ }
+
+ //--------------------------------------------------------------------
+ Sequence< ::sal_Int16 > SAL_CALL OListBoxControl::getSelectedItemsPos( ) throw (RuntimeException)
+ {
+ if ( m_xAggregateListBox.is() )
+ return m_xAggregateListBox->getSelectedItemsPos();
+ return Sequence< ::sal_Int16 >( );
+ }
+
+ //--------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL OListBoxControl::getSelectedItem( ) throw (RuntimeException)
+ {
+ if ( m_xAggregateListBox.is() )
+ return m_xAggregateListBox->getSelectedItem();
+ return ::rtl::OUString( );
+ }
+
+ //--------------------------------------------------------------------
+ Sequence< ::rtl::OUString > SAL_CALL OListBoxControl::getSelectedItems( ) throw (RuntimeException)
+ {
+ if ( m_xAggregateListBox.is() )
+ return m_xAggregateListBox->getSelectedItems();
+ return Sequence< ::rtl::OUString >( );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OListBoxControl::selectItemPos( ::sal_Int16 nPos, ::sal_Bool bSelect ) throw (RuntimeException)
+ {
+ if ( m_xAggregateListBox.is() )
+ m_xAggregateListBox->selectItemPos( nPos, bSelect );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OListBoxControl::selectItemsPos( const Sequence< ::sal_Int16 >& aPositions, ::sal_Bool bSelect ) throw (RuntimeException)
+ {
+ if ( m_xAggregateListBox.is() )
+ m_xAggregateListBox->selectItemsPos( aPositions, bSelect );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OListBoxControl::selectItem( const ::rtl::OUString& aItem, ::sal_Bool bSelect ) throw (RuntimeException)
+ {
+ if ( m_xAggregateListBox.is() )
+ m_xAggregateListBox->selectItem( aItem, bSelect );
+ }
+
+ //--------------------------------------------------------------------
+ ::sal_Bool SAL_CALL OListBoxControl::isMutipleMode( ) throw (RuntimeException)
+ {
+ if ( m_xAggregateListBox.is() )
+ return m_xAggregateListBox->isMutipleMode();
+ return sal_False;
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OListBoxControl::setMultipleMode( ::sal_Bool bMulti ) throw (RuntimeException)
+ {
+ if ( m_xAggregateListBox.is() )
+ m_xAggregateListBox->setMultipleMode( bMulti );
+ }
+
+ //--------------------------------------------------------------------
+ ::sal_Int16 SAL_CALL OListBoxControl::getDropDownLineCount( ) throw (RuntimeException)
+ {
+ if ( m_xAggregateListBox.is() )
+ return m_xAggregateListBox->getDropDownLineCount();
+ return 0;
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OListBoxControl::setDropDownLineCount( ::sal_Int16 nLines ) throw (RuntimeException)
+ {
+ if ( m_xAggregateListBox.is() )
+ m_xAggregateListBox->setDropDownLineCount( nLines );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OListBoxControl::makeVisible( ::sal_Int16 nEntry ) throw (RuntimeException)
+ {
+ if ( m_xAggregateListBox.is() )
+ m_xAggregateListBox->makeVisible( nEntry );
+ }
+
+//.........................................................................
+}
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/ListBox.hxx b/forms/source/component/ListBox.hxx
new file mode 100644
index 000000000000..cd1302c35fcc
--- /dev/null
+++ b/forms/source/component/ListBox.hxx
@@ -0,0 +1,288 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FORMS_LISTBOX_HXX_
+#define _FORMS_LISTBOX_HXX_
+
+#include "FormComponent.hxx"
+#include "cachedrowset.hxx"
+#include "errorbroadcaster.hxx"
+#include "entrylisthelper.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/util/XNumberFormatter.hpp>
+#include <com/sun/star/sdb/XSQLErrorBroadcaster.hpp>
+#include <com/sun/star/form/ListSourceType.hpp>
+#include <com/sun/star/awt/XItemListener.hpp>
+#include <com/sun/star/awt/XFocusListener.hpp>
+#include <com/sun/star/awt/XListBox.hpp>
+#include <com/sun/star/form/XChangeBroadcaster.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/asyncnotification.hxx>
+#include <connectivity/FValue.hxx>
+#include <cppuhelper/interfacecontainer.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <vcl/timer.hxx>
+
+#include <vector>
+
+namespace dbtools
+{
+ class FormattedColumnValue;
+}
+
+//.........................................................................
+namespace frm
+{
+
+//==================================================================
+//= OListBoxModel
+//==================================================================
+typedef ::std::vector< ::connectivity::ORowSetValue > ValueList;
+
+class OListBoxModel :public OBoundControlModel
+ ,public OEntryListHelper
+ ,public OErrorBroadcaster
+{
+
+ CachedRowSet m_aListRowSet; // the row set to fill the list
+ ::connectivity::ORowSetValue m_aSaveValue;
+
+ // <properties>
+ ::com::sun::star::form::ListSourceType m_eListSourceType; // type der list source
+ ::com::sun::star::uno::Any m_aBoundColumn;
+ ValueList m_aListSourceValues;
+ ValueList m_aBoundValues;
+ ::com::sun::star::uno::Sequence<sal_Int16> m_aDefaultSelectSeq; // DefaultSelected
+ // </properties>
+
+ sal_Int16 m_nNULLPos; // position of the NULL value in our list
+ sal_Int32 m_nBoundColumnType;
+
+private:
+ ::connectivity::ORowSetValue getFirstSelectedValue() const;
+
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();
+
+public:
+ DECLARE_DEFAULT_LEAF_XTOR( OListBoxModel );
+
+// XServiceInfo
+ IMPLEMENTATION_NAME(OListBoxModel);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
+
+// UNO Anbindung
+ DECLARE_UNO3_AGG_DEFAULTS(OListBoxModel, OBoundControlModel);
+ virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException);
+
+// OComponentHelper
+ virtual void SAL_CALL disposing();
+
+// OPropertySetHelper
+ virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const;
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
+ throw (::com::sun::star::uno::Exception);
+ virtual sal_Bool SAL_CALL convertFastPropertyValue(
+ ::com::sun::star::uno::Any& _rConvertedValue, ::com::sun::star::uno::Any& _rOldValue, sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue )
+ throw (::com::sun::star::lang::IllegalArgumentException);
+
+protected:
+ // XMultiPropertySet
+ virtual void SAL_CALL setPropertyValues(const ::com::sun::star::uno::Sequence< ::rtl::OUString >& PropertyNames, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& Values) throw(::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ // XPersistObject
+ virtual ::rtl::OUString SAL_CALL getServiceName() throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL
+ write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL
+ read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ // OControlModel's property handling
+ virtual void describeFixedProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps
+ ) const;
+ virtual void describeAggregateProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rAggregateProps
+ ) const;
+
+ // XEventListener
+ virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException);
+
+ // OPropertyChangeListener
+ virtual void _propertyChanged( const ::com::sun::star::beans::PropertyChangeEvent& _rEvt ) throw ( ::com::sun::star::uno::RuntimeException );
+
+ // prevent method hiding
+ using OBoundControlModel::getFastPropertyValue;
+ using OBoundControlModel::setPropertyValues;
+
+protected:
+ // OBoundControlModel overridables
+ virtual ::com::sun::star::uno::Any
+ translateDbColumnToControlValue( );
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type >
+ getSupportedBindingTypes();
+ virtual ::com::sun::star::uno::Any
+ translateExternalValueToControlValue( const ::com::sun::star::uno::Any& _rExternalValue ) const;
+ virtual ::com::sun::star::uno::Any
+ translateControlValueToExternalValue( ) const;
+ virtual sal_Bool commitControlValueToDbColumn( bool _bPostReset );
+
+ virtual void onConnectedDbColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxForm );
+ virtual void onDisconnectedDbColumn();
+
+ virtual ::com::sun::star::uno::Any
+ getDefaultForReset() const;
+ virtual void resetNoBroadcast();
+
+ virtual ::com::sun::star::uno::Any
+ getCurrentFormComponentValue() const;
+
+ // OEntryListHelper overriables
+ virtual void stringItemListChanged( ControlModelLock& _rInstanceLock );
+ virtual void connectedExternalListSource( );
+ virtual void disconnectedExternalListSource( );
+ virtual void refreshInternalEntryList();
+
+protected:
+ DECLARE_XCLONEABLE();
+
+private:
+ void loadData( bool _bForce );
+
+ /** refreshes the list boxes list data
+ @precond we don't actually have an external list source
+ */
+ void impl_refreshDbEntryList( bool _bForce );
+
+ ValueList impl_getValues() const;
+
+ bool impl_hasBoundComponent() const { return m_nBoundColumnType != ::com::sun::star::sdbc::DataType::SQLNULL; }
+};
+
+//==================================================================
+//= OListBoxControl
+//==================================================================
+typedef ::cppu::ImplHelper4 < ::com::sun::star::awt::XFocusListener
+ , ::com::sun::star::awt::XItemListener
+ , ::com::sun::star::awt::XListBox
+ , ::com::sun::star::form::XChangeBroadcaster
+ > OListBoxControl_BASE;
+
+class ChangeListeners;
+
+class OListBoxControl :public OBoundControl
+ ,public OListBoxControl_BASE
+ ,public IEventProcessor
+{
+private:
+ ::cppu::OInterfaceContainerHelper m_aChangeListeners;
+ ::cppu::OInterfaceContainerHelper m_aItemListeners;
+
+ ::com::sun::star::uno::Any m_aCurrentSelection;
+ Timer m_aChangeTimer;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XListBox >
+ m_xAggregateListBox;
+
+ ::rtl::Reference< ::comphelper::AsyncEventNotifier >
+ m_pItemBroadcaster;
+
+protected:
+ // UNO Anbindung
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();
+
+public:
+ OListBoxControl(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);
+ virtual ~OListBoxControl();
+
+ // UNO Anbindung
+ DECLARE_UNO3_AGG_DEFAULTS(OListBoxControl, OBoundControl);
+ virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException);
+
+// XServiceInfo
+ IMPLEMENTATION_NAME(OListBoxControl);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
+
+// XChangeBroadcaster
+ virtual void SAL_CALL addChangeListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XChangeListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeChangeListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XChangeListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);
+
+// XFocusListener
+ virtual void SAL_CALL focusGained(const ::com::sun::star::awt::FocusEvent& _rEvent) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL focusLost(const ::com::sun::star::awt::FocusEvent& _rEvent) throw(::com::sun::star::uno::RuntimeException);
+
+// XItemListener
+ virtual void SAL_CALL itemStateChanged(const ::com::sun::star::awt::ItemEvent& _rEvent) throw(::com::sun::star::uno::RuntimeException);
+
+// XEventListener
+ virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException);
+
+// OComponentHelper
+ virtual void SAL_CALL disposing();
+
+// XListBox
+ virtual void SAL_CALL addItemListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XItemListener >& l ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeItemListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XItemListener >& l ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addActionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XActionListener >& l ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeActionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XActionListener >& l ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addItem( const ::rtl::OUString& aItem, ::sal_Int16 nPos ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addItems( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aItems, ::sal_Int16 nPos ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeItems( ::sal_Int16 nPos, ::sal_Int16 nCount ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int16 SAL_CALL getItemCount( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getItem( ::sal_Int16 nPos ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getItems( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int16 SAL_CALL getSelectedItemPos( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::sal_Int16 > SAL_CALL getSelectedItemsPos( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getSelectedItem( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSelectedItems( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL selectItemPos( ::sal_Int16 nPos, ::sal_Bool bSelect ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL selectItemsPos( const ::com::sun::star::uno::Sequence< ::sal_Int16 >& aPositions, ::sal_Bool bSelect ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL selectItem( const ::rtl::OUString& aItem, ::sal_Bool bSelect ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL isMutipleMode( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setMultipleMode( ::sal_Bool bMulti ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int16 SAL_CALL getDropDownLineCount( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setDropDownLineCount( ::sal_Int16 nLines ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL makeVisible( ::sal_Int16 nEntry ) throw (::com::sun::star::uno::RuntimeException);
+
+protected:
+ // IEventProcessor
+ virtual void processEvent( const ::comphelper::AnyEvent& _rEvent );
+
+private:
+ DECL_LINK( OnTimeout, void* );
+};
+
+//.........................................................................
+}
+//.........................................................................
+
+#endif // _FORMS_LISTBOX_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/Numeric.cxx b/forms/source/component/Numeric.cxx
new file mode 100644
index 000000000000..b722c8058f4d
--- /dev/null
+++ b/forms/source/component/Numeric.cxx
@@ -0,0 +1,224 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+#include "Numeric.hxx"
+#include <tools/debug.hxx>
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::form;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::form::binding;
+
+//==================================================================
+// ONumericControl
+//==================================================================
+
+//------------------------------------------------------------------
+ONumericControl::ONumericControl(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OBoundControl(_rxFactory, VCL_CONTROL_NUMERICFIELD)
+{
+}
+
+//------------------------------------------------------------------------------
+StringSequence ONumericControl::getSupportedServiceNames() throw()
+{
+ StringSequence aSupported = OBoundControl::getSupportedServiceNames();
+ aSupported.realloc(aSupported.getLength() + 1);
+
+ ::rtl::OUString*pArray = aSupported.getArray();
+ pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_NUMERICFIELD;
+ return aSupported;
+}
+
+
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL ONumericControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
+{
+ return *(new ONumericControl(_rxFactory));
+}
+
+//------------------------------------------------------------------------------
+Sequence<Type> ONumericControl::_getTypes()
+{
+ return OBoundControl::_getTypes();
+}
+
+//==================================================================
+// ONumericModel
+//==================================================================
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL ONumericModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
+{
+ return *(new ONumericModel(_rxFactory));
+}
+
+//------------------------------------------------------------------------------
+Sequence<Type> ONumericModel::_getTypes()
+{
+ return OEditBaseModel::_getTypes();
+}
+
+//------------------------------------------------------------------
+DBG_NAME( ONumericModel )
+//------------------------------------------------------------------
+ONumericModel::ONumericModel(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OEditBaseModel( _rxFactory, VCL_CONTROLMODEL_NUMERICFIELD, FRM_SUN_CONTROL_NUMERICFIELD, sal_True, sal_True )
+ // use the old control name for compytibility reasons
+{
+ DBG_CTOR( ONumericModel, NULL );
+
+ m_nClassId = FormComponentType::NUMERICFIELD;
+ initValueProperty( PROPERTY_VALUE, PROPERTY_ID_VALUE );
+}
+
+//------------------------------------------------------------------
+ONumericModel::ONumericModel( const ONumericModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
+ :OEditBaseModel( _pOriginal, _rxFactory )
+{
+ DBG_CTOR( ONumericModel, NULL );
+}
+
+//------------------------------------------------------------------
+ONumericModel::~ONumericModel()
+{
+ DBG_DTOR( ONumericModel, NULL );
+}
+
+// XCloneable
+//------------------------------------------------------------------------------
+IMPLEMENT_DEFAULT_CLONING( ONumericModel )
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+StringSequence ONumericModel::getSupportedServiceNames() throw()
+{
+ StringSequence aSupported = OBoundControlModel::getSupportedServiceNames();
+
+ sal_Int32 nOldLen = aSupported.getLength();
+ aSupported.realloc( nOldLen + 8 );
+ ::rtl::OUString* pStoreTo = aSupported.getArray() + nOldLen;
+
+ *pStoreTo++ = BINDABLE_CONTROL_MODEL;
+ *pStoreTo++ = DATA_AWARE_CONTROL_MODEL;
+ *pStoreTo++ = VALIDATABLE_CONTROL_MODEL;
+
+ *pStoreTo++ = BINDABLE_DATA_AWARE_CONTROL_MODEL;
+ *pStoreTo++ = VALIDATABLE_BINDABLE_CONTROL_MODEL;
+
+ *pStoreTo++ = FRM_SUN_COMPONENT_NUMERICFIELD;
+ *pStoreTo++ = FRM_SUN_COMPONENT_DATABASE_NUMERICFIELD;
+ *pStoreTo++ = BINDABLE_DATABASE_NUMERIC_FIELD;
+
+ return aSupported;
+}
+
+//------------------------------------------------------------------------------
+void ONumericModel::describeFixedProperties( Sequence< Property >& _rProps ) const
+{
+ BEGIN_DESCRIBE_PROPERTIES( 2, OEditBaseModel )
+ DECL_PROP3(DEFAULT_VALUE, double, BOUND, MAYBEDEFAULT, MAYBEVOID);
+ DECL_PROP1(TABINDEX, sal_Int16, BOUND);
+ END_DESCRIBE_PROPERTIES();
+}
+
+//------------------------------------------------------------------------------
+::rtl::OUString SAL_CALL ONumericModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException)
+{
+ return FRM_COMPONENT_NUMERICFIELD; // old (non-sun) name for compatibility !
+}
+
+//------------------------------------------------------------------------------
+sal_Bool ONumericModel::commitControlValueToDbColumn( bool /*_bPostReset*/ )
+{
+ Any aControlValue( m_xAggregateFastSet->getFastPropertyValue( getValuePropertyAggHandle() ) );
+ if ( !compare( aControlValue, m_aSaveValue ) )
+ {
+ if ( !aControlValue.hasValue() )
+ m_xColumnUpdate->updateNull();
+ else
+ {
+ try
+ {
+ m_xColumnUpdate->updateDouble( getDouble( aControlValue ) );
+ }
+ catch(Exception&)
+ {
+ return sal_False;
+ }
+ }
+ m_aSaveValue = aControlValue;
+ }
+ return sal_True;
+}
+
+//------------------------------------------------------------------------------
+Any ONumericModel::translateDbColumnToControlValue()
+{
+ m_aSaveValue <<= (double)m_xColumn->getDouble();
+ if ( m_xColumn->wasNull() )
+ m_aSaveValue.clear();
+
+ return m_aSaveValue;
+}
+
+//------------------------------------------------------------------------------
+Any ONumericModel::getDefaultForReset() const
+{
+ Any aValue;
+ if (m_aDefault.getValueType().getTypeClass() == TypeClass_DOUBLE)
+ aValue = m_aDefault;
+
+ return aValue;
+}
+
+//------------------------------------------------------------------------------
+void ONumericModel::resetNoBroadcast()
+{
+ OEditBaseModel::resetNoBroadcast();
+ m_aSaveValue.clear();
+}
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/Numeric.hxx b/forms/source/component/Numeric.hxx
new file mode 100644
index 000000000000..7cef3c7ef5bb
--- /dev/null
+++ b/forms/source/component/Numeric.hxx
@@ -0,0 +1,101 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FORMS_NUMERIC_HXX_
+#define _FORMS_NUMERIC_HXX_
+
+#include "EditBase.hxx"
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+//==================================================================
+//= ONumericModel
+//==================================================================
+class ONumericModel
+ :public OEditBaseModel
+{
+private:
+ ::com::sun::star::uno::Any m_aSaveValue;
+protected:
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();
+
+public:
+ DECLARE_DEFAULT_LEAF_XTOR( ONumericModel );
+
+ // ::com::sun::star::lang::XServiceInfo
+ IMPLEMENTATION_NAME(ONumericModel);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw();
+
+ // ::com::sun::star::io::XPersistObject
+ virtual ::rtl::OUString SAL_CALL getServiceName() throw ( ::com::sun::star::uno::RuntimeException);
+
+ // OControlModel's property handling
+ virtual void describeFixedProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps
+ ) const;
+
+protected:
+ // OBoundControlModel overridables
+ virtual ::com::sun::star::uno::Any
+ translateDbColumnToControlValue( );
+ virtual sal_Bool commitControlValueToDbColumn( bool _bPostReset );
+
+ virtual ::com::sun::star::uno::Any
+ getDefaultForReset() const;
+ virtual void resetNoBroadcast();
+
+protected:
+ DECLARE_XCLONEABLE();
+};
+
+//==================================================================
+//= ONumericControl
+//==================================================================
+class ONumericControl: public OBoundControl
+{
+protected:
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();
+
+public:
+ ONumericControl(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);
+
+ // ::com::sun::star::lang::XServiceInfo
+ IMPLEMENTATION_NAME(ONumericControl);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw();
+};
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+#endif // _FORMS_NUMERIC_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/Pattern.cxx b/forms/source/component/Pattern.cxx
new file mode 100644
index 000000000000..1600af87649d
--- /dev/null
+++ b/forms/source/component/Pattern.cxx
@@ -0,0 +1,264 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+
+#include "Pattern.hxx"
+
+/** === begin UNO includes === **/
+/** === end UNO includes === **/
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::lang::XMultiServiceFactory;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::uno::Type;
+ using ::com::sun::star::beans::Property;
+ using ::com::sun::star::uno::Exception;
+ using ::com::sun::star::uno::XInterface;
+ using ::com::sun::star::uno::Any;
+ using ::com::sun::star::uno::makeAny;
+ using ::com::sun::star::sdbc::XRowSet;
+ using ::com::sun::star::uno::UNO_QUERY;
+ /** === end UNO using === **/
+ namespace FormComponentType = ::com::sun::star::form::FormComponentType;
+
+//==================================================================
+// OPatternControl
+//==================================================================
+//------------------------------------------------------------------
+OPatternControl::OPatternControl(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OBoundControl(_rxFactory, VCL_CONTROL_PATTERNFIELD)
+{
+}
+
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL OPatternControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
+{
+ return *(new OPatternControl(_rxFactory));
+}
+
+//------------------------------------------------------------------------------
+Sequence<Type> OPatternControl::_getTypes()
+{
+ return OBoundControl::_getTypes();
+}
+
+//------------------------------------------------------------------------------
+StringSequence OPatternControl::getSupportedServiceNames() throw()
+{
+ StringSequence aSupported = OBoundControl::getSupportedServiceNames();
+ aSupported.realloc(aSupported.getLength() + 1);
+
+ ::rtl::OUString*pArray = aSupported.getArray();
+ pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_PATTERNFIELD;
+ return aSupported;
+}
+
+//==================================================================
+// OPatternModel
+//==================================================================
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL OPatternModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
+{
+ return *(new OPatternModel(_rxFactory));
+}
+
+//------------------------------------------------------------------------------
+Sequence<Type> OPatternModel::_getTypes()
+{
+ return OEditBaseModel::_getTypes();
+}
+
+//------------------------------------------------------------------
+DBG_NAME( OPatternModel )
+//------------------------------------------------------------------
+OPatternModel::OPatternModel(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OEditBaseModel( _rxFactory, VCL_CONTROLMODEL_PATTERNFIELD, FRM_SUN_CONTROL_PATTERNFIELD, sal_False, sal_False )
+ // use the old control name for compytibility reasons
+{
+ DBG_CTOR( OPatternModel, NULL );
+
+ m_nClassId = FormComponentType::PATTERNFIELD;
+ initValueProperty( PROPERTY_TEXT, PROPERTY_ID_TEXT );
+}
+
+//------------------------------------------------------------------
+OPatternModel::OPatternModel( const OPatternModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
+ :OEditBaseModel( _pOriginal, _rxFactory )
+{
+ DBG_CTOR( OPatternModel, NULL );
+}
+
+//------------------------------------------------------------------
+OPatternModel::~OPatternModel()
+{
+ DBG_DTOR( OPatternModel, NULL );
+}
+
+// XCloneable
+//------------------------------------------------------------------------------
+IMPLEMENT_DEFAULT_CLONING( OPatternModel )
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+StringSequence SAL_CALL OPatternModel::getSupportedServiceNames() throw()
+{
+ StringSequence aSupported = OBoundControlModel::getSupportedServiceNames();
+ aSupported.realloc(aSupported.getLength() + 2);
+
+ ::rtl::OUString*pArray = aSupported.getArray();
+ pArray[aSupported.getLength()-2] = FRM_SUN_COMPONENT_DATABASE_PATTERNFIELD;
+ pArray[aSupported.getLength()-1] = FRM_SUN_COMPONENT_PATTERNFIELD;
+ return aSupported;
+}
+
+
+//------------------------------------------------------------------------------
+void OPatternModel::describeFixedProperties( Sequence< Property >& _rProps ) const
+{
+ BEGIN_DESCRIBE_PROPERTIES( 4, OEditBaseModel )
+ DECL_PROP2(DEFAULT_TEXT, ::rtl::OUString, BOUND, MAYBEDEFAULT);
+ DECL_BOOL_PROP1(EMPTY_IS_NULL, BOUND);
+ DECL_PROP1(TABINDEX, sal_Int16, BOUND);
+ DECL_PROP2(FILTERPROPOSAL, sal_Bool, BOUND, MAYBEDEFAULT);
+ END_DESCRIBE_PROPERTIES();
+}
+
+//------------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OPatternModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException)
+{
+ return FRM_COMPONENT_PATTERNFIELD; // old (non-sun) name for compatibility !
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OPatternModel::commitControlValueToDbColumn( bool /*_bPostReset*/ )
+{
+ Any aNewValue( m_xAggregateFastSet->getFastPropertyValue( getValuePropertyAggHandle() ) );
+
+ if ( aNewValue != m_aLastKnownValue )
+ {
+ ::rtl::OUString sNewValue;
+ aNewValue >>= sNewValue;
+
+ if ( !aNewValue.hasValue()
+ || ( !sNewValue.getLength() // an empty string
+ && m_bEmptyIsNull // which should be interpreted as NULL
+ )
+ )
+ {
+ m_xColumnUpdate->updateNull();
+ }
+ else
+ {
+ OSL_ENSURE( m_pFormattedValue.get(), "OPatternModel::commitControlValueToDbColumn: no value helper!" );
+ if ( !m_pFormattedValue.get() )
+ return sal_False;
+
+ if ( !m_pFormattedValue->setFormattedValue( sNewValue ) )
+ return sal_False;
+ }
+
+ m_aLastKnownValue = aNewValue;
+ }
+
+ return sal_True;
+}
+
+//------------------------------------------------------------------------------
+void OPatternModel::onConnectedDbColumn( const Reference< XInterface >& _rxForm )
+{
+ OEditBaseModel::onConnectedDbColumn( _rxForm );
+
+ Reference< XPropertySet > xField( getField() );
+ if ( !xField.is() )
+ return;
+
+ m_pFormattedValue.reset( new ::dbtools::FormattedColumnValue( getContext(), Reference< XRowSet >( _rxForm, UNO_QUERY ), xField ) );
+}
+
+//------------------------------------------------------------------------------
+void OPatternModel::onDisconnectedDbColumn()
+{
+ OEditBaseModel::onDisconnectedDbColumn();
+ m_pFormattedValue.reset();
+}
+
+// XPropertyChangeListener
+//------------------------------------------------------------------------------
+Any OPatternModel::translateDbColumnToControlValue()
+{
+ OSL_PRECOND( m_pFormattedValue.get(), "OPatternModel::translateDbColumnToControlValue: no value helper!" );
+
+ if ( m_pFormattedValue.get() )
+ {
+ ::rtl::OUString sValue( m_pFormattedValue->getFormattedValue() );
+ if ( !sValue.getLength()
+ && m_pFormattedValue->getColumn().is()
+ && m_pFormattedValue->getColumn()->wasNull()
+ )
+ {
+ m_aLastKnownValue.clear();
+ }
+ else
+ {
+ m_aLastKnownValue <<= sValue;
+ }
+ }
+ else
+ m_aLastKnownValue.clear();
+
+ return m_aLastKnownValue.hasValue() ? m_aLastKnownValue : makeAny( ::rtl::OUString() );
+ // (m_aLastKnownValue is alllowed to be VOID, the control value isn't)
+}
+
+// XReset
+//------------------------------------------------------------------------------
+Any OPatternModel::getDefaultForReset() const
+{
+ return makeAny( m_aDefaultText );
+}
+
+//------------------------------------------------------------------------------
+void OPatternModel::resetNoBroadcast()
+{
+ OEditBaseModel::resetNoBroadcast();
+ m_aLastKnownValue.clear();
+}
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/Pattern.hxx b/forms/source/component/Pattern.hxx
new file mode 100644
index 000000000000..9460bb42fa4e
--- /dev/null
+++ b/forms/source/component/Pattern.hxx
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FORMS_PATTERN_HXX_
+#define _FORMS_PATTERN_HXX_
+
+#include "EditBase.hxx"
+
+#include <connectivity/formattedcolumnvalue.hxx>
+
+#include <memory>
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+//==================================================================
+//= OPatternModel
+//==================================================================
+class OPatternModel
+ :public OEditBaseModel
+{
+private:
+ ::com::sun::star::uno::Any m_aLastKnownValue;
+ ::std::auto_ptr< ::dbtools::FormattedColumnValue >
+ m_pFormattedValue;
+
+protected:
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();
+
+public:
+ DECLARE_DEFAULT_LEAF_XTOR( OPatternModel );
+
+ // ::com::sun::star::lang::XServiceInfo
+ IMPLEMENTATION_NAME(OPatternModel);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw();
+
+ // ::com::sun::star::io::XPersistObject
+ virtual ::rtl::OUString SAL_CALL getServiceName() throw ( ::com::sun::star::uno::RuntimeException);
+
+ // OControlModel's property handling
+ virtual void describeFixedProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps
+ ) const;
+
+protected:
+ // OBoundControlModel overridables
+ virtual ::com::sun::star::uno::Any
+ translateDbColumnToControlValue( );
+ virtual sal_Bool commitControlValueToDbColumn( bool _bPostReset );
+ virtual void onConnectedDbColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxForm );
+ virtual void onDisconnectedDbColumn();
+
+ virtual ::com::sun::star::uno::Any
+ getDefaultForReset() const;
+ virtual void resetNoBroadcast();
+
+protected:
+ DECLARE_XCLONEABLE();
+};
+
+//==================================================================
+//= OPatternControl
+//==================================================================
+class OPatternControl: public OBoundControl
+{
+protected:
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();
+
+public:
+ OPatternControl(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);
+
+ // ::com::sun::star::lang::XServiceInfo
+ IMPLEMENTATION_NAME(OPatternControl);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw();
+};
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+#endif // _FORMS_PATTERN_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/RadioButton.cxx b/forms/source/component/RadioButton.cxx
new file mode 100644
index 000000000000..5227e5396db8
--- /dev/null
+++ b/forms/source/component/RadioButton.cxx
@@ -0,0 +1,438 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+#include "RadioButton.hxx"
+#include "GroupManager.hxx"
+#include "property.hxx"
+#include "property.hrc"
+#include "services.hxx"
+#include <tools/debug.hxx>
+#include <comphelper/extract.hxx>
+#include <comphelper/basicio.hxx>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/awt/XVclWindowPeer.hpp>
+
+//.........................................................................
+namespace frm
+{
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::form;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::form::binding;
+
+//==================================================================
+//------------------------------------------------------------------------------
+InterfaceRef SAL_CALL ORadioButtonControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory) throw (RuntimeException)
+{
+ return *(new ORadioButtonControl(_rxFactory));
+}
+
+//------------------------------------------------------------------------------
+StringSequence SAL_CALL ORadioButtonControl::getSupportedServiceNames() throw(RuntimeException)
+{
+ StringSequence aSupported = OBoundControl::getSupportedServiceNames();
+ aSupported.realloc(aSupported.getLength() + 1);
+
+ ::rtl::OUString* pArray = aSupported.getArray();
+ pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_RADIOBUTTON;
+ return aSupported;
+}
+
+
+//------------------------------------------------------------------
+ORadioButtonControl::ORadioButtonControl(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OBoundControl(_rxFactory, VCL_CONTROL_RADIOBUTTON)
+{
+}
+
+//------------------------------------------------------------------
+void SAL_CALL ORadioButtonControl::createPeer(const Reference<starawt::XToolkit>& _rxToolkit, const Reference<starawt::XWindowPeer>& _rxParent) throw (RuntimeException)
+{
+ OBoundControl::createPeer(_rxToolkit, _rxParent);
+
+ // switch off the auto-toggle, we do this ourself ....
+ // (formerly this switch-off was done in the toolkit - but the correct place is here ...)
+// Reference< XVclWindowPeer > xVclWindowPeer( getPeer(), UNO_QUERY );
+// if (xVclWindowPeer.is())
+// xVclWindowPeer->setProperty(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AutoToggle")), ::cppu::bool2any(sal_False));
+ // new order: do _not_ switch off the auto toggle because:
+ // * today, it is not necessary anymore to handle the toggling ourself (everything works fine without it)
+ // * without auto toggle, the AccessibleEvents as fired by the radio buttons are
+ // a. newly checked button: "unchecked"->"checked"
+ // b. previously checked button: "checked"->"unchecked"
+ // This is deadly for AT-tools, which then get the "unchecked" event _immediately_ after the "checked" event,
+ // and only read the latter. This makes radio buttons pretty unusable in form documents.
+ // So we switched AutoToggle _on_, again, because then VCL can handle the notifications, and will send
+ // them in the proper order.
+}
+
+//==================================================================
+InterfaceRef SAL_CALL ORadioButtonModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory) throw (RuntimeException)
+{
+ return *(new ORadioButtonModel(_rxFactory));
+}
+
+//------------------------------------------------------------------
+DBG_NAME( ORadioButtonModel )
+//------------------------------------------------------------------
+ORadioButtonModel::ORadioButtonModel(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OReferenceValueComponent( _rxFactory, VCL_CONTROLMODEL_RADIOBUTTON, FRM_SUN_CONTROL_RADIOBUTTON,sal_True )
+ // use the old control name for compytibility reasons
+{
+ DBG_CTOR( ORadioButtonModel, NULL );
+
+ m_nClassId = FormComponentType::RADIOBUTTON;
+ m_aLabelServiceName = FRM_SUN_COMPONENT_GROUPBOX;
+ initValueProperty( PROPERTY_STATE, PROPERTY_ID_STATE );
+ startAggregatePropertyListening( PROPERTY_GROUP_NAME );
+}
+
+//------------------------------------------------------------------
+ORadioButtonModel::ORadioButtonModel( const ORadioButtonModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
+ :OReferenceValueComponent( _pOriginal, _rxFactory )
+{
+ DBG_CTOR( ORadioButtonModel, NULL );
+}
+
+//------------------------------------------------------------------------------
+ORadioButtonModel::~ORadioButtonModel()
+{
+ DBG_DTOR( ORadioButtonModel, NULL );
+}
+
+// XCloneable
+//------------------------------------------------------------------------------
+IMPLEMENT_DEFAULT_CLONING( ORadioButtonModel )
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+StringSequence SAL_CALL ORadioButtonModel::getSupportedServiceNames() throw(RuntimeException)
+{
+ StringSequence aSupported = OReferenceValueComponent::getSupportedServiceNames();
+
+ sal_Int32 nOldLen = aSupported.getLength();
+ aSupported.realloc( nOldLen + 8 );
+ ::rtl::OUString* pStoreTo = aSupported.getArray() + nOldLen;
+
+ *pStoreTo++ = BINDABLE_CONTROL_MODEL;
+ *pStoreTo++ = DATA_AWARE_CONTROL_MODEL;
+ *pStoreTo++ = VALIDATABLE_CONTROL_MODEL;
+
+ *pStoreTo++ = BINDABLE_DATA_AWARE_CONTROL_MODEL;
+ *pStoreTo++ = VALIDATABLE_BINDABLE_CONTROL_MODEL;
+
+ *pStoreTo++ = FRM_SUN_COMPONENT_RADIOBUTTON;
+ *pStoreTo++ = FRM_SUN_COMPONENT_DATABASE_RADIOBUTTON;
+ *pStoreTo++ = BINDABLE_DATABASE_RADIO_BUTTON;
+
+ return aSupported;
+}
+
+//------------------------------------------------------------------------------
+void ORadioButtonModel::SetSiblingPropsTo(const ::rtl::OUString& rPropName, const Any& rValue)
+{
+ // my name
+ ::rtl::OUString sMyGroup;
+ if (hasProperty(PROPERTY_GROUP_NAME, this))
+ this->getPropertyValue(PROPERTY_GROUP_NAME) >>= sMyGroup;
+ if (sMyGroup.getLength() == 0)
+ sMyGroup = m_aName;
+
+ // meine Siblings durchiterieren
+ Reference<XIndexAccess> xIndexAccess(getParent(), UNO_QUERY);
+ if (xIndexAccess.is())
+ {
+ Reference<XPropertySet> xMyProps;
+ query_interface(static_cast<XWeak*>(this), xMyProps);
+ ::rtl::OUString sCurrentGroup;
+ sal_Int32 nNumSiblings = xIndexAccess->getCount();
+ for (sal_Int32 i=0; i<nNumSiblings; ++i)
+ {
+ Reference<XPropertySet> xSiblingProperties(*(InterfaceRef*)xIndexAccess->getByIndex(i).getValue(), UNO_QUERY);
+ if (!xSiblingProperties.is())
+ continue;
+ if (xMyProps == xSiblingProperties)
+ continue; // mich selber nicht umsetzen
+
+ // nur wenn es ein Radio-Button ist
+ if (!hasProperty(PROPERTY_CLASSID, xSiblingProperties))
+ continue;
+ sal_Int16 nType = 0;
+ xSiblingProperties->getPropertyValue(PROPERTY_CLASSID) >>= nType;
+ if (nType != FormComponentType::RADIOBUTTON)
+ continue;
+
+ // das 'zur selben Gruppe gehoeren' wird am Namen festgemacht
+ sCurrentGroup = OGroupManager::GetGroupName( xSiblingProperties );
+ if (sCurrentGroup == sMyGroup)
+ xSiblingProperties->setPropertyValue(rPropName, rValue);
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void ORadioButtonModel::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const Any& rValue) throw (Exception)
+{
+ OReferenceValueComponent::setFastPropertyValue_NoBroadcast( nHandle, rValue );
+
+ // if the label control changed ...
+ if (nHandle == PROPERTY_ID_CONTROLLABEL)
+ { // ... forward this to our siblings
+ SetSiblingPropsTo(PROPERTY_CONTROLLABEL, rValue);
+ }
+
+ // wenn sich die ControlSource-Eigenschaft geaendert hat ...
+ if (nHandle == PROPERTY_ID_CONTROLSOURCE)
+ { // ... muss ich allen meinen Siblings, die in der selben RadioButton-Gruppe sind wie ich, auch die
+ // neue ControlSource mitgeben
+ SetSiblingPropsTo(PROPERTY_CONTROLSOURCE, rValue);
+ }
+
+ // die andere Richtung : wenn sich mein Name aendert ...
+ if (nHandle == PROPERTY_ID_NAME)
+ {
+ setControlSource();
+ }
+
+ if (nHandle == PROPERTY_ID_DEFAULT_STATE)
+ {
+ sal_Int16 nValue;
+ rValue >>= nValue;
+ if (1 == nValue)
+ { // bei allen Radios der selben Gruppe das 'default checked' ruecksetzen, denn wie schon der highlander wusste :
+ // es kann nur einen geben.
+ Any aZero;
+ nValue = 0;
+ aZero <<= nValue;
+ SetSiblingPropsTo(PROPERTY_DEFAULT_STATE, aZero);
+ }
+ }
+}
+
+void ORadioButtonModel::setControlSource()
+{
+ Reference<XIndexAccess> xIndexAccess(getParent(), UNO_QUERY);
+ if (xIndexAccess.is())
+ {
+ ::rtl::OUString sName, sGroupName;
+
+ if (hasProperty(PROPERTY_GROUP_NAME, this))
+ this->getPropertyValue(PROPERTY_GROUP_NAME) >>= sGroupName;
+ this->getPropertyValue(PROPERTY_NAME) >>= sName;
+
+ Reference<XPropertySet> xMyProps;
+ query_interface(static_cast<XWeak*>(this), xMyProps);
+ for (sal_Int32 i=0; i<xIndexAccess->getCount(); ++i)
+ {
+ Reference<XPropertySet> xSiblingProperties(*(InterfaceRef*)xIndexAccess->getByIndex(i).getValue(), UNO_QUERY);
+ if (!xSiblingProperties.is())
+ continue;
+
+ if (xMyProps == xSiblingProperties)
+ // nur wenn ich nicht mich selber gefunden habe
+ continue;
+
+ sal_Int16 nType = 0;
+ xSiblingProperties->getPropertyValue(PROPERTY_CLASSID) >>= nType;
+ if (nType != FormComponentType::RADIOBUTTON)
+ // nur Radio-Buttons
+ continue;
+
+ ::rtl::OUString sSiblingName, sSiblingGroupName;
+ if (hasProperty(PROPERTY_GROUP_NAME, xSiblingProperties))
+ xSiblingProperties->getPropertyValue(PROPERTY_GROUP_NAME) >>= sSiblingGroupName;
+ xSiblingProperties->getPropertyValue(PROPERTY_NAME) >>= sSiblingName;
+
+ if ((sGroupName.getLength() == 0 && sSiblingGroupName.getLength() == 0 && // (no group name
+ sName == sSiblingName) || // names match) or
+ (sGroupName.getLength() != 0 && sSiblingGroupName.getLength() != 0 && // (have group name
+ sGroupName == sSiblingGroupName)) // they match)
+ {
+ setPropertyValue(PROPERTY_CONTROLSOURCE, xSiblingProperties->getPropertyValue(PROPERTY_CONTROLSOURCE));
+ break;
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void ORadioButtonModel::describeFixedProperties( Sequence< Property >& _rProps ) const
+{
+ BEGIN_DESCRIBE_PROPERTIES( 1, OReferenceValueComponent )
+ DECL_PROP1(TABINDEX, sal_Int16, BOUND);
+ END_DESCRIBE_PROPERTIES();
+}
+
+//------------------------------------------------------------------------------
+::rtl::OUString SAL_CALL ORadioButtonModel::getServiceName() throw(RuntimeException)
+{
+ return FRM_COMPONENT_RADIOBUTTON; // old (non-sun) name for compatibility !
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ORadioButtonModel::write(const Reference<XObjectOutputStream>& _rxOutStream)
+ throw(IOException, RuntimeException)
+{
+ OReferenceValueComponent::write(_rxOutStream);
+
+ // Version
+ _rxOutStream->writeShort(0x0003);
+
+ // Properties
+ _rxOutStream << getReferenceValue();
+ _rxOutStream << (sal_Int16)getDefaultChecked();
+ writeHelpTextCompatibly(_rxOutStream);
+
+ // from version 0x0003 : common properties
+ writeCommonProperties(_rxOutStream);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ORadioButtonModel::read(const Reference<XObjectInputStream>& _rxInStream) throw(IOException, RuntimeException)
+{
+ OReferenceValueComponent::read(_rxInStream);
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ // Version
+ sal_uInt16 nVersion = _rxInStream->readShort();
+
+ ::rtl::OUString sReferenceValue;
+ sal_Int16 nDefaultChecked( 0 );
+ switch (nVersion)
+ {
+ case 0x0001 :
+ _rxInStream >> sReferenceValue;
+ _rxInStream >> nDefaultChecked;
+ break;
+ case 0x0002 :
+ _rxInStream >> sReferenceValue;
+ _rxInStream >> nDefaultChecked;
+ readHelpTextCompatibly(_rxInStream);
+ break;
+ case 0x0003 :
+ _rxInStream >> sReferenceValue;
+ _rxInStream >> nDefaultChecked;
+ readHelpTextCompatibly(_rxInStream);
+ readCommonProperties(_rxInStream);
+ break;
+ default :
+ OSL_FAIL("ORadioButtonModel::read : unknown version !");
+ defaultCommonProperties();
+ break;
+ }
+
+ setReferenceValue( sReferenceValue );
+ setDefaultChecked( (ToggleState)nDefaultChecked );
+
+ // Nach dem Lesen die Defaultwerte anzeigen
+ if ( getControlSource().getLength() )
+ // (not if we don't have a control source - the "State" property acts like it is persistent, then
+ resetNoBroadcast();
+}
+
+//------------------------------------------------------------------------------
+void ORadioButtonModel::_propertyChanged(const PropertyChangeEvent& _rEvent) throw(RuntimeException)
+{
+ if ( _rEvent.PropertyName.equals( PROPERTY_STATE ) )
+ {
+ if ( _rEvent.NewValue == (sal_Int16)1 )
+ {
+ // wenn sich mein Status auf 'checked' geaendert hat, muss ich alle meine Siblings, die in der selben Gruppe
+ // sind wie ich, entsprechend zuruecksetzen
+ Any aZero;
+ aZero <<= (sal_Int16)0;
+ SetSiblingPropsTo( PROPERTY_STATE, aZero );
+ }
+ }
+ else if ( _rEvent.PropertyName.equals( PROPERTY_GROUP_NAME ) )
+ {
+ setControlSource();
+ // Can't call OReferenceValueComponent::_propertyChanged(), as it
+ // doesn't know what to do with the GroupName property.
+ return;
+ }
+
+ OReferenceValueComponent::_propertyChanged( _rEvent );
+}
+
+//------------------------------------------------------------------------------
+Any ORadioButtonModel::translateDbColumnToControlValue()
+{
+ return makeAny( (sal_Int16)
+ ( ( m_xColumn->getString() == getReferenceValue() ) ? STATE_CHECK : STATE_NOCHECK )
+ );
+}
+
+//------------------------------------------------------------------------------
+Any ORadioButtonModel::translateExternalValueToControlValue( const Any& _rExternalValue ) const
+{
+ Any aControlValue = OReferenceValueComponent::translateExternalValueToControlValue( _rExternalValue );
+ sal_Int16 nState = STATE_NOCHECK;
+ if ( ( aControlValue >>= nState ) && ( nState == STATE_DONTKNOW ) )
+ // radio buttons do not have the DONTKNOW state
+ aControlValue <<= (sal_Int16)STATE_NOCHECK;
+ return aControlValue;
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool ORadioButtonModel::commitControlValueToDbColumn( bool /*_bPostReset*/ )
+{
+ Reference< XPropertySet > xField( getField() );
+ OSL_PRECOND( xField.is(), "ORadioButtonModel::commitControlValueToDbColumn: not bound!" );
+ if ( xField.is() )
+ {
+ try
+ {
+ sal_Int16 nValue = 0;
+ m_xAggregateSet->getPropertyValue( PROPERTY_STATE ) >>= nValue;
+ if ( nValue == 1 )
+ xField->setPropertyValue( PROPERTY_VALUE, makeAny( getReferenceValue() ) );
+ }
+ catch(Exception&)
+ {
+ OSL_FAIL("ORadioButtonModel::commitControlValueToDbColumn: could not commit !");
+ }
+ }
+ return sal_True;
+}
+
+//.........................................................................
+}
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/RadioButton.hxx b/forms/source/component/RadioButton.hxx
new file mode 100644
index 000000000000..0ffd8a2ba9b5
--- /dev/null
+++ b/forms/source/component/RadioButton.hxx
@@ -0,0 +1,115 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FORMS_RADIOBUTTON_HXX_
+#define _FORMS_RADIOBUTTON_HXX_
+
+#include "refvaluecomponent.hxx"
+
+//.........................................................................
+namespace frm
+{
+
+//==================================================================
+// ORadioButtonModel
+//==================================================================
+class ORadioButtonModel :public OReferenceValueComponent
+{
+public:
+ DECLARE_DEFAULT_LEAF_XTOR( ORadioButtonModel );
+
+ // XServiceInfo
+ IMPLEMENTATION_NAME(ORadioButtonModel);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
+
+ // OPropertySetHelper
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
+ throw (::com::sun::star::uno::Exception);
+
+ // XPersistObject
+ virtual ::rtl::OUString SAL_CALL getServiceName() throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL
+ write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL
+ read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ // OPropertyChangeListener
+ virtual void _propertyChanged(const ::com::sun::star::beans::PropertyChangeEvent& evt) throw(::com::sun::star::uno::RuntimeException);
+
+ // OControlModel's property handling
+ virtual void describeFixedProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps
+ ) const;
+
+protected:
+ // OBoundControlModel overridables
+ virtual ::com::sun::star::uno::Any
+ translateDbColumnToControlValue( );
+ virtual sal_Bool commitControlValueToDbColumn( bool _bPostReset );
+ virtual ::com::sun::star::uno::Any
+ translateExternalValueToControlValue( const ::com::sun::star::uno::Any& _rExternalValue ) const;
+
+protected:
+ void SetSiblingPropsTo(const ::rtl::OUString& rPropName, const ::com::sun::star::uno::Any& rValue);
+
+ DECLARE_XCLONEABLE( );
+
+private:
+ /** sets the given value as new State at the aggregate
+ @precond
+ our mutex is aquired exactly once
+ */
+ void setNewAggregateState( const ::com::sun::star::uno::Any& _rValue );
+
+ void setControlSource();
+};
+
+//==================================================================
+// ORadioButtonControl
+//==================================================================
+class ORadioButtonControl: public OBoundControl
+{
+public:
+ ORadioButtonControl(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);
+
+ // XServiceInfo
+ IMPLEMENTATION_NAME(ORadioButtonControl);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
+
+protected:
+ // XControl
+ virtual void SAL_CALL createPeer(const ::com::sun::star::uno::Reference<starawt::XToolkit>& Toolkit, const ::com::sun::star::uno::Reference<starawt::XWindowPeer>& Parent) throw (::com::sun::star::uno::RuntimeException);
+};
+
+//.........................................................................
+}
+//.........................................................................
+
+#endif // _FORMS_RADIOBUTTON_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/Time.cxx b/forms/source/component/Time.cxx
new file mode 100644
index 000000000000..0f0bb6336b33
--- /dev/null
+++ b/forms/source/component/Time.cxx
@@ -0,0 +1,367 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+#include "Time.hxx"
+#include <tools/debug.hxx>
+#include <tools/time.hxx>
+#include <connectivity/dbconversion.hxx>
+#include <com/sun/star/sdbc/DataType.hpp>
+
+using namespace dbtools;
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+using namespace ::com::sun::star;
+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::util;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+
+//==================================================================
+//=
+//==================================================================
+
+//==================================================================
+//= OTimeControl
+//==================================================================
+//------------------------------------------------------------------
+OTimeControl::OTimeControl(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OBoundControl(_rxFactory, VCL_CONTROL_TIMEFIELD)
+{
+}
+
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL OTimeControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
+{
+ return *(new OTimeControl(_rxFactory));
+}
+
+//------------------------------------------------------------------------------
+Sequence<Type> OTimeControl::_getTypes()
+{
+ return OBoundControl::_getTypes();
+}
+
+//------------------------------------------------------------------------------
+StringSequence SAL_CALL OTimeControl::getSupportedServiceNames() throw()
+{
+ StringSequence aSupported = OBoundControl::getSupportedServiceNames();
+ aSupported.realloc(aSupported.getLength() + 1);
+
+ ::rtl::OUString*pArray = aSupported.getArray();
+ pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_TIMEFIELD;
+ return aSupported;
+}
+
+//==================================================================
+//= OTimeModel
+//==================================================================
+//------------------------------------------------------------------
+InterfaceRef SAL_CALL OTimeModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
+{
+ return *(new OTimeModel(_rxFactory));
+}
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+StringSequence SAL_CALL OTimeModel::getSupportedServiceNames() throw()
+{
+ StringSequence aSupported = OBoundControlModel::getSupportedServiceNames();
+
+ sal_Int32 nOldLen = aSupported.getLength();
+ aSupported.realloc( nOldLen + 8 );
+ ::rtl::OUString* pStoreTo = aSupported.getArray() + nOldLen;
+
+ *pStoreTo++ = BINDABLE_CONTROL_MODEL;
+ *pStoreTo++ = DATA_AWARE_CONTROL_MODEL;
+ *pStoreTo++ = VALIDATABLE_CONTROL_MODEL;
+
+ *pStoreTo++ = BINDABLE_DATA_AWARE_CONTROL_MODEL;
+ *pStoreTo++ = VALIDATABLE_BINDABLE_CONTROL_MODEL;
+
+ *pStoreTo++ = FRM_SUN_COMPONENT_TIMEFIELD;
+ *pStoreTo++ = FRM_SUN_COMPONENT_DATABASE_TIMEFIELD;
+ *pStoreTo++ = BINDABLE_DATABASE_TIME_FIELD;
+
+ return aSupported;
+}
+
+//------------------------------------------------------------------------------
+Sequence<Type> OTimeModel::_getTypes()
+{
+ return OBoundControlModel::_getTypes();
+}
+
+//------------------------------------------------------------------
+DBG_NAME( OTimeModel )
+//------------------------------------------------------------------
+OTimeModel::OTimeModel(const Reference<XMultiServiceFactory>& _rxFactory)
+ :OEditBaseModel( _rxFactory, VCL_CONTROLMODEL_TIMEFIELD, FRM_SUN_CONTROL_TIMEFIELD, sal_True, sal_True )
+ // use the old control name for compytibility reasons
+ ,OLimitedFormats(_rxFactory, FormComponentType::TIMEFIELD)
+{
+ DBG_CTOR( OTimeModel, NULL );
+
+ m_nClassId = FormComponentType::TIMEFIELD;
+ initValueProperty( PROPERTY_TIME, PROPERTY_ID_TIME );
+
+ setAggregateSet(m_xAggregateFastSet, getOriginalHandle(PROPERTY_ID_TIMEFORMAT));
+}
+
+//------------------------------------------------------------------------------
+OTimeModel::OTimeModel( const OTimeModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
+ :OEditBaseModel( _pOriginal, _rxFactory )
+ ,OLimitedFormats( _rxFactory, FormComponentType::TIMEFIELD )
+{
+ DBG_CTOR( OTimeModel, NULL );
+
+ setAggregateSet( m_xAggregateFastSet, getOriginalHandle( PROPERTY_ID_TIMEFORMAT ) );
+}
+
+//------------------------------------------------------------------------------
+OTimeModel::~OTimeModel( )
+{
+ setAggregateSet(Reference< XFastPropertySet >(), -1);
+ DBG_DTOR( OTimeModel, NULL );
+}
+
+// XCloneable
+//------------------------------------------------------------------------------
+IMPLEMENT_DEFAULT_CLONING( OTimeModel )
+
+//------------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OTimeModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException)
+{
+ return FRM_COMPONENT_TIMEFIELD; // old (non-sun) name for compatibility !
+}
+
+// XPropertySet
+//------------------------------------------------------------------------------
+void OTimeModel::describeFixedProperties( Sequence< Property >& _rProps ) const
+{
+ BEGIN_DESCRIBE_PROPERTIES( 4, OEditBaseModel )
+ DECL_PROP3(DEFAULT_TIME, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID);
+ DECL_PROP1(TABINDEX, sal_Int16, BOUND);
+ DECL_PROP1(FORMATKEY, sal_Int32, TRANSIENT);
+ DECL_IFACE_PROP2(FORMATSSUPPLIER, XNumberFormatsSupplier, READONLY, TRANSIENT);
+ END_DESCRIBE_PROPERTIES();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OTimeModel::getFastPropertyValue(Any& _rValue, sal_Int32 _nHandle ) const
+{
+ switch (_nHandle)
+ {
+ case PROPERTY_ID_FORMATKEY:
+ getFormatKeyPropertyValue(_rValue);
+ break;
+ case PROPERTY_ID_FORMATSSUPPLIER:
+ _rValue <<= getFormatsSupplier();
+ break;
+ default:
+ OEditBaseModel::getFastPropertyValue(_rValue, _nHandle);
+ break;
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL OTimeModel::convertFastPropertyValue(Any& _rConvertedValue, Any& _rOldValue,
+ sal_Int32 _nHandle, const Any& _rValue ) throw(IllegalArgumentException)
+{
+ if (PROPERTY_ID_FORMATKEY == _nHandle)
+ return convertFormatKeyPropertyValue(_rConvertedValue, _rOldValue, _rValue);
+ else
+ return OEditBaseModel::convertFastPropertyValue(_rConvertedValue, _rOldValue, _nHandle, _rValue );
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OTimeModel::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle, const Any& _rValue) throw ( ::com::sun::star::uno::Exception)
+{
+ if (PROPERTY_ID_FORMATKEY == _nHandle)
+ setFormatKeyPropertyValue(_rValue);
+ else
+ OEditBaseModel::setFastPropertyValue_NoBroadcast(_nHandle, _rValue);
+}
+
+// XLoadListener
+//------------------------------------------------------------------------------
+void OTimeModel::onConnectedDbColumn( const Reference< XInterface >& _rxForm )
+{
+ OBoundControlModel::onConnectedDbColumn( _rxForm );
+ Reference<XPropertySet> xField = getField();
+ if (xField.is())
+ {
+ m_bDateTimeField = sal_False;
+ try
+ {
+ sal_Int32 nFieldType = 0;
+ xField->getPropertyValue(PROPERTY_FIELDTYPE) >>= nFieldType;
+ m_bDateTimeField = (nFieldType == DataType::TIMESTAMP);
+ }
+ catch(Exception&)
+ {
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OTimeModel::commitControlValueToDbColumn( bool /*_bPostReset*/ )
+{
+ Any aControlValue( m_xAggregateFastSet->getFastPropertyValue( getValuePropertyAggHandle() ) );
+ if ( !compare( aControlValue, m_aSaveValue ) )
+ {
+ if ( !aControlValue.hasValue() )
+ m_xColumnUpdate->updateNull();
+ else
+ {
+ try
+ {
+ util::Time aTime;
+ if ( !( aControlValue >>= aTime ) )
+ {
+ sal_Int32 nAsInt(0);
+ aControlValue >>= nAsInt;
+ aTime = DBTypeConversion::toTime(nAsInt);
+ }
+
+ if (!m_bDateTimeField)
+ m_xColumnUpdate->updateTime(aTime);
+ else
+ {
+ util::DateTime aDateTime = m_xColumn->getTimestamp();
+ aDateTime.HundredthSeconds = aTime.HundredthSeconds;
+ aDateTime.Seconds = aTime.Seconds;
+ aDateTime.Minutes = aTime.Minutes;
+ aDateTime.Hours = aTime.Hours;
+ m_xColumnUpdate->updateTimestamp(aDateTime);
+ }
+ }
+ catch(Exception&)
+ {
+ return sal_False;
+ }
+ }
+ m_aSaveValue = aControlValue;
+ }
+ return sal_True;
+}
+
+//------------------------------------------------------------------------------
+void OTimeModel::impl_translateControlValueToUNOTime( Any& _rUNOValue ) const
+{
+ _rUNOValue = getControlValue();
+ if ( _rUNOValue.hasValue() )
+ {
+ sal_Int32 nTime = 0;
+ OSL_VERIFY( _rUNOValue >>= nTime );
+ if ( nTime == ::Time( 99, 99, 99 ).GetTime() )
+ // "invalid time" in VCL is different from "invalid time" in UNO
+ _rUNOValue.clear();
+ else
+ _rUNOValue <<= DBTypeConversion::toTime( nTime );
+ }
+}
+
+//------------------------------------------------------------------------------
+Any OTimeModel::translateControlValueToExternalValue( ) const
+{
+ Any aExternalValue;
+ impl_translateControlValueToUNOTime( aExternalValue );
+ return aExternalValue;
+}
+
+//------------------------------------------------------------------------------
+Any OTimeModel::translateExternalValueToControlValue( const Any& _rExternalValue ) const
+{
+ Any aControlValue;
+ if ( _rExternalValue.hasValue() )
+ {
+ util::Time aTime;
+ OSL_VERIFY( _rExternalValue >>= aTime );
+ aControlValue <<= DBTypeConversion::toINT32( aTime );
+ }
+ return aControlValue;
+}
+
+//------------------------------------------------------------------------------
+Any OTimeModel::translateControlValueToValidatableValue( ) const
+{
+ Any aValidatableValue;
+ impl_translateControlValueToUNOTime( aValidatableValue );
+ return aValidatableValue;
+}
+
+//------------------------------------------------------------------------------
+Any OTimeModel::translateDbColumnToControlValue()
+{
+ util::Time aTime = m_xColumn->getTime();
+ if ( m_xColumn->wasNull() )
+ m_aSaveValue.clear();
+ else
+ // the aggregated set expects an Int32 as value ...
+ m_aSaveValue <<= DBTypeConversion::toINT32( aTime );
+
+ return m_aSaveValue;
+}
+
+//------------------------------------------------------------------------------
+Any OTimeModel::getDefaultForReset() const
+{
+ return m_aDefault;
+}
+
+//------------------------------------------------------------------------------
+void OTimeModel::resetNoBroadcast()
+{
+ OEditBaseModel::resetNoBroadcast();
+ m_aSaveValue.clear();
+}
+
+//------------------------------------------------------------------------------
+Sequence< Type > OTimeModel::getSupportedBindingTypes()
+{
+ return Sequence< Type >( &::getCppuType( static_cast< util::Time* >( NULL ) ), 1 );
+}
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/Time.hxx b/forms/source/component/Time.hxx
new file mode 100644
index 000000000000..60aadc6e5e26
--- /dev/null
+++ b/forms/source/component/Time.hxx
@@ -0,0 +1,135 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FORMS_TIME_HXX_
+#define _FORMS_TIME_HXX_
+
+#include "EditBase.hxx"
+#include "limitedformats.hxx"
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+//==================================================================
+//= OTimeModel
+//==================================================================
+class OTimeModel
+ :public OEditBaseModel
+ ,public OLimitedFormats
+{
+private:
+ ::com::sun::star::uno::Any m_aSaveValue;
+ sal_Bool m_bDateTimeField;
+
+protected:
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();
+
+public:
+ DECLARE_DEFAULT_LEAF_XTOR( OTimeModel );
+
+ // stario::XPersistObject
+ virtual ::rtl::OUString SAL_CALL getServiceName() throw ( ::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::beans::XPropertySet
+ virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle ) const;
+ virtual sal_Bool SAL_CALL convertFastPropertyValue(::com::sun::star::uno::Any& rConvertedValue, ::com::sun::star::uno::Any& rOldValue,
+ sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
+ throw(::com::sun::star::lang::IllegalArgumentException);
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue) throw ( ::com::sun::star::uno::Exception);
+
+ // ::com::sun::star::lang::XServiceInfo
+ IMPLEMENTATION_NAME(OTimeModel);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw();
+
+ // OControlModel's property handling
+ virtual void describeFixedProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps
+ ) const;
+
+ // prevent method hiding
+ using OBoundControlModel::getFastPropertyValue;
+
+protected:
+ // OBoundControlModel overridables
+ virtual ::com::sun::star::uno::Any
+ translateDbColumnToControlValue( );
+ virtual sal_Bool commitControlValueToDbColumn( bool _bPostReset );
+
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type >
+ getSupportedBindingTypes();
+ virtual ::com::sun::star::uno::Any
+ translateControlValueToExternalValue( ) const;
+ virtual ::com::sun::star::uno::Any
+ translateExternalValueToControlValue( const ::com::sun::star::uno::Any& _rExternalValue ) const;
+
+ virtual ::com::sun::star::uno::Any
+ translateControlValueToValidatableValue( ) const;
+
+ virtual ::com::sun::star::uno::Any
+ getDefaultForReset() const;
+ virtual void resetNoBroadcast();
+
+ virtual void onConnectedDbColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxForm );
+
+protected:
+ DECLARE_XCLONEABLE();
+
+private:
+ /** translates the control value (the VCL-internal integer representation of a date) into
+ a UNO-Date.
+ */
+ void impl_translateControlValueToUNOTime(
+ ::com::sun::star::uno::Any& _rUNOValue ) const;
+};
+
+//==================================================================
+//= OTimeControl
+//==================================================================
+class OTimeControl: public OBoundControl
+{
+protected:
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();
+
+public:
+ OTimeControl(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);
+ DECLARE_UNO3_AGG_DEFAULTS(OTimeControl, OBoundControl);
+
+ // ::com::sun::star::lang::XServiceInfo
+ IMPLEMENTATION_NAME(OTimeControl);
+ virtual StringSequence SAL_CALL getSupportedServiceNames() throw();
+};
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+#endif // _FORMS_TIME_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/cachedrowset.cxx b/forms/source/component/cachedrowset.cxx
new file mode 100644
index 000000000000..ac277e8310ec
--- /dev/null
+++ b/forms/source/component/cachedrowset.cxx
@@ -0,0 +1,205 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+
+#include "cachedrowset.hxx"
+#include "services.hxx"
+#include "frm_strings.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sdb/XQueriesSupplier.hpp>
+#include <com/sun/star/sdbc/ResultSetType.hpp>
+/** === end UNO includes === **/
+
+#include <tools/diagnose_ex.h>
+
+//........................................................................
+namespace frm
+{
+//........................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::UNO_QUERY;
+ using ::com::sun::star::uno::UNO_QUERY_THROW;
+ using ::com::sun::star::uno::UNO_SET_THROW;
+ using ::com::sun::star::uno::Exception;
+ using ::com::sun::star::uno::RuntimeException;
+ using ::com::sun::star::sdbc::XConnection;
+ using ::com::sun::star::lang::XComponent;
+ using ::com::sun::star::beans::XPropertySet;
+ using ::com::sun::star::uno::makeAny;
+ using ::com::sun::star::sdbc::SQLException;
+ using ::com::sun::star::uno::Any;
+ using ::com::sun::star::sdb::XQueriesSupplier;
+ using ::com::sun::star::container::XNameAccess;
+ using ::com::sun::star::sdbc::XResultSet;
+ using ::com::sun::star::sdbc::XStatement;
+ /** === end UNO using === **/
+ namespace ResultSetType = ::com::sun::star::sdbc::ResultSetType;
+
+ //====================================================================
+ //= CachedRowSet_Data
+ //====================================================================
+ struct CachedRowSet_Data
+ {
+ ::comphelper::ComponentContext aContext;
+ ::rtl::OUString sCommand;
+ sal_Bool bEscapeProcessing;
+ Reference< XConnection > xConnection;
+
+ bool bStatementDirty;
+
+ CachedRowSet_Data( const ::comphelper::ComponentContext& _rContext )
+ :aContext( _rContext )
+ ,sCommand()
+ ,bEscapeProcessing( sal_False )
+ ,xConnection()
+ ,bStatementDirty( true )
+ {
+ }
+ };
+
+ //====================================================================
+ //= CachedRowSet
+ //====================================================================
+ //--------------------------------------------------------------------
+ CachedRowSet::CachedRowSet( const ::comphelper::ComponentContext& _rContext )
+ :m_pData( new CachedRowSet_Data( _rContext ) )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ CachedRowSet::~CachedRowSet()
+ {
+ dispose();
+ }
+
+ //--------------------------------------------------------------------
+ void CachedRowSet::setCommand( const ::rtl::OUString& _rCommand )
+ {
+ if ( m_pData->sCommand == _rCommand )
+ return;
+
+ m_pData->sCommand = _rCommand;
+ m_pData->bStatementDirty = true;
+ }
+
+ //--------------------------------------------------------------------
+ void CachedRowSet::setCommandFromQuery( const ::rtl::OUString& _rQueryName )
+ {
+ Reference< XQueriesSupplier > xSupplyQueries( m_pData->xConnection, UNO_QUERY_THROW );
+ Reference< XNameAccess > xQueries ( xSupplyQueries->getQueries(), UNO_QUERY_THROW );
+ Reference< XPropertySet > xQuery ( xQueries->getByName( _rQueryName ), UNO_QUERY_THROW );
+
+ sal_Bool bEscapeProcessing( sal_False );
+ OSL_VERIFY( xQuery->getPropertyValue( PROPERTY_ESCAPE_PROCESSING ) >>= bEscapeProcessing );
+ setEscapeProcessing( bEscapeProcessing );
+
+ ::rtl::OUString sCommand;
+ OSL_VERIFY( xQuery->getPropertyValue( PROPERTY_COMMAND ) >>= sCommand );
+ setCommand( sCommand );
+ }
+
+ //--------------------------------------------------------------------
+ void CachedRowSet::setEscapeProcessing ( const sal_Bool _bEscapeProcessing )
+ {
+ if ( m_pData->bEscapeProcessing == _bEscapeProcessing )
+ return;
+
+ m_pData->bEscapeProcessing = _bEscapeProcessing;
+ m_pData->bStatementDirty = true;
+ }
+
+ //--------------------------------------------------------------------
+ void CachedRowSet::setConnection( const Reference< XConnection >& _rxConnection )
+ {
+ if ( m_pData->xConnection == _rxConnection )
+ return;
+
+ m_pData->xConnection = _rxConnection;
+ m_pData->bStatementDirty = true;
+ }
+
+ //--------------------------------------------------------------------
+ Reference< XResultSet > CachedRowSet::execute()
+ {
+ Reference< XResultSet > xResult;
+ try
+ {
+ OSL_PRECOND( m_pData->xConnection.is(), "CachedRowSet::execute: how am I expected to do this without a connection?" );
+ if ( !m_pData->xConnection.is() )
+ return xResult;
+
+ Reference< XStatement > xStatement( m_pData->xConnection->createStatement(), UNO_SET_THROW );
+ Reference< XPropertySet > xStatementProps( xStatement, UNO_QUERY_THROW );
+ xStatementProps->setPropertyValue( PROPERTY_ESCAPE_PROCESSING, makeAny( m_pData->bEscapeProcessing ) );
+ xStatementProps->setPropertyValue( PROPERTY_RESULTSET_TYPE, makeAny( ResultSetType::FORWARD_ONLY ) );
+
+ xResult.set( xStatement->executeQuery( m_pData->sCommand ), UNO_SET_THROW );
+ m_pData->bStatementDirty = false;
+ }
+ catch( const SQLException& )
+ {
+ throw;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return xResult;
+ }
+
+ //--------------------------------------------------------------------
+ bool CachedRowSet::isDirty() const
+ {
+ return m_pData->bStatementDirty;
+ }
+
+ //--------------------------------------------------------------------
+ void CachedRowSet::dispose()
+ {
+ try
+ {
+ m_pData.reset( new CachedRowSet_Data( m_pData->aContext ) );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+//........................................................................
+} // namespace frm
+//........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/cachedrowset.hxx b/forms/source/component/cachedrowset.hxx
new file mode 100644
index 000000000000..6c0ebc645367
--- /dev/null
+++ b/forms/source/component/cachedrowset.hxx
@@ -0,0 +1,100 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CACHEDROWSET_HXX
+#define CACHEDROWSET_HXX
+
+/** === begin UNO includes === **/
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/componentcontext.hxx>
+#include <unotools/sharedunocomponent.hxx>
+
+#include <memory>
+
+//........................................................................
+namespace frm
+{
+//........................................................................
+
+ struct CachedRowSet_Data;
+ //====================================================================
+ //= CachedRowSet
+ //====================================================================
+ /** caches a result set obtained from a SQL statement
+ */
+ class CachedRowSet
+ {
+ public:
+ CachedRowSet( const ::comphelper::ComponentContext& _rContext );
+ ~CachedRowSet();
+
+ public:
+ /** executes the statement
+
+ @return
+ the result set produced by the statement. The caller takes ownership of the
+ given object.
+
+ @throws ::com::sun::star::sdbc::SQLException
+ if such an exception is thrown when executing the statement
+ */
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet >
+ execute();
+
+ /// determines whether the row set properties are dirty, i.e. have changed since the last call to execute
+ bool isDirty() const;
+
+ /// disposes the instance and frees all associated resources
+ void dispose();
+
+ /** sets the command of a query as command to be executed
+
+ A connection must have been set before.
+
+ @throws Exception
+ */
+ void setCommandFromQuery ( const ::rtl::OUString& _rQueryName );
+
+ void setCommand ( const ::rtl::OUString& _rCommand );
+ void setEscapeProcessing ( const sal_Bool _bEscapeProcessing );
+ void setConnection ( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection );
+
+ private:
+ ::std::auto_ptr< CachedRowSet_Data > m_pData;
+ };
+
+//........................................................................
+} // namespace frm
+//........................................................................
+
+#endif // CACHEDROWSET_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/clickableimage.cxx b/forms/source/component/clickableimage.cxx
new file mode 100644
index 000000000000..bcccac7f7822
--- /dev/null
+++ b/forms/source/component/clickableimage.cxx
@@ -0,0 +1,927 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+#include "clickableimage.hxx"
+#include "controlfeatureinterception.hxx"
+#include "urltransformer.hxx"
+#include "componenttools.hxx"
+#include <com/sun/star/form/XSubmit.hpp>
+#include <com/sun/star/awt/SystemPointer.hpp>
+#include <com/sun/star/form/FormComponentType.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/awt/ActionEvent.hpp>
+#include <com/sun/star/awt/XActionListener.hpp>
+#include <tools/urlobj.hxx>
+#include <tools/debug.hxx>
+#include <vcl/svapp.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/objsh.hxx>
+#include <osl/mutex.hxx>
+#include "services.hxx"
+#include <comphelper/container.hxx>
+#include <comphelper/listenernotification.hxx>
+#include <svtools/imageresourceaccess.hxx>
+#define LOCAL_URL_PREFIX '#'
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::sdb;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::sdbcx;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::container;
+ using namespace ::com::sun::star::form;
+ using namespace ::com::sun::star::awt;
+ using namespace ::com::sun::star::io;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::util;
+ using namespace ::com::sun::star::frame;
+ using namespace ::com::sun::star::form::submission;
+ using ::com::sun::star::awt::MouseEvent;
+ using ::com::sun::star::task::XInteractionHandler;
+
+ //==================================================================
+ // OClickableImageBaseControl
+ //==================================================================
+ //------------------------------------------------------------------------------
+ Sequence<Type> OClickableImageBaseControl::_getTypes()
+ {
+ static Sequence<Type> aTypes;
+ if (!aTypes.getLength())
+ aTypes = concatSequences(OControl::_getTypes(), OClickableImageBaseControl_BASE::getTypes());
+ return aTypes;
+ }
+
+ //------------------------------------------------------------------------------
+ OClickableImageBaseControl::OClickableImageBaseControl(const Reference<XMultiServiceFactory>& _rxFactory, const ::rtl::OUString& _aService)
+ :OControl(_rxFactory, _aService)
+ ,m_pThread(NULL)
+ ,m_aSubmissionVetoListeners( m_aMutex )
+ ,m_aApproveActionListeners( m_aMutex )
+ ,m_aActionListeners( m_aMutex )
+ {
+ m_pFeatureInterception.reset( new ControlFeatureInterception( _rxFactory ) );
+ }
+
+ //------------------------------------------------------------------------------
+ OClickableImageBaseControl::~OClickableImageBaseControl()
+ {
+ if (!OComponentHelper::rBHelper.bDisposed)
+ {
+ acquire();
+ dispose();
+ }
+ }
+
+ // UNO Anbindung
+ //------------------------------------------------------------------------------
+ Any SAL_CALL OClickableImageBaseControl::queryAggregation(const Type& _rType) throw (RuntimeException)
+ {
+ Any aReturn = OControl::queryAggregation(_rType);
+ if (!aReturn.hasValue())
+ aReturn = OClickableImageBaseControl_BASE::queryInterface(_rType);
+ return aReturn;
+ }
+
+ // XApproveActionBroadcaster
+ //------------------------------------------------------------------------------
+ void OClickableImageBaseControl::addApproveActionListener(
+ const Reference<XApproveActionListener>& l) throw( RuntimeException )
+ {
+ m_aApproveActionListeners.addInterface(l);
+ }
+
+ //------------------------------------------------------------------------------
+ void OClickableImageBaseControl::removeApproveActionListener(
+ const Reference<XApproveActionListener>& l) throw( RuntimeException )
+ {
+ m_aApproveActionListeners.removeInterface(l);
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OClickableImageBaseControl::registerDispatchProviderInterceptor( const Reference< XDispatchProviderInterceptor >& _rxInterceptor ) throw (RuntimeException)
+ {
+ m_pFeatureInterception->registerDispatchProviderInterceptor( _rxInterceptor );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OClickableImageBaseControl::releaseDispatchProviderInterceptor( const Reference< XDispatchProviderInterceptor >& _rxInterceptor ) throw (RuntimeException)
+ {
+ m_pFeatureInterception->releaseDispatchProviderInterceptor( _rxInterceptor );
+ }
+
+ // OComponentHelper
+ //------------------------------------------------------------------------------
+ void OClickableImageBaseControl::disposing()
+ {
+ EventObject aEvent( static_cast< XWeak* >( this ) );
+ m_aApproveActionListeners.disposeAndClear( aEvent );
+ m_aActionListeners.disposeAndClear( aEvent );
+ m_aSubmissionVetoListeners.disposeAndClear( aEvent );
+ m_pFeatureInterception->dispose();
+
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if( m_pThread )
+ {
+ m_pThread->release();
+ m_pThread = NULL;
+ }
+ }
+
+ OControl::disposing();
+ }
+
+ //------------------------------------------------------------------------------
+ OImageProducerThread_Impl* OClickableImageBaseControl::getImageProducerThread()
+ {
+ if ( !m_pThread )
+ {
+ m_pThread = new OImageProducerThread_Impl( this );
+ m_pThread->acquire();
+ m_pThread->create();
+ }
+ return m_pThread;
+ }
+
+ //------------------------------------------------------------------------------
+ bool OClickableImageBaseControl::approveAction( )
+ {
+ sal_Bool bCancelled = sal_False;
+ EventObject aEvent( static_cast< XWeak* >( this ) );
+
+ ::cppu::OInterfaceIteratorHelper aIter( m_aApproveActionListeners );
+ while( !bCancelled && aIter.hasMoreElements() )
+ {
+ // Jede approveAction-Methode muss thread-safe sein!!!
+ if( !static_cast< XApproveActionListener* >( aIter.next() )->approveAction( aEvent ) )
+ bCancelled = sal_True;
+ }
+
+ return !bCancelled;
+ }
+
+ //------------------------------------------------------------------------------
+ // Diese Methode wird auch aus einem Thread gerufen und muss deshalb
+ // thread-safe sein.
+ void OClickableImageBaseControl::actionPerformed_Impl(sal_Bool bNotifyListener, const MouseEvent& rEvt)
+ {
+ if( bNotifyListener )
+ {
+ if ( !approveAction() )
+ return;
+ }
+
+ // Ob der Rest des Codes Thread-Safe ist weiss man nicht genau. Deshalb
+ // wird das meiste bei gelocktem Solar-Mutex erledigen.
+ Reference<XPropertySet> xSet;
+ Reference< XInterface > xModelsParent;
+ FormButtonType eButtonType = FormButtonType_PUSH;
+ {
+ SolarMutexGuard aGuard;
+
+ // Parent holen
+ Reference<XFormComponent> xComp(getModel(), UNO_QUERY);
+ if (!xComp.is())
+ return;
+
+ xModelsParent = xComp->getParent();
+ if (!xModelsParent.is())
+ return;
+
+ // which button type?
+ xSet = xSet.query( xComp );
+ if ( !xSet.is() )
+ return;
+ xSet->getPropertyValue(PROPERTY_BUTTONTYPE) >>= eButtonType;
+ }
+
+ switch (eButtonType)
+ {
+ case FormButtonType_RESET:
+ {
+ // reset-Methoden muessen thread-safe sein!
+ Reference<XReset> xReset(xModelsParent, UNO_QUERY);
+ if (!xReset.is())
+ return;
+
+ xReset->reset();
+ }
+ break;
+
+ case FormButtonType_SUBMIT:
+ {
+ // if some outer component can provide an interaction handler, use it
+ Reference< XInteractionHandler > xHandler( m_pFeatureInterception->queryDispatch( "private:/InteractionHandler" ), UNO_QUERY );
+ try
+ {
+ implSubmit( rEvt, xHandler );
+ }
+ catch( const Exception& )
+ {
+ // ignore
+ }
+ }
+ break;
+
+ case FormButtonType_URL:
+ {
+ SolarMutexGuard aGuard;
+
+ Reference< XModel > xModel = getXModel(xModelsParent);
+ if (!xModel.is())
+ return;
+
+ ///////////////////////////////////////////////////////////////////////
+ // Jetzt URL ausfuehren
+ Reference< XController > xController = xModel->getCurrentController();
+ if (!xController.is())
+ return;
+
+ Reference< XFrame > xFrame = xController->getFrame();
+ if( !xFrame.is() )
+ return;
+
+ URL aURL;
+ aURL.Complete =
+ getString(xSet->getPropertyValue(PROPERTY_TARGET_URL));
+
+ if (aURL.Complete.getLength() && (LOCAL_URL_PREFIX == aURL.Complete.getStr()[0]))
+ { // the URL contains a local URL only. Since the URLTransformer does not handle this case correctly
+ // (it can't: it does not know the document URL), we have to take care for this ourself.
+ // The real solution would be to not allow such relative URLs (there is a rule that at runtime, all
+ // URLs have to be absolute), but for compatibility reasons this is no option.
+ // The more as the user does not want to see a local URL as "file://<path>/<document>#mark" if it
+ // could be "#mark" as well.
+ // If we someday say that this hack (yes, it's kind of a hack) is not sustainable anymore, the complete
+ // solutiuon would be:
+ // * recognize URLs consisting of a mark only while _reading_ the document
+ // * for this, allow the INetURLObject (which at the moment is invoked when reading URLs) to
+ // transform such mark-only URLs into correct absolute URLs
+ // * at the UI, show only the mark
+ // * !!!! recognize every SAVEAS on the document, so the absolute URL can be adjusted. This seems
+ // rather impossible !!!
+ aURL.Mark = aURL.Complete;
+ aURL.Complete = xModel->getURL();
+ aURL.Complete += aURL.Mark;
+ }
+
+ sal_Bool bDispatchUrlInternal = sal_False;
+ xSet->getPropertyValue(PROPERTY_DISPATCHURLINTERNAL) >>= bDispatchUrlInternal;
+ if ( bDispatchUrlInternal )
+ {
+ m_pFeatureInterception->getTransformer().parseSmartWithAsciiProtocol( aURL, INET_FILE_SCHEME );
+
+ ::rtl::OUString aTargetFrame;
+ xSet->getPropertyValue(PROPERTY_TARGET_FRAME) >>= aTargetFrame;
+
+ Reference< XDispatch > xDisp = Reference< XDispatchProvider > (xFrame,UNO_QUERY)->queryDispatch( aURL, aTargetFrame,
+ FrameSearchFlag::SELF | FrameSearchFlag::PARENT |
+ FrameSearchFlag::SIBLINGS | FrameSearchFlag::CREATE );
+
+ Sequence<PropertyValue> aArgs(1);
+ PropertyValue& rProp = aArgs.getArray()[0];
+ rProp.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Referer") );
+ rProp.Value <<= xModel->getURL();
+
+ if (xDisp.is())
+ xDisp->dispatch( aURL, aArgs );
+ }
+ else
+ {
+ URL aHyperLink = m_pFeatureInterception->getTransformer().getStrictURLFromAscii( ".uno:OpenHyperlink" );
+
+ Reference< XDispatch > xDisp = Reference< XDispatchProvider > (xFrame,UNO_QUERY)->queryDispatch(aHyperLink, ::rtl::OUString() , 0);
+
+ if ( xDisp.is() )
+ {
+ Sequence<PropertyValue> aProps(3);
+ aProps[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("URL"));
+ aProps[0].Value <<= aURL.Complete;
+
+ aProps[1].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FrameName"));
+ aProps[1].Value = xSet->getPropertyValue(PROPERTY_TARGET_FRAME);
+
+ aProps[2].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Referer"));
+ aProps[2].Value <<= xModel->getURL();
+
+ xDisp->dispatch( aHyperLink, aProps );
+ }
+ }
+ } break;
+ default:
+ {
+ // notify the action listeners for a push button
+ ActionEvent aEvt(static_cast<XWeak*>(this), m_aActionCommand);
+ m_aActionListeners.notifyEach( &XActionListener::actionPerformed, aEvt );
+ }
+ }
+ }
+
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OClickableImageBaseControl::addSubmissionVetoListener( const Reference< submission::XSubmissionVetoListener >& listener ) throw (NoSupportException, RuntimeException)
+ {
+ m_aSubmissionVetoListeners.addInterface( listener );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OClickableImageBaseControl::removeSubmissionVetoListener( const Reference< submission::XSubmissionVetoListener >& listener ) throw (NoSupportException, RuntimeException)
+ {
+ m_aSubmissionVetoListeners.removeInterface( listener );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OClickableImageBaseControl::submitWithInteraction( const Reference< XInteractionHandler >& _rxHandler ) throw (VetoException, WrappedTargetException, RuntimeException)
+ {
+ implSubmit( MouseEvent(), _rxHandler );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OClickableImageBaseControl::submit( ) throw (VetoException, WrappedTargetException, RuntimeException)
+ {
+ implSubmit( MouseEvent(), NULL );
+ }
+
+ //--------------------------------------------------------------------
+ Sequence< ::rtl::OUString > SAL_CALL OClickableImageBaseControl::getSupportedServiceNames( ) throw (RuntimeException)
+ {
+ Sequence< ::rtl::OUString > aSupported = OControl::getSupportedServiceNames();
+ aSupported.realloc( aSupported.getLength() + 1 );
+
+ ::rtl::OUString* pArray = aSupported.getArray();
+ pArray[ aSupported.getLength() - 1 ] = FRM_SUN_CONTROL_SUBMITBUTTON;
+
+ return aSupported;
+ }
+
+ //--------------------------------------------------------------------
+ void OClickableImageBaseControl::implSubmit( const MouseEvent& _rEvent, const Reference< XInteractionHandler >& _rxHandler ) SAL_THROW((VetoException, WrappedTargetException, RuntimeException))
+ {
+ try
+ {
+ // allow the veto listeners to join the game
+ m_aSubmissionVetoListeners.notifyEach( &XSubmissionVetoListener::submitting, EventObject( *this ) );
+
+ // see whether there's an "submit interceptor" set at our model
+ Reference< submission::XSubmissionSupplier > xSubmissionSupp( getModel(), UNO_QUERY );
+ Reference< XSubmission > xSubmission;
+ if ( xSubmissionSupp.is() )
+ xSubmission = xSubmissionSupp->getSubmission();
+
+ if ( xSubmission.is() )
+ {
+ if ( !_rxHandler.is() )
+ xSubmission->submit();
+ else
+ xSubmission->submitWithInteraction( _rxHandler );
+ }
+ else
+ {
+ // no "interceptor" -> ordinary (old-way) submission
+ Reference< XChild > xChild( getModel(), UNO_QUERY );
+ Reference< XSubmit > xParentSubmission;
+ if ( xChild.is() )
+ xParentSubmission = xParentSubmission.query( xChild->getParent() );
+ if ( xParentSubmission.is() )
+ xParentSubmission->submit( this, _rEvent );
+ }
+ }
+ catch( const VetoException& )
+ {
+ // allowed to leave
+ throw;
+ }
+ catch( const RuntimeException& )
+ {
+ // allowed to leave
+ throw;
+ }
+ catch( const WrappedTargetException& e )
+ {
+ // allowed to leave
+ throw;
+ }
+ catch( const Exception& e )
+ {
+ OSL_FAIL( "OClickableImageBaseControl::implSubmit: caught an unknown exception!" );
+ throw WrappedTargetException( ::rtl::OUString(), *this, makeAny( e ) );
+ }
+ }
+
+ //==================================================================
+ // OClickableImageBaseModel
+ //==================================================================
+ //------------------------------------------------------------------------------
+ Sequence<Type> OClickableImageBaseModel::_getTypes()
+ {
+ return concatSequences(
+ OControlModel::_getTypes(),
+ OClickableImageBaseModel_Base::getTypes()
+ );
+ }
+
+ //------------------------------------------------------------------
+ DBG_NAME( OClickableImageBaseModel )
+ //------------------------------------------------------------------
+ OClickableImageBaseModel::OClickableImageBaseModel( const Reference< XMultiServiceFactory >& _rxFactory, const ::rtl::OUString& _rUnoControlModelTypeName,
+ const ::rtl::OUString& rDefault )
+ :OControlModel( _rxFactory, _rUnoControlModelTypeName, rDefault )
+ ,OPropertyChangeListener(m_aMutex)
+ ,m_pMedium(NULL)
+ ,m_pProducer( NULL )
+ ,m_bDispatchUrlInternal(sal_False)
+ ,m_bDownloading(sal_False)
+ ,m_bProdStarted(sal_False)
+ {
+ DBG_CTOR( OClickableImageBaseModel, NULL );
+ implConstruct();
+ m_eButtonType = FormButtonType_PUSH;
+ }
+
+ //------------------------------------------------------------------
+ OClickableImageBaseModel::OClickableImageBaseModel( const OClickableImageBaseModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
+ :OControlModel( _pOriginal, _rxFactory )
+ ,OPropertyChangeListener( m_aMutex )
+ ,m_pMedium( NULL )
+ ,m_pProducer( NULL )
+ ,m_bDispatchUrlInternal(sal_False)
+ ,m_bDownloading( sal_False )
+ ,m_bProdStarted( sal_False )
+ {
+ DBG_CTOR( OClickableImageBaseModel, NULL );
+ implConstruct();
+
+ // copy properties
+ m_eButtonType = _pOriginal->m_eButtonType;
+ m_sTargetURL = _pOriginal->m_sTargetURL;
+ m_sTargetFrame = _pOriginal->m_sTargetFrame;
+ m_bDispatchUrlInternal = _pOriginal->m_bDispatchUrlInternal;
+ }
+
+ //------------------------------------------------------------------------------
+ void OClickableImageBaseModel::implInitializeImageURL( )
+ {
+ osl_incrementInterlockedCount( &m_refCount );
+ {
+ // simulate a propertyChanged event for the ImageURL
+ Any aImageURL;
+ getFastPropertyValue( aImageURL, PROPERTY_ID_IMAGE_URL );
+ _propertyChanged( PropertyChangeEvent( *this, PROPERTY_IMAGE_URL, sal_False, PROPERTY_ID_IMAGE_URL, Any( ), aImageURL ) );
+ }
+ osl_decrementInterlockedCount( &m_refCount );
+ }
+
+ //------------------------------------------------------------------------------
+ void OClickableImageBaseModel::implConstruct()
+ {
+ m_pProducer = new ImageProducer;
+ increment( m_refCount );
+ {
+ m_xProducer = m_pProducer;
+
+ if ( m_xAggregateSet.is() )
+ {
+ OPropertyChangeMultiplexer* pMultiplexer = new OPropertyChangeMultiplexer( this, m_xAggregateSet );
+ pMultiplexer->addProperty( PROPERTY_IMAGE_URL );
+ }
+ }
+ decrement(m_refCount);
+ }
+
+ //------------------------------------------------------------------------------
+ OClickableImageBaseModel::~OClickableImageBaseModel()
+ {
+ if (!OComponentHelper::rBHelper.bDisposed)
+ {
+ acquire();
+ dispose();
+ }
+ DBG_ASSERT(m_pMedium == NULL, "OClickableImageBaseModel::~OClickableImageBaseModel : leaving a memory leak ...");
+ // spaetestens im dispose sollte das aufgeraeumt worden sein
+
+ DBG_DTOR( OClickableImageBaseModel, NULL );
+ }
+
+ // XImageProducer
+ //--------------------------------------------------------------------
+ void SAL_CALL OClickableImageBaseModel::addConsumer( const Reference< XImageConsumer >& _rxConsumer ) throw (RuntimeException)
+ {
+ ImageModelMethodGuard aGuard( *this );
+ GetImageProducer()->addConsumer( _rxConsumer );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OClickableImageBaseModel::removeConsumer( const Reference< XImageConsumer >& _rxConsumer ) throw (RuntimeException)
+ {
+ ImageModelMethodGuard aGuard( *this );
+ GetImageProducer()->removeConsumer( _rxConsumer );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OClickableImageBaseModel::startProduction( ) throw (RuntimeException)
+ {
+ ImageModelMethodGuard aGuard( *this );
+ GetImageProducer()->startProduction();
+ }
+
+ //--------------------------------------------------------------------
+ Reference< submission::XSubmission > SAL_CALL OClickableImageBaseModel::getSubmission() throw (RuntimeException)
+ {
+ return m_xSubmissionDelegate;
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OClickableImageBaseModel::setSubmission( const Reference< submission::XSubmission >& _submission ) throw (RuntimeException)
+ {
+ m_xSubmissionDelegate = _submission;
+ }
+
+ //--------------------------------------------------------------------
+ Sequence< ::rtl::OUString > SAL_CALL OClickableImageBaseModel::getSupportedServiceNames( ) throw (RuntimeException)
+ {
+ Sequence< ::rtl::OUString > aSupported = OControlModel::getSupportedServiceNames();
+ aSupported.realloc( aSupported.getLength() + 1 );
+
+ ::rtl::OUString* pArray = aSupported.getArray();
+ pArray[ aSupported.getLength() - 1 ] = FRM_SUN_COMPONENT_SUBMITBUTTON;
+
+ return aSupported;
+ }
+
+ // OComponentHelper
+ //------------------------------------------------------------------------------
+ void OClickableImageBaseModel::disposing()
+ {
+ OControlModel::disposing();
+ if (m_pMedium)
+ {
+ delete m_pMedium;
+ m_pMedium = NULL;
+ }
+
+ m_xProducer = NULL;
+ m_pProducer = NULL;
+ }
+
+ //------------------------------------------------------------------------------
+ Any SAL_CALL OClickableImageBaseModel::queryAggregation(const Type& _rType) throw (RuntimeException)
+ {
+ // order matters:
+ // we definately want to "overload" the XImageProducer interface of our aggregate,
+ // thus check OClickableImageBaseModel_Base (which provides this) first
+ Any aReturn = OClickableImageBaseModel_Base::queryInterface( _rType );
+
+ // BUT: _don't_ let it feel responsible for the XTypeProvider interface
+ // (as this is implemented by our base class in the proper way)
+ if ( _rType.equals( ::getCppuType( static_cast< Reference< XTypeProvider >* >( NULL ) ) )
+ || !aReturn.hasValue()
+ )
+ aReturn = OControlModel::queryAggregation( _rType );
+
+ return aReturn;
+ }
+
+ //------------------------------------------------------------------------------
+ void OClickableImageBaseModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle) const
+ {
+ switch (nHandle)
+ {
+ case PROPERTY_ID_BUTTONTYPE : rValue <<= m_eButtonType; break;
+ case PROPERTY_ID_TARGET_URL : rValue <<= m_sTargetURL; break;
+ case PROPERTY_ID_TARGET_FRAME : rValue <<= m_sTargetFrame; break;
+ case PROPERTY_ID_DISPATCHURLINTERNAL : rValue <<= m_bDispatchUrlInternal; break;
+ default:
+ OControlModel::getFastPropertyValue(rValue, nHandle);
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ void OClickableImageBaseModel::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const Any& rValue) throw ( Exception)
+ {
+ switch (nHandle)
+ {
+ case PROPERTY_ID_BUTTONTYPE :
+ DBG_ASSERT(isA(rValue, static_cast<FormButtonType*>(NULL)), "OClickableImageBaseModel::setFastPropertyValue_NoBroadcast : invalid type !" );
+ rValue >>= m_eButtonType;
+ break;
+
+ case PROPERTY_ID_TARGET_URL :
+ DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_STRING, "OClickableImageBaseModel::setFastPropertyValue_NoBroadcast : invalid type !" );
+ rValue >>= m_sTargetURL;
+ break;
+
+ case PROPERTY_ID_TARGET_FRAME :
+ DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_STRING, "OClickableImageBaseModel::setFastPropertyValue_NoBroadcast : invalid type !" );
+ rValue >>= m_sTargetFrame;
+ break;
+
+ case PROPERTY_ID_DISPATCHURLINTERNAL:
+ DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_BOOLEAN, "OClickableImageBaseModel::setFastPropertyValue_NoBroadcast : invalid type !" );
+ rValue >>= m_bDispatchUrlInternal;
+ break;
+
+ default:
+ OControlModel::setFastPropertyValue_NoBroadcast(nHandle, rValue);
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ sal_Bool OClickableImageBaseModel::convertFastPropertyValue(Any& rConvertedValue, Any& rOldValue, sal_Int32 nHandle, const Any& rValue)
+ throw( IllegalArgumentException )
+ {
+ switch (nHandle)
+ {
+ case PROPERTY_ID_BUTTONTYPE :
+ return tryPropertyValueEnum( rConvertedValue, rOldValue, rValue, m_eButtonType );
+
+ case PROPERTY_ID_TARGET_URL :
+ return tryPropertyValue(rConvertedValue, rOldValue, rValue, m_sTargetURL);
+
+ case PROPERTY_ID_TARGET_FRAME :
+ return tryPropertyValue(rConvertedValue, rOldValue, rValue, m_sTargetFrame);
+
+ case PROPERTY_ID_DISPATCHURLINTERNAL :
+ return tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bDispatchUrlInternal);
+
+ default:
+ return OControlModel::convertFastPropertyValue(rConvertedValue, rOldValue, nHandle, rValue);
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ void OClickableImageBaseModel::StartProduction()
+ {
+ ImageProducer *pImgProd = GetImageProducer();
+ // grab the ImageURL
+ rtl::OUString sURL;
+ getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ImageURL") ) ) >>= sURL;
+ if (!m_pMedium)
+ {
+ if ( ::svt::GraphicAccess::isSupportedURL( sURL ) )
+ pImgProd->SetImage( sURL );
+ else
+ // caution: the medium may be NULL if somebody gave us a invalid URL to work with
+ pImgProd->SetImage(String());
+ m_bDownloading = sal_False;
+ return;
+ }
+ if (m_pMedium->GetErrorCode()==0)
+ {
+ SvStream* pStream = m_pMedium->GetInStream();
+
+ pImgProd->SetImage(*pStream);
+ pImgProd->startProduction();
+ m_bProdStarted = sal_True;
+ }
+ else
+ {
+ pImgProd->SetImage(String());
+ delete m_pMedium;
+ m_pMedium = 0;
+ m_bDownloading = sal_False;
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ void OClickableImageBaseModel::SetURL( const ::rtl::OUString& rURL )
+ {
+ if (m_pMedium || !rURL.getLength())
+ {
+ // Den Stream am Producer freigeben, bevor das Medium geloscht wird.
+ GetImageProducer()->SetImage(String());
+ delete m_pMedium;
+ m_pMedium = NULL;
+ }
+
+ // the SfxMedium is not allowed to be created with an invalid URL, so we have to check this first
+ INetURLObject aUrl(rURL);
+ if (INET_PROT_NOT_VALID == aUrl.GetProtocol())
+ // we treat an invalid URL like we would treat no URL
+ return;
+
+ if (rURL.getLength() && !::svt::GraphicAccess::isSupportedURL( rURL ) )
+ {
+ if (m_pMedium)
+ delete m_pMedium;
+
+ m_pMedium = new SfxMedium(rURL, STREAM_STD_READ, sal_False);
+ m_pMedium->SetDataAvailableLink(
+ STATIC_LINK(this, OClickableImageBaseModel, DataAvailableLink));
+
+ // Das XModel suchen, um an die Object-Shell oder zumindest den
+ // Referer zu gelangen.
+ // Das Model findet man allerdings nur beim Laden von HTML-Dokumenten
+ // und dann, wenn die URL in einem bereits geladenen Dokument
+ // geaendert wird. Waehrend des Ladens kommt man nicht an das
+ // Model ran.
+ Reference< XModel > xModel;
+ InterfaceRef xIfc( *this );
+ while( !xModel.is() && xIfc.is() )
+ {
+ Reference<XChild> xChild( xIfc, UNO_QUERY );
+ xIfc = xChild->getParent();
+ query_interface(xIfc, xModel);
+ }
+
+ // Die Object-Shell suchen, indem wir
+ // ueber alle Object-Shells iterieren und deren XModel mit dem
+ // eigenen vergleichen. Als Optimierung probieren wir aber erstmal
+ // die aktuelle Object-Shell.
+ // wir unser XModel mit dem aller Object
+ SfxObjectShell *pObjSh = 0;
+
+ if( xModel.is() )
+ {
+ SfxObjectShell *pTestObjSh = SfxObjectShell::Current();
+ if( pTestObjSh )
+ {
+ Reference< XModel > xTestModel = pTestObjSh->GetModel();
+ if( xTestModel == xModel )
+ pObjSh = pTestObjSh;
+ }
+ if( !pObjSh )
+ {
+ pTestObjSh = SfxObjectShell::GetFirst();
+ while( !pObjSh && pTestObjSh )
+ {
+ Reference< XModel > xTestModel = pTestObjSh->GetModel();
+ if( xTestModel == xModel )
+ pObjSh = pTestObjSh;
+ else
+ pTestObjSh = SfxObjectShell::GetNext( *pTestObjSh );
+ }
+ }
+ }
+
+ #ifdef USE_REGISTER_TRANSFER
+ if( pObjSh )
+ {
+ // Medium registrieren, damit abgebrochen werden kann
+ pObjSh->RegisterTransfer( *m_pMedium );
+
+ // Target-Frame uebertragen, damit auch javascript:-URLs
+ // "geladen" werden koennen.
+ const SfxMedium *pShMedium = pObjSh->GetMedium();
+ if( pShMedium )
+ m_pMedium->SetLoadTargetFrame(pShMedium->GetLoadTargetFrame());
+ }
+ else
+ {
+ // Keine Object-Shell, aber ein Medium? Dann uebernehmen wir
+ // zumindest den Referer.
+ if( xModel.is() )
+ {
+ ::rtl::OUString sReferer( xModel->getURL() );
+ if( sReferer.getLength() )
+ m_pMedium->SetReferer( OUStringToString(sReferer, CHARSET_SYSTEM) );
+ }
+ }
+ #else
+ if( pObjSh )
+ {
+ // Target-Frame uebertragen, damit auch javascript:-URLs
+ // "geladen" werden koennen.
+ const SfxMedium *pShMedium = pObjSh->GetMedium();
+ if( pShMedium )
+ m_pMedium->SetLoadTargetFrame(pShMedium->GetLoadTargetFrame());
+ }
+
+ if( xModel.is() )
+ {
+ ::rtl::OUString sReferer( xModel->getURL() );
+ if( sReferer.getLength() )
+ m_pMedium->SetReferer( sReferer );
+ }
+ #endif
+
+ // Downloading-Flag auf sal_True setzen. Es werden dann auch
+ // Data-Available-Links, wenn wir in den Pending-Staus gelangen.
+ m_bDownloading = sal_True;
+ m_bProdStarted = sal_False;
+
+ // Download anstossen (Achtung: Kann auch synchron sein).
+ m_pMedium->DownLoad(STATIC_LINK(this, OClickableImageBaseModel, DownloadDoneLink));
+ }
+ else
+ {
+ if ( ::svt::GraphicAccess::isSupportedURL( rURL ) )
+ GetImageProducer()->SetImage( rURL );
+ GetImageProducer()->startProduction();
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ void OClickableImageBaseModel::DataAvailable()
+ {
+ if (!m_bProdStarted)
+ StartProduction();
+
+ GetImageProducer()->NewDataAvailable();
+ }
+
+ //------------------------------------------------------------------------------
+ void OClickableImageBaseModel::DownloadDone()
+ {
+ DataAvailable();
+ m_bDownloading = sal_False;
+ }
+
+ //------------------------------------------------------------------------------
+ IMPL_STATIC_LINK( OClickableImageBaseModel, DownloadDoneLink, void*, EMPTYARG )
+ {
+ ::osl::MutexGuard aGuard( pThis->m_aMutex );
+ pThis->DownloadDone();
+ return 0;
+ }
+
+ //------------------------------------------------------------------------------
+ IMPL_STATIC_LINK( OClickableImageBaseModel, DataAvailableLink, void*, EMPTYARG )
+ {
+ ::osl::MutexGuard aGuard( pThis->m_aMutex );
+ pThis->DataAvailable();
+ return 0;
+ }
+
+ //------------------------------------------------------------------------------
+ void OClickableImageBaseModel::_propertyChanged( const PropertyChangeEvent& rEvt )
+ throw( RuntimeException )
+ {
+ // Wenn eine URL gesetzt worden ist, muss die noch an den ImageProducer
+ // weitergereicht werden.
+ ::osl::MutexGuard aGuard(m_aMutex);
+ SetURL( getString(rEvt.NewValue) );
+ }
+
+ // -----------------------------------------------------------------------------
+ Any OClickableImageBaseModel::getPropertyDefaultByHandle( sal_Int32 nHandle ) const
+ {
+ switch (nHandle)
+ {
+ case PROPERTY_ID_BUTTONTYPE : return makeAny( FormButtonType_PUSH );
+ case PROPERTY_ID_TARGET_URL :
+ case PROPERTY_ID_TARGET_FRAME : return makeAny( ::rtl::OUString() );
+ case PROPERTY_ID_DISPATCHURLINTERNAL : return makeAny( sal_False );
+ default:
+ return OControlModel::getPropertyDefaultByHandle(nHandle);
+ }
+ }
+
+ //==================================================================
+ // OImageProducerThread_Impl
+ //==================================================================
+ //------------------------------------------------------------------
+ EventObject* OImageProducerThread_Impl::cloneEvent( const EventObject* _pEvt ) const
+ {
+ return new EventObject( *_pEvt );
+ }
+
+ //------------------------------------------------------------------
+ void OImageProducerThread_Impl::processEvent( ::cppu::OComponentHelper *pCompImpl,
+ const EventObject* pEvt,
+ const Reference<XControl>&,
+ sal_Bool )
+ {
+ ((OClickableImageBaseControl *)pCompImpl)->actionPerformed_Impl( sal_True, *(MouseEvent *)pEvt );
+ }
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/clickableimage.hxx b/forms/source/component/clickableimage.hxx
new file mode 100644
index 000000000000..816a2aeb827d
--- /dev/null
+++ b/forms/source/component/clickableimage.hxx
@@ -0,0 +1,297 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef FORMS_SOURCE_CLICKABLEIMAGE_HXX
+#define FORMS_SOURCE_CLICKABLEIMAGE_HXX
+
+#include "FormComponent.hxx"
+#include "EventThread.hxx"
+#include "imgprod.hxx"
+#include <tools/link.hxx>
+#include <comphelper/propmultiplex.hxx>
+#include <com/sun/star/form/XImageProducerSupplier.hpp>
+#include <com/sun/star/form/FormButtonType.hpp>
+#include <com/sun/star/form/XApproveActionListener.hpp>
+#include <com/sun/star/form/XApproveActionBroadcaster.hpp>
+#include <com/sun/star/form/submission/XSubmissionSupplier.hpp>
+#include <com/sun/star/form/submission/XSubmission.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/XDispatchProviderInterception.hpp>
+#include <cppuhelper/implbase3.hxx>
+
+
+class SfxMedium;
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+ class OImageProducerThread_Impl;
+ class ControlFeatureInterception;
+ //==================================================================
+ // OClickableImageBaseModel
+ //==================================================================
+ typedef ::cppu::ImplHelper3 < ::com::sun::star::form::XImageProducerSupplier
+ , ::com::sun::star::awt::XImageProducer
+ , ::com::sun::star::form::submission::XSubmissionSupplier
+ > OClickableImageBaseModel_Base;
+
+ class OClickableImageBaseModel :public OClickableImageBaseModel_Base
+ ,public OControlModel
+ ,public OPropertyChangeListener
+ {
+ protected:
+ ::com::sun::star::form::FormButtonType m_eButtonType; // Art des Buttons (push,submit,reset)
+ ::rtl::OUString m_sTargetURL; // URL fuer den URL-Button
+ ::rtl::OUString m_sTargetFrame; // TargetFrame zum Oeffnen
+
+ // ImageProducer stuff
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageProducer> m_xProducer;
+ SfxMedium* m_pMedium; // Download-Medium
+ ImageProducer* m_pProducer;
+ sal_Bool m_bDispatchUrlInternal; // property: is not allowed to set : 1
+ sal_Bool m_bDownloading : 1; // laeuft ein Download?
+ sal_Bool m_bProdStarted : 1;
+
+ // XSubmission stuff
+ ::com::sun::star::uno::Reference< ::com::sun::star::form::submission::XSubmission >
+ m_xSubmissionDelegate;
+
+
+ DECL_STATIC_LINK( OClickableImageBaseModel, DataAvailableLink, void* );
+ DECL_STATIC_LINK( OClickableImageBaseModel, DownloadDoneLink, void* );
+
+ inline ImageProducer* GetImageProducer() { return m_pProducer; }
+
+ void StartProduction();
+ void SetURL(const ::rtl::OUString& rURL);
+ void DataAvailable();
+ void DownloadDone();
+
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();
+ inline sal_Bool isDispatchUrlInternal() const { return m_bDispatchUrlInternal; }
+ inline void setDispatchUrlInternal(sal_Bool _bDispatch) { m_bDispatchUrlInternal = _bDispatch; }
+
+ public:
+ DECLARE_DEFAULT_XTOR( OClickableImageBaseModel );
+
+ // UNO Anbindung
+ DECLARE_UNO3_AGG_DEFAULTS(OClickableImageBaseModel, OControlModel);
+ virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation(const ::com::sun::star::uno::Type& _rType) throw(::com::sun::star::uno::RuntimeException);
+
+ protected:
+ // OComponentHelper
+ virtual void SAL_CALL disposing();
+
+ // ::com::sun::star::form::XImageProducerSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageProducer> SAL_CALL getImageProducer() throw (::com::sun::star::uno::RuntimeException) { return m_xProducer; }
+
+ // OPropertySetHelper
+ virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle ) const;
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue) throw (::com::sun::star::uno::Exception);
+
+ virtual sal_Bool SAL_CALL convertFastPropertyValue(::com::sun::star::uno::Any& rConvertedValue, ::com::sun::star::uno::Any& rOldValue, sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
+ throw(::com::sun::star::lang::IllegalArgumentException);
+
+ using ::cppu::OPropertySetHelper::getFastPropertyValue;
+
+ // OPropertyChangeListener
+ virtual void _propertyChanged(const ::com::sun::star::beans::PropertyChangeEvent&) throw(::com::sun::star::uno::RuntimeException);
+
+ // XPropertyState
+ virtual ::com::sun::star::uno::Any getPropertyDefaultByHandle( sal_Int32 nHandle ) const;
+
+ // XImageProducer
+ virtual void SAL_CALL addConsumer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer >& xConsumer ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeConsumer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer >& xConsumer ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL startProduction( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XSubmissionSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::form::submission::XSubmission > SAL_CALL getSubmission() throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setSubmission( const ::com::sun::star::uno::Reference< ::com::sun::star::form::submission::XSubmission >& _submission ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XEventListener
+ using OControlModel::disposing;
+
+ public:
+ struct GuardAccess { friend class ImageModelMethodGuard; private: GuardAccess() { } };
+ ::osl::Mutex& getMutex( GuardAccess ) { return m_aMutex; }
+ ImageProducer* getImageProducer( GuardAccess ) { return m_pProducer; }
+
+ protected:
+ using OControlModel::getMutex;
+
+ void implConstruct();
+
+ // to be called from within the cloning-ctor of your derived class
+ void implInitializeImageURL( );
+ };
+
+ //==================================================================
+ // ImageModelMethodGuard
+ //==================================================================
+ class ImageModelMethodGuard : public ::osl::MutexGuard
+ {
+ private:
+ typedef ::osl::MutexGuard GuardBase;
+
+ public:
+ ImageModelMethodGuard( OClickableImageBaseModel& _rModel )
+ :GuardBase( _rModel.getMutex( OClickableImageBaseModel::GuardAccess() ) )
+ {
+ if ( NULL == _rModel.getImageProducer( OClickableImageBaseModel::GuardAccess() ) )
+ throw ::com::sun::star::lang::DisposedException(
+ ::rtl::OUString(),
+ static_cast< ::com::sun::star::form::XImageProducerSupplier* >( &_rModel )
+ );
+ }
+ };
+
+ //==================================================================
+ // OClickableImageBaseControl
+ //==================================================================
+ typedef ::cppu::ImplHelper3 < ::com::sun::star::form::XApproveActionBroadcaster
+ , ::com::sun::star::form::submission::XSubmission
+ , ::com::sun::star::frame::XDispatchProviderInterception
+ > OClickableImageBaseControl_BASE;
+
+ class OClickableImageBaseControl :public OClickableImageBaseControl_BASE
+ ,public OControl
+ {
+ friend class OImageProducerThread_Impl;
+
+ private:
+ OImageProducerThread_Impl* m_pThread;
+ ::cppu::OInterfaceContainerHelper m_aSubmissionVetoListeners;
+ ::std::auto_ptr< ControlFeatureInterception >
+ m_pFeatureInterception;
+
+ protected:
+ ::cppu::OInterfaceContainerHelper m_aApproveActionListeners;
+ ::cppu::OInterfaceContainerHelper m_aActionListeners;
+ ::rtl::OUString m_aActionCommand;
+
+ // XSubmission
+ virtual void SAL_CALL submit( ) throw (::com::sun::star::util::VetoException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL submitWithInteraction( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& aHandler ) throw (::com::sun::star::util::VetoException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addSubmissionVetoListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::submission::XSubmissionVetoListener >& listener ) throw (::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeSubmissionVetoListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::submission::XSubmissionVetoListener >& listener ) throw (::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XEventListener
+ using OControl::disposing;
+
+ public:
+ OClickableImageBaseControl(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory,
+ const ::rtl::OUString& _aService);
+ virtual ~OClickableImageBaseControl();
+
+ protected:
+ // UNO Anbindung
+ DECLARE_UNO3_AGG_DEFAULTS(OClickableImageBaseControl, OControl);
+ virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation(const ::com::sun::star::uno::Type& _rType) throw(::com::sun::star::uno::RuntimeException);
+
+ // OComponentHelper
+ virtual void SAL_CALL disposing();
+
+ // ::com::sun::star::form::XApproveActionBroadcaster
+ virtual void SAL_CALL addApproveActionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XApproveActionListener>& _rxListener)
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeApproveActionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XApproveActionListener>& _rxListener)
+ throw(::com::sun::star::uno::RuntimeException);
+
+ // XDispatchProviderInterception
+ virtual void SAL_CALL registerDispatchProviderInterceptor( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProviderInterceptor >& Interceptor ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL releaseDispatchProviderInterceptor( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProviderInterceptor >& Interceptor ) throw (::com::sun::star::uno::RuntimeException);
+
+ protected:
+ virtual void actionPerformed_Impl( sal_Bool bNotifyListener, const ::com::sun::star::awt::MouseEvent& rEvt );
+
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > _getTypes();
+
+ /** approves the action by calling the approve listeners
+ @return <TRUE/> if and only if the action has <em>not</em> been cancelled by a listener
+ */
+ bool approveAction( );
+
+ /** retrieves (and if necessary creates) the image producer thread.
+
+ Must be called with our mutex locked
+ */
+ OImageProducerThread_Impl* getImageProducerThread();
+
+ private:
+ void implSubmit(
+ const ::com::sun::star::awt::MouseEvent& _rEvent,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& aHandler
+ ) SAL_THROW((com::sun::star::util::VetoException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException));
+ };
+
+ //==================================================================
+ // OImageProducerThread_Impl
+ //==================================================================
+ class OImageProducerThread_Impl: public OComponentEventThread
+ {
+ protected:
+
+ // Die folgende Methode wrrd gerufen um das Event unter Beruecksichtigung
+ // seines Typs zu duplizieren
+ virtual ::com::sun::star::lang::EventObject* cloneEvent( const ::com::sun::star::lang::EventObject* _pEvt ) const;
+
+ // Ein Event bearbeiten. Der Mutex ist dabei nicht gelockt, pCompImpl
+ // bleibt aber in jedem Fall gueltig.
+ virtual void processEvent( ::cppu::OComponentHelper *pCompImpl,
+ const ::com::sun::star::lang::EventObject*,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl>&,
+ sal_Bool );
+
+ public:
+ OImageProducerThread_Impl( OClickableImageBaseControl *pControl ) :
+ OComponentEventThread( pControl )
+ {}
+
+ void addEvent() { ::com::sun::star::lang::EventObject aEvt; OComponentEventThread::addEvent( &aEvt ); }
+
+ protected:
+ using OComponentEventThread::addEvent;
+ };
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+#endif // FORMS_SOURCE_CLICKABLEIMAGE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/cloneable.cxx b/forms/source/component/cloneable.cxx
new file mode 100644
index 000000000000..368c3b701d02
--- /dev/null
+++ b/forms/source/component/cloneable.cxx
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+#include "cloneable.hxx"
+#include <com/sun/star/util/XCloneable.hpp>
+#include <comphelper/uno3.hxx>
+#include <tools/debug.hxx>
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+ using namespace ::comphelper;
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::util;
+
+ //====================================================================
+ //= OCloneableAggregation
+ //====================================================================
+ //------------------------------------------------------------------
+ Reference< XAggregation > OCloneableAggregation::createAggregateClone( const OCloneableAggregation* _pOriginal )
+ {
+ Reference< XCloneable > xAggregateCloneable; // will be the aggregate's XCloneable
+ Reference< XAggregation > xAggregateClone; // will be the aggregate's clone
+
+ if ( query_aggregation( _pOriginal->m_xAggregate, xAggregateCloneable ) )
+ {
+ xAggregateClone = xAggregateClone.query( xAggregateCloneable->createClone() );
+ DBG_ASSERT( xAggregateClone.is(), "OCloneableAggregation::createAggregateClone: invalid clone returned by the aggregate!" );
+ }
+ else {
+ DBG_ASSERT( !_pOriginal->m_xAggregate.is(), "OCloneableAggregation::createAggregateClone: aggregate is not cloneable!" );
+ }
+
+ return xAggregateClone;
+ }
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/entrylisthelper.cxx b/forms/source/component/entrylisthelper.cxx
new file mode 100644
index 000000000000..c894f3fce150
--- /dev/null
+++ b/forms/source/component/entrylisthelper.cxx
@@ -0,0 +1,324 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+#include "entrylisthelper.hxx"
+#include "FormComponent.hxx"
+
+#include <osl/diagnose.h>
+#include <comphelper/sequence.hxx>
+#include <comphelper/property.hxx>
+#include <algorithm>
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::util;
+ using namespace ::com::sun::star::form::binding;
+
+ //=====================================================================
+ //= OEntryListHelper
+ //=====================================================================
+ //---------------------------------------------------------------------
+ OEntryListHelper::OEntryListHelper( OControlModel& _rControlModel )
+ :m_rControlModel( _rControlModel )
+ ,m_aRefreshListeners( _rControlModel.getInstanceMutex() )
+ {
+ }
+
+ //---------------------------------------------------------------------
+ OEntryListHelper::OEntryListHelper( const OEntryListHelper& _rSource, OControlModel& _rControlModel )
+ :m_rControlModel( _rControlModel )
+ ,m_xListSource ( _rSource.m_xListSource )
+ ,m_aStringItems( _rSource.m_aStringItems )
+ ,m_aRefreshListeners( _rControlModel.getInstanceMutex() )
+ {
+ }
+
+ //---------------------------------------------------------------------
+ OEntryListHelper::~OEntryListHelper( )
+ {
+ }
+
+ //---------------------------------------------------------------------
+ void SAL_CALL OEntryListHelper::setListEntrySource( const Reference< XListEntrySource >& _rxSource ) throw (RuntimeException)
+ {
+ ControlModelLock aLock( m_rControlModel );
+
+ // disconnect from the current external list source
+ disconnectExternalListSource();
+
+ // and connect to the new one
+ if ( _rxSource.is() )
+ connectExternalListSource( _rxSource, aLock );
+ }
+
+ //---------------------------------------------------------------------
+ Reference< XListEntrySource > SAL_CALL OEntryListHelper::getListEntrySource( ) throw (RuntimeException)
+ {
+ return m_xListSource;
+ }
+
+
+ //---------------------------------------------------------------------
+ void SAL_CALL OEntryListHelper::entryChanged( const ListEntryEvent& _rEvent ) throw (RuntimeException)
+ {
+ ControlModelLock aLock( m_rControlModel );
+
+ OSL_ENSURE( _rEvent.Source == m_xListSource,
+ "OEntryListHelper::entryChanged: where did this come from?" );
+ OSL_ENSURE( ( _rEvent.Position >= 0 ) && ( _rEvent.Position < m_aStringItems.getLength() ),
+ "OEntryListHelper::entryChanged: invalid index!" );
+ OSL_ENSURE( _rEvent.Entries.getLength() == 1,
+ "OEntryListHelper::entryChanged: invalid string list!" );
+
+ if ( ( _rEvent.Position >= 0 )
+ && ( _rEvent.Position < m_aStringItems.getLength() )
+ && ( _rEvent.Entries.getLength() > 0 )
+ )
+ {
+ m_aStringItems[ _rEvent.Position ] = _rEvent.Entries[ 0 ];
+ stringItemListChanged( aLock );
+ }
+ }
+
+ //---------------------------------------------------------------------
+ void SAL_CALL OEntryListHelper::entryRangeInserted( const ListEntryEvent& _rEvent ) throw (RuntimeException)
+ {
+ ControlModelLock aLock( m_rControlModel );
+
+ OSL_ENSURE( _rEvent.Source == m_xListSource,
+ "OEntryListHelper::entryRangeInserted: where did this come from?" );
+ OSL_ENSURE( ( _rEvent.Position > 0 ) && ( _rEvent.Position < m_aStringItems.getLength() ) && ( _rEvent.Entries.getLength() > 0 ),
+ "OEntryListHelper::entryRangeRemoved: invalid count and/or position!" );
+
+ if ( ( _rEvent.Position > 0 )
+ && ( _rEvent.Position < m_aStringItems.getLength() )
+ && ( _rEvent.Entries.getLength() > 0 )
+ )
+ {
+ // the entries *before* the insertion pos
+ Sequence< ::rtl::OUString > aKeepEntries(
+ m_aStringItems.getConstArray(),
+ _rEvent.Position
+ );
+ // the entries *behind* the insertion pos
+ Sequence< ::rtl::OUString > aMovedEntries(
+ m_aStringItems.getConstArray() + _rEvent.Position,
+ m_aStringItems.getLength() - _rEvent.Position
+ );
+
+ // concat all three parts
+ m_aStringItems = ::comphelper::concatSequences(
+ aKeepEntries,
+ _rEvent.Entries,
+ aMovedEntries
+ );
+
+ stringItemListChanged( aLock );
+ }
+ }
+
+ //---------------------------------------------------------------------
+ void SAL_CALL OEntryListHelper::entryRangeRemoved( const ListEntryEvent& _rEvent ) throw (RuntimeException)
+ {
+ ControlModelLock aLock( m_rControlModel );
+
+ OSL_ENSURE( _rEvent.Source == m_xListSource,
+ "OEntryListHelper::entryRangeRemoved: where did this come from?" );
+ OSL_ENSURE( ( _rEvent.Position > 0 ) && ( _rEvent.Count > 0 ) && ( _rEvent.Position + _rEvent.Count <= m_aStringItems.getLength() ),
+ "OEntryListHelper::entryRangeRemoved: invalid count and/or position!" );
+
+ if ( ( _rEvent.Position > 0 )
+ && ( _rEvent.Count > 0 )
+ && ( _rEvent.Position + _rEvent.Count <= m_aStringItems.getLength() )
+ )
+ {
+ // copy all items after the removed ones
+ ::std::copy(
+ m_aStringItems.getConstArray() + _rEvent.Position + _rEvent.Count,
+ m_aStringItems.getConstArray() + m_aStringItems.getLength(),
+ m_aStringItems.getArray( ) + _rEvent.Position
+ );
+ // shrink the array
+ m_aStringItems.realloc( m_aStringItems.getLength() - _rEvent.Count );
+
+ stringItemListChanged( aLock );
+ }
+ }
+
+ //---------------------------------------------------------------------
+ void SAL_CALL OEntryListHelper::allEntriesChanged( const EventObject& _rEvent ) throw (RuntimeException)
+ {
+ ControlModelLock aLock( m_rControlModel );
+
+ OSL_ENSURE( _rEvent.Source == m_xListSource,
+ "OEntryListHelper::allEntriesChanged: where did this come from?" );
+
+ Reference< XListEntrySource > xSource( _rEvent.Source, UNO_QUERY );
+ if ( _rEvent.Source == m_xListSource )
+ {
+ impl_lock_refreshList( aLock );
+ }
+ }
+
+ // XRefreshable
+ //------------------------------------------------------------------------------
+ void SAL_CALL OEntryListHelper::addRefreshListener(const Reference<XRefreshListener>& _rxListener) throw(RuntimeException)
+ {
+ if ( _rxListener.is() )
+ m_aRefreshListeners.addInterface( _rxListener );
+ }
+
+ //------------------------------------------------------------------------------
+ void SAL_CALL OEntryListHelper::removeRefreshListener(const Reference<XRefreshListener>& _rxListener) throw(RuntimeException)
+ {
+ if ( _rxListener.is() )
+ m_aRefreshListeners.removeInterface( _rxListener );
+ }
+
+ //------------------------------------------------------------------------------
+ void SAL_CALL OEntryListHelper::refresh() throw(RuntimeException)
+ {
+ {
+ ControlModelLock aLock( m_rControlModel );
+ impl_lock_refreshList( aLock );
+ }
+
+ EventObject aEvt( static_cast< XRefreshable* >( this ) );
+ m_aRefreshListeners.notifyEach( &XRefreshListener::refreshed, aEvt );
+ }
+
+ //---------------------------------------------------------------------
+ void OEntryListHelper::impl_lock_refreshList( ControlModelLock& _rInstanceLock )
+ {
+ if ( hasExternalListSource() )
+ {
+ m_aStringItems = m_xListSource->getAllListEntries( );
+ stringItemListChanged( _rInstanceLock );
+ }
+ else
+ refreshInternalEntryList();
+ }
+
+ //---------------------------------------------------------------------
+ bool OEntryListHelper::handleDisposing( const EventObject& _rEvent )
+ {
+ if ( m_xListSource .is() && ( _rEvent.Source == m_xListSource ) )
+ {
+ disconnectExternalListSource( );
+ return true;
+ }
+ return false;
+ }
+
+ //---------------------------------------------------------------------
+ void OEntryListHelper::disposing( )
+ {
+ EventObject aEvt( static_cast< XRefreshable* >( this ) );
+ m_aRefreshListeners.disposeAndClear(aEvt);
+
+ if ( hasExternalListSource( ) )
+ disconnectExternalListSource( );
+ }
+
+ //---------------------------------------------------------------------
+ void OEntryListHelper::disconnectExternalListSource( )
+ {
+ if ( m_xListSource.is() )
+ m_xListSource->removeListEntryListener( this );
+
+ m_xListSource.clear();
+
+ disconnectedExternalListSource();
+ }
+
+ //---------------------------------------------------------------------
+ void OEntryListHelper::connectedExternalListSource( )
+ {
+ // nothing to do here
+ }
+
+ //---------------------------------------------------------------------
+ void OEntryListHelper::disconnectedExternalListSource( )
+ {
+ // nothing to do here
+ }
+
+ //---------------------------------------------------------------------
+ void OEntryListHelper::connectExternalListSource( const Reference< XListEntrySource >& _rxSource, ControlModelLock& _rInstanceLock )
+ {
+ OSL_ENSURE( !hasExternalListSource(), "OEntryListHelper::connectExternalListSource: only to be called if no external source is active!" );
+ OSL_ENSURE( _rxSource.is(), "OEntryListHelper::connectExternalListSource: invalid list source!" );
+
+ // remember it
+ m_xListSource = _rxSource;
+
+ // initially fill our item list
+ if ( m_xListSource.is() )
+ {
+ // be notified when the list changes ...
+ m_xListSource->addListEntryListener( this );
+
+ m_aStringItems = m_xListSource->getAllListEntries( );
+ stringItemListChanged( _rInstanceLock );
+
+ // let derivees react on the new list source
+ connectedExternalListSource();
+ }
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool OEntryListHelper::convertNewListSourceProperty( Any& _rConvertedValue,
+ Any& _rOldValue, const Any& _rValue ) SAL_THROW( ( IllegalArgumentException ) )
+ {
+ if ( hasExternalListSource() )
+ throw IllegalArgumentException( );
+ // TODO: error message
+
+ return ::comphelper::tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, m_aStringItems );
+ }
+
+ //---------------------------------------------------------------------
+ void OEntryListHelper::setNewStringItemList( const ::com::sun::star::uno::Any& _rValue, ControlModelLock& _rInstanceLock )
+ {
+ OSL_PRECOND( !hasExternalListSource(), "OEntryListHelper::setNewStringItemList: this should never have survived convertNewListSourceProperty!" );
+ OSL_VERIFY( _rValue >>= m_aStringItems );
+ stringItemListChanged( _rInstanceLock );
+ }
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/entrylisthelper.hxx b/forms/source/component/entrylisthelper.hxx
new file mode 100644
index 000000000000..64f99feb740f
--- /dev/null
+++ b/forms/source/component/entrylisthelper.hxx
@@ -0,0 +1,201 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef FORMS_ENTRYLISTHELPER_HXX
+#define FORMS_ENTRYLISTHELPER_HXX
+
+/** === begin UNO includes === **/
+#include <com/sun/star/form/binding/XListEntrySink.hpp>
+#include <com/sun/star/util/XRefreshable.hpp>
+#include <com/sun/star/form/binding/XListEntryListener.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+/** === end UNO includes === **/
+
+#include <cppuhelper/implbase3.hxx>
+#include <cppuhelper/interfacecontainer.hxx>
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+ class OControlModel;
+ class ControlModelLock;
+
+ //=====================================================================
+ //= OEntryListHelper
+ //=====================================================================
+ typedef ::cppu::ImplHelper3 < ::com::sun::star::form::binding::XListEntrySink
+ , ::com::sun::star::form::binding::XListEntryListener
+ , ::com::sun::star::util::XRefreshable
+ > OEntryListHelper_BASE;
+
+ class OEntryListHelper : public OEntryListHelper_BASE
+ {
+ private:
+ OControlModel& m_rControlModel;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XListEntrySource >
+ m_xListSource; /// our external list source
+ ::com::sun::star::uno::Sequence< ::rtl::OUString >
+ m_aStringItems; /// "overridden" StringItemList property value
+ ::cppu::OInterfaceContainerHelper
+ m_aRefreshListeners;
+
+
+ protected:
+ OEntryListHelper( OControlModel& _rControlModel );
+ OEntryListHelper( const OEntryListHelper& _rSource, OControlModel& _rControlModel );
+ virtual ~OEntryListHelper( );
+
+ /// returns the current string item list
+ inline const ::com::sun::star::uno::Sequence< ::rtl::OUString >&
+ getStringItemList() const { return m_aStringItems; }
+ inline const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XListEntrySource >&
+ getExternalListEntrySource() const { return m_xListSource; }
+
+ /// determines whether we actually have an external list source
+ inline bool hasExternalListSource( ) const { return m_xListSource.is(); }
+
+ /** handling the XEventListener::disposing call for the case where
+ our list source is being disposed
+ @return
+ <TRUE/> if and only if the disposed object was our list source, and so the
+ event was handled
+ */
+ bool handleDisposing( const ::com::sun::star::lang::EventObject& _rEvent );
+
+ /** to be called by derived classes' instances when they're being disposed
+ */
+ void disposing( );
+
+ // prevent method hiding
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException) = 0;
+
+ /** helper for implementing convertFastPropertyValue( StringItemList )
+
+ <p>The signature of this method and the return type have the same semantics
+ as convertFastPropertyValue.</p>
+ */
+ sal_Bool convertNewListSourceProperty(
+ ::com::sun::star::uno::Any& _rConvertedValue,
+ ::com::sun::star::uno::Any& _rOldValue,
+ const ::com::sun::star::uno::Any& _rValue
+ )
+ SAL_THROW( ( ::com::sun::star::lang::IllegalArgumentException ) );
+
+ /** helper for implementing setFastPropertyValueNoBroadcast
+
+ <p>Will internally call stringItemListChanged after the new item list
+ has been set.</p>
+
+ @precond
+ not to be called when we have an external list source
+ @see hasExternalListSource
+ */
+ void setNewStringItemList( const ::com::sun::star::uno::Any& _rValue, ControlModelLock& _rInstanceLock );
+
+ /** announces that the list of entries has changed.
+
+ <p>Derived classes have to override this. Most probably, they'll set the new
+ as model property.</p>
+
+ @pure
+ @see getStringItemList
+ */
+ virtual void stringItemListChanged( ControlModelLock& _rInstanceLock ) = 0;
+
+ /** called whenever a connection to a new external list source has been established
+ */
+ virtual void connectedExternalListSource( );
+
+ /** called whenever a connection to a new external list source has been revoked
+ */
+ virtual void disconnectedExternalListSource( );
+
+ /** called when XRefreshable::refresh has been called, and we do *not* have an external
+ list source
+ */
+ virtual void refreshInternalEntryList() = 0;
+
+ private:
+ // XListEntrySink
+ virtual void SAL_CALL setListEntrySource( const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XListEntrySource >& _rxSource ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XListEntrySource > SAL_CALL getListEntrySource( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XListEntryListener
+ virtual void SAL_CALL entryChanged( const ::com::sun::star::form::binding::ListEntryEvent& _rSource ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL entryRangeInserted( const ::com::sun::star::form::binding::ListEntryEvent& _rSource ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL entryRangeRemoved( const ::com::sun::star::form::binding::ListEntryEvent& _rSource ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL allEntriesChanged( const ::com::sun::star::lang::EventObject& _rSource ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XRefreshable
+ virtual void SAL_CALL refresh() throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addRefreshListener(const ::com::sun::star::uno::Reference< ::com::sun::star::util::XRefreshListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeRefreshListener(const ::com::sun::star::uno::Reference< ::com::sun::star::util::XRefreshListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);
+
+ private:
+ /** disconnects from the active external list source, if present
+ @see connectExternalListSource
+ */
+ void disconnectExternalListSource( );
+
+ /** connects to a new external list source
+ @param _rxSource
+ the new list source. Must not be <NULL/>
+ @see disconnectExternalListSource
+ */
+ void connectExternalListSource(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XListEntrySource >& _rxSource,
+ ControlModelLock& _rInstanceLock
+ );
+
+ /** refreshes our list entries
+
+ In case we have an external list source, its used to obtain the new entries, and then
+ stringItemListChanged is called to give the derived class the possibility to
+ react on this.
+
+ In case we do not have an external list source, refreshInternalEntryList is called.
+ */
+ void impl_lock_refreshList( ControlModelLock& _rInstanceLock );
+
+ private:
+ OEntryListHelper(); // never implemented
+ OEntryListHelper( const OEntryListHelper& ); // never implemented
+ OEntryListHelper& operator=( const OEntryListHelper& ); // never implemented
+ };
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+
+#endif // FORMS_ENTRYLISTHELPER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/errorbroadcaster.cxx b/forms/source/component/errorbroadcaster.cxx
new file mode 100644
index 000000000000..40d1afd06c22
--- /dev/null
+++ b/forms/source/component/errorbroadcaster.cxx
@@ -0,0 +1,115 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+#include "errorbroadcaster.hxx"
+#include <connectivity/dbtools.hxx>
+#include <com/sun/star/sdb/SQLContext.hpp>
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::sdb;
+ using namespace ::dbtools;
+
+ //=====================================================================
+ //= OErrorBroadcaster
+ //=====================================================================
+ //---------------------------------------------------------------------
+ OErrorBroadcaster::OErrorBroadcaster( ::cppu::OBroadcastHelper& _rBHelper )
+ :m_rBHelper( _rBHelper )
+ ,m_aErrorListeners( _rBHelper.rMutex )
+ {
+ }
+
+ //---------------------------------------------------------------------
+ OErrorBroadcaster::~OErrorBroadcaster( )
+ {
+ OSL_ENSURE( m_rBHelper.bDisposed || m_rBHelper.bInDispose,
+ "OErrorBroadcaster::~OErrorBroadcaster: not disposed!" );
+ // herein, we don't have a chance to do the dispose ourself ....
+
+ OSL_ENSURE( 0 == m_aErrorListeners.getLength(),
+ "OErrorBroadcaster::~OErrorBroadcaster: still have listeners!" );
+ // either we're not disposed, or the derived class did not call our dispose from within their dispose
+ }
+
+ //---------------------------------------------------------------------
+ void SAL_CALL OErrorBroadcaster::disposing()
+ {
+ EventObject aDisposeEvent( static_cast< XSQLErrorBroadcaster* >( this ) );
+ m_aErrorListeners.disposeAndClear( aDisposeEvent );
+ }
+
+ //------------------------------------------------------------------------------
+ void SAL_CALL OErrorBroadcaster::onError( const SQLException& _rException, const ::rtl::OUString& _rContextDescription )
+ {
+ Any aError;
+ if ( _rContextDescription.getLength() )
+ aError = makeAny( prependErrorInfo( _rException, static_cast< XSQLErrorBroadcaster* >( this ), _rContextDescription ) );
+ else
+ aError = makeAny( _rException );
+
+ onError( SQLErrorEvent( static_cast< XSQLErrorBroadcaster* >( this ), aError ) );
+ }
+
+ //------------------------------------------------------------------------------
+ void SAL_CALL OErrorBroadcaster::onError( const ::com::sun::star::sdb::SQLErrorEvent& _rError )
+ {
+ if ( m_aErrorListeners.getLength() )
+ {
+
+ ::cppu::OInterfaceIteratorHelper aIter( m_aErrorListeners );
+ while ( aIter.hasMoreElements() )
+ static_cast< XSQLErrorListener* >( aIter.next() )->errorOccured( _rError );
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ void SAL_CALL OErrorBroadcaster::addSQLErrorListener( const Reference< XSQLErrorListener >& _rxListener ) throw( RuntimeException )
+ {
+ m_aErrorListeners.addInterface( _rxListener );
+ }
+
+ //------------------------------------------------------------------------------
+ void SAL_CALL OErrorBroadcaster::removeSQLErrorListener( const Reference< XSQLErrorListener >& _rxListener ) throw( RuntimeException )
+ {
+ m_aErrorListeners.removeInterface( _rxListener );
+ }
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/errorbroadcaster.hxx b/forms/source/component/errorbroadcaster.hxx
new file mode 100644
index 000000000000..86e96c1fce7e
--- /dev/null
+++ b/forms/source/component/errorbroadcaster.hxx
@@ -0,0 +1,76 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef FORMS_ERRORBROADCASTER_HXX
+#define FORMS_ERRORBROADCASTER_HXX
+
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/sdb/XSQLErrorBroadcaster.hpp>
+#include <cppuhelper/interfacecontainer.h>
+#include <com/sun/star/sdbc/SQLException.hpp>
+#include <com/sun/star/sdb/SQLErrorEvent.hpp>
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+ //=====================================================================
+ //= OErrorBroadcaster
+ //=====================================================================
+ typedef ::cppu::ImplHelper1 < ::com::sun::star::sdb::XSQLErrorBroadcaster
+ > OErrorBroadcaster_BASE;
+
+ class OErrorBroadcaster : public OErrorBroadcaster_BASE
+ {
+ private:
+ ::cppu::OBroadcastHelper& m_rBHelper;
+ ::cppu::OInterfaceContainerHelper m_aErrorListeners;
+
+ protected:
+ OErrorBroadcaster( ::cppu::OBroadcastHelper& _rBHelper );
+ virtual ~OErrorBroadcaster( );
+
+ void SAL_CALL disposing();
+
+ void SAL_CALL onError( const ::com::sun::star::sdbc::SQLException& _rException, const ::rtl::OUString& _rContextDescription );
+ void SAL_CALL onError( const ::com::sun::star::sdb::SQLErrorEvent& _rException );
+
+ protected:
+ // XSQLErrorBroadcaster
+ virtual void SAL_CALL addSQLErrorListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XSQLErrorListener >& _rListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeSQLErrorListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XSQLErrorListener >& _rListener ) throw (::com::sun::star::uno::RuntimeException);
+ };
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+#endif // FORMS_ERRORBROADCASTER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/findpos.cxx b/forms/source/component/findpos.cxx
new file mode 100644
index 000000000000..86c07c080113
--- /dev/null
+++ b/forms/source/component/findpos.cxx
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+
+#include "sal/config.h"
+
+#include "findpos.hxx"
+
+#include "com/sun/star/uno/Sequence.hxx"
+#include "comphelper/types.hxx"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+
+#include <algorithm>
+
+namespace detail {
+
+sal_Int32 findPos(
+ const ::rtl::OUString& aStr,
+ const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rList)
+{
+ const ::rtl::OUString* pStrList = rList.getConstArray();
+ const ::rtl::OUString* pResult = ::std::lower_bound(
+ pStrList, pStrList + rList.getLength(), aStr );
+ if ( ( pResult != pStrList + rList.getLength() ) && ( *pResult == aStr ) )
+ return ( pResult - pStrList );
+
+ return -1;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/findpos.hxx b/forms/source/component/findpos.hxx
new file mode 100644
index 000000000000..28d33311ae9b
--- /dev/null
+++ b/forms/source/component/findpos.hxx
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_FORMS_SOURCE_COMPONENT_FINDPOS_HXX
+#define INCLUDED_FORMS_SOURCE_COMPONENT_FINDPOS_HXX
+
+#include "sal/config.h"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "sal/types.h"
+
+namespace rtl { class OUString; }
+
+namespace detail {
+
+sal_Int32 findPos(
+ const ::rtl::OUString& aStr,
+ const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rList);
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/formcontrolfont.cxx b/forms/source/component/formcontrolfont.cxx
new file mode 100644
index 000000000000..f936dc65b86c
--- /dev/null
+++ b/forms/source/component/formcontrolfont.cxx
@@ -0,0 +1,552 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+#include "formcontrolfont.hxx"
+#include "property.hrc"
+#include "property.hxx"
+#include <tools/debug.hxx>
+#include <comphelper/property.hxx>
+#include <comphelper/types.hxx>
+#include <tools/color.hxx>
+#include <toolkit/helper/emptyfontdescriptor.hxx>
+#include <com/sun/star/awt/FontRelief.hpp>
+#include <com/sun/star/awt/FontEmphasisMark.hpp>
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+ using namespace ::comphelper;
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::awt;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::beans;
+
+ //------------------------------------------------------------------------------
+ namespace
+ {
+ Any lcl_extractFontDescriptorAggregate( sal_Int32 _nHandle, const FontDescriptor& _rFont )
+ {
+ Any aValue;
+ switch ( _nHandle )
+ {
+ case PROPERTY_ID_FONT_NAME:
+ aValue <<= _rFont.Name;
+ break;
+
+ case PROPERTY_ID_FONT_STYLENAME:
+ aValue <<= _rFont.StyleName;
+ break;
+
+ case PROPERTY_ID_FONT_FAMILY:
+ aValue <<= (sal_Int16)_rFont.Family;
+ break;
+
+ case PROPERTY_ID_FONT_CHARSET:
+ aValue <<= (sal_Int16)_rFont.CharSet;
+ break;
+
+ case PROPERTY_ID_FONT_CHARWIDTH:
+ aValue <<= _rFont.CharacterWidth;
+ break;
+
+ case PROPERTY_ID_FONT_KERNING:
+ aValue <<= _rFont.Kerning;
+ break;
+
+ case PROPERTY_ID_FONT_ORIENTATION:
+ aValue <<= _rFont.Orientation;
+ break;
+
+ case PROPERTY_ID_FONT_PITCH:
+ aValue <<= _rFont.Pitch;
+ break;
+
+ case PROPERTY_ID_FONT_TYPE:
+ aValue <<= _rFont.Type;
+ break;
+
+ case PROPERTY_ID_FONT_WIDTH:
+ aValue <<= _rFont.Width;
+ break;
+
+ case PROPERTY_ID_FONT_HEIGHT:
+ aValue <<= (float)( _rFont.Height );
+ break;
+
+ case PROPERTY_ID_FONT_WEIGHT:
+ aValue <<= (float)_rFont.Weight;
+ break;
+
+ case PROPERTY_ID_FONT_SLANT:
+ aValue = makeAny(_rFont.Slant);
+ break;
+
+ case PROPERTY_ID_FONT_UNDERLINE:
+ aValue <<= (sal_Int16)_rFont.Underline;
+ break;
+
+ case PROPERTY_ID_FONT_STRIKEOUT:
+ aValue <<= (sal_Int16)_rFont.Strikeout;
+ break;
+
+ case PROPERTY_ID_FONT_WORDLINEMODE:
+ aValue = makeAny( (sal_Bool)_rFont.WordLineMode );
+ break;
+
+ default:
+ OSL_FAIL( "lcl_extractFontDescriptorAggregate: invalid handle!" );
+ break;
+ }
+ return aValue;
+ }
+ }
+
+ //=====================================================================
+ //= FontControlModel
+ //=====================================================================
+ //---------------------------------------------------------------------
+ FontControlModel::FontControlModel( bool _bToolkitCompatibleDefaults )
+ :m_nFontRelief( FontRelief::NONE )
+ ,m_nFontEmphasis( FontEmphasisMark::NONE )
+ ,m_bToolkitCompatibleDefaults( _bToolkitCompatibleDefaults )
+ {
+ }
+
+ //---------------------------------------------------------------------
+ FontControlModel::FontControlModel( const FontControlModel* _pOriginal )
+ {
+ m_aFont = _pOriginal->m_aFont;
+ m_nFontRelief = _pOriginal->m_nFontRelief;
+ m_nFontEmphasis = _pOriginal->m_nFontEmphasis;
+ m_aTextLineColor = _pOriginal->m_aTextLineColor;
+ m_aTextColor = _pOriginal->m_aTextColor;
+ m_bToolkitCompatibleDefaults = _pOriginal->m_bToolkitCompatibleDefaults;
+ }
+
+ //---------------------------------------------------------------------
+ bool FontControlModel::isFontRelatedProperty( sal_Int32 _nPropertyHandle ) const
+ {
+ return isFontAggregateProperty( _nPropertyHandle )
+ || ( _nPropertyHandle == PROPERTY_ID_FONT )
+ || ( _nPropertyHandle == PROPERTY_ID_FONTEMPHASISMARK )
+ || ( _nPropertyHandle == PROPERTY_ID_FONTRELIEF )
+ || ( _nPropertyHandle == PROPERTY_ID_TEXTLINECOLOR )
+ || ( _nPropertyHandle == PROPERTY_ID_TEXTCOLOR );
+ }
+
+ //---------------------------------------------------------------------
+ bool FontControlModel::isFontAggregateProperty( sal_Int32 _nPropertyHandle ) const
+ {
+ return ( _nPropertyHandle == PROPERTY_ID_FONT_CHARWIDTH )
+ || ( _nPropertyHandle == PROPERTY_ID_FONT_ORIENTATION )
+ || ( _nPropertyHandle == PROPERTY_ID_FONT_WIDTH )
+ || ( _nPropertyHandle == PROPERTY_ID_FONT_NAME )
+ || ( _nPropertyHandle == PROPERTY_ID_FONT_STYLENAME )
+ || ( _nPropertyHandle == PROPERTY_ID_FONT_FAMILY )
+ || ( _nPropertyHandle == PROPERTY_ID_FONT_CHARSET )
+ || ( _nPropertyHandle == PROPERTY_ID_FONT_HEIGHT )
+ || ( _nPropertyHandle == PROPERTY_ID_FONT_WEIGHT )
+ || ( _nPropertyHandle == PROPERTY_ID_FONT_SLANT )
+ || ( _nPropertyHandle == PROPERTY_ID_FONT_UNDERLINE )
+ || ( _nPropertyHandle == PROPERTY_ID_FONT_STRIKEOUT )
+ || ( _nPropertyHandle == PROPERTY_ID_FONT_WORDLINEMODE )
+ || ( _nPropertyHandle == PROPERTY_ID_FONT_PITCH )
+ || ( _nPropertyHandle == PROPERTY_ID_FONT_KERNING )
+ || ( _nPropertyHandle == PROPERTY_ID_FONT_TYPE );
+ }
+
+ //---------------------------------------------------------------------
+ sal_Int32 FontControlModel::getTextColor( ) const
+ {
+ sal_Int32 nColor = COL_TRANSPARENT;
+ m_aTextColor >>= nColor;
+ return nColor;
+ }
+
+ //---------------------------------------------------------------------
+ sal_Int32 FontControlModel::getTextLineColor( ) const
+ {
+ sal_Int32 nColor = COL_TRANSPARENT;
+ m_aTextLineColor >>= nColor;
+ return nColor;
+ }
+
+ //------------------------------------------------------------------------------
+ void FontControlModel::describeFontRelatedProperties( Sequence< Property >& /* [out] */ _rProps ) const
+ {
+ sal_Int32 nPos = _rProps.getLength();
+ _rProps.realloc( nPos + 21 );
+ Property* pProperties = _rProps.getArray();
+
+ DECL_PROP2 ( FONT, FontDescriptor, BOUND, MAYBEDEFAULT );
+ DECL_PROP2 ( FONTEMPHASISMARK, sal_Int16, BOUND, MAYBEDEFAULT );
+ DECL_PROP2 ( FONTRELIEF, sal_Int16, BOUND, MAYBEDEFAULT );
+ DECL_PROP3 ( TEXTCOLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID );
+ DECL_PROP3 ( TEXTLINECOLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID );
+
+ DECL_PROP1 ( FONT_CHARWIDTH, float, MAYBEDEFAULT );
+ DECL_BOOL_PROP1 ( FONT_KERNING, MAYBEDEFAULT );
+ DECL_PROP1 ( FONT_ORIENTATION, float, MAYBEDEFAULT );
+ DECL_PROP1 ( FONT_PITCH, sal_Int16, MAYBEDEFAULT );
+ DECL_PROP1 ( FONT_TYPE, sal_Int16, MAYBEDEFAULT );
+ DECL_PROP1 ( FONT_WIDTH, sal_Int16, MAYBEDEFAULT );
+ DECL_PROP1 ( FONT_NAME, ::rtl::OUString, MAYBEDEFAULT );
+ DECL_PROP1 ( FONT_STYLENAME, ::rtl::OUString, MAYBEDEFAULT );
+ DECL_PROP1 ( FONT_FAMILY, sal_Int16, MAYBEDEFAULT );
+ DECL_PROP1 ( FONT_CHARSET, sal_Int16, MAYBEDEFAULT );
+ DECL_PROP1 ( FONT_HEIGHT, float, MAYBEDEFAULT );
+ DECL_PROP1 ( FONT_WEIGHT, float, MAYBEDEFAULT );
+ DECL_PROP1 ( FONT_SLANT, sal_Int16, MAYBEDEFAULT );
+ DECL_PROP1 ( FONT_UNDERLINE, sal_Int16, MAYBEDEFAULT );
+ DECL_PROP1 ( FONT_STRIKEOUT, sal_Int16, MAYBEDEFAULT );
+ DECL_BOOL_PROP1 ( FONT_WORDLINEMODE, MAYBEDEFAULT );
+ }
+
+ //---------------------------------------------------------------------
+ void FontControlModel::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const
+ {
+ switch( _nHandle )
+ {
+ case PROPERTY_ID_TEXTCOLOR:
+ _rValue = m_aTextColor;
+ break;
+
+ case PROPERTY_ID_FONTEMPHASISMARK:
+ _rValue <<= m_nFontEmphasis;
+ break;
+
+ case PROPERTY_ID_FONTRELIEF:
+ _rValue <<= m_nFontRelief;
+ break;
+
+ case PROPERTY_ID_TEXTLINECOLOR:
+ _rValue = m_aTextLineColor;
+ break;
+
+ case PROPERTY_ID_FONT:
+ _rValue = makeAny( m_aFont );
+ break;
+
+ default:
+ _rValue = lcl_extractFontDescriptorAggregate( _nHandle, m_aFont );
+ break;
+ }
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool FontControlModel::convertFastPropertyValue( Any& _rConvertedValue, Any& _rOldValue,
+ sal_Int32 _nHandle, const Any& _rValue ) throw( IllegalArgumentException )
+ {
+ sal_Bool bModified = sal_False;
+ switch( _nHandle )
+ {
+ case PROPERTY_ID_TEXTCOLOR:
+ bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, m_aTextColor, ::getCppuType( static_cast< const sal_Int32* >( NULL ) ) );
+ break;
+
+ case PROPERTY_ID_TEXTLINECOLOR:
+ bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, m_aTextLineColor, ::getCppuType( static_cast< sal_Int32* >( NULL ) ) );
+ break;
+
+ case PROPERTY_ID_FONTEMPHASISMARK:
+ bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, m_nFontEmphasis );
+ break;
+
+ case PROPERTY_ID_FONTRELIEF:
+ bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, m_nFontRelief );
+ break;
+
+ case PROPERTY_ID_FONT:
+ {
+ Any aWorkAroundGccLimitation = makeAny( m_aFont );
+ bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, aWorkAroundGccLimitation, ::getCppuType( &m_aFont ) );
+ }
+ break;
+
+ case PROPERTY_ID_FONT_NAME:
+ bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, m_aFont.Name );
+ break;
+
+ case PROPERTY_ID_FONT_STYLENAME:
+ bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, m_aFont.StyleName );
+ break;
+
+ case PROPERTY_ID_FONT_FAMILY:
+ bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, (sal_Int16)m_aFont.Family );
+ break;
+
+ case PROPERTY_ID_FONT_CHARSET:
+ bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, (sal_Int16)m_aFont.CharSet );
+ break;
+
+ case PROPERTY_ID_FONT_CHARWIDTH:
+ bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, float( m_aFont.CharacterWidth ) );
+ break;
+
+ case PROPERTY_ID_FONT_KERNING:
+ bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, (sal_Int16)m_aFont.Kerning );
+ break;
+
+ case PROPERTY_ID_FONT_ORIENTATION:
+ bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, float( m_aFont.Orientation ) );
+ break;
+
+ case PROPERTY_ID_FONT_PITCH:
+ bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, (sal_Int16)m_aFont.Pitch );
+ break;
+
+ case PROPERTY_ID_FONT_TYPE:
+ bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, (sal_Int16)m_aFont.Type );
+ break;
+
+ case PROPERTY_ID_FONT_WIDTH:
+ bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, (sal_Int16)m_aFont.Width );
+ break;
+
+ case PROPERTY_ID_FONT_HEIGHT:
+ bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, float( m_aFont.Height ) );
+ break;
+
+ case PROPERTY_ID_FONT_WEIGHT:
+ bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, m_aFont.Weight );
+ break;
+
+ case PROPERTY_ID_FONT_SLANT:
+ bModified = tryPropertyValueEnum( _rConvertedValue, _rOldValue, _rValue, m_aFont.Slant );
+ break;
+
+ case PROPERTY_ID_FONT_UNDERLINE:
+ bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, (sal_Int16)m_aFont.Underline );
+ break;
+
+ case PROPERTY_ID_FONT_STRIKEOUT:
+ bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, (sal_Int16)m_aFont.Strikeout );
+ break;
+
+ case PROPERTY_ID_FONT_WORDLINEMODE:
+ bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, (sal_Bool)m_aFont.WordLineMode );
+ break;
+
+ default:
+ OSL_FAIL( "FontControlModel::convertFastPropertyValue: no font aggregate!" );
+ }
+ return bModified;
+ }
+
+ //------------------------------------------------------------------------------
+ void FontControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const Any& _rValue ) throw ( Exception )
+ {
+ switch( _nHandle )
+ {
+ case PROPERTY_ID_TEXTCOLOR:
+ m_aTextColor = _rValue;
+ break;
+
+ case PROPERTY_ID_TEXTLINECOLOR:
+ m_aTextLineColor = _rValue;
+ break;
+
+ case PROPERTY_ID_FONTEMPHASISMARK:
+ _rValue >>= m_nFontEmphasis;
+ break;
+
+ case PROPERTY_ID_FONTRELIEF:
+ _rValue >>= m_nFontRelief;
+ break;
+
+ case PROPERTY_ID_FONT:
+ _rValue >>= m_aFont;
+ break;
+
+ case PROPERTY_ID_FONT_NAME:
+ _rValue >>= m_aFont.Name;
+ break;
+
+ case PROPERTY_ID_FONT_STYLENAME:
+ _rValue >>= m_aFont.StyleName;
+ break;
+
+ case PROPERTY_ID_FONT_FAMILY:
+ _rValue >>= m_aFont.Family;
+ break;
+
+ case PROPERTY_ID_FONT_CHARSET:
+ _rValue >>= m_aFont.CharSet;
+ break;
+
+ case PROPERTY_ID_FONT_CHARWIDTH:
+ _rValue >>= m_aFont.CharacterWidth;
+ break;
+
+ case PROPERTY_ID_FONT_KERNING:
+ _rValue >>= m_aFont.Kerning;
+ break;
+
+ case PROPERTY_ID_FONT_ORIENTATION:
+ _rValue >>= m_aFont.Orientation;
+ break;
+
+ case PROPERTY_ID_FONT_PITCH:
+ _rValue >>= m_aFont.Pitch;
+ break;
+
+ case PROPERTY_ID_FONT_TYPE:
+ _rValue >>= m_aFont.Type;
+ break;
+
+ case PROPERTY_ID_FONT_WIDTH:
+ _rValue >>= m_aFont.Width;
+ break;
+
+ case PROPERTY_ID_FONT_HEIGHT:
+ {
+ float nHeight = 0;
+ _rValue >>= nHeight;
+ m_aFont.Height = (sal_Int16)nHeight;
+ }
+ break;
+
+ case PROPERTY_ID_FONT_WEIGHT:
+ _rValue >>= m_aFont.Weight;
+ break;
+
+ case PROPERTY_ID_FONT_SLANT:
+ _rValue >>= m_aFont.Slant;
+ break;
+
+ case PROPERTY_ID_FONT_UNDERLINE:
+ _rValue >>= m_aFont.Underline;
+ break;
+
+ case PROPERTY_ID_FONT_STRIKEOUT:
+ _rValue >>= m_aFont.Strikeout;
+ break;
+
+ case PROPERTY_ID_FONT_WORDLINEMODE:
+ {
+ sal_Bool bWordLineMode = sal_False;
+ _rValue >>= bWordLineMode;
+ m_aFont.WordLineMode = bWordLineMode;
+ }
+ break;
+
+ default:
+ OSL_FAIL( "FontControlModel::setFastPropertyValue_NoBroadcast: invalid property!" );
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ Any FontControlModel::getPropertyDefaultByHandle( sal_Int32 _nHandle ) const
+ {
+ Any aReturn;
+ // some defaults which are the same, not matter if we have toolkit-compatible
+ // defaults or not
+ bool bHandled = false;
+ switch( _nHandle )
+ {
+ case PROPERTY_ID_TEXTCOLOR:
+ case PROPERTY_ID_TEXTLINECOLOR:
+ // void
+ bHandled = true;
+ break;
+
+ case PROPERTY_ID_FONTEMPHASISMARK:
+ aReturn <<= FontEmphasisMark::NONE;
+ bHandled = true;
+ break;
+
+ case PROPERTY_ID_FONTRELIEF:
+ aReturn <<= FontRelief::NONE;
+ bHandled = true;
+ break;
+ }
+ if ( bHandled )
+ return aReturn;
+
+ if ( m_bToolkitCompatibleDefaults )
+ {
+ EmptyFontDescriptor aEmpty;
+ if ( PROPERTY_ID_FONT == _nHandle )
+ return makeAny( (FontDescriptor)aEmpty );
+ return lcl_extractFontDescriptorAggregate( _nHandle, aEmpty );
+ }
+
+ switch( _nHandle )
+ {
+ case PROPERTY_ID_FONT:
+ aReturn <<= ::comphelper::getDefaultFont();
+ break;
+
+ case PROPERTY_ID_FONT_WORDLINEMODE:
+ aReturn = makeBoolAny(sal_False);
+
+ case PROPERTY_ID_FONT_NAME:
+ case PROPERTY_ID_FONT_STYLENAME:
+ aReturn <<= ::rtl::OUString();
+
+ case PROPERTY_ID_FONT_FAMILY:
+ case PROPERTY_ID_FONT_CHARSET:
+ case PROPERTY_ID_FONT_SLANT:
+ case PROPERTY_ID_FONT_UNDERLINE:
+ case PROPERTY_ID_FONT_STRIKEOUT:
+ aReturn <<= (sal_Int16)1;
+ break;
+
+ case PROPERTY_ID_FONT_KERNING:
+ aReturn = makeBoolAny(sal_False);
+ break;
+
+ case PROPERTY_ID_FONT_PITCH:
+ case PROPERTY_ID_FONT_TYPE:
+ case PROPERTY_ID_FONT_WIDTH:
+ aReturn <<= (sal_Int16)0;
+ break;
+
+ case PROPERTY_ID_FONT_HEIGHT:
+ case PROPERTY_ID_FONT_WEIGHT:
+ case PROPERTY_ID_FONT_CHARWIDTH:
+ case PROPERTY_ID_FONT_ORIENTATION:
+ aReturn <<= (float)0;
+ break;
+
+ default:
+ OSL_FAIL( "FontControlModel::getPropertyDefaultByHandle: invalid property!" );
+ }
+
+ return aReturn;
+ }
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/imgprod.cxx b/forms/source/component/imgprod.cxx
new file mode 100644
index 000000000000..702f7fca461b
--- /dev/null
+++ b/forms/source/component/imgprod.cxx
@@ -0,0 +1,582 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+
+#include "imgprod.hxx"
+
+#include <vcl/bmpacc.hxx>
+#include <vcl/cvtgrf.hxx>
+#include <vcl/svapp.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <svtools/filter.hxx>
+#include <com/sun/star/io/XInputStream.hpp>
+
+#include "svtools/imageresourceaccess.hxx"
+#include <comphelper/processfactory.hxx>
+
+// --------------------
+// - ImgProdLockBytes -
+// --------------------
+
+class ImgProdLockBytes : public SvLockBytes
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > xStmRef;
+ ::com::sun::star::uno::Sequence<sal_Int8> maSeq;
+
+ ImgProdLockBytes() {};
+
+public:
+
+ ImgProdLockBytes( SvStream* pStm, sal_Bool bOwner );
+ ImgProdLockBytes( ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > & rStreamRef );
+ virtual ~ImgProdLockBytes();
+
+ virtual ErrCode ReadAt( sal_Size nPos, void* pBuffer, sal_Size nCount, sal_Size* pRead ) const;
+ virtual ErrCode WriteAt( sal_Size nPos, const void* pBuffer, sal_Size nCount, sal_Size* pWritten );
+ virtual ErrCode Flush() const;
+ virtual ErrCode SetSize( sal_Size nSize );
+ virtual ErrCode Stat( SvLockBytesStat*, SvLockBytesStatFlag ) const;
+};
+
+// ------------------------------------------------------------------------
+
+ImgProdLockBytes::ImgProdLockBytes( SvStream* pStm, sal_Bool bOwner ) :
+ SvLockBytes( pStm, bOwner )
+{
+}
+
+// ------------------------------------------------------------------------
+
+ImgProdLockBytes::ImgProdLockBytes( ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > & rStmRef ) :
+ xStmRef( rStmRef )
+{
+ if( xStmRef.is() )
+ {
+ const sal_uInt32 nBytesToRead = 65535;
+ sal_uInt32 nRead;
+
+ do
+ {
+ ::com::sun::star::uno::Sequence< sal_Int8 > aReadSeq;
+
+ nRead = xStmRef->readSomeBytes( aReadSeq, nBytesToRead );
+
+ if( nRead )
+ {
+ const sal_uInt32 nOldLength = maSeq.getLength();
+ maSeq.realloc( nOldLength + nRead );
+ rtl_copyMemory( maSeq.getArray() + nOldLength, aReadSeq.getConstArray(), aReadSeq.getLength() );
+ }
+ }
+ while( nBytesToRead == nRead );
+ }
+}
+
+// ------------------------------------------------------------------------
+
+ImgProdLockBytes::~ImgProdLockBytes()
+{
+}
+
+// ------------------------------------------------------------------------
+
+ErrCode ImgProdLockBytes::ReadAt( sal_Size nPos, void* pBuffer, sal_Size nCount, sal_Size* pRead ) const
+{
+ if( GetStream() )
+ {
+ ( (SvStream*) GetStream() )->ResetError();
+ const ErrCode nErr = SvLockBytes::ReadAt( nPos, pBuffer, nCount, pRead );
+ ( (SvStream*) GetStream() )->ResetError();
+ return nErr;
+ }
+ else
+ {
+ const sal_Size nSeqLen = maSeq.getLength();
+ ErrCode nErr = ERRCODE_NONE;
+
+ if( nPos < nSeqLen )
+ {
+ if( ( nPos + nCount ) > nSeqLen )
+ nCount = nSeqLen - nPos;
+
+ memcpy( pBuffer, maSeq.getConstArray() + nPos, nCount );
+ *pRead = nCount;
+ }
+ else
+ *pRead = 0UL;
+
+ return nErr;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+ErrCode ImgProdLockBytes::WriteAt( sal_Size nPos, const void* pBuffer, sal_Size nCount, sal_Size* pWritten )
+{
+ if( GetStream() )
+ return SvLockBytes::WriteAt( nPos, pBuffer, nCount, pWritten );
+ else
+ {
+ DBG_ASSERT( xStmRef.is(), "ImgProdLockBytes::WriteAt: xInputStream has no reference..." );
+ return ERRCODE_IO_CANTWRITE;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+ErrCode ImgProdLockBytes::Flush() const
+{
+ return ERRCODE_NONE;
+}
+
+// ------------------------------------------------------------------------
+
+ErrCode ImgProdLockBytes::SetSize( sal_Size nSize )
+{
+ if( GetStream() )
+ return SvLockBytes::SetSize( nSize );
+ else
+ {
+ OSL_FAIL( "ImgProdLockBytes::SetSize not supported for xInputStream..." );
+ return ERRCODE_IO_CANTWRITE;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+ErrCode ImgProdLockBytes::Stat( SvLockBytesStat* pStat, SvLockBytesStatFlag eFlag ) const
+{
+ if( GetStream() )
+ return SvLockBytes::Stat( pStat, eFlag );
+ else
+ {
+ DBG_ASSERT( xStmRef.is(), "ImgProdLockBytes::Stat: xInputStream has no reference..." );
+ pStat->nSize = maSeq.getLength();
+ return ERRCODE_NONE;
+ }
+}
+
+// -----------------
+// - ImageProducer -
+// -----------------
+
+ImageProducer::ImageProducer() :
+ mpStm ( NULL ),
+ mbConsInit ( sal_False )
+{
+ mpGraphic = new Graphic;
+ DBG_ASSERT( Application::GetFilterHdl().IsSet(), "ImageProducer::ImageProducer(): No filter handler set" );
+}
+
+// ------------------------------------------------------------
+
+ImageProducer::~ImageProducer()
+{
+ delete mpGraphic;
+ mpGraphic = NULL;
+
+ delete mpStm;
+ mpStm = NULL;
+}
+
+// ------------------------------------------------------------
+
+// ::com::sun::star::uno::XInterface
+::com::sun::star::uno::Any ImageProducer::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
+ SAL_STATIC_CAST( ::com::sun::star::lang::XInitialization*, this ),
+ SAL_STATIC_CAST( ::com::sun::star::awt::XImageProducer*, this ) );
+ return (aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ));
+}
+
+// ------------------------------------------------------------
+
+void ImageProducer::addConsumer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer >& rxConsumer ) throw(::com::sun::star::uno::RuntimeException)
+{
+ DBG_ASSERT( rxConsumer.is(), "::AddConsumer(...): No consumer referenced!" );
+ if( rxConsumer.is() )
+ maConsList.push_back( new ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer > ( rxConsumer ));
+}
+
+// ------------------------------------------------------------
+
+void ImageProducer::removeConsumer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer >& rxConsumer ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ConsumerList_t::reverse_iterator riter = std::find(maConsList.rbegin(),maConsList.rend(),rxConsumer);
+
+ if (riter != maConsList.rend())
+ maConsList.erase(riter.base()-1);
+}
+
+// ------------------------------------------------------------
+
+void ImageProducer::SetImage( const ::rtl::OUString& rPath )
+{
+ maURL = rPath;
+ mpGraphic->Clear();
+ mbConsInit = sal_False;
+ delete mpStm;
+
+ if ( ::svt::GraphicAccess::isSupportedURL( maURL ) )
+ {
+ mpStm = ::svt::GraphicAccess::getImageStream( ::comphelper::getProcessServiceFactory(), maURL );
+ }
+ else if( maURL.getLength() )
+ {
+ SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( maURL, STREAM_STD_READ );
+ mpStm = pIStm ? new SvStream( new ImgProdLockBytes( pIStm, sal_True ) ) : NULL;
+ }
+ else
+ mpStm = NULL;
+}
+
+// ------------------------------------------------------------
+
+void ImageProducer::SetImage( SvStream& rStm )
+{
+ maURL = ::rtl::OUString();
+ mpGraphic->Clear();
+ mbConsInit = sal_False;
+
+ delete mpStm;
+ mpStm = new SvStream( new ImgProdLockBytes( &rStm, sal_False ) );
+}
+
+// ------------------------------------------------------------
+
+void ImageProducer::setImage( ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > & rInputStmRef )
+{
+ maURL = ::rtl::OUString();
+ mpGraphic->Clear();
+ mbConsInit = sal_False;
+ delete mpStm;
+
+ if( rInputStmRef.is() )
+ mpStm = new SvStream( new ImgProdLockBytes( rInputStmRef ) );
+ else
+ mpStm = NULL;
+}
+
+// ------------------------------------------------------------
+
+void ImageProducer::NewDataAvailable()
+{
+ if( ( GRAPHIC_NONE == mpGraphic->GetType() ) || mpGraphic->GetContext() )
+ startProduction();
+}
+
+// ------------------------------------------------------------
+
+void ImageProducer::startProduction() throw(::com::sun::star::uno::RuntimeException)
+{
+ if( !maConsList.empty() || maDoneHdl.IsSet() )
+ {
+ bool bNotifyEmptyGraphics = false;
+
+ // valid stream or filled graphic? => update consumers
+ if( mpStm || ( mpGraphic->GetType() != GRAPHIC_NONE ) )
+ {
+ // if we already have a graphic, we don't have to import again;
+ // graphic is cleared if a new Stream is set
+ if( ( mpGraphic->GetType() == GRAPHIC_NONE ) || mpGraphic->GetContext() )
+ {
+ if ( ImplImportGraphic( *mpGraphic ) && maDoneHdl.IsSet() )
+ maDoneHdl.Call( mpGraphic );
+ }
+
+ if( mpGraphic->GetType() != GRAPHIC_NONE )
+ ImplUpdateData( *mpGraphic );
+ else
+ bNotifyEmptyGraphics = true;
+ }
+ else
+ bNotifyEmptyGraphics = true;
+
+ if ( bNotifyEmptyGraphics )
+ {
+ // reset image
+ // create temporary list to hold interfaces
+ ConsumerList_t aTmp = maConsList;
+
+ // iterate through interfaces
+ for( ConsumerList_t::iterator iter = aTmp.begin(); iter != aTmp.end(); ++iter )
+ {
+ (*iter)->init( 0, 0 );
+ (*iter)->complete( ::com::sun::star::awt::ImageStatus::IMAGESTATUS_STATICIMAGEDONE, this );
+ }
+
+ if ( maDoneHdl.IsSet() )
+ maDoneHdl.Call( NULL );
+ }
+ }
+}
+
+// ------------------------------------------------------------
+
+sal_Bool ImageProducer::ImplImportGraphic( Graphic& rGraphic )
+{
+ if( ERRCODE_IO_PENDING == mpStm->GetError() )
+ mpStm->ResetError();
+
+ mpStm->Seek( 0UL );
+
+ sal_Bool bRet = GraphicConverter::Import( *mpStm, rGraphic ) == ERRCODE_NONE;
+
+ if( ERRCODE_IO_PENDING == mpStm->GetError() )
+ mpStm->ResetError();
+
+ return bRet;
+}
+
+// ------------------------------------------------------------
+
+void ImageProducer::ImplUpdateData( const Graphic& rGraphic )
+{
+ ImplInitConsumer( rGraphic );
+
+ if( mbConsInit && !maConsList.empty() )
+ {
+ // create temporary list to hold interfaces
+ ConsumerList_t aTmp = maConsList;
+
+ ImplUpdateConsumer( rGraphic );
+ mbConsInit = sal_False;
+
+ // iterate through interfaces
+ for( ConsumerList_t::iterator iter = aTmp.begin(); iter != aTmp.end(); ++iter )
+ (*iter)->complete( ::com::sun::star::awt::ImageStatus::IMAGESTATUS_STATICIMAGEDONE, this );
+ }
+}
+
+// ------------------------------------------------------------
+
+void ImageProducer::ImplInitConsumer( const Graphic& rGraphic )
+{
+ Bitmap aBmp( rGraphic.GetBitmapEx().GetBitmap() );
+ BitmapReadAccess* pBmpAcc = aBmp.AcquireReadAccess();
+
+ if( pBmpAcc )
+ {
+ sal_uInt16 nPalCount = 0;
+ sal_uInt32 nRMask = 0;
+ sal_uInt32 nGMask = 0;
+ sal_uInt32 nBMask = 0;
+ sal_uInt32 nAMask = 0;
+ ::com::sun::star::uno::Sequence< sal_Int32 > aRGBPal;
+
+ if( pBmpAcc->HasPalette() )
+ {
+ nPalCount = pBmpAcc->GetPaletteEntryCount();
+
+ if( nPalCount )
+ {
+ aRGBPal = ::com::sun::star::uno::Sequence< sal_Int32 >( nPalCount + 1 );
+
+ sal_Int32* pTmp = aRGBPal.getArray();
+
+ for( sal_uInt32 i = 0; i < nPalCount; i++, pTmp++ )
+ {
+ const BitmapColor& rCol = pBmpAcc->GetPaletteColor( (sal_uInt16) i );
+
+ *pTmp = ( (sal_Int32) rCol.GetRed() ) << (sal_Int32)(24L);
+ *pTmp |= ( (sal_Int32) rCol.GetGreen() ) << (sal_Int32)(16L);
+ *pTmp |= ( (sal_Int32) rCol.GetBlue() ) << (sal_Int32)(8L);
+ *pTmp |= (sal_Int32)(0x000000ffL);
+ }
+
+ if( rGraphic.IsTransparent() )
+ {
+ // append transparent entry
+ *pTmp = (sal_Int32)(0xffffff00L);
+ mnTransIndex = nPalCount;
+ nPalCount++;
+ }
+ else
+ mnTransIndex = 0;
+
+ }
+ }
+ else
+ {
+ nRMask = 0xff000000UL;
+ nGMask = 0x00ff0000UL;
+ nBMask = 0x0000ff00UL;
+ nAMask = 0x000000ffUL;
+ }
+
+ // create temporary list to hold interfaces
+ ConsumerList_t aTmp = maConsList;
+
+ // iterate through interfaces
+ for( ConsumerList_t::iterator iter = aTmp.begin(); iter != aTmp.end(); ++iter)
+ {
+ (*iter)->init( pBmpAcc->Width(), pBmpAcc->Height() );
+ (*iter)->setColorModel( pBmpAcc->GetBitCount(),aRGBPal, nRMask, nGMask, nBMask, nAMask );
+ }
+
+ aBmp.ReleaseAccess( pBmpAcc );
+ mbConsInit = sal_True;
+ }
+}
+
+// ------------------------------------------------------------
+
+void ImageProducer::ImplUpdateConsumer( const Graphic& rGraphic )
+{
+ BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
+ Bitmap aBmp( aBmpEx.GetBitmap() );
+ BitmapReadAccess* pBmpAcc = aBmp.AcquireReadAccess();
+
+ if( pBmpAcc )
+ {
+ Bitmap aMask( aBmpEx.GetMask() );
+ BitmapReadAccess* pMskAcc = !!aMask ? aMask.AcquireReadAccess() : NULL;
+ const long nWidth = pBmpAcc->Width();
+ const long nHeight = pBmpAcc->Height();
+ const long nStartX = 0L;
+ const long nEndX = nWidth - 1L;
+ const long nStartY = 0L;
+ const long nEndY = nHeight - 1L;
+ const long nPartWidth = nEndX - nStartX + 1;
+ const long nPartHeight = nEndY - nStartY + 1;
+
+ if( !pMskAcc )
+ {
+ aMask = Bitmap( aBmp.GetSizePixel(), 1 );
+ aMask.Erase( COL_BLACK );
+ pMskAcc = aMask.AcquireReadAccess();
+ }
+
+ // create temporary list to hold interfaces
+ ConsumerList_t aTmp = maConsList;
+
+ if( pBmpAcc->HasPalette() )
+ {
+ const BitmapColor aWhite( pMskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
+
+ if( mnTransIndex < 256 )
+ {
+ ::com::sun::star::uno::Sequence<sal_Int8> aData( nPartWidth * nPartHeight );
+ sal_Int8* pTmp = aData.getArray();
+
+ for( long nY = nStartY; nY <= nEndY; nY++ )
+ {
+ for( long nX = nStartX; nX <= nEndX; nX++ )
+ {
+ if( pMskAcc->GetPixel( nY, nX ) == aWhite )
+ *pTmp++ = sal::static_int_cast< sal_Int8 >(
+ mnTransIndex );
+ else
+ *pTmp++ = pBmpAcc->GetPixel( nY, nX ).GetIndex();
+ }
+ }
+
+ // iterate through interfaces
+ for (ConsumerList_t::iterator iter = aTmp.begin(); iter != aTmp.end(); ++iter)
+ (*iter)->setPixelsByBytes( nStartX, nStartY, nPartWidth, nPartHeight, aData, 0UL, nPartWidth );
+ }
+ else
+ {
+ ::com::sun::star::uno::Sequence<sal_Int32> aData( nPartWidth * nPartHeight );
+ sal_Int32* pTmp = aData.getArray();
+
+ for( long nY = nStartY; nY <= nEndY; nY++ )
+ {
+ for( long nX = nStartX; nX <= nEndX; nX++ )
+ {
+ if( pMskAcc->GetPixel( nY, nX ) == aWhite )
+ *pTmp++ = mnTransIndex;
+ else
+ *pTmp++ = pBmpAcc->GetPixel( nY, nX ).GetIndex();
+ }
+ }
+
+ // iterate through interfaces
+ for (ConsumerList_t::iterator iter = aTmp.begin(); iter != aTmp.end(); ++iter)
+ (*iter)->setPixelsByLongs( nStartX, nStartY, nPartWidth, nPartHeight, aData, 0UL, nPartWidth );
+ }
+ }
+ else
+ {
+ ::com::sun::star::uno::Sequence<sal_Int32> aData( nPartWidth * nPartHeight );
+ const BitmapColor aWhite( pMskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
+ sal_Int32* pTmp = aData.getArray();
+
+ for( long nY = nStartY; nY <= nEndY; nY++ )
+ {
+ for( long nX = nStartX; nX <= nEndX; nX++, pTmp++ )
+ {
+ const BitmapColor aCol( pBmpAcc->GetPixel( nY, nX ) );
+
+ *pTmp = ( (sal_Int32) aCol.GetRed() ) << (sal_Int32)(24L);
+ *pTmp |= ( (sal_Int32) aCol.GetGreen() ) << (sal_Int32)(16L);
+ *pTmp |= ( (sal_Int32) aCol.GetBlue() ) << (sal_Int32)(8L);
+
+ if( pMskAcc->GetPixel( nY, nX ) != aWhite )
+ *pTmp |= 0x000000ffUL;
+ }
+ }
+
+ // iterate through interfaces
+ for (ConsumerList_t::iterator iter = aTmp.begin(); iter != aTmp.end(); ++iter)
+ (*iter)->setPixelsByLongs( nStartX, nStartY, nPartWidth, nPartHeight, aData, 0UL, nPartWidth );
+ }
+
+ aBmp.ReleaseAccess( pBmpAcc );
+ aMask.ReleaseAccess( pMskAcc );
+ }
+}
+
+void ImageProducer::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ if ( aArguments.getLength() == 1 )
+ {
+ ::com::sun::star::uno::Any aArg = aArguments.getConstArray()[0];
+ rtl::OUString aURL;
+ if ( aArg >>= aURL )
+ {
+ SetImage( aURL );
+ }
+ }
+}
+
+namespace frm
+{
+::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
+SAL_CALL ImageProducer_CreateInstance(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& )
+{
+ return ::com::sun::star::uno::Reference < ::com::sun::star::uno::XInterface >(
+ ( ::cppu::OWeakObject* ) new ImageProducer );
+}
+} // namespace frm
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/imgprod.hxx b/forms/source/component/imgprod.hxx
new file mode 100644
index 000000000000..53d673cbe065
--- /dev/null
+++ b/forms/source/component/imgprod.hxx
@@ -0,0 +1,113 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _PRODUCE_HXX
+#define _PRODUCE_HXX
+
+#include <boost/ptr_container/ptr_vector.hpp>
+
+#include <tools/link.hxx>
+#include <tools/string.hxx>
+#include <com/sun/star/awt/ImageStatus.hpp>
+#include <com/sun/star/awt/XImageConsumer.hpp>
+#include <com/sun/star/awt/XImageProducer.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <cppuhelper/weak.hxx>
+
+
+// -----------------
+// - ImageProducer -
+// -----------------
+
+
+
+class SvStream;
+class ImageConsumer;
+class Graphic;
+class GraphicFilter;
+
+namespace com { namespace sun { namespace star { namespace io {
+ class XInputStream;
+}}}}
+
+
+class ImageProducer : public ::com::sun::star::awt::XImageProducer,
+ public ::com::sun::star::lang::XInitialization,
+ public ::cppu::OWeakObject
+{
+private:
+
+ typedef boost::ptr_vector< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer > > ConsumerList_t;
+
+ ::rtl::OUString maURL;
+ ConsumerList_t maConsList;
+ Graphic* mpGraphic;
+ SvStream* mpStm;
+ sal_uInt32 mnTransIndex;
+ sal_Bool mbConsInit;
+ Link maDoneHdl;
+
+ sal_Bool ImplImportGraphic( Graphic& rGraphic );
+ void ImplUpdateData( const Graphic& rGraphic );
+ void ImplInitConsumer( const Graphic& rGraphic );
+ void ImplUpdateConsumer( const Graphic& rGraphic );
+
+public:
+
+ ImageProducer();
+ ~ImageProducer();
+
+ void SetImage( const ::rtl::OUString& rPath );
+ void SetImage( SvStream& rStm );
+
+ void NewDataAvailable();
+
+ void SetDoneHdl( const Link& i_rHdl ) { maDoneHdl = i_rHdl; }
+ const Link& GetDoneHdl() const { return maDoneHdl; }
+
+ // ::com::sun::star::uno::XInterface
+ ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL acquire() throw() { OWeakObject::acquire(); }
+ void SAL_CALL release() throw() { OWeakObject::release(); }
+
+ // MT: ???
+ void setImage( ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > & rStmRef );
+
+ // ::com::sun::star::awt::XImageProducer
+ void SAL_CALL addConsumer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer >& rxConsumer ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL removeConsumer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer >& rxConsumer ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL startProduction( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::lang::XInitialization
+ void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+};
+
+#endif // _PRODUCE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/makefile.mk b/forms/source/component/makefile.mk
new file mode 100644
index 000000000000..c3bfce4d3247
--- /dev/null
+++ b/forms/source/component/makefile.mk
@@ -0,0 +1,95 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJINC=..
+PRJNAME=forms
+TARGET=component
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings ----------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE: $(PRJ)$/makefile.pmk
+
+# --- Types -------------------------------------
+
+INCPRE+=$(SOLARINCDIR)$/offuh
+
+# --- Files -------------------------------------
+
+.IF "$(COM)"=="GCC"
+NOOPTFILES= $(SLO)$/EventThread.obj
+.ENDIF
+
+SLOFILES= $(SLO)$/Grid.obj \
+ $(SLO)$/Columns.obj \
+ $(SLO)$/DatabaseForm.obj \
+ $(SLO)$/GroupManager.obj \
+ $(SLO)$/FormsCollection.obj \
+ $(SLO)$/EventThread.obj \
+ $(SLO)$/File.obj \
+ $(SLO)$/Edit.obj \
+ $(SLO)$/EditBase.obj \
+ $(SLO)$/Numeric.obj \
+ $(SLO)$/Pattern.obj \
+ $(SLO)$/Currency.obj \
+ $(SLO)$/Date.obj \
+ $(SLO)$/Time.obj \
+ $(SLO)$/FormattedField.obj \
+ $(SLO)$/FormattedFieldWrapper.obj \
+ $(SLO)$/ListBox.obj \
+ $(SLO)$/ComboBox.obj \
+ $(SLO)$/GroupBox.obj \
+ $(SLO)$/Hidden.obj \
+ $(SLO)$/CheckBox.obj \
+ $(SLO)$/RadioButton.obj \
+ $(SLO)$/FixedText.obj \
+ $(SLO)$/FormComponent.obj \
+ $(SLO)$/clickableimage.obj \
+ $(SLO)$/Button.obj \
+ $(SLO)$/ImageButton.obj \
+ $(SLO)$/ImageControl.obj \
+ $(SLO)$/errorbroadcaster.obj \
+ $(SLO)$/cloneable.obj \
+ $(SLO)$/Filter.obj \
+ $(SLO)$/entrylisthelper.obj \
+ $(SLO)$/scrollbar.obj \
+ $(SLO)$/spinbutton.obj \
+ $(SLO)$/navigationbar.obj \
+ $(SLO)$/formcontrolfont.obj \
+ $(SLO)$/refvaluecomponent.obj \
+ $(SLO)$/imgprod.obj \
+ $(SLO)$/findpos.obj \
+ $(SLO)$/propertybaghelper.obj \
+ $(SLO)$/cachedrowset.obj \
+
+# --- Targets ----------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/forms/source/component/navigationbar.cxx b/forms/source/component/navigationbar.cxx
new file mode 100644
index 000000000000..7799779d4b3f
--- /dev/null
+++ b/forms/source/component/navigationbar.cxx
@@ -0,0 +1,512 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+#include "navigationbar.hxx"
+#include "frm_module.hxx"
+
+#include <com/sun/star/text/WritingMode2.hpp>
+
+#include <comphelper/streamsection.hxx>
+#include <comphelper/basicio.hxx>
+
+//--------------------------------------------------------------------------
+extern "C" void SAL_CALL createRegistryInfo_ONavigationBarModel()
+{
+ static ::frm::OMultiInstanceAutoRegistration< ::frm::ONavigationBarModel > aAutoRegistration;
+}
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::form;
+ using namespace ::com::sun::star::awt;
+ using namespace ::com::sun::star::io;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::util;
+ using namespace ::com::sun::star::container;
+ using namespace ::comphelper;
+
+ namespace WritingMode2 = ::com::sun::star::text::WritingMode2;
+
+#define REGISTER_VOID_PROP( prop, memberAny, type ) \
+ registerMayBeVoidProperty( PROPERTY_##prop, PROPERTY_ID_##prop, PropertyAttribute::BOUND | PropertyAttribute::MAYBEDEFAULT | PropertyAttribute::MAYBEVOID, \
+ &memberAny, ::getCppuType( static_cast< type* >( NULL ) ) );
+
+ //==================================================================
+ // ONavigationBarModel
+ //==================================================================
+ DBG_NAME( ONavigationBarModel )
+ //------------------------------------------------------------------
+ ONavigationBarModel::ONavigationBarModel( const Reference< XMultiServiceFactory >& _rxFactory )
+ :OControlModel( _rxFactory, ::rtl::OUString() )
+ ,FontControlModel( true )
+ {
+ DBG_CTOR( ONavigationBarModel, NULL );
+
+ m_nClassId = FormComponentType::NAVIGATIONBAR;
+ implInitPropertyContainer();
+
+ getPropertyDefaultByHandle( PROPERTY_ID_DEFAULTCONTROL ) >>= m_sDefaultControl;
+ getPropertyDefaultByHandle( PROPERTY_ID_ICONSIZE ) >>= m_nIconSize;
+ getPropertyDefaultByHandle( PROPERTY_ID_BORDER ) >>= m_nBorder;
+ getPropertyDefaultByHandle( PROPERTY_ID_DELAY ) >>= m_nDelay;
+ getPropertyDefaultByHandle( PROPERTY_ID_ENABLED ) >>= m_bEnabled;
+ getPropertyDefaultByHandle( PROPERTY_ID_ENABLEVISIBLE ) >>= m_bEnableVisible;
+ getPropertyDefaultByHandle( PROPERTY_ID_SHOW_POSITION ) >>= m_bShowPosition;
+ getPropertyDefaultByHandle( PROPERTY_ID_SHOW_NAVIGATION ) >>= m_bShowNavigation;
+ getPropertyDefaultByHandle( PROPERTY_ID_SHOW_RECORDACTIONS ) >>= m_bShowActions;
+ getPropertyDefaultByHandle( PROPERTY_ID_SHOW_FILTERSORT ) >>= m_bShowFilterSort;
+ getPropertyDefaultByHandle( PROPERTY_ID_WRITING_MODE ) >>= m_nWritingMode;
+ getPropertyDefaultByHandle( PROPERTY_ID_CONTEXT_WRITING_MODE ) >>= m_nContextWritingMode;
+ }
+
+ //------------------------------------------------------------------
+ ONavigationBarModel::ONavigationBarModel( const ONavigationBarModel* _pOriginal, const Reference< XMultiServiceFactory >& _rxFactory )
+ :OControlModel( _pOriginal, _rxFactory )
+ ,FontControlModel( _pOriginal )
+ {
+ DBG_CTOR( ONavigationBarModel, NULL );
+
+ implInitPropertyContainer();
+
+ m_aTabStop = _pOriginal->m_aTabStop;
+ m_aBackgroundColor = _pOriginal->m_aBackgroundColor;
+ m_sDefaultControl = _pOriginal->m_sDefaultControl;
+ m_sHelpText = _pOriginal->m_sHelpText;
+ m_sHelpURL = _pOriginal->m_sHelpURL;
+ m_bEnabled = _pOriginal->m_bEnabled;
+ m_bEnableVisible = _pOriginal->m_bEnableVisible;
+ m_nIconSize = _pOriginal->m_nIconSize;
+ m_nBorder = _pOriginal->m_nBorder;
+ m_nDelay = _pOriginal->m_nDelay;
+ m_bShowPosition = _pOriginal->m_bShowPosition;
+ m_bShowNavigation = _pOriginal->m_bShowNavigation;
+ m_bShowActions = _pOriginal->m_bShowActions;
+ m_bShowFilterSort = _pOriginal->m_bShowFilterSort;
+ m_nWritingMode = _pOriginal->m_nWritingMode;
+ m_nContextWritingMode = _pOriginal->m_nContextWritingMode;
+ }
+
+ //------------------------------------------------------------------
+ void ONavigationBarModel::implInitPropertyContainer()
+ {
+ REGISTER_PROP_2( DEFAULTCONTROL, m_sDefaultControl, BOUND, MAYBEDEFAULT );
+ REGISTER_PROP_2( HELPTEXT, m_sHelpText, BOUND, MAYBEDEFAULT );
+ REGISTER_PROP_2( HELPURL, m_sHelpURL, BOUND, MAYBEDEFAULT );
+ REGISTER_PROP_2( ENABLED, m_bEnabled, BOUND, MAYBEDEFAULT );
+ REGISTER_PROP_2( ENABLEVISIBLE, m_bEnableVisible, BOUND, MAYBEDEFAULT );
+ REGISTER_PROP_2( ICONSIZE, m_nIconSize, BOUND, MAYBEDEFAULT );
+ REGISTER_PROP_2( BORDER, m_nBorder, BOUND, MAYBEDEFAULT );
+ REGISTER_PROP_2( DELAY, m_nDelay, BOUND, MAYBEDEFAULT );
+ REGISTER_PROP_2( SHOW_POSITION, m_bShowPosition, BOUND, MAYBEDEFAULT );
+ REGISTER_PROP_2( SHOW_NAVIGATION, m_bShowNavigation, BOUND, MAYBEDEFAULT );
+ REGISTER_PROP_2( SHOW_RECORDACTIONS, m_bShowActions, BOUND, MAYBEDEFAULT );
+ REGISTER_PROP_2( SHOW_FILTERSORT, m_bShowFilterSort, BOUND, MAYBEDEFAULT );
+ REGISTER_PROP_2( WRITING_MODE, m_nWritingMode, BOUND, MAYBEDEFAULT );
+ REGISTER_PROP_3( CONTEXT_WRITING_MODE,m_nContextWritingMode, BOUND, MAYBEDEFAULT, TRANSIENT );
+
+ REGISTER_VOID_PROP( TABSTOP, m_aTabStop, sal_Bool );
+ REGISTER_VOID_PROP( BACKGROUNDCOLOR, m_aBackgroundColor, sal_Int32 );
+ }
+
+ //------------------------------------------------------------------
+ ONavigationBarModel::~ONavigationBarModel()
+ {
+ if ( !OComponentHelper::rBHelper.bDisposed )
+ {
+ acquire();
+ dispose();
+ }
+
+ DBG_DTOR( ONavigationBarModel, NULL );
+ }
+
+ //------------------------------------------------------------------
+ Any SAL_CALL ONavigationBarModel::queryAggregation( const Type& _rType ) throw ( RuntimeException )
+ {
+ Any aReturn = ONavigationBarModel_BASE::queryInterface( _rType );
+
+ if ( !aReturn.hasValue() )
+ aReturn = OControlModel::queryAggregation( _rType );
+
+ return aReturn;
+ }
+
+ //------------------------------------------------------------------
+ IMPLEMENT_FORWARD_XTYPEPROVIDER2( ONavigationBarModel, OControlModel, ONavigationBarModel_BASE )
+
+ //------------------------------------------------------------------------------
+ IMPLEMENT_DEFAULT_CLONING( ONavigationBarModel )
+
+ //------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL ONavigationBarModel::getImplementationName() throw(RuntimeException)
+ {
+ return getImplementationName_Static();
+ }
+
+ //------------------------------------------------------------------
+ Sequence< ::rtl::OUString > SAL_CALL ONavigationBarModel::getSupportedServiceNames() throw(RuntimeException)
+ {
+ return getSupportedServiceNames_Static();
+ }
+
+ //------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL ONavigationBarModel::getImplementationName_Static()
+ {
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.form.ONavigationBarModel" ) );
+ }
+
+ //------------------------------------------------------------------
+ Sequence< ::rtl::OUString > SAL_CALL ONavigationBarModel::getSupportedServiceNames_Static()
+ {
+ Sequence< ::rtl::OUString > aSupported = OControlModel::getSupportedServiceNames_Static();
+ aSupported.realloc( aSupported.getLength() + 2 );
+
+ ::rtl::OUString* pArray = aSupported.getArray();
+ pArray[ aSupported.getLength() - 2 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControlModel" ) );
+ pArray[ aSupported.getLength() - 1 ] = FRM_SUN_COMPONENT_NAVTOOLBAR;
+ return aSupported;
+ }
+
+ //------------------------------------------------------------------
+ Reference< XInterface > SAL_CALL ONavigationBarModel::Create( const Reference< XMultiServiceFactory >& _rxFactory )
+ {
+ return *( new ONavigationBarModel( _rxFactory ) );
+ }
+
+ //------------------------------------------------------------------
+ void SAL_CALL ONavigationBarModel::disposing()
+ {
+ OControlModel::disposing( );
+ }
+
+ //------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL ONavigationBarModel::getServiceName() throw ( RuntimeException )
+ {
+ return FRM_SUN_COMPONENT_NAVTOOLBAR;
+ }
+
+ //------------------------------------------------------------------
+ #define PERSIST_TABSTOP 0x0001
+ #define PERSIST_BACKGROUND 0x0002
+ #define PERSIST_TEXTCOLOR 0x0004
+ #define PERSIST_TEXTLINECOLOR 0x0008
+
+ #define PERSIST_ENABLED 0x0001
+ #define PERSIST_LARGEICONS 0x0002
+ // leaf a leap here - this will allow for two more icon size values to be stored compatibly
+ #define PERSIST_SHOW_POSITION 0x0008
+ #define PERSIST_SHOW_NAVIGATION 0x0010
+ #define PERSIST_SHOW_ACTIONS 0x0020
+ #define PERSIST_SHOW_FILTERSORT 0x0040
+
+ //------------------------------------------------------------------
+ void SAL_CALL ONavigationBarModel::write( const Reference< XObjectOutputStream >& _rxOutStream ) throw ( IOException, RuntimeException )
+ {
+ // open a section for compatibility - if we later on write additional members,
+ // then older versions can skip them
+ Reference< XDataOutputStream > xDataOut( _rxOutStream, UNO_QUERY );
+ OStreamSection aEnsureBlockCompat( xDataOut );
+
+ // base class
+ OControlModel::write( _rxOutStream );
+
+ {
+ OStreamSection aEnsureCompat( xDataOut );
+ // determine which properties are not void and need to be written
+ sal_Int32 nNonVoids = 0;
+ if ( m_aTabStop.hasValue() )
+ nNonVoids |= PERSIST_TABSTOP;
+ if ( m_aBackgroundColor.hasValue() )
+ nNonVoids |= PERSIST_BACKGROUND;
+ if ( hasTextColor() )
+ nNonVoids |= PERSIST_TEXTCOLOR;
+ if ( hasTextLineColor() )
+ nNonVoids |= PERSIST_TEXTLINECOLOR;
+
+ _rxOutStream->writeLong( nNonVoids );
+
+ // the maybeboid anys
+ if ( nNonVoids & PERSIST_TABSTOP )
+ {
+ sal_Bool bTabStop( sal_False );
+ m_aTabStop >>= bTabStop;
+ _rxOutStream->writeBoolean( bTabStop );
+ }
+ if ( nNonVoids & PERSIST_BACKGROUND )
+ {
+ sal_Int32 nBackgroundColor = 0;
+ m_aBackgroundColor >>= nBackgroundColor;
+ _rxOutStream->writeLong( nBackgroundColor );
+ }
+ if ( nNonVoids & PERSIST_TEXTCOLOR )
+ {
+ _rxOutStream->writeLong( getTextColor() );
+ }
+ if ( nNonVoids & PERSIST_TEXTLINECOLOR )
+ {
+ _rxOutStream->writeLong( getTextLineColor() );
+ }
+ }
+
+ {
+ OStreamSection aEnsureCompat( xDataOut );
+ ::comphelper::operator<<( _rxOutStream, getFont() );
+ }
+
+ // our boolean flags
+ sal_Int32 nFlags = 0;
+ if ( m_bEnabled ) nFlags |= PERSIST_ENABLED;
+ if ( m_nIconSize ) nFlags |= PERSIST_LARGEICONS; // at the moment, this is quasi boolean
+ if ( m_bShowPosition ) nFlags |= PERSIST_SHOW_POSITION;
+ if ( m_bShowNavigation ) nFlags |= PERSIST_SHOW_NAVIGATION;
+ if ( m_bShowActions ) nFlags |= PERSIST_SHOW_ACTIONS;
+ if ( m_bShowFilterSort ) nFlags |= PERSIST_SHOW_FILTERSORT;
+ _rxOutStream->writeLong( nFlags );
+
+ // our strings
+ _rxOutStream->writeUTF( m_sHelpText );
+ _rxOutStream->writeUTF( m_sHelpURL );
+ _rxOutStream->writeUTF( m_sDefaultControl );
+
+ // misc
+ _rxOutStream->writeShort( m_nBorder );
+ _rxOutStream->writeLong ( m_nDelay );
+ }
+
+ //------------------------------------------------------------------
+ void SAL_CALL ONavigationBarModel::read( const Reference< XObjectInputStream >& _rxInStream ) throw ( IOException, RuntimeException )
+ {
+ Reference< XDataInputStream > xDataIn( _rxInStream, UNO_QUERY );
+ OStreamSection aEnsureBlockCompat( xDataIn );
+
+ // base class
+ OControlModel::read( _rxInStream );
+
+ {
+ OStreamSection aEnsureCompat( xDataIn );
+ // determine which properties were non-void
+ sal_Int32 nNonVoids = _rxInStream->readLong( );
+
+ // the maybeboid anys
+ if ( nNonVoids & PERSIST_TABSTOP )
+ m_aTabStop = makeAny( _rxInStream->readBoolean() );
+ else
+ m_aTabStop.clear();
+
+ if ( nNonVoids & PERSIST_BACKGROUND )
+ m_aBackgroundColor = makeAny( _rxInStream->readLong() );
+ else
+ m_aBackgroundColor.clear();
+
+ if ( nNonVoids & PERSIST_TEXTCOLOR )
+ setTextColor( _rxInStream->readLong() );
+ else
+ clearTextColor();
+
+ if ( nNonVoids & PERSIST_TEXTLINECOLOR )
+ setTextLineColor( _rxInStream->readLong() );
+ else
+ clearTextLineColor();
+ }
+
+ {
+ OStreamSection aEnsureCompat( xDataIn );
+ FontDescriptor aFont;
+ ::comphelper::operator>>( _rxInStream, aFont );
+ setFont( aFont );
+ }
+
+ // our boolean flags
+ sal_Int32 nFlags = _rxInStream->readLong( );
+ m_bEnabled = ( nFlags & PERSIST_ENABLED ) ? sal_True : sal_False;
+ m_nIconSize = ( nFlags & PERSIST_LARGEICONS ) ? 1 : 0;
+ m_bShowPosition = ( nFlags & PERSIST_SHOW_POSITION ) ? sal_True : sal_False;
+ m_bShowNavigation = ( nFlags & PERSIST_SHOW_NAVIGATION ) ? sal_True : sal_False;
+ m_bShowActions = ( nFlags & PERSIST_SHOW_ACTIONS ) ? sal_True : sal_False;
+ m_bShowFilterSort = ( nFlags & PERSIST_SHOW_FILTERSORT ) ? sal_True : sal_False;
+
+ // our strings
+ m_sHelpText = _rxInStream->readUTF( );
+ m_sHelpURL = _rxInStream->readUTF( );
+ m_sDefaultControl = _rxInStream->readUTF( );
+
+ // misc
+ m_nBorder = _rxInStream->readShort();
+ m_nDelay = _rxInStream->readLong();
+ }
+
+ //------------------------------------------------------------------
+ void SAL_CALL ONavigationBarModel::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const
+ {
+ if ( isRegisteredProperty( _nHandle ) )
+ {
+ OPropertyContainerHelper::getFastPropertyValue( _rValue, _nHandle );
+ }
+ else if ( isFontRelatedProperty( _nHandle ) )
+ {
+ FontControlModel::getFastPropertyValue( _rValue, _nHandle );
+ }
+ else
+ {
+ OControlModel::getFastPropertyValue( _rValue, _nHandle );
+ }
+ }
+
+ //------------------------------------------------------------------
+ sal_Bool SAL_CALL ONavigationBarModel::convertFastPropertyValue( Any& _rConvertedValue, Any& _rOldValue,
+ sal_Int32 _nHandle, const Any& _rValue ) throw( IllegalArgumentException )
+ {
+ sal_Bool bModified = sal_False;
+
+ if ( isRegisteredProperty( _nHandle ) )
+ {
+ bModified = OPropertyContainerHelper::convertFastPropertyValue( _rConvertedValue, _rOldValue, _nHandle, _rValue );
+ }
+ else if ( isFontRelatedProperty( _nHandle ) )
+ {
+ bModified = FontControlModel::convertFastPropertyValue( _rConvertedValue, _rOldValue, _nHandle, _rValue );
+ }
+ else
+ {
+ bModified = OControlModel::convertFastPropertyValue( _rConvertedValue, _rOldValue, _nHandle, _rValue );
+ }
+
+ return bModified;
+ }
+
+ //------------------------------------------------------------------
+ void SAL_CALL ONavigationBarModel::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const Any& _rValue ) throw ( Exception )
+ {
+ if ( isRegisteredProperty( _nHandle ) )
+ {
+ OPropertyContainerHelper::setFastPropertyValue( _nHandle, _rValue );
+ }
+ else if ( isFontRelatedProperty( _nHandle ) )
+ {
+ FontDescriptor aOldFont( getFont() );
+
+ FontControlModel::setFastPropertyValue_NoBroadcast( _nHandle, _rValue );
+
+ if ( isFontAggregateProperty( _nHandle ) )
+ firePropertyChange( PROPERTY_ID_FONT, makeAny( getFont() ), makeAny( aOldFont ) );
+ }
+ else
+ {
+ OControlModel::setFastPropertyValue_NoBroadcast( _nHandle, _rValue );
+ }
+ }
+
+ //------------------------------------------------------------------
+ Any ONavigationBarModel::getPropertyDefaultByHandle( sal_Int32 _nHandle ) const
+ {
+ Any aDefault;
+
+ switch ( _nHandle )
+ {
+ case PROPERTY_ID_TABSTOP:
+ case PROPERTY_ID_BACKGROUNDCOLOR:
+ /* void */
+ break;
+ case PROPERTY_ID_WRITING_MODE:
+ case PROPERTY_ID_CONTEXT_WRITING_MODE:
+ aDefault <<= WritingMode2::CONTEXT;
+ break;
+
+ case PROPERTY_ID_ENABLED:
+ case PROPERTY_ID_ENABLEVISIBLE:
+ case PROPERTY_ID_SHOW_POSITION:
+ case PROPERTY_ID_SHOW_NAVIGATION:
+ case PROPERTY_ID_SHOW_RECORDACTIONS:
+ case PROPERTY_ID_SHOW_FILTERSORT:
+ aDefault <<= (sal_Bool)sal_True;
+ break;
+
+ case PROPERTY_ID_ICONSIZE:
+ aDefault <<= (sal_Int16)0;
+ break;
+
+ case PROPERTY_ID_DEFAULTCONTROL:
+ aDefault <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.control.NavigationToolBar" ) );
+ break;
+
+ case PROPERTY_ID_HELPTEXT:
+ case PROPERTY_ID_HELPURL:
+ aDefault <<= ::rtl::OUString();
+ break;
+
+ case PROPERTY_ID_BORDER:
+ aDefault <<= (sal_Int16)0;
+ break;
+
+ case PROPERTY_ID_DELAY:
+ aDefault <<= (sal_Int32)20;
+ break;
+
+ default:
+ if ( isFontRelatedProperty( _nHandle ) )
+ aDefault = FontControlModel::getPropertyDefaultByHandle( _nHandle );
+ else
+ aDefault = OControlModel::getPropertyDefaultByHandle( _nHandle );
+ }
+ return aDefault;
+ }
+
+ //------------------------------------------------------------------
+ void ONavigationBarModel::describeFixedProperties( Sequence< Property >& _rProps ) const
+ {
+ BEGIN_DESCRIBE_PROPERTIES( 1, OControlModel )
+ DECL_PROP2( TABINDEX, sal_Int16, BOUND, MAYBEDEFAULT );
+ END_DESCRIBE_PROPERTIES();
+
+ // properties which the OPropertyContainerHelper is responsible for
+ Sequence< Property > aContainedProperties;
+ describeProperties( aContainedProperties );
+
+ // properties which the FontControlModel is responsible for
+ Sequence< Property > aFontProperties;
+ describeFontRelatedProperties( aFontProperties );
+
+ _rProps = concatSequences(
+ aContainedProperties,
+ aFontProperties,
+ _rProps
+ );
+ }
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/navigationbar.hxx b/forms/source/component/navigationbar.hxx
new file mode 100644
index 000000000000..e410a13c64f6
--- /dev/null
+++ b/forms/source/component/navigationbar.hxx
@@ -0,0 +1,140 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef FORMS_COMPONENT_NAVIGATION_BAR_HXX
+#define FORMS_COMPONENT_NAVIGATION_BAR_HXX
+
+#include "FormComponent.hxx"
+#include <com/sun/star/io/XPersistObject.hpp>
+#include <comphelper/proparrhlp.hxx>
+#include <comphelper/propertycontainerhelper.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/interfacecontainer.hxx>
+#include <com/sun/star/container/XSet.hpp>
+#include <com/sun/star/container/XContainer.hpp>
+#include "formcontrolfont.hxx"
+
+#include <set>
+
+//.........................................................................
+namespace frm
+{
+//.........................................................................
+
+ //==================================================================
+ // ONavigationBarModel
+ //==================================================================
+ typedef ::cppu::ImplHelper1 < ::com::sun::star::awt::XControlModel
+ > ONavigationBarModel_BASE;
+
+ class ONavigationBarModel
+ :public OControlModel
+ ,public FontControlModel
+ ,public OPropertyContainerHelper
+ ,public ONavigationBarModel_BASE
+ {
+ // <properties>
+ ::com::sun::star::uno::Any m_aTabStop;
+ ::com::sun::star::uno::Any m_aBackgroundColor;
+ ::rtl::OUString m_sDefaultControl;
+ ::rtl::OUString m_sHelpText;
+ ::rtl::OUString m_sHelpURL;
+ sal_Int16 m_nIconSize;
+ sal_Int16 m_nBorder;
+ sal_Int32 m_nDelay;
+ sal_Bool m_bEnabled;
+ sal_Bool m_bEnableVisible;
+ sal_Bool m_bShowPosition;
+ sal_Bool m_bShowNavigation;
+ sal_Bool m_bShowActions;
+ sal_Bool m_bShowFilterSort;
+ sal_Int16 m_nWritingMode;
+ sal_Int16 m_nContextWritingMode;
+ // </properties>
+
+ public:
+ DECLARE_DEFAULT_LEAF_XTOR( ONavigationBarModel );
+
+ // XServiceInfo - static version
+ static ::rtl::OUString SAL_CALL getImplementationName_Static();
+ static ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_Static();
+ static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL Create( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory );
+
+ protected:
+ // UNO
+ DECLARE_UNO3_AGG_DEFAULTS( ONavigationBarModel, OControlModel );
+ virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
+
+ // XTypeProvider
+ DECLARE_XTYPEPROVIDER()
+
+ // OComponentHelper
+ virtual void SAL_CALL disposing();
+
+ // XPersistObject
+ virtual ::rtl::OUString SAL_CALL getServiceName() throw ( ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ // XPropertySet
+ virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle ) const;
+ virtual sal_Bool SAL_CALL convertFastPropertyValue(::com::sun::star::uno::Any& rConvertedValue, ::com::sun::star::uno::Any& rOldValue,
+ sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
+ throw(::com::sun::star::lang::IllegalArgumentException);
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue) throw ( ::com::sun::star::uno::Exception);
+
+ // XPropertyState
+ virtual ::com::sun::star::uno::Any getPropertyDefaultByHandle( sal_Int32 nHandle ) const;
+
+ // OControlModel's property handling
+ virtual void describeFixedProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps
+ ) const;
+
+ // prevent method hiding
+ using OControlModel::disposing;
+ using OControlModel::getFastPropertyValue;
+
+ protected:
+ DECLARE_XCLONEABLE();
+
+ private:
+ void implInitPropertyContainer();
+ };
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+#endif // FORMS_COMPONENT_NAVIGATION_BAR_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/propertybaghelper.cxx b/forms/source/component/propertybaghelper.cxx
new file mode 100644
index 000000000000..ef09d4841148
--- /dev/null
+++ b/forms/source/component/propertybaghelper.cxx
@@ -0,0 +1,360 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+#include "propertybaghelper.hxx"
+
+#include "property.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/beans/PropertyExistException.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/beans/NotRemoveableException.hpp>
+#include <com/sun/star/beans/UnknownPropertyException.hpp>
+/** === end UNO includes === **/
+
+#include <tools/diagnose_ex.h>
+
+#include <comphelper/sequence.hxx>
+#include <rtl/logfile.hxx>
+#include "rtl/instance.hxx"
+
+
+#define NEW_HANDLE_BASE 10000
+
+//........................................................................
+namespace frm
+{
+//........................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::lang::DisposedException;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::beans::Property;
+ using ::com::sun::star::uno::Any;
+ using ::com::sun::star::beans::PropertyExistException;
+ using ::com::sun::star::beans::PropertyValue;
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::UNO_QUERY_THROW;
+ using ::com::sun::star::beans::XMultiPropertySet;
+ using ::com::sun::star::beans::XPropertySetInfo;
+ using ::com::sun::star::uno::RuntimeException;
+ using ::com::sun::star::uno::Exception;
+ using ::com::sun::star::beans::NotRemoveableException;
+ using ::com::sun::star::beans::UnknownPropertyException;
+ /** === end UNO using === **/
+ namespace PropertyAttribute = ::com::sun::star::beans::PropertyAttribute;
+
+ //====================================================================
+ //= helper
+ //====================================================================
+ namespace
+ {
+ //----------------------------------------------------------------
+ static ::comphelper::IPropertyInfoService& lcl_getPropertyInfos()
+ {
+ static ConcreteInfoService s_aPropInfos;
+ return s_aPropInfos;
+ }
+ }
+
+ //====================================================================
+ //= PropertyBagHelper
+ //====================================================================
+ //--------------------------------------------------------------------
+ PropertyBagHelper::PropertyBagHelper( IPropertyBagHelperContext& _rContext )
+ :m_rContext( _rContext )
+ ,m_pPropertyArrayHelper( NULL )
+ ,m_bDisposed( false )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ PropertyBagHelper::~PropertyBagHelper()
+ {
+ delete m_pPropertyArrayHelper, m_pPropertyArrayHelper = NULL;
+ }
+
+ //--------------------------------------------------------------------
+ void PropertyBagHelper::dispose()
+ {
+ m_bDisposed = true;
+ }
+
+ //--------------------------------------------------------------------
+ void PropertyBagHelper::impl_nts_checkDisposed_throw() const
+ {
+ if ( m_bDisposed )
+ throw DisposedException();
+ }
+
+ //--------------------------------------------------------------------
+ void PropertyBagHelper::impl_nts_invalidatePropertySetInfo()
+ {
+ delete m_pPropertyArrayHelper, m_pPropertyArrayHelper = NULL;
+ }
+
+ //--------------------------------------------------------------------
+ sal_Int32 PropertyBagHelper::impl_findFreeHandle( const ::rtl::OUString& _rPropertyName )
+ {
+ ::comphelper::OPropertyArrayAggregationHelper& rPropInfo( impl_ts_getArrayHelper() );
+
+ // check the preferred handle
+ sal_Int32 nHandle = lcl_getPropertyInfos().getPreferedPropertyId( _rPropertyName );
+ if ( ( nHandle != -1 ) && rPropInfo.fillPropertyMembersByHandle( NULL, NULL, nHandle ) )
+ nHandle = -1;
+
+ // seach a free handle in <math>F_1009</math>
+ if ( nHandle == -1 )
+ {
+ sal_Int32 nPrime = 1009;
+ sal_Int32 nFactor = 11;
+ sal_Int32 nNum = nFactor;
+ while ( nNum != 1 )
+ {
+ if ( !rPropInfo.fillPropertyMembersByHandle( NULL, NULL, nNum + NEW_HANDLE_BASE ) )
+ {
+ // handle not used, yet
+ nHandle = nNum + NEW_HANDLE_BASE;
+ break;
+ }
+ nNum = ( nNum * nFactor ) % nPrime;
+ }
+ }
+
+ // search a free handle greater NEW_HANDLE_BASE
+ if ( nHandle == -1 )
+ {
+ nHandle = NEW_HANDLE_BASE + 1009;
+ while ( rPropInfo.fillPropertyMembersByHandle( NULL, NULL, nHandle ) )
+ ++nHandle;
+ }
+
+ return nHandle;
+ }
+
+ //--------------------------------------------------------------------
+ ::comphelper::OPropertyArrayAggregationHelper& PropertyBagHelper::impl_ts_getArrayHelper() const
+ {
+ OPropertyArrayAggregationHelper* p = m_pPropertyArrayHelper;
+ if ( !p )
+ {
+ ::osl::MutexGuard aGuard( m_rContext.getMutex() );
+ p = m_pPropertyArrayHelper;
+ if ( !p )
+ {
+ // our own fixed and our aggregate's properties
+ Sequence< Property > aFixedProps;
+ Sequence< Property > aAggregateProps;
+ m_rContext.describeFixedAndAggregateProperties( aFixedProps, aAggregateProps );
+
+ // our dynamic properties
+ Sequence< Property > aDynamicProps;
+ m_aDynamicProperties.describeProperties( aDynamicProps );
+
+ Sequence< Property > aOwnProps(
+ ::comphelper::concatSequences( aFixedProps, aDynamicProps ) );
+
+ p = new OPropertyArrayAggregationHelper( aOwnProps, aAggregateProps, &lcl_getPropertyInfos(), NEW_HANDLE_BASE );
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ const_cast< PropertyBagHelper* >( this )->m_pPropertyArrayHelper = p;
+ }
+ } // if ( !p )
+ else
+ {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ }
+ return *p;
+ }
+
+ //--------------------------------------------------------------------
+ void PropertyBagHelper::addProperty( const ::rtl::OUString& _rName, ::sal_Int16 _nAttributes, const Any& _rInitialValue )
+ {
+ ::osl::MutexGuard aGuard( m_rContext.getMutex() );
+ impl_nts_checkDisposed_throw();
+
+ //----------------------------------------------
+ // check name sanity
+ ::comphelper::OPropertyArrayAggregationHelper& aPropInfo( impl_ts_getArrayHelper() );
+ if ( aPropInfo.hasPropertyByName( _rName ) )
+ throw PropertyExistException( _rName, m_rContext.getPropertiesInterface() );
+
+ //----------------------------------------------
+ // normalize the REMOVEABLE attribute - the FormComponent service
+ // requires that all dynamic properties are REMOVEABLE
+ _nAttributes |= PropertyAttribute::REMOVEABLE;
+
+ //----------------------------------------------
+ // find a free handle
+ sal_Int32 nHandle = impl_findFreeHandle( _rName );
+
+ //----------------------------------------------
+ // register the property, and invalidate our property meta data
+ m_aDynamicProperties.addProperty( _rName, nHandle, _nAttributes, _rInitialValue );
+ impl_nts_invalidatePropertySetInfo();
+ }
+
+ //--------------------------------------------------------------------
+ void PropertyBagHelper::removeProperty( const ::rtl::OUString& _rName )
+ {
+ ::osl::MutexGuard aGuard( m_rContext.getMutex() );
+ impl_nts_checkDisposed_throw();
+
+ // check whether it's removeable at all
+ Reference< XMultiPropertySet > xMe( m_rContext.getPropertiesInterface(), UNO_QUERY_THROW );
+ Reference< XPropertySetInfo > xPSI( xMe->getPropertySetInfo(), UNO_QUERY_THROW );
+ Property aProperty( xPSI->getPropertyByName( _rName ) );
+ if ( ( aProperty.Attributes & PropertyAttribute::REMOVEABLE ) == 0 )
+ throw NotRemoveableException( _rName, xMe );
+
+ m_aDynamicProperties.removeProperty( _rName );
+ impl_nts_invalidatePropertySetInfo();
+ }
+
+ //--------------------------------------------------------------------
+ namespace
+ {
+ //----------------------------------------------------------------
+ struct SelectNameOfProperty : public ::std::unary_function< Property, ::rtl::OUString >
+ {
+ const ::rtl::OUString& operator()( const Property& _rProp ) const { return _rProp.Name; }
+ };
+
+ //----------------------------------------------------------------
+ struct SelectNameOfPropertyValue : public ::std::unary_function< PropertyValue, ::rtl::OUString >
+ {
+ const ::rtl::OUString& operator()( const PropertyValue& _rProp ) const { return _rProp.Name; }
+ };
+
+ //----------------------------------------------------------------
+ struct SelectValueOfPropertyValue : public ::std::unary_function< PropertyValue, Any >
+ {
+ const Any& operator()( const PropertyValue& _rProp ) const { return _rProp.Value; }
+ };
+
+ //----------------------------------------------------------------
+ struct PropertyValueLessByName : public ::std::binary_function< PropertyValue, PropertyValue, bool >
+ {
+ bool operator()( const PropertyValue& _lhs, const PropertyValue _rhs ) const
+ {
+ return _lhs.Name < _rhs.Name;
+ }
+ };
+ }
+
+ //--------------------------------------------------------------------
+ Sequence< PropertyValue > PropertyBagHelper::getPropertyValues()
+ {
+ ::osl::MutexGuard aGuard( m_rContext.getMutex() );
+ impl_nts_checkDisposed_throw();
+
+ Reference< XMultiPropertySet > xMe( m_rContext.getPropertiesInterface(), UNO_QUERY_THROW );
+ Reference< XPropertySetInfo > xPSI( xMe->getPropertySetInfo(), UNO_QUERY_THROW );
+
+ Sequence< Property > aProperties( xPSI->getProperties() );
+ Sequence< ::rtl::OUString > aPropertyNames( aProperties.getLength() );
+ ::std::transform( aProperties.getConstArray(), aProperties.getConstArray() + aProperties.getLength(),
+ aPropertyNames.getArray(), SelectNameOfProperty() );
+
+ Sequence< Any > aValues;
+ try
+ {
+ aValues = xMe->getPropertyValues( aPropertyNames );
+
+ if ( aValues.getLength() != aPropertyNames.getLength() )
+ throw RuntimeException();
+ }
+ catch( const RuntimeException& ) { throw; }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ Sequence< PropertyValue > aPropertyValues( aValues.getLength() );
+ PropertyValue* pPropertyValue = aPropertyValues.getArray();
+
+ const ::rtl::OUString* pName = aPropertyNames.getConstArray();
+ const ::rtl::OUString* pNameEnd = aPropertyNames.getConstArray() + aPropertyNames.getLength();
+ const Any* pValue = aValues.getConstArray();
+ for ( ; pName != pNameEnd; ++pName, ++pValue, ++pPropertyValue )
+ {
+ pPropertyValue->Name = *pName;
+ pPropertyValue->Value = *pValue;
+ }
+
+ return aPropertyValues;
+ }
+
+ //--------------------------------------------------------------------
+ void PropertyBagHelper::setPropertyValues( const Sequence< PropertyValue >& _rProps )
+ {
+ ::osl::ClearableMutexGuard aGuard( m_rContext.getMutex() );
+ impl_nts_checkDisposed_throw();
+
+ sal_Int32 nPropertyValues = _rProps.getLength();
+
+ // XMultiPropertySet::setPropertyValues expects its arguments to be sorted by name
+ // while XPropertyAccess::setPropertyValues doesn't. So first of all, sort.
+ Sequence< PropertyValue > aSortedProps( _rProps );
+ ::std::sort( aSortedProps.getArray(), aSortedProps.getArray() + nPropertyValues, PropertyValueLessByName() );
+
+ // also, XPropertyAccess::setPropertyValues is expected to throw an UnknownPropertyException
+ // for unsupported properties, while XMultiPropertySet::setPropertyValues is expected to ignore
+ // those. So, check for unsupported properties first.
+ ::comphelper::OPropertyArrayAggregationHelper& rArrayHelper( impl_ts_getArrayHelper() );
+ for ( const PropertyValue* pProperties = aSortedProps.getConstArray();
+ pProperties != aSortedProps.getConstArray() + nPropertyValues;
+ ++pProperties
+ )
+ {
+ if ( !rArrayHelper.hasPropertyByName( pProperties->Name ) )
+ throw UnknownPropertyException( pProperties->Name, m_rContext.getPropertiesInterface() );
+ }
+
+ // Now finally split into a Name and a Value sequence, and forward to
+ // XMultiPropertySet::setPropertyValues
+ Sequence< ::rtl::OUString > aNames( nPropertyValues );
+ ::std::transform( aSortedProps.getConstArray(), aSortedProps.getConstArray() + nPropertyValues,
+ aNames.getArray(), SelectNameOfPropertyValue() );
+
+ Sequence< Any > aValues( nPropertyValues );
+ ::std::transform( aSortedProps.getConstArray(), aSortedProps.getConstArray() + nPropertyValues,
+ aValues.getArray(), SelectValueOfPropertyValue() );
+
+ Reference< XMultiPropertySet > xMe( m_rContext.getPropertiesInterface(), UNO_QUERY_THROW );
+
+ aGuard.clear();
+ xMe->setPropertyValues( aNames, aValues );
+ }
+
+//........................................................................
+} // namespace frm
+//........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/refvaluecomponent.cxx b/forms/source/component/refvaluecomponent.cxx
new file mode 100644
index 000000000000..b586e393ea33
--- /dev/null
+++ b/forms/source/component/refvaluecomponent.cxx
@@ -0,0 +1,303 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+#include "refvaluecomponent.hxx"
+
+/** === begin UNO includes === **/
+/** === end UNO includes === **/
+
+#include <tools/diagnose_ex.h>
+
+#include <list>
+
+//........................................................................
+namespace frm
+{
+//........................................................................
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::form::binding;
+
+ //====================================================================
+ //=
+ //====================================================================
+ //--------------------------------------------------------------------
+ OReferenceValueComponent::OReferenceValueComponent( const Reference< XMultiServiceFactory>& _rxFactory, const ::rtl::OUString& _rUnoControlModelTypeName, const ::rtl::OUString& _rDefault, sal_Bool _bSupportNoCheckRefValue )
+ :OBoundControlModel( _rxFactory, _rUnoControlModelTypeName, _rDefault, sal_False, sal_True, sal_True )
+ ,m_eDefaultChecked( STATE_NOCHECK )
+ ,m_bSupportSecondRefValue( _bSupportNoCheckRefValue )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ OReferenceValueComponent::OReferenceValueComponent( const OReferenceValueComponent* _pOriginal, const Reference< XMultiServiceFactory>& _rxFactory )
+ :OBoundControlModel( _pOriginal, _rxFactory )
+ {
+ m_sReferenceValue = _pOriginal->m_sReferenceValue;
+ m_sNoCheckReferenceValue = _pOriginal->m_sNoCheckReferenceValue;
+ m_eDefaultChecked = _pOriginal->m_eDefaultChecked;
+ m_bSupportSecondRefValue = _pOriginal->m_bSupportSecondRefValue;
+
+ calculateExternalValueType();
+ }
+
+ //--------------------------------------------------------------------
+ OReferenceValueComponent::~OReferenceValueComponent()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ void OReferenceValueComponent::setReferenceValue( const ::rtl::OUString& _rRefValue )
+ {
+ m_sReferenceValue = _rRefValue;
+ calculateExternalValueType();
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OReferenceValueComponent::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const
+ {
+ switch ( _nHandle )
+ {
+ case PROPERTY_ID_REFVALUE: _rValue <<= m_sReferenceValue; break;
+ case PROPERTY_ID_DEFAULT_STATE: _rValue <<= (sal_Int16)m_eDefaultChecked; break;
+
+ case PROPERTY_ID_UNCHECKED_REFVALUE:
+ OSL_ENSURE( m_bSupportSecondRefValue, "OReferenceValueComponent::getFastPropertyValue: not supported!" );
+ _rValue <<= m_sNoCheckReferenceValue;
+ break;
+
+ default:
+ OBoundControlModel::getFastPropertyValue( _rValue, _nHandle );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OReferenceValueComponent::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const Any& _rValue ) throw (Exception)
+ {
+ switch ( _nHandle )
+ {
+ case PROPERTY_ID_REFVALUE :
+ OSL_VERIFY( _rValue >>= m_sReferenceValue );
+ calculateExternalValueType();
+ break;
+
+ case PROPERTY_ID_UNCHECKED_REFVALUE:
+ OSL_ENSURE( m_bSupportSecondRefValue, "OReferenceValueComponent::setFastPropertyValue_NoBroadcast: not supported!" );
+ OSL_VERIFY( _rValue >>= m_sNoCheckReferenceValue );
+ break;
+
+ case PROPERTY_ID_DEFAULT_STATE:
+ {
+ sal_Int16 nDefaultChecked( (sal_Int16)STATE_NOCHECK );
+ OSL_VERIFY( _rValue >>= nDefaultChecked );
+ m_eDefaultChecked = (ToggleState)nDefaultChecked;
+ resetNoBroadcast();
+ }
+ break;
+
+ default:
+ OBoundControlModel::setFastPropertyValue_NoBroadcast( _nHandle, _rValue );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ sal_Bool SAL_CALL OReferenceValueComponent::convertFastPropertyValue( Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue ) throw (IllegalArgumentException)
+ {
+ sal_Bool bModified = sal_False;
+ switch ( _nHandle )
+ {
+ case PROPERTY_ID_REFVALUE:
+ bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, m_sReferenceValue );
+ break;
+
+ case PROPERTY_ID_UNCHECKED_REFVALUE:
+ OSL_ENSURE( m_bSupportSecondRefValue, "OReferenceValueComponent::convertFastPropertyValue: not supported!" );
+ bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, m_sNoCheckReferenceValue );
+ break;
+
+ case PROPERTY_ID_DEFAULT_STATE:
+ bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, (sal_Int16)m_eDefaultChecked );
+ break;
+
+ default:
+ bModified = OBoundControlModel::convertFastPropertyValue( _rConvertedValue, _rOldValue, _nHandle, _rValue );
+ break;
+ }
+ return bModified;
+ }
+
+ //------------------------------------------------------------------------------
+ Any OReferenceValueComponent::getDefaultForReset() const
+ {
+ return makeAny( (sal_Int16)m_eDefaultChecked );
+ }
+
+ //--------------------------------------------------------------------
+ void OReferenceValueComponent::describeFixedProperties( Sequence< Property >& _rProps ) const
+ {
+ BEGIN_DESCRIBE_PROPERTIES( m_bSupportSecondRefValue ? 3 : 2, OBoundControlModel )
+ DECL_PROP1( REFVALUE, ::rtl::OUString, BOUND );
+ DECL_PROP1( DEFAULT_STATE, sal_Int16, BOUND );
+ if ( m_bSupportSecondRefValue )
+ {
+ DECL_PROP1( UNCHECKED_REFVALUE, ::rtl::OUString, BOUND );
+ }
+ END_DESCRIBE_PROPERTIES();
+ }
+
+ //-----------------------------------------------------------------------------
+ Sequence< Type > OReferenceValueComponent::getSupportedBindingTypes()
+ {
+ ::std::list< Type > aTypes;
+ aTypes.push_back( ::getCppuType( static_cast< sal_Bool* >( NULL ) ) );
+
+ if ( m_sReferenceValue.getLength() )
+ aTypes.push_front( ::getCppuType( static_cast< ::rtl::OUString* >( NULL ) ) );
+ // push_front, because this is the preferred type
+
+ Sequence< Type > aTypesRet( aTypes.size() );
+ ::std::copy( aTypes.begin(), aTypes.end(), aTypesRet.getArray() );
+ return aTypesRet;
+ }
+
+ //-----------------------------------------------------------------------------
+ Any OReferenceValueComponent::translateExternalValueToControlValue( const Any& _rExternalValue ) const
+ {
+ sal_Int16 nState = STATE_DONTKNOW;
+
+ sal_Bool bExternalState = sal_False;
+ ::rtl::OUString sExternalValue;
+ if ( _rExternalValue >>= bExternalState )
+ {
+ nState = ::sal::static_int_cast< sal_Int16 >( bExternalState ? STATE_CHECK : STATE_NOCHECK );
+ }
+ else if ( _rExternalValue >>= sExternalValue )
+ {
+ if ( sExternalValue == m_sReferenceValue )
+ nState = STATE_CHECK;
+ else
+ {
+ if ( !m_bSupportSecondRefValue || ( sExternalValue == m_sNoCheckReferenceValue ) )
+ nState = STATE_NOCHECK;
+ else
+ nState = STATE_DONTKNOW;
+ }
+ }
+ else if ( !_rExternalValue.hasValue() )
+ {
+ nState = STATE_DONTKNOW;
+ }
+ else
+ {
+ OSL_FAIL( "OReferenceValueComponent::translateExternalValueToControlValue: unexpected value type!" );
+ }
+
+ return makeAny( nState );
+ }
+
+ //-----------------------------------------------------------------------------
+ Any OReferenceValueComponent::translateControlValueToExternalValue( ) const
+ {
+ Any aExternalValue;
+
+ try
+ {
+ Any aControlValue( m_xAggregateSet->getPropertyValue( PROPERTY_STATE ) );
+ sal_Int16 nControlValue = STATE_DONTKNOW;
+ aControlValue >>= nControlValue;
+
+ bool bBooleanExchange = getExternalValueType().getTypeClass() == TypeClass_BOOLEAN;
+ bool bStringExchange = getExternalValueType().getTypeClass() == TypeClass_STRING;
+ OSL_ENSURE( bBooleanExchange || bStringExchange,
+ "OReferenceValueComponent::translateControlValueToExternalValue: unexpected value exchange type!" );
+
+ switch( nControlValue )
+ {
+ case STATE_CHECK:
+ if ( bBooleanExchange )
+ {
+ aExternalValue <<= (sal_Bool)sal_True;
+ }
+ else if ( bStringExchange )
+ {
+ aExternalValue <<= m_sReferenceValue;
+ }
+ break;
+
+ case STATE_NOCHECK:
+ if ( bBooleanExchange )
+ {
+ aExternalValue <<= (sal_Bool)sal_False;
+ }
+ else if ( bStringExchange )
+ {
+ aExternalValue <<= m_bSupportSecondRefValue ? m_sNoCheckReferenceValue : ::rtl::OUString();
+ }
+ break;
+ }
+ }
+ catch( const Exception& )
+ {
+ OSL_FAIL( "OReferenceValueComponent::translateControlValueToExternalValue: caught an exception!" );
+ }
+
+ return aExternalValue;
+ }
+
+ //-----------------------------------------------------------------------------
+ Any OReferenceValueComponent::translateControlValueToValidatableValue( ) const
+ {
+ if ( !m_xAggregateSet.is() )
+ return Any();
+
+ Any aControlValue( m_xAggregateSet->getPropertyValue( PROPERTY_STATE ) );
+ sal_Int16 nControlValue = STATE_DONTKNOW;
+ aControlValue >>= nControlValue;
+
+ Any aValidatableValue;
+ switch ( nControlValue )
+ {
+ case STATE_CHECK:
+ aValidatableValue <<= (sal_Bool)sal_True;
+ break;
+ case STATE_NOCHECK:
+ aValidatableValue <<= (sal_Bool)sal_False;
+ break;
+ }
+ return aValidatableValue;
+ }
+
+//........................................................................
+} // namespace frm
+//........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/refvaluecomponent.hxx b/forms/source/component/refvaluecomponent.hxx
new file mode 100644
index 000000000000..f88fb5e93f41
--- /dev/null
+++ b/forms/source/component/refvaluecomponent.hxx
@@ -0,0 +1,111 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef FORMS_SOURCE_COMPONENT_REFVALUECOMPONENT_HXX
+#define FORMS_SOURCE_COMPONENT_REFVALUECOMPONENT_HXX
+
+#include "FormComponent.hxx"
+#include "togglestate.hxx"
+
+/** === begin UNO includes === **/
+/** === end UNO includes === **/
+
+//........................................................................
+namespace frm
+{
+//........................................................................
+
+ //====================================================================
+ //= OReferenceValueComponent
+ //====================================================================
+ /** a OBoundControlModel which features the exchange of a reference value
+ */
+ class OReferenceValueComponent : public OBoundControlModel
+ {
+ private:
+ // <properties>
+ ::rtl::OUString m_sReferenceValue; // the reference value to use for data exchange
+ ::rtl::OUString m_sNoCheckReferenceValue; // the reference value to be exchanged when the control is not checked
+ ToggleState m_eDefaultChecked; // the default check state
+ // </properties>
+
+ sal_Bool m_bSupportSecondRefValue; // do we support the SecondaryRefValue property?
+
+ protected:
+ const ::rtl::OUString& getReferenceValue() const { return m_sReferenceValue; }
+ void setReferenceValue( const ::rtl::OUString& _rRefValue );
+
+ const ::rtl::OUString& getNoCheckReferenceValue() const { return m_sNoCheckReferenceValue; }
+
+ ToggleState getDefaultChecked() const { return m_eDefaultChecked; }
+ void setDefaultChecked( ToggleState _eChecked ) { m_eDefaultChecked = _eChecked; }
+
+ protected:
+ OReferenceValueComponent(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory,
+ const ::rtl::OUString& _rUnoControlModelTypeName,
+ const ::rtl::OUString& _rDefault,
+ sal_Bool _bSupportNoCheckRefValue = sal_False
+ );
+ DECLARE_DEFAULT_CLONE_CTOR( OReferenceValueComponent )
+ DECLARE_DEFAULT_DTOR( OReferenceValueComponent );
+
+ // OPropertySet and friends
+ virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const;
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
+ throw (::com::sun::star::uno::Exception);
+ virtual sal_Bool SAL_CALL convertFastPropertyValue(
+ ::com::sun::star::uno::Any& _rConvertedValue, ::com::sun::star::uno::Any& _rOldValue, sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue )
+ throw (::com::sun::star::lang::IllegalArgumentException);
+ virtual void describeFixedProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps
+ ) const;
+ using ::cppu::OPropertySetHelper::getFastPropertyValue;
+
+ // OBoundControlModel overridables
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type >
+ getSupportedBindingTypes();
+ virtual ::com::sun::star::uno::Any
+ translateExternalValueToControlValue( const ::com::sun::star::uno::Any& _rExternalValue ) const;
+ virtual ::com::sun::star::uno::Any
+ translateControlValueToExternalValue( ) const;
+
+ virtual ::com::sun::star::uno::Any
+ translateControlValueToValidatableValue( ) const;
+
+ virtual ::com::sun::star::uno::Any
+ getDefaultForReset() const;
+ };
+
+//........................................................................
+} // namespace frm
+//........................................................................
+
+#endif // FORMS_SOURCE_COMPONENT_REFVALUECOMPONENT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/scrollbar.cxx b/forms/source/component/scrollbar.cxx
new file mode 100644
index 000000000000..d8b230a03b3d
--- /dev/null
+++ b/forms/source/component/scrollbar.cxx
@@ -0,0 +1,322 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+#include "scrollbar.hxx"
+#include <comphelper/streamsection.hxx>
+#include <comphelper/basicio.hxx>
+#include <rtl/math.hxx>
+
+//--------------------------------------------------------------------------
+extern "C" void SAL_CALL createRegistryInfo_OScrollBarModel()
+{
+ static ::frm::OMultiInstanceAutoRegistration< ::frm::OScrollBarModel > aRegisterModel;
+}
+
+//........................................................................
+namespace frm
+{
+//........................................................................
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::form;
+ using namespace ::com::sun::star::awt;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::util;
+ using namespace ::com::sun::star::io;
+ using namespace ::com::sun::star::form::binding;
+
+ //====================================================================
+ //= helper
+ //====================================================================
+ //--------------------------------------------------------------------
+ Any translateExternalDoubleToControlIntValue(
+ const Any& _rExternalValue, const Reference< XPropertySet >& _rxProperties,
+ const ::rtl::OUString& _rMinValueName, const ::rtl::OUString& _rMaxValueName )
+ {
+ OSL_ENSURE( _rxProperties.is(), "translateExternalDoubleToControlIntValue: no aggregate!?" );
+
+ sal_Int32 nControlValue( 0 );
+ double nExternalValue = 0;
+ if ( _rExternalValue >>= nExternalValue )
+ {
+ if ( ::rtl::math::isInf( nExternalValue ) )
+ {
+ // set the minimum or maximum of the scroll values
+ ::rtl::OUString sLimitPropertyName = ::rtl::math::isSignBitSet( nExternalValue )
+ ? _rMinValueName : _rMaxValueName;
+ if ( _rxProperties.is() )
+ _rxProperties->getPropertyValue( sLimitPropertyName ) >>= nControlValue;
+ }
+ else
+ {
+ nControlValue = (sal_Int32)::rtl::math::round( nExternalValue );
+ }
+ }
+ else
+ {
+ if ( _rxProperties.is() )
+ _rxProperties->getPropertyValue( _rMinValueName ) >>= nControlValue;
+ }
+
+ return makeAny( nControlValue );
+ }
+
+ //--------------------------------------------------------------------
+ Any translateControlIntToExternalDoubleValue( const Any& _rControlIntValue )
+ {
+ Any aExternalDoubleValue;
+ sal_Int32 nScrollValue = 0;
+ if ( _rControlIntValue >>= nScrollValue )
+ aExternalDoubleValue <<= (double)nScrollValue;
+ else
+ {
+ OSL_FAIL( "translateControlIntToExternalDoubleValue: no integer scroll value!" );
+ // aExternalDoubleValue is void here, which is okay for this purpose ...
+ }
+
+ return aExternalDoubleValue;
+ }
+
+ //====================================================================
+ //= OScrollBarModel
+ //====================================================================
+ //--------------------------------------------------------------------
+ DBG_NAME( OScrollBarModel )
+ //--------------------------------------------------------------------
+ OScrollBarModel::OScrollBarModel( const Reference<XMultiServiceFactory>& _rxFactory )
+ :OBoundControlModel( _rxFactory, VCL_CONTROLMODEL_SCROLLBAR, VCL_CONTROL_SCROLLBAR, sal_True, sal_True, sal_False )
+ ,m_nDefaultScrollValue( 0 )
+ {
+ DBG_CTOR( OScrollBarModel, NULL );
+
+ m_nClassId = FormComponentType::SCROLLBAR;
+ initValueProperty( PROPERTY_SCROLL_VALUE, PROPERTY_ID_SCROLL_VALUE );
+ }
+
+ //--------------------------------------------------------------------
+ OScrollBarModel::OScrollBarModel( const OScrollBarModel* _pOriginal, const Reference< XMultiServiceFactory >& _rxFactory )
+ :OBoundControlModel( _pOriginal, _rxFactory )
+ {
+ DBG_CTOR( OScrollBarModel, NULL );
+ m_nDefaultScrollValue = _pOriginal->m_nDefaultScrollValue;
+ }
+
+ //--------------------------------------------------------------------
+ OScrollBarModel::~OScrollBarModel( )
+ {
+ DBG_DTOR( OScrollBarModel, NULL );
+ }
+
+ //--------------------------------------------------------------------
+ IMPLEMENT_SERVICE_REGISTRATION_2( OScrollBarModel, OControlModel, FRM_SUN_COMPONENT_SCROLLBAR, BINDABLE_INTEGER_VALUE_RANGE )
+ // note that we're passing OControlModel as "base class". This is because
+ // OBoundControlModel, our real base class, claims to support the DataAwareControlModel
+ // service, which isn't really true for us. We only derive from this class
+ // to benefit from the functionality for binding to spreadsheet cells
+
+ //------------------------------------------------------------------------------
+ IMPLEMENT_DEFAULT_CLONING( OScrollBarModel )
+
+ //------------------------------------------------------------------------------
+ void SAL_CALL OScrollBarModel::disposing()
+ {
+ OBoundControlModel::disposing();
+ }
+
+ //--------------------------------------------------------------------
+ void OScrollBarModel::describeFixedProperties( Sequence< Property >& _rProps ) const
+ {
+ BEGIN_DESCRIBE_PROPERTIES( 3, OControlModel )
+ DECL_PROP1( DEFAULT_SCROLL_VALUE, sal_Int32, BOUND );
+ DECL_PROP1( TABINDEX, sal_Int16, BOUND );
+ DECL_PROP2( CONTROLSOURCEPROPERTY,::rtl::OUString, READONLY, TRANSIENT );
+ END_DESCRIBE_PROPERTIES();
+ }
+
+ //------------------------------------------------------------------------------
+ void OScrollBarModel::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const
+ {
+ switch ( _nHandle )
+ {
+ case PROPERTY_ID_DEFAULT_SCROLL_VALUE:
+ _rValue <<= m_nDefaultScrollValue;
+ break;
+
+ default:
+ OBoundControlModel::getFastPropertyValue( _rValue, _nHandle );
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ void OScrollBarModel::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const Any& _rValue ) throw ( Exception )
+ {
+ switch ( _nHandle )
+ {
+ case PROPERTY_ID_DEFAULT_SCROLL_VALUE:
+ OSL_VERIFY( _rValue >>= m_nDefaultScrollValue );
+ resetNoBroadcast();
+ break;
+
+ default:
+ OBoundControlModel::setFastPropertyValue_NoBroadcast( _nHandle, _rValue );
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ sal_Bool OScrollBarModel::convertFastPropertyValue(
+ Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue )
+ throw ( IllegalArgumentException )
+ {
+ sal_Bool bModified( sal_False );
+ switch ( _nHandle )
+ {
+ case PROPERTY_ID_DEFAULT_SCROLL_VALUE:
+ bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, m_nDefaultScrollValue );
+ break;
+
+ default:
+ bModified = OBoundControlModel::convertFastPropertyValue( _rConvertedValue, _rOldValue, _nHandle, _rValue );
+ break;
+ }
+ return bModified;
+ }
+
+ //--------------------------------------------------------------------
+ Any OScrollBarModel::getPropertyDefaultByHandle( sal_Int32 _nHandle ) const
+ {
+ Any aReturn;
+
+ switch ( _nHandle )
+ {
+ case PROPERTY_ID_DEFAULT_SCROLL_VALUE:
+ aReturn <<= (sal_Int32)0;
+ break;
+
+ default:
+ aReturn = OBoundControlModel::getPropertyDefaultByHandle( _nHandle );
+ break;
+ }
+
+ return aReturn;
+ }
+
+ //------------------------------------------------------------------------------
+ Any OScrollBarModel::translateDbColumnToControlValue( )
+ {
+ OSL_FAIL( "OScrollBarModel::commitControlValueToDbColumn: never to be called (we're not bound)!" );
+ return Any();
+ }
+
+ //------------------------------------------------------------------------------
+ sal_Bool OScrollBarModel::commitControlValueToDbColumn( bool /*_bPostReset*/ )
+ {
+ OSL_FAIL( "OScrollBarModel::commitControlValueToDbColumn: never to be called (we're not bound)!" );
+ return sal_True;
+ }
+
+ //------------------------------------------------------------------------------
+ Any OScrollBarModel::getDefaultForReset() const
+ {
+ return makeAny( (sal_Int32)m_nDefaultScrollValue );
+ }
+
+ //--------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL OScrollBarModel::getServiceName() throw( RuntimeException )
+ {
+ return FRM_SUN_COMPONENT_SCROLLBAR;
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OScrollBarModel::write( const Reference< XObjectOutputStream >& _rxOutStream )
+ throw( IOException, RuntimeException )
+ {
+ OBoundControlModel::write( _rxOutStream );
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ OStreamSection aSection( Reference< XDataOutputStream >( _rxOutStream, UNO_QUERY ) );
+
+ // version
+ _rxOutStream->writeShort( 0x0001 );
+
+ // properties
+ _rxOutStream << m_nDefaultScrollValue;
+ writeHelpTextCompatibly( _rxOutStream );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OScrollBarModel::read( const Reference< XObjectInputStream>& _rxInStream ) throw( IOException, RuntimeException )
+ {
+ OBoundControlModel::read( _rxInStream );
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ // version
+ {
+ OStreamSection aSection( Reference< XDataInputStream >( _rxInStream, UNO_QUERY ) );
+
+ sal_uInt16 nVersion = _rxInStream->readShort();
+ if ( nVersion == 0x0001 )
+ {
+ _rxInStream >> m_nDefaultScrollValue;
+ readHelpTextCompatibly( _rxInStream );
+ }
+ else
+ defaultCommonProperties();
+
+ // here, everything in the stream section which is left will be skipped
+ }
+ }
+
+ //--------------------------------------------------------------------
+ Any OScrollBarModel::translateExternalValueToControlValue( const Any& _rExternalValue ) const
+ {
+ return translateExternalDoubleToControlIntValue( _rExternalValue, m_xAggregateSet,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ScrollValueMin" ) ),
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ScrollValueMax" ) ) );
+ }
+
+ //--------------------------------------------------------------------
+ Any OScrollBarModel::translateControlValueToExternalValue( ) const
+ {
+ // by definition, the base class simply obtains the property value
+ return translateControlIntToExternalDoubleValue( OBoundControlModel::translateControlValueToExternalValue() );
+ }
+
+ //--------------------------------------------------------------------
+ Sequence< Type > OScrollBarModel::getSupportedBindingTypes()
+ {
+ return Sequence< Type >( &::getCppuType( static_cast< double* >( NULL ) ), 1 );
+ }
+
+//........................................................................
+} // namespace frm
+//........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/scrollbar.hxx b/forms/source/component/scrollbar.hxx
new file mode 100644
index 000000000000..93a946268a14
--- /dev/null
+++ b/forms/source/component/scrollbar.hxx
@@ -0,0 +1,104 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef FORMS_SOURCE_COMPONENT_SCROLLBAR_HXX
+#define FORMS_SOURCE_COMPONENT_SCROLLBAR_HXX
+
+#include "FormComponent.hxx"
+#include "frm_module.hxx"
+
+//........................................................................
+namespace frm
+{
+//........................................................................
+
+ //====================================================================
+ //= OScrollBarModel
+ //====================================================================
+ class OScrollBarModel :public OBoundControlModel
+ {
+ private:
+ // <properties>
+ sal_Int32 m_nDefaultScrollValue;
+ // </properties>
+
+ protected:
+ DECLARE_DEFAULT_LEAF_XTOR( OScrollBarModel );
+
+ // XServiceInfo
+ DECLARE_SERVICE_REGISTRATION( OScrollBarModel )
+
+ // XPersistObject
+ DECLARE_XPERSISTOBJECT()
+
+ // XCloneable
+ DECLARE_XCLONEABLE();
+
+ // XPropertyState
+ virtual ::com::sun::star::uno::Any getPropertyDefaultByHandle( sal_Int32 _nHandle ) const;
+
+ // OControlModel's property handling
+ virtual void describeFixedProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps
+ ) const;
+
+ // OPropertySetHelper
+ virtual void SAL_CALL getFastPropertyValue( ::com::sun::star::uno::Any& _rValue, sal_Int32 _nHandle ) const;
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue )
+ throw ( ::com::sun::star::uno::Exception );
+ virtual sal_Bool SAL_CALL convertFastPropertyValue( ::com::sun::star::uno::Any& _rConvertedValue, ::com::sun::star::uno::Any& _rOldValue, sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue )
+ throw ( ::com::sun::star::lang::IllegalArgumentException );
+
+ // OBoundControlModel
+ virtual ::com::sun::star::uno::Any
+ translateDbColumnToControlValue( );
+ virtual sal_Bool commitControlValueToDbColumn( bool _bPostReset );
+ virtual ::com::sun::star::uno::Any
+ getDefaultForReset() const;
+
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type >
+ getSupportedBindingTypes();
+ virtual ::com::sun::star::uno::Any
+ translateExternalValueToControlValue( const ::com::sun::star::uno::Any& _rExternalValue ) const;
+ virtual ::com::sun::star::uno::Any
+ translateControlValueToExternalValue( ) const;
+
+ // XCoponent and related helpers
+ virtual void SAL_CALL disposing();
+
+ // prevent method hiding
+ using OBoundControlModel::disposing;
+ using OBoundControlModel::getFastPropertyValue;
+
+ };
+//........................................................................
+} // namespacefrm
+//........................................................................
+
+#endif // FORMS_SOURCE_COMPONENT_SCROLLBAR_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/spinbutton.cxx b/forms/source/component/spinbutton.cxx
new file mode 100644
index 000000000000..cef0c2d1e223
--- /dev/null
+++ b/forms/source/component/spinbutton.cxx
@@ -0,0 +1,278 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_forms.hxx"
+#include "spinbutton.hxx"
+#include <comphelper/streamsection.hxx>
+#include <comphelper/basicio.hxx>
+
+//--------------------------------------------------------------------------
+extern "C" void SAL_CALL createRegistryInfo_OSpinButtonModel()
+{
+ static ::frm::OMultiInstanceAutoRegistration< ::frm::OSpinButtonModel > aRegisterModel;
+}
+
+//........................................................................
+namespace frm
+{
+//........................................................................
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::form;
+ using namespace ::com::sun::star::awt;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::util;
+ using namespace ::com::sun::star::io;
+ using namespace ::com::sun::star::form::binding;
+
+ //====================================================================
+ //= OSpinButtonModel
+ //====================================================================
+ // implemented elsewhere
+ Any translateExternalDoubleToControlIntValue(
+ const Any& _rExternalValue, const Reference< XPropertySet >& _rxProperties,
+ const ::rtl::OUString& _rMinValueName, const ::rtl::OUString& _rMaxValueName );
+ Any translateControlIntToExternalDoubleValue( const Any& _rControlIntValue );
+
+ //====================================================================
+ //= OSpinButtonModel
+ //====================================================================
+ //--------------------------------------------------------------------
+ DBG_NAME( OSpinButtonModel )
+ //--------------------------------------------------------------------
+ OSpinButtonModel::OSpinButtonModel( const Reference<XMultiServiceFactory>& _rxFactory )
+ :OBoundControlModel( _rxFactory, VCL_CONTROLMODEL_SPINBUTTON, VCL_CONTROL_SPINBUTTON, sal_True, sal_True, sal_False )
+ ,m_nDefaultSpinValue( 0 )
+ {
+ DBG_CTOR( OSpinButtonModel, NULL );
+
+ m_nClassId = FormComponentType::SPINBUTTON;
+ initValueProperty( PROPERTY_SPIN_VALUE, PROPERTY_ID_SPIN_VALUE );
+ }
+
+ //--------------------------------------------------------------------
+ OSpinButtonModel::OSpinButtonModel( const OSpinButtonModel* _pOriginal, const Reference< XMultiServiceFactory >& _rxFactory )
+ :OBoundControlModel( _pOriginal, _rxFactory )
+ {
+ DBG_CTOR( OSpinButtonModel, NULL );
+ m_nDefaultSpinValue = _pOriginal->m_nDefaultSpinValue;
+ }
+
+ //--------------------------------------------------------------------
+ OSpinButtonModel::~OSpinButtonModel( )
+ {
+ DBG_DTOR( OSpinButtonModel, NULL );
+ }
+
+ //--------------------------------------------------------------------
+ IMPLEMENT_SERVICE_REGISTRATION_2( OSpinButtonModel, OControlModel, FRM_SUN_COMPONENT_SPINBUTTON, BINDABLE_INTEGER_VALUE_RANGE )
+ // note that we're passing OControlModel as "base class". This is because
+ // OBoundControlModel, our real base class, claims to support the DataAwareControlModel
+ // service, which isn't really true for us. We only derive from this class
+ // to benefit from the functionality for binding to spreadsheet cells
+
+ //------------------------------------------------------------------------------
+ IMPLEMENT_DEFAULT_CLONING( OSpinButtonModel )
+
+ //------------------------------------------------------------------------------
+ void SAL_CALL OSpinButtonModel::disposing()
+ {
+ OBoundControlModel::disposing();
+ }
+
+ //--------------------------------------------------------------------
+ void OSpinButtonModel::describeFixedProperties( Sequence< Property >& _rProps ) const
+ {
+ BEGIN_DESCRIBE_PROPERTIES( 3, OControlModel )
+ DECL_PROP1( DEFAULT_SPIN_VALUE, sal_Int32, BOUND );
+ DECL_PROP1( TABINDEX, sal_Int16, BOUND );
+ DECL_PROP2( CONTROLSOURCEPROPERTY,::rtl::OUString, READONLY, TRANSIENT );
+ END_DESCRIBE_PROPERTIES();
+ }
+
+ //------------------------------------------------------------------------------
+ void OSpinButtonModel::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const
+ {
+ switch ( _nHandle )
+ {
+ case PROPERTY_ID_DEFAULT_SPIN_VALUE:
+ _rValue <<= m_nDefaultSpinValue;
+ break;
+
+ default:
+ OBoundControlModel::getFastPropertyValue( _rValue, _nHandle );
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ void OSpinButtonModel::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const Any& _rValue ) throw ( Exception )
+ {
+ switch ( _nHandle )
+ {
+ case PROPERTY_ID_DEFAULT_SPIN_VALUE:
+ OSL_VERIFY( _rValue >>= m_nDefaultSpinValue );
+ resetNoBroadcast();
+ break;
+
+ default:
+ OBoundControlModel::setFastPropertyValue_NoBroadcast( _nHandle, _rValue );
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ sal_Bool OSpinButtonModel::convertFastPropertyValue(
+ Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue )
+ throw ( IllegalArgumentException )
+ {
+ sal_Bool bModified( sal_False );
+ switch ( _nHandle )
+ {
+ case PROPERTY_ID_DEFAULT_SPIN_VALUE:
+ bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, m_nDefaultSpinValue );
+ break;
+
+ default:
+ bModified = OBoundControlModel::convertFastPropertyValue( _rConvertedValue, _rOldValue, _nHandle, _rValue );
+ break;
+ }
+ return bModified;
+ }
+
+ //--------------------------------------------------------------------
+ Any OSpinButtonModel::getPropertyDefaultByHandle( sal_Int32 _nHandle ) const
+ {
+ Any aReturn;
+
+ switch ( _nHandle )
+ {
+ case PROPERTY_ID_DEFAULT_SPIN_VALUE:
+ aReturn <<= (sal_Int32)0;
+ break;
+
+ default:
+ aReturn = OBoundControlModel::getPropertyDefaultByHandle( _nHandle );
+ break;
+ }
+
+ return aReturn;
+ }
+
+ //------------------------------------------------------------------------------
+ Any OSpinButtonModel::translateDbColumnToControlValue( )
+ {
+ OSL_FAIL( "OSpinButtonModel::commitControlValueToDbColumn: never to be called (we're not bound)!" );
+ return Any();
+ }
+
+ //------------------------------------------------------------------------------
+ sal_Bool OSpinButtonModel::commitControlValueToDbColumn( bool /*_bPostReset*/ )
+ {
+ OSL_FAIL( "OSpinButtonModel::commitControlValueToDbColumn: never to be called (we're not bound)!" );
+ return sal_True;
+ }
+
+ //------------------------------------------------------------------------------
+ Any OSpinButtonModel::getDefaultForReset() const
+ {
+ return makeAny( (sal_Int32)m_nDefaultSpinValue );
+ }
+
+ //--------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL OSpinButtonModel::getServiceName() throw( RuntimeException )
+ {
+ return FRM_SUN_COMPONENT_SPINBUTTON;
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OSpinButtonModel::write( const Reference< XObjectOutputStream >& _rxOutStream )
+ throw( IOException, RuntimeException )
+ {
+ OBoundControlModel::write( _rxOutStream );
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ OStreamSection aSection( Reference< XDataOutputStream >( _rxOutStream, UNO_QUERY ) );
+
+ // version
+ _rxOutStream->writeShort( 0x0001 );
+
+ // properties
+ _rxOutStream << m_nDefaultSpinValue;
+ writeHelpTextCompatibly( _rxOutStream );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL OSpinButtonModel::read( const Reference< XObjectInputStream>& _rxInStream ) throw( IOException, RuntimeException )
+ {
+ OBoundControlModel::read( _rxInStream );
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ // version
+ {
+ OStreamSection aSection( Reference< XDataInputStream >( _rxInStream, UNO_QUERY ) );
+
+ sal_uInt16 nVersion = _rxInStream->readShort();
+ if ( nVersion == 0x0001 )
+ {
+ _rxInStream >> m_nDefaultSpinValue;
+ readHelpTextCompatibly( _rxInStream );
+ }
+ else
+ defaultCommonProperties();
+
+ // here, everything in the stream section which is left will be skipped
+ }
+ }
+
+ //--------------------------------------------------------------------
+ Any OSpinButtonModel::translateExternalValueToControlValue( const Any& _rExternalValue ) const
+ {
+ return translateExternalDoubleToControlIntValue( _rExternalValue, m_xAggregateSet,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SpinValueMin" ) ),
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SpinValueMax" ) ) );
+ }
+
+ //--------------------------------------------------------------------
+ Any OSpinButtonModel::translateControlValueToExternalValue( ) const
+ {
+ // by definition, the base class simply obtains the property value
+ return translateControlIntToExternalDoubleValue( OBoundControlModel::translateControlValueToExternalValue() );
+ }
+
+ //--------------------------------------------------------------------
+ Sequence< Type > OSpinButtonModel::getSupportedBindingTypes()
+ {
+ return Sequence< Type >( &::getCppuType( static_cast< double* >( NULL ) ), 1 );
+ }
+
+//........................................................................
+} // namespace frm
+//........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/component/spinbutton.hxx b/forms/source/component/spinbutton.hxx
new file mode 100644
index 000000000000..2b811ab97459
--- /dev/null
+++ b/forms/source/component/spinbutton.hxx
@@ -0,0 +1,104 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef FORMS_SOURCE_COMPONENT_SPINBUTTON_HXX
+#define FORMS_SOURCE_COMPONENT_SPINBUTTON_HXX
+
+#include "FormComponent.hxx"
+#include "frm_module.hxx"
+
+//........................................................................
+namespace frm
+{
+//........................................................................
+
+ //====================================================================
+ //= OSpinButtonModel
+ //====================================================================
+ class OSpinButtonModel :public OBoundControlModel
+ {
+ private:
+ // <properties>
+ sal_Int32 m_nDefaultSpinValue;
+ // </properties>
+
+ protected:
+ DECLARE_DEFAULT_LEAF_XTOR( OSpinButtonModel );
+
+ // XServiceInfo
+ DECLARE_SERVICE_REGISTRATION( OSpinButtonModel )
+
+ // XPersistObject
+ DECLARE_XPERSISTOBJECT()
+
+ // XCloneable
+ DECLARE_XCLONEABLE();
+
+ // XPropertyState
+ virtual ::com::sun::star::uno::Any getPropertyDefaultByHandle( sal_Int32 _nHandle ) const;
+
+ // OControlModel's property handling
+ virtual void describeFixedProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps
+ ) const;
+
+ // OPropertySetHelper
+ virtual void SAL_CALL getFastPropertyValue( ::com::sun::star::uno::Any& _rValue, sal_Int32 _nHandle ) const;
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue )
+ throw ( ::com::sun::star::uno::Exception );
+ virtual sal_Bool SAL_CALL convertFastPropertyValue( ::com::sun::star::uno::Any& _rConvertedValue, ::com::sun::star::uno::Any& _rOldValue, sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue )
+ throw ( ::com::sun::star::lang::IllegalArgumentException );
+
+ // OBoundControlModel
+ virtual ::com::sun::star::uno::Any
+ translateDbColumnToControlValue( );
+ virtual sal_Bool commitControlValueToDbColumn( bool _bPostReset );
+ virtual ::com::sun::star::uno::Any
+ getDefaultForReset() const;
+
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type >
+ getSupportedBindingTypes();
+ virtual ::com::sun::star::uno::Any
+ translateExternalValueToControlValue( const ::com::sun::star::uno::Any& _rExternalValue ) const;
+ virtual ::com::sun::star::uno::Any
+ translateControlValueToExternalValue( ) const;
+
+ // XCoponent and related helpers
+ virtual void SAL_CALL disposing();
+
+ // prevent method hiding
+ using OBoundControlModel::disposing;
+ using OBoundControlModel::getFastPropertyValue;
+
+ };
+//........................................................................
+} // namespacefrm
+//........................................................................
+
+#endif // FORMS_SOURCE_COMPONENT_SPINBUTTON_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */