diff options
Diffstat (limited to 'forms/source/misc')
-rw-r--r-- | forms/source/misc/InterfaceContainer.cxx | 1237 | ||||
-rw-r--r-- | forms/source/misc/componenttools.cxx | 114 | ||||
-rw-r--r-- | forms/source/misc/frm_module.cxx | 39 | ||||
-rw-r--r-- | forms/source/misc/frm_strings.cxx | 37 | ||||
-rw-r--r-- | forms/source/misc/ids.cxx | 39 | ||||
-rw-r--r-- | forms/source/misc/limitedformats.cxx | 405 | ||||
-rw-r--r-- | forms/source/misc/listenercontainers.cxx | 75 | ||||
-rw-r--r-- | forms/source/misc/makefile.mk | 64 | ||||
-rw-r--r-- | forms/source/misc/property.cxx | 260 | ||||
-rw-r--r-- | forms/source/misc/services.cxx | 467 |
10 files changed, 2737 insertions, 0 deletions
diff --git a/forms/source/misc/InterfaceContainer.cxx b/forms/source/misc/InterfaceContainer.cxx new file mode 100644 index 000000000000..f1b59d77af7e --- /dev/null +++ b/forms/source/misc/InterfaceContainer.cxx @@ -0,0 +1,1237 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: InterfaceContainer.cxx,v $ + * $Revision: 1.30 $ + * + * 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 "frm_resource.hrc"
+#include "frm_resource.hxx"
+#include "InterfaceContainer.hxx"
+#include "property.hrc"
+#include "services.hxx"
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/io/WrongFormatException.hpp>
+#include <com/sun/star/io/XMarkableStream.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/util/XCloneable.hpp>
+
+#include <comphelper/container.hxx>
+#include <comphelper/enumhelper.hxx>
+#include <comphelper/eventattachermgr.hxx>
+#include <comphelper/property.hxx>
+#include <comphelper/sequence.hxx>
+#include <comphelper/types.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <cppuhelper/queryinterface.hxx>
+#include <rtl/logfile.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+ +#include <algorithm>
+#include <memory>
+ +//......................................................................... +namespace frm +{ +//......................................................................... + +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::script; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::form; +using namespace ::com::sun::star::util; + +namespace +{ + //--------------------------------------------------------------------- + static void lcl_throwIllegalArgumentException() + { + throw IllegalArgumentException(); + } +} + +//================================================================== +//= ElementDescription +//================================================================== +//------------------------------------------------------------------ +ElementDescription::ElementDescription( ) +{ +} + +//------------------------------------------------------------------ +ElementDescription::~ElementDescription() +{ +} + +//================================================================== +//= OInterfaceContainer +//================================================================== +//------------------------------------------------------------------ +OInterfaceContainer::OInterfaceContainer( + const Reference<XMultiServiceFactory>& _rxFactory, + ::osl::Mutex& _rMutex, + const Type& _rElementType) + :OInterfaceContainer_BASE() + ,m_rMutex(_rMutex) + ,m_aContainerListeners(_rMutex) + ,m_aElementType(_rElementType) + ,m_xServiceFactory(_rxFactory) +{ + impl_createEventAttacher_nothrow(); +} + +//------------------------------------------------------------------------------ +OInterfaceContainer::OInterfaceContainer( ::osl::Mutex& _rMutex, const OInterfaceContainer& _cloneSource ) + :OInterfaceContainer_BASE() + ,m_rMutex( _rMutex ) + ,m_aContainerListeners( _rMutex ) + ,m_aElementType( _cloneSource.m_aElementType ) + ,m_xServiceFactory( _cloneSource.m_xServiceFactory ) +{ + impl_createEventAttacher_nothrow(); +} + +//------------------------------------------------------------------------------ +void OInterfaceContainer::clonedFrom( const OInterfaceContainer& _cloneSource ) +{ + try + { + const Reference< XIndexAccess > xSourceHierarchy( const_cast< OInterfaceContainer* >( &_cloneSource ) ); + const sal_Int32 nCount = xSourceHierarchy->getCount(); + for ( sal_Int32 i=0; i<nCount; ++i ) + { + Reference< XCloneable > xCloneable( xSourceHierarchy->getByIndex( i ), UNO_QUERY_THROW ); + Reference< XInterface > xClone( xCloneable->createClone() ); + insertByIndex( i, makeAny( xClone ) ); + } + } + catch( const Exception& ) + { + throw WrappedTargetException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Could not clone the given interface hierarchy." ) ), + static_cast< XIndexContainer* >( const_cast< OInterfaceContainer* >( &_cloneSource ) ), + ::cppu::getCaughtException() + ); + } +} + +//------------------------------------------------------------------------------ +void OInterfaceContainer::impl_createEventAttacher_nothrow() +{ + try + { + m_xEventAttacher.set( ::comphelper::createEventAttacherManager( m_xServiceFactory ), UNO_SET_THROW ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } +} + +//------------------------------------------------------------------------------ +OInterfaceContainer::~OInterfaceContainer() +{ +} + +//------------------------------------------------------------------------------ +void OInterfaceContainer::disposing() +{ + // dispose all elements + for (sal_Int32 i = m_aItems.size(); i > 0; --i) + { + Reference<XPropertySet> xSet(m_aItems[i - 1], UNO_QUERY); + if (xSet.is()) + xSet->removePropertyChangeListener(PROPERTY_NAME, this); + + // revoke event knittings + if ( m_xEventAttacher.is() ) + { + Reference< XInterface > xIfc( xSet, UNO_QUERY ); + m_xEventAttacher->detach( i - 1, xIfc ); + m_xEventAttacher->removeEntry( i - 1 ); + } + + Reference<XComponent> xComponent(xSet, UNO_QUERY); + if (xComponent.is()) + xComponent->dispose(); + } + m_aMap.clear(); + m_aItems.clear(); + + EventObject aEvt(static_cast<XContainer*>(this)); + m_aContainerListeners.disposeAndClear(aEvt); +} + +// XPersistObject +//------------------------------------------------------------------------------ +namespace +{ + //.......................................................................... + void lcl_saveEvents( ::std::vector< Sequence< ScriptEventDescriptor > >& _rSave, + const Reference< XEventAttacherManager >& _rxManager, const sal_Int32 _nItemCount ) + { + OSL_ENSURE( _rxManager.is(), "lcl_saveEvents: invalid event attacher manager!" ); + if ( !_rxManager.is() ) + return; + + // reserve the space needed + _rSave.reserve( _nItemCount ); + + // copy the events + for (sal_Int32 i=0; i<_nItemCount; ++i) + _rSave.push_back(_rxManager->getScriptEvents( i )); + } + + //.......................................................................... + void lcl_restoreEvents( const ::std::vector< Sequence< ScriptEventDescriptor > >& _rSave, + const Reference< XEventAttacherManager >& _rxManager ) + { + OSL_ENSURE( _rxManager.is(), "lcl_restoreEvents: invalid event attacher manager!" ); + if ( !_rxManager.is() ) + return; + + ::std::vector< Sequence< ScriptEventDescriptor > >::const_iterator aLoop = _rSave.begin(); + ::std::vector< Sequence< ScriptEventDescriptor > >::const_iterator aEnd = _rSave.end(); + for ( sal_Int32 i=0; aLoop != aEnd; ++aLoop, ++i ) + { + _rxManager->revokeScriptEvents( i ); + _rxManager->registerScriptEvents( i, *aLoop ); + } + } +} + +//------------------------------------------------------------------------------ +void SAL_CALL OInterfaceContainer::writeEvents(const Reference<XObjectOutputStream>& _rxOutStream) +{ + // We're writing a document in SO 5.2 format (or even from earlier versions) + // -> convert the events from the new runtime format to the format of the 5.2 files + // but before, remember the current script events set for our children + ::std::vector< Sequence< ScriptEventDescriptor > > aSave; + if ( m_xEventAttacher.is() ) + lcl_saveEvents( aSave, m_xEventAttacher, m_aItems.size() ); + + transformEvents( efVersionSO5x ); + + try + { + Reference<XMarkableStream> xMark(_rxOutStream, UNO_QUERY); + sal_Int32 nMark = xMark->createMark(); + + sal_Int32 nObjLen = 0; + _rxOutStream->writeLong(nObjLen); + + Reference<XPersistObject> xScripts(m_xEventAttacher, UNO_QUERY); + if (xScripts.is()) + xScripts->write(_rxOutStream); + + // feststellen der Laenge + nObjLen = xMark->offsetToMark(nMark) - 4; + xMark->jumpToMark(nMark); + _rxOutStream->writeLong(nObjLen); + xMark->jumpToFurthest(); + xMark->deleteMark(nMark); + } + catch( const Exception& ) + { + // restore the events + if ( m_xEventAttacher.is() ) + lcl_restoreEvents( aSave, m_xEventAttacher ); + throw; + } + + // restore the events + if ( m_xEventAttacher.is() ) + lcl_restoreEvents( aSave, m_xEventAttacher ); +} + +//------------------------------------------------------------------------------ +struct TransformEventTo52Format : public ::std::unary_function< ScriptEventDescriptor, void > +{ + void operator()( ScriptEventDescriptor& _rDescriptor ) + { + if ( 0 == _rDescriptor.ScriptType.compareToAscii( "StarBasic" ) ) + { // it's a starbasic macro + sal_Int32 nPrefixLength = _rDescriptor.ScriptCode.indexOf( ':' ); + if ( 0 <= nPrefixLength ) + { // the macro name does not already contain a : +#ifdef DBG_UTIL + const ::rtl::OUString sPrefix = _rDescriptor.ScriptCode.copy( 0, nPrefixLength ); + DBG_ASSERT( 0 == sPrefix.compareToAscii( "document" ) + || 0 == sPrefix.compareToAscii( "application" ), + "TransformEventTo52Format: invalid (unknown) prefix!" ); +#endif + // cut the prefix + _rDescriptor.ScriptCode = _rDescriptor.ScriptCode.copy( nPrefixLength + 1 ); + } + } + } +}; + +//------------------------------------------------------------------------------ +struct TransformEventTo60Format : public ::std::unary_function< ScriptEventDescriptor, void > +{ + void operator()( ScriptEventDescriptor& _rDescriptor ) + { + if ( 0 == _rDescriptor.ScriptType.compareToAscii( "StarBasic" ) ) + { // it's a starbasic macro + if ( _rDescriptor.ScriptCode.indexOf( ':' ) < 0 ) + { // the macro name does not already contain a : + // -> default the type to "document" + ::rtl::OUString sNewScriptCode( RTL_CONSTASCII_USTRINGPARAM( "document:" ) ); + sNewScriptCode += _rDescriptor.ScriptCode; + _rDescriptor.ScriptCode = sNewScriptCode; + } + } + } +}; + +//------------------------------------------------------------------------------ +void OInterfaceContainer::transformEvents( const EventFormat _eTargetFormat ) +{ + OSL_ENSURE( m_xEventAttacher.is(), "OInterfaceContainer::transformEvents: no event attacher manager!" ); + if ( !m_xEventAttacher.is() ) + return; + + try + { + // loop through all our children + sal_Int32 nItems = m_aItems.size(); + Sequence< ScriptEventDescriptor > aChildEvents; + + for (sal_Int32 i=0; i<nItems; ++i) + { + // get the script events for this object + aChildEvents = m_xEventAttacher->getScriptEvents( i ); + + if ( aChildEvents.getLength() ) + { + // the "iterators" for the events for this child + ScriptEventDescriptor* pChildEvents = aChildEvents.getArray(); + ScriptEventDescriptor* pChildEventsEnd = pChildEvents + aChildEvents.getLength(); + + // do the transformation + if ( efVersionSO6x == _eTargetFormat ) + ::std::for_each( pChildEvents, pChildEventsEnd, TransformEventTo60Format() ); + else + ::std::for_each( pChildEvents, pChildEventsEnd, TransformEventTo52Format() ); + + // revoke the script events + m_xEventAttacher->revokeScriptEvents( i ); + // and re-register them + m_xEventAttacher->registerScriptEvents( i, aChildEvents ); + } + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } +} + +//------------------------------------------------------------------------------ +void SAL_CALL OInterfaceContainer::readEvents(const Reference<XObjectInputStream>& _rxInStream) +{ + ::osl::MutexGuard aGuard( m_rMutex ); + + // Scripting Info lesen + Reference<XMarkableStream> xMark(_rxInStream, UNO_QUERY); + 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 + if ( m_xEventAttacher.is() ) + { + OInterfaceArray::const_iterator aAttach = m_aItems.begin(); + OInterfaceArray::const_iterator aAttachEnd = m_aItems.end(); + for ( sal_Int32 i=0; aAttach != aAttachEnd; ++aAttach, ++i ) + { + Reference< XInterface > xAsIFace( *aAttach, UNO_QUERY ); // important to normalize this .... + Reference< XPropertySet > xAsSet( xAsIFace, UNO_QUERY ); + m_xEventAttacher->attach( i, xAsIFace, makeAny( xAsSet ) ); + } + } +} + +//------------------------------------------------------------------------------ +void SAL_CALL OInterfaceContainer::write( const Reference< XObjectOutputStream >& _rxOutStream ) throw(IOException, RuntimeException) +{ + ::osl::MutexGuard aGuard( m_rMutex ); + sal_Int32 nLen = m_aItems.size(); + + // schreiben der laenge + _rxOutStream->writeLong(nLen); + + if (nLen) + { + // 1. Version + _rxOutStream->writeShort(0x0001); + + // 2. Objekte + for (sal_Int32 i = 0; i < nLen; i++) + { + Reference<XPersistObject> xObj(m_aItems[i], UNO_QUERY); + if (xObj.is()) + _rxOutStream->writeObject(xObj); + else + { + // ::com::sun::star::chaos::Error + } + } + + // 3. Scripts + writeEvents(_rxOutStream); + } +} + +//------------------------------------------------------------------------------ +namespace +{ + Reference< XPersistObject > lcl_createPlaceHolder( const Reference< XMultiServiceFactory >& _rxORB ) + { + Reference< XPersistObject > xObject( _rxORB->createInstance( FRM_COMPONENT_HIDDENCONTROL ), UNO_QUERY ); + DBG_ASSERT( xObject.is(), "lcl_createPlaceHolder: could not create a substitute for the unknown object!" ); + if ( xObject.is() ) + { + // set some properties describing what we did + Reference< XPropertySet > xObjProps( xObject, UNO_QUERY ); + if ( xObject.is() ) + { + try + { + xObjProps->setPropertyValue( PROPERTY_NAME, makeAny( FRM_RES_STRING( RID_STR_CONTROL_SUBSTITUTED_NAME ) ) ); + xObjProps->setPropertyValue( PROPERTY_TAG, makeAny( FRM_RES_STRING( RID_STR_CONTROL_SUBSTITUTED_EPXPLAIN ) ) ); + } + catch(Exception&) + { + } + } + } + return xObject; + } +} + +//------------------------------------------------------------------------------ +void SAL_CALL OInterfaceContainer::read( const Reference< XObjectInputStream >& _rxInStream ) throw(IOException, RuntimeException) +{ + ::osl::MutexGuard aGuard( m_rMutex ); + + // after ::read the object is expected to be in the state it was when ::write was called, so we have + // to empty ourself here + // FS - 71598 - 12.01.00 + while (getCount()) + removeByIndex(0); + + // Schreibt nur in Abhaengigkeit der Laenge + sal_Int32 nLen = _rxInStream->readLong(); + + if (nLen) + { + // 1. Version + sal_uInt16 nVersion = _rxInStream->readShort(); (void)nVersion; + + // 2. Objekte + for (sal_Int32 i = 0; i < nLen; i++) + { + Reference<XPersistObject> xObj; + try + { + xObj = _rxInStream->readObject(); + } + catch(WrongFormatException& e) + { + (void)e; // make compiler happy + // the object could not be read + // create a object (so the readEvents below will assign the events to the right controls) + xObj = lcl_createPlaceHolder( m_xServiceFactory ); + if ( !xObj.is() ) + // couldn't handle it + throw; + // 72133 - 09.02.00 - FS + } + catch(Exception&) + { + // unsere Map leeren + while (!m_aItems.empty()) + removeElementsNoEvents(0); + + // und die Exception nach aussen + throw; + } + + if ( xObj.is() ) + { + Reference< XPropertySet > xElement( xObj, UNO_QUERY ); + try + { + implInsert( + m_aItems.size(), // position + xElement, // element to insert + sal_False, // no event attacher manager handling + NULL, // not yet approved - let implInsert do it + sal_True // fire the event + ); + } + catch( const Exception& ) + { + DBG_ERROR( "OInterfaceContainerHelper::read: reading succeeded, but not inserting!" ); + // create a placeholder + xElement = xElement.query( lcl_createPlaceHolder( m_xServiceFactory ) ); + if ( !xElement.is() ) + // couldn't handle it + throw; + // insert the placeholder + implInsert( m_aItems.size(), xElement, sal_False, NULL, sal_True ); + } + } + } + + readEvents(_rxInStream); + } + else + { + try + { + m_xEventAttacher = ::comphelper::createEventAttacherManager( m_xServiceFactory ); + OSL_ENSURE( m_xEventAttacher.is(), "OInterfaceContainer::read: could not create an event attacher manager!" ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } +} + +// XContainer +//------------------------------------------------------------------------------ +void SAL_CALL OInterfaceContainer::addContainerListener(const Reference<XContainerListener>& _rxListener) throw( RuntimeException ) +{ + m_aContainerListeners.addInterface(_rxListener); +} + +//------------------------------------------------------------------------------ +void SAL_CALL OInterfaceContainer::removeContainerListener(const Reference<XContainerListener>& _rxListener) throw( RuntimeException ) +{ + m_aContainerListeners.removeInterface(_rxListener); +} + +// XEventListener +//------------------------------------------------------------------------------ +void SAL_CALL OInterfaceContainer::disposing(const EventObject& _rSource) throw( RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_rMutex ); + + Reference< XInterface > xSource( _rSource.Source, UNO_QUERY ); + // normalized source + + OInterfaceArray::iterator j; + for ( j = m_aItems.begin(); j != m_aItems.end(); ++j ) + { + DBG_ASSERT( j->get() == Reference< XInterface >( *j, UNO_QUERY ).get(), + "OInterfaceContainer::disposing: vector element not normalized!" ); + + if ( xSource.get() == j->get() ) + // found the element + break; + } + + if ( m_aItems.end() != j ) + { + m_aItems.erase(j); + + // look up in, and erase from, m_aMap, too + OInterfaceMap::iterator i = m_aMap.begin(); + while ( i != m_aMap.end() ) + { + DBG_ASSERT( i->second.get() == Reference< XInterface >( i->second, UNO_QUERY ).get(), + "OInterfaceContainer::disposing: map element not normalized!" ); + + if ( i->second.get() == xSource.get() ) + { + // found it + m_aMap.erase(i); + break; + } + + ++i; + + DBG_ASSERT( i != m_aMap.end(), "OInterfaceContainer::disposing: inconsistency: the element was in m_aItems, but not in m_aMap!" ); + } + } +} + +// XPropertyChangeListener +//------------------------------------------------------------------------------ +void OInterfaceContainer::propertyChange(const PropertyChangeEvent& evt) +throw (::com::sun::star::uno::RuntimeException) { + if (evt.PropertyName == PROPERTY_NAME) + { + ::osl::MutexGuard aGuard( m_rMutex ); + OInterfaceMap::iterator i = ::std::find(m_aMap.begin(), m_aMap.end(), + ::std::pair<const ::rtl::OUString, InterfaceRef >(::comphelper::getString(evt.OldValue),evt.Source)); + if (i != m_aMap.end()) + { + InterfaceRef xCorrectType((*i).second); + m_aMap.erase(i); + m_aMap.insert(::std::pair<const ::rtl::OUString, InterfaceRef >(::comphelper::getString(evt.NewValue),xCorrectType)); + } + } +} + +// XElementAccess +//------------------------------------------------------------------------------ +sal_Bool SAL_CALL OInterfaceContainer::hasElements() throw( RuntimeException ) +{ + return !m_aMap.empty(); +} + +//------------------------------------------------------------------------------ +Type SAL_CALL OInterfaceContainer::getElementType() throw(RuntimeException) +{ + return m_aElementType; +} + +// XEnumerationAccess +//------------------------------------------------------------------------------ +Reference<XEnumeration> SAL_CALL OInterfaceContainer::createEnumeration() throw( RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_rMutex ); + return new ::comphelper::OEnumerationByIndex(static_cast<XIndexAccess*>(this)); +} + +// XNameAccess +//------------------------------------------------------------------------------ +Any SAL_CALL OInterfaceContainer::getByName( const ::rtl::OUString& _rName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException) +{ + ::std::pair <OInterfaceMap::iterator, + OInterfaceMap::iterator> aPair = m_aMap.equal_range(_rName); + + if (aPair.first == aPair.second) + throw NoSuchElementException(); + + return (*aPair.first).second->queryInterface( m_aElementType ); +} + +//------------------------------------------------------------------------------ +StringSequence SAL_CALL OInterfaceContainer::getElementNames() throw(RuntimeException) +{ + StringSequence aNameList(m_aItems.size()); + ::rtl::OUString* pStringArray = aNameList.getArray(); + + for (OInterfaceMap::const_iterator i = m_aMap.begin(); i != m_aMap.end(); ++i, ++pStringArray) + { + *pStringArray = (*i).first; + } + return aNameList; +} + +//------------------------------------------------------------------------------ +sal_Bool SAL_CALL OInterfaceContainer::hasByName( const ::rtl::OUString& _rName ) throw(RuntimeException) +{ + ::std::pair <OInterfaceMap::iterator, + OInterfaceMap::iterator> aPair = m_aMap.equal_range(_rName); + return aPair.first != aPair.second; +} + +// XIndexAccess +//------------------------------------------------------------------------------ +sal_Int32 OInterfaceContainer::getCount() throw( RuntimeException ) +{ + return m_aItems.size(); +} + +//------------------------------------------------------------------------------ +Any OInterfaceContainer::getByIndex(sal_Int32 _nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) +{ + if (_nIndex < 0 || (_nIndex >= (sal_Int32)m_aItems.size())) + throw IndexOutOfBoundsException(); + + return m_aItems[_nIndex]->queryInterface( m_aElementType ); +} + +//------------------------------------------------------------------------------ +void OInterfaceContainer::approveNewElement( const Reference< XPropertySet >& _rxObject, ElementDescription* _pElement ) +{ + // it has to be non-NULL + if ( !_rxObject.is() ) + throw IllegalArgumentException(FRM_RES_STRING(RID_STR_NEED_NON_NULL_OBJECT), static_cast<XContainer*>(this), 1); + + // it has to support our element type interface + Any aCorrectType = _rxObject->queryInterface( m_aElementType ); + if ( !aCorrectType.hasValue() ) + lcl_throwIllegalArgumentException(); + + // it has to have a "Name" property + if ( !hasProperty( PROPERTY_NAME, _rxObject ) ) + lcl_throwIllegalArgumentException(); + + // it has to be a child, and it must not have a parent already + Reference< XChild > xChild( _rxObject, UNO_QUERY ); + if ( !xChild.is() || xChild->getParent().is() ) + { +#ifdef FS_PRIV_DEBUG + ::rtl::OUString sChildName, sParentName; + Reference< XNamed > xNamed( xChild, UNO_QUERY ); + if ( xNamed.is() ) + sChildName = xNamed->getName(); + if ( xChild.is() ) + { + xNamed = xNamed.query( xChild->getParent() ); + if ( xNamed.is() ) + sParentName = xNamed->getName(); + } +#endif + lcl_throwIllegalArgumentException(); + } + + // passed all tests. cache the information we have so far + DBG_ASSERT( _pElement, "OInterfaceContainer::approveNewElement: invalid event descriptor!" ); + if ( _pElement ) + { + _pElement->xPropertySet = _rxObject; + _pElement->xChild = xChild; + _pElement->aElementTypeInterface = aCorrectType; + _pElement->xInterface = Reference< XInterface >( _rxObject, UNO_QUERY ); // normalized XInterface + } +} + +//------------------------------------------------------------------------------ +void OInterfaceContainer::implInsert(sal_Int32 _nIndex, const Reference< XPropertySet >& _rxElement, + sal_Bool _bEvents, ElementDescription* _pApprovalResult, sal_Bool _bFire ) throw( IllegalArgumentException ) +{ + RTL_LOGFILE_CONTEXT( aLogger, "forms::OInterfaceContainer::implInsert" ); + + ::osl::ClearableMutexGuard aGuard( m_rMutex ); + + ::std::auto_ptr< ElementDescription > aAutoDeleteMetaData; + ElementDescription* pElementMetaData = _pApprovalResult; + if ( !pElementMetaData ) + { // not yet approved by the caller -> do ourself + pElementMetaData = createElementMetaData(); + DBG_ASSERT( pElementMetaData, "OInterfaceContainer::implInsert: createElementMetaData returned nonsense!" ); + + // ensure that the meta data structure will be deleted later on + aAutoDeleteMetaData = ::std::auto_ptr< ElementDescription >( pElementMetaData ); + + // will throw an exception if necessary + approveNewElement( _rxElement, pElementMetaData ); + } + + + // approveNewElement (no matter if called here or outside) has ensure that all relevant interfaces + // exist + + // set the name, and add as change listener for the name + ::rtl::OUString sName; + _rxElement->getPropertyValue(PROPERTY_NAME) >>= sName; + _rxElement->addPropertyChangeListener(PROPERTY_NAME, this); + + // insert the object into our internal structures + if (_nIndex > (sal_Int32)m_aItems.size()) // ermitteln des tatsaechlichen Indexs + { + _nIndex = m_aItems.size(); + m_aItems.push_back( pElementMetaData->xInterface ); + } + else + m_aItems.insert( m_aItems.begin() + _nIndex, pElementMetaData->xInterface ); + + m_aMap.insert( ::std::pair< const ::rtl::OUString, InterfaceRef >( sName, pElementMetaData->xInterface ) ); + + // announce ourself as parent to the new element + { + RTL_LOGFILE_CONTEXT( aLogger, "forms::OInterfaceContainer::implInsert::settingParent" ); + pElementMetaData->xChild->setParent(static_cast<XContainer*>(this)); + } + + // handle the events + if ( _bEvents && m_xEventAttacher.is() ) + { + m_xEventAttacher->insertEntry(_nIndex); + m_xEventAttacher->attach( _nIndex, pElementMetaData->xInterface, makeAny( _rxElement ) ); + } + + // notify derived classes + implInserted( pElementMetaData ); + + // fire the notification about the change + if ( _bFire ) + { + // notify listeners + ContainerEvent aEvt; + aEvt.Source = static_cast<XContainer*>(this); + aEvt.Accessor <<= _nIndex; + aEvt.Element = pElementMetaData->aElementTypeInterface; + + aGuard.clear(); + m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvt ); + } +} + +//------------------------------------------------------------------------------ +void OInterfaceContainer::removeElementsNoEvents(sal_Int32 nIndex) +{ + OInterfaceArray::iterator i = m_aItems.begin() + nIndex; + InterfaceRef xElement(*i); + + OInterfaceMap::iterator j = m_aMap.begin(); + while (j != m_aMap.end() && (*j).second != xElement) ++j; + + m_aItems.erase(i); + m_aMap.erase(j); + + Reference<XPropertySet> xSet(xElement, UNO_QUERY); + if (xSet.is()) + xSet->removePropertyChangeListener(PROPERTY_NAME, this); + + Reference<XChild> xChild(xElement, UNO_QUERY); + if (xChild.is()) + xChild->setParent(InterfaceRef ()); +} + +//------------------------------------------------------------------------------ +void OInterfaceContainer::implInserted( const ElementDescription* /*_pElement*/ ) +{ + // not inrerested in +} + +//------------------------------------------------------------------------------ +void OInterfaceContainer::implRemoved( const InterfaceRef& /*_rxObject*/ ) +{ + // not inrerested in +} + +//------------------------------------------------------------------------------ +void OInterfaceContainer::impl_replacedElement( const ContainerEvent& _rEvent, ::osl::ClearableMutexGuard& _rInstanceLock ) +{ + _rInstanceLock.clear(); + m_aContainerListeners.notifyEach( &XContainerListener::elementReplaced, _rEvent ); +} + +// XIndexContainer +//------------------------------------------------------------------------------ +void SAL_CALL OInterfaceContainer::insertByIndex( sal_Int32 _nIndex, const Any& _rElement ) throw(IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException) +{ + Reference< XPropertySet > xElement; + _rElement >>= xElement; + implInsert( _nIndex, xElement, sal_True /* event handling */ , NULL /* not yet approved */ , sal_True /* notification */ ); +} + +//------------------------------------------------------------------------------ +void OInterfaceContainer::implReplaceByIndex( const sal_Int32 _nIndex, const Any& _rNewElement, ::osl::ClearableMutexGuard& _rClearBeforeNotify ) +{ + OSL_PRECOND( ( _nIndex >= 0 ) && ( _nIndex < (sal_Int32)m_aItems.size() ), "OInterfaceContainer::implReplaceByIndex: precondition not met (index)!" ); + + // approve the new object + ::std::auto_ptr< ElementDescription > aElementMetaData( createElementMetaData() ); + DBG_ASSERT( aElementMetaData.get(), "OInterfaceContainer::implReplaceByIndex: createElementMetaData returned nonsense!" ); + { + Reference< XPropertySet > xElementProps; + _rNewElement >>= xElementProps; + approveNewElement( xElementProps, aElementMetaData.get() ); + } + + // get the old element + InterfaceRef xOldElement( m_aItems[ _nIndex ] ); + DBG_ASSERT( xOldElement.get() == Reference< XInterface >( xOldElement, UNO_QUERY ).get(), + "OInterfaceContainer::implReplaceByIndex: elements should be held normalized!" ); + + // locate the old element in the map + OInterfaceMap::iterator j = m_aMap.begin(); + while ( ( j != m_aMap.end() ) && ( j->second.get() != xOldElement.get() ) ) + ++j; + + // remove event knittings + if ( m_xEventAttacher.is() ) + { + InterfaceRef xNormalized( xOldElement, UNO_QUERY ); + m_xEventAttacher->detach( _nIndex, xNormalized ); + m_xEventAttacher->removeEntry( _nIndex ); + } + + // don't listen for property changes anymore + Reference<XPropertySet> xSet( xOldElement, UNO_QUERY ); + if (xSet.is()) + xSet->removePropertyChangeListener(PROPERTY_NAME, this); + + // give the old element a new (void) parent + Reference<XChild> xChild(xOldElement, UNO_QUERY); + if (xChild.is()) + xChild->setParent(InterfaceRef ()); + + // remove the old one + m_aMap.erase(j); + + // examine the new element + ::rtl::OUString sName; + DBG_ASSERT( aElementMetaData.get()->xPropertySet.is(), "OInterfaceContainer::implReplaceByIndex: what did approveNewElement do?" ); + + aElementMetaData.get()->xPropertySet->getPropertyValue(PROPERTY_NAME) >>= sName; + aElementMetaData.get()->xPropertySet->addPropertyChangeListener(PROPERTY_NAME, this); + + // insert the new one + m_aMap.insert( ::std::pair<const ::rtl::OUString, InterfaceRef >( sName, aElementMetaData.get()->xInterface ) ); + m_aItems[ _nIndex ] = aElementMetaData.get()->xInterface; + + aElementMetaData.get()->xChild->setParent(static_cast<XContainer*>(this)); + + if ( m_xEventAttacher.is() ) + { + m_xEventAttacher->insertEntry( _nIndex ); + m_xEventAttacher->attach( _nIndex, aElementMetaData.get()->xInterface, makeAny( aElementMetaData.get()->xPropertySet ) ); + } + + ContainerEvent aReplaceEvent; + aReplaceEvent.Source = static_cast< XContainer* >( this ); + aReplaceEvent.Accessor <<= _nIndex; + aReplaceEvent.Element = aElementMetaData.get()->xInterface->queryInterface( m_aElementType ); + aReplaceEvent.ReplacedElement = xOldElement->queryInterface( m_aElementType ); + + impl_replacedElement( aReplaceEvent, _rClearBeforeNotify ); +} + +//------------------------------------------------------------------------------ +void OInterfaceContainer::implCheckIndex( const sal_Int32 _nIndex ) SAL_THROW( ( ::com::sun::star::lang::IndexOutOfBoundsException ) ) +{ + if (_nIndex < 0 || _nIndex >= (sal_Int32)m_aItems.size()) + throw IndexOutOfBoundsException(); +} + +//------------------------------------------------------------------------------ +void SAL_CALL OInterfaceContainer::replaceByIndex(sal_Int32 _nIndex, const Any& Element) throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) +{ + ::osl::ClearableMutexGuard aGuard( m_rMutex ); + // check the index + implCheckIndex( _nIndex ); + // do the replace + implReplaceByIndex( _nIndex, Element, aGuard ); +} + +//------------------------------------------------------------------------------ +void OInterfaceContainer::implRemoveByIndex( const sal_Int32 _nIndex, ::osl::ClearableMutexGuard& _rClearBeforeNotify ) +{ + OSL_PRECOND( ( _nIndex >= 0 ) && ( _nIndex < (sal_Int32)m_aItems.size() ), "OInterfaceContainer::implRemoveByIndex: precondition not met (index)!" ); + + OInterfaceArray::iterator i = m_aItems.begin() + _nIndex; + InterfaceRef xElement(*i); + + OInterfaceMap::iterator j = m_aMap.begin(); + while (j != m_aMap.end() && (*j).second != xElement) ++j; + + m_aItems.erase(i); + m_aMap.erase(j); + + // remove event knittings + if ( m_xEventAttacher.is() ) + { + InterfaceRef xNormalized( xElement, UNO_QUERY ); + m_xEventAttacher->detach( _nIndex, xNormalized ); + m_xEventAttacher->removeEntry( _nIndex ); + } + + Reference<XPropertySet> xSet(xElement, UNO_QUERY); + if (xSet.is()) + xSet->removePropertyChangeListener(PROPERTY_NAME, this); + + Reference<XChild> xChild(xElement, UNO_QUERY); + if (xChild.is()) + xChild->setParent(InterfaceRef ()); + + // notify derived classes + implRemoved(xElement); + + // notify listeners + ContainerEvent aEvt; + aEvt.Source = static_cast<XContainer*>(this); + aEvt.Element = xElement->queryInterface( m_aElementType ); + aEvt.Accessor <<= _nIndex; + + _rClearBeforeNotify.clear(); + m_aContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvt ); +} + +//------------------------------------------------------------------------------ +void SAL_CALL OInterfaceContainer::removeByIndex(sal_Int32 _nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) +{ + ::osl::ClearableMutexGuard aGuard( m_rMutex ); + // check the index + implCheckIndex( _nIndex ); + // do the removal + implRemoveByIndex( _nIndex, aGuard ); +} + +//------------------------------------------------------------------------ +ElementDescription* OInterfaceContainer::createElementMetaData( ) +{ + return new ElementDescription; +} + +//------------------------------------------------------------------------ +void SAL_CALL OInterfaceContainer::insertByName(const ::rtl::OUString& _rName, const Any& _rElement) throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException ) +{ + Reference< XPropertySet > xElementProps; + + ::std::auto_ptr< ElementDescription > aElementMetaData( createElementMetaData() ); + DBG_ASSERT( aElementMetaData.get(), "OInterfaceContainer::insertByName: createElementMetaData returned nonsense!" ); + + // ensure the correct name of the element + try + { + _rElement >>= xElementProps; + approveNewElement( xElementProps, aElementMetaData.get() ); + + xElementProps->setPropertyValue( PROPERTY_NAME, makeAny( _rName ) ); + } + catch( const IllegalArgumentException& ) + { + throw; // allowed to leave + } + catch( const ElementExistException& ) + { + throw; // allowed to leave + } + catch( const Exception& ) + { + DBG_ERROR( "OInterfaceContainer::insertByName: caught an exception!" ); + } + implInsert( m_aItems.size(), xElementProps, sal_True, aElementMetaData.get(), sal_True ); +} + +//------------------------------------------------------------------------ +void SAL_CALL OInterfaceContainer::replaceByName(const ::rtl::OUString& Name, const Any& Element) throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException ) +{ + ::osl::ClearableMutexGuard aGuard( m_rMutex ); + ::std::pair <OInterfaceMap::iterator, + OInterfaceMap::iterator> aPair = m_aMap.equal_range(Name); + if (aPair.first == aPair.second) + throw NoSuchElementException(); + + if (Element.getValueType().getTypeClass() != TypeClass_INTERFACE) + lcl_throwIllegalArgumentException(); + + Reference<XPropertySet> xSet; + Element >>= xSet; + if (xSet.is()) + { + if (!hasProperty(PROPERTY_NAME, xSet)) + lcl_throwIllegalArgumentException(); + + xSet->setPropertyValue(PROPERTY_NAME, makeAny(Name)); + } + + // determine the element pos + sal_Int32 nPos = ::std::find(m_aItems.begin(), m_aItems.end(), (*aPair.first).second) - m_aItems.begin(); + + implReplaceByIndex( nPos, Element, aGuard ); +} + +//------------------------------------------------------------------------ +void SAL_CALL OInterfaceContainer::removeByName(const ::rtl::OUString& Name) throw( NoSuchElementException, WrappedTargetException, RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_rMutex ); + ::std::pair <OInterfaceMap::iterator, + OInterfaceMap::iterator> aPair = m_aMap.equal_range(Name); + if (aPair.first == aPair.second) + throw NoSuchElementException(); + + sal_Int32 nPos = ::std::find(m_aItems.begin(), m_aItems.end(), (*aPair.first).second) - m_aItems.begin(); + removeByIndex(nPos); +} + + +// XEventAttacherManager +//------------------------------------------------------------------------ +void SAL_CALL OInterfaceContainer::registerScriptEvent( sal_Int32 nIndex, const ScriptEventDescriptor& aScriptEvent ) throw(IllegalArgumentException, RuntimeException) +{ + if ( m_xEventAttacher.is() ) + m_xEventAttacher->registerScriptEvent( nIndex, aScriptEvent ); +} + +//------------------------------------------------------------------------ +void SAL_CALL OInterfaceContainer::registerScriptEvents( sal_Int32 nIndex, const Sequence< ScriptEventDescriptor >& aScriptEvents ) throw(IllegalArgumentException, RuntimeException) +{ + if ( m_xEventAttacher.is() ) + m_xEventAttacher->registerScriptEvents( nIndex, aScriptEvents ); +} + +//------------------------------------------------------------------------ +void SAL_CALL OInterfaceContainer::revokeScriptEvent( sal_Int32 nIndex, const ::rtl::OUString& aListenerType, const ::rtl::OUString& aEventMethod, const ::rtl::OUString& aRemoveListenerParam ) throw(IllegalArgumentException, RuntimeException) +{ + if ( m_xEventAttacher.is() ) + m_xEventAttacher->revokeScriptEvent( nIndex, aListenerType, aEventMethod, aRemoveListenerParam ); +} + +//------------------------------------------------------------------------ +void SAL_CALL OInterfaceContainer::revokeScriptEvents( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException) +{ + if ( m_xEventAttacher.is() ) + m_xEventAttacher->revokeScriptEvents( nIndex ); +} + +//------------------------------------------------------------------------ +void SAL_CALL OInterfaceContainer::insertEntry( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException) +{ + if ( m_xEventAttacher.is() ) + m_xEventAttacher->insertEntry( nIndex ); +} + +//------------------------------------------------------------------------ +void SAL_CALL OInterfaceContainer::removeEntry( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException) +{ + if ( m_xEventAttacher.is() ) + m_xEventAttacher->removeEntry( nIndex ); +} + +//------------------------------------------------------------------------ +Sequence< ScriptEventDescriptor > SAL_CALL OInterfaceContainer::getScriptEvents( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException) +{ + Sequence< ScriptEventDescriptor > aReturn; + if ( m_xEventAttacher.is() ) + aReturn = m_xEventAttacher->getScriptEvents( nIndex ); + return aReturn; +} + +//------------------------------------------------------------------------ +void SAL_CALL OInterfaceContainer::attach( sal_Int32 nIndex, const Reference< XInterface >& xObject, const Any& aHelper ) throw(IllegalArgumentException, ServiceNotRegisteredException, RuntimeException) +{ + if ( m_xEventAttacher.is() ) + m_xEventAttacher->attach( nIndex, xObject, aHelper ); +} + +//------------------------------------------------------------------------ +void SAL_CALL OInterfaceContainer::detach( sal_Int32 nIndex, const Reference< XInterface >& xObject ) throw(IllegalArgumentException, RuntimeException) +{ + if ( m_xEventAttacher.is() ) + m_xEventAttacher->detach( nIndex, xObject ); +} + +//------------------------------------------------------------------------ +void SAL_CALL OInterfaceContainer::addScriptListener( const Reference< XScriptListener >& xListener ) throw(IllegalArgumentException, RuntimeException) +{ + if ( m_xEventAttacher.is() ) + m_xEventAttacher->addScriptListener( xListener ); +} + +//------------------------------------------------------------------------ +void SAL_CALL OInterfaceContainer::removeScriptListener( const Reference< XScriptListener >& xListener ) throw(IllegalArgumentException, RuntimeException) +{ + if ( m_xEventAttacher.is() ) + m_xEventAttacher->removeScriptListener( xListener ); +} + +//================================================================== +//= OFormComponents +//================================================================== +//------------------------------------------------------------------------------ +Any SAL_CALL OFormComponents::queryAggregation(const Type& _rType) throw(RuntimeException) +{ + Any aReturn = OFormComponents_BASE::queryInterface(_rType); + if (!aReturn.hasValue()) + { + aReturn = OInterfaceContainer::queryInterface(_rType); + + if (!aReturn.hasValue()) + aReturn = FormComponentsBase::queryAggregation(_rType); + } + + return aReturn; +} + +//------------------------------------------------------------------ +Sequence<Type> SAL_CALL OFormComponents::getTypes() throw(RuntimeException) +{ + return ::comphelper::concatSequences(OInterfaceContainer::getTypes(), FormComponentsBase::getTypes(), OFormComponents_BASE::getTypes()); +} + +//------------------------------------------------------------------------------ +OFormComponents::OFormComponents(const Reference<XMultiServiceFactory>& _rxFactory) + :FormComponentsBase( m_aMutex ) + ,OInterfaceContainer( _rxFactory, m_aMutex, XFormComponent::static_type() ) + ,OFormComponents_BASE() +{ +} + +//------------------------------------------------------------------------------ +OFormComponents::OFormComponents( const OFormComponents& _cloneSource ) + :FormComponentsBase( m_aMutex ) + ,OInterfaceContainer( m_aMutex, _cloneSource ) + ,OFormComponents_BASE() +{ +} + +//------------------------------------------------------------------------------ +OFormComponents::~OFormComponents() +{ + if (!FormComponentsBase::rBHelper.bDisposed) + { + acquire(); + dispose(); + } +} + +// OComponentHelper +//------------------------------------------------------------------------------ +void OFormComponents::disposing() +{ + OInterfaceContainer::disposing(); + FormComponentsBase::disposing(); + m_xParent = NULL; +} + +//XChild +//------------------------------------------------------------------------------ +void OFormComponents::setParent(const InterfaceRef& Parent) throw( NoSupportException, RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + m_xParent = Parent; +} + +//------------------------------------------------------------------------------ +InterfaceRef OFormComponents::getParent() throw( RuntimeException ) +{ + return m_xParent; +} + +//......................................................................... +} // namespace frm +//......................................................................... + diff --git a/forms/source/misc/componenttools.cxx b/forms/source/misc/componenttools.cxx new file mode 100644 index 000000000000..21740749d4d4 --- /dev/null +++ b/forms/source/misc/componenttools.cxx @@ -0,0 +1,114 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: componenttools.cxx,v $ + * $Revision: 1.6.42.1 $ + * + * 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" + +/** === begin UNO includes === **/ +#include <com/sun/star/container/XChild.hpp> +/** === end UNO includes === **/ + +#include <algorithm> +#include <iterator> + +//........................................................................ +namespace frm +{ +//........................................................................ + + /** === begin UNO using === **/ + using ::com::sun::star::frame::XModel; + using ::com::sun::star::uno::XInterface; + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::UNO_QUERY; + using ::com::sun::star::container::XChild; + /** === end UNO using === **/ + + //==================================================================== + //= TypeBag + //==================================================================== + //-------------------------------------------------------------------- + TypeBag::TypeBag( const TypeSequence& _rTypes1 ) + { + addTypes( _rTypes1 ); + } + + //-------------------------------------------------------------------- + TypeBag::TypeBag( const TypeSequence& _rTypes1, const TypeSequence& _rTypes2 ) + { + addTypes( _rTypes1 ); + addTypes( _rTypes2 ); + } + + //-------------------------------------------------------------------- + TypeBag::TypeBag( const TypeSequence& _rTypes1, const TypeSequence& _rTypes2, const TypeSequence& _rTypes3 ) + { + addTypes( _rTypes1 ); + addTypes( _rTypes2 ); + addTypes( _rTypes3 ); + } + + //-------------------------------------------------------------------- + void TypeBag::addTypes( const TypeSequence& _rTypes ) + { + ::std::copy( + _rTypes.getConstArray(), + _rTypes.getConstArray() + _rTypes.getLength(), + ::std::insert_iterator< TypeSet >( m_aTypes, m_aTypes.begin() ) + ); + } + + //-------------------------------------------------------------------- + TypeBag::TypeSequence TypeBag::getTypes() const + { + TypeSequence aTypes( m_aTypes.size() ); + ::std::copy( m_aTypes.begin(), m_aTypes.end(), aTypes.getArray() ); + return aTypes; + } + + //==================================================================== + Reference< XModel > getXModel( const Reference< XInterface >& _rxComponent ) + { + Reference< XInterface > xParent = _rxComponent; + Reference< XModel > xModel( xParent, UNO_QUERY );; + while ( xParent.is() && !xModel.is() ) + { + Reference< XChild > xChild( xParent, UNO_QUERY ); + xParent.set( xChild.is() ? xChild->getParent() : Reference< XInterface >(), UNO_QUERY ); + xModel.set( xParent, UNO_QUERY ); + } + return xModel; + } + +//........................................................................ +} // namespace frm +//........................................................................ + diff --git a/forms/source/misc/frm_module.cxx b/forms/source/misc/frm_module.cxx new file mode 100644 index 000000000000..1240d411b909 --- /dev/null +++ b/forms/source/misc/frm_module.cxx @@ -0,0 +1,39 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: frm_module.cxx,v $ + * $Revision: 1.5 $ + * + * 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 "frm_module.hxx" + +#define FORMS_MODULE_IMPLEMENTATION_INCLUDE_CONTEXT + #define FORMS_MODULE_NAMESPACE frm + #include "forms_module_impl.hxx" +#undef FORMS_MODULE_IMPLEMENTATION_INCLUDE_CONTEXT + diff --git a/forms/source/misc/frm_strings.cxx b/forms/source/misc/frm_strings.cxx new file mode 100644 index 000000000000..68a4fd5f418b --- /dev/null +++ b/forms/source/misc/frm_strings.cxx @@ -0,0 +1,37 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: frm_strings.cxx,v $ + * $Revision: 1.5 $ + * + * 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" + +#define FORMS_IMPLEMENT_STRINGS +#include "frm_strings.hxx" +#include "services.hxx" + diff --git a/forms/source/misc/ids.cxx b/forms/source/misc/ids.cxx new file mode 100644 index 000000000000..c9213f636be4 --- /dev/null +++ b/forms/source/misc/ids.cxx @@ -0,0 +1,39 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ids.cxx,v $ + * $Revision: 1.4 $ + * + * 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 "ids.hxx" + +IMPLEMENT_IMPLEMENTATIONID_HELPER(frm, OImplementationIds) + + diff --git a/forms/source/misc/limitedformats.cxx b/forms/source/misc/limitedformats.cxx new file mode 100644 index 000000000000..4aaf40033062 --- /dev/null +++ b/forms/source/misc/limitedformats.cxx @@ -0,0 +1,405 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: limitedformats.cxx,v $ + * $Revision: 1.9 $ + * + * 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 "limitedformats.hxx" +#include "services.hxx" +#include <osl/diagnose.h> +#include <comphelper/types.hxx> +#include <comphelper/extract.hxx> +#include <com/sun/star/form/FormComponentType.hpp> + +//......................................................................... +namespace frm +{ +//......................................................................... + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::util; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::form; + using namespace ::com::sun::star::beans; + + sal_Int32 OLimitedFormats::s_nInstanceCount(0); + ::osl::Mutex OLimitedFormats::s_aMutex; + Reference< XNumberFormatsSupplier > OLimitedFormats::s_xStandardFormats; + + //===================================================================== + //= + //===================================================================== + //--------------------------------------------------------------------- + enum LocaleType + { + ltEnglishUS, + ltGerman, + ltSystem + }; + + //--------------------------------------------------------------------- + static const Locale& getLocale(LocaleType _eType) + { + static const Locale s_aEnglishUS( ::rtl::OUString::createFromAscii("en"), ::rtl::OUString::createFromAscii("us"), ::rtl::OUString() ); + static const Locale s_aGerman( ::rtl::OUString::createFromAscii("de"), ::rtl::OUString::createFromAscii("DE"), ::rtl::OUString() ); + static const ::rtl::OUString s_sEmptyString; + static const Locale s_aSystem( s_sEmptyString, s_sEmptyString, s_sEmptyString ); + + switch (_eType) + { + case ltEnglishUS: + return s_aEnglishUS; + + case ltGerman: + return s_aGerman; + + case ltSystem: + return s_aSystem; + } + + OSL_ENSURE(sal_False, "getLocale: invalid enum value!"); + return s_aSystem; + } + + //--------------------------------------------------------------------- + struct FormatEntry + { + const sal_Char* pDescription; + sal_Int32 nKey; + LocaleType eLocale; + }; + + //--------------------------------------------------------------------- + static const FormatEntry* lcl_getFormatTable(sal_Int16 nTableId) + { + switch (nTableId) + { + case FormComponentType::TIMEFIELD: + { + static FormatEntry s_aFormats[] = { + { "HH:MM", -1, ltEnglishUS }, + { "HH:MM:SS", -1, ltEnglishUS }, + { "HH:MM AM/PM", -1, ltEnglishUS }, + { "HH:MM:SS AM/PM", -1, ltEnglishUS }, + { NULL, -1, ltSystem } + }; + // don't switch this table here to const. The compiler could be tempted to really place this + // in a non-writeable segment, but we want to fill in the format keys later .... + return s_aFormats; + } + case FormComponentType::DATEFIELD: + { + static FormatEntry s_aFormats[] = { + { "T-M-JJ", -1, ltGerman }, + { "TT-MM-JJ", -1, ltGerman }, + { "TT-MM-JJJJ", -1, ltGerman }, + { "NNNNT. MMMM JJJJ", -1, ltGerman }, + + { "DD/MM/YY", -1, ltEnglishUS }, + { "MM/DD/YY", -1, ltEnglishUS }, + { "YY/MM/DD", -1, ltEnglishUS }, + { "DD/MM/YYYY", -1, ltEnglishUS }, + { "MM/DD/YYYY", -1, ltEnglishUS }, + { "YYYY/MM/DD", -1, ltEnglishUS }, + + { "JJ-MM-TT", -1, ltGerman }, + { "JJJJ-MM-TT", -1, ltGerman }, + + { NULL, -1, ltSystem } + }; + return s_aFormats; + } + } + + OSL_ENSURE(sal_False, "lcl_getFormatTable: invalid id!"); + return NULL; + } + + //===================================================================== + //= OLimitedFormats + //===================================================================== + //--------------------------------------------------------------------- + OLimitedFormats::OLimitedFormats(const Reference< XMultiServiceFactory >& _rxORB, const sal_Int16 _nClassId) + :m_nFormatEnumPropertyHandle(-1) + ,m_nTableId(_nClassId) + { + OSL_ENSURE(_rxORB.is(), "OLimitedFormats::OLimitedFormats: invalid service factory!"); + acquireSupplier(_rxORB); + ensureTableInitialized(m_nTableId); + } + + //--------------------------------------------------------------------- + OLimitedFormats::~OLimitedFormats() + { + releaseSupplier(); + } + + //--------------------------------------------------------------------- + void OLimitedFormats::ensureTableInitialized(const sal_Int16 _nTableId) + { + const FormatEntry* pFormatTable = lcl_getFormatTable(_nTableId); + if (-1 == pFormatTable->nKey) + { + ::osl::MutexGuard aGuard(s_aMutex); + if (-1 == pFormatTable->nKey) + { + // initialize the keys + Reference<XNumberFormats> xStandardFormats; + if (s_xStandardFormats.is()) + xStandardFormats = s_xStandardFormats->getNumberFormats(); + OSL_ENSURE(xStandardFormats.is(), "OLimitedFormats::ensureTableInitialized: don't have a formats supplier!"); + + if (xStandardFormats.is()) + { + // loop through the table + FormatEntry* pLoopFormats = const_cast<FormatEntry*>(pFormatTable); + while (pLoopFormats->pDescription) + { + // get the key for the description + pLoopFormats->nKey = xStandardFormats->queryKey( + ::rtl::OUString::createFromAscii(pLoopFormats->pDescription), + getLocale(pLoopFormats->eLocale), + sal_False + ); + + if (-1 == pLoopFormats->nKey) + { + pLoopFormats->nKey = xStandardFormats->addNew( + ::rtl::OUString::createFromAscii(pLoopFormats->pDescription), + getLocale(pLoopFormats->eLocale) + ); +#ifdef DBG_UTIL + try + { + xStandardFormats->getByKey(pLoopFormats->nKey); + } + catch(const Exception&) + { + OSL_ENSURE(sal_False, "OLimitedFormats::ensureTableInitialized: adding the key to the formats collection failed!"); + } +#endif + } + + // next + ++pLoopFormats; + } + } + } + } + } + + //--------------------------------------------------------------------- + void OLimitedFormats::clearTable(const sal_Int16 _nTableId) + { + ::osl::MutexGuard aGuard(s_aMutex); + const FormatEntry* pFormats = lcl_getFormatTable(_nTableId); + FormatEntry* pResetLoop = const_cast<FormatEntry*>(pFormats); + while (pResetLoop->pDescription) + { + pResetLoop->nKey = -1; + ++pResetLoop; + } + } + + //--------------------------------------------------------------------- + void OLimitedFormats::setAggregateSet(const Reference< XFastPropertySet >& _rxAggregate, sal_Int32 _nOriginalPropertyHandle) + { + // changes (NULL -> not NULL) and (not NULL -> NULL) are allowed + OSL_ENSURE(!m_xAggregate.is() || !_rxAggregate.is(), "OLimitedFormats::setAggregateSet: already have an aggregate!"); + OSL_ENSURE(_rxAggregate.is() || m_xAggregate.is(), "OLimitedFormats::setAggregateSet: invalid new aggregate!"); + + m_xAggregate = _rxAggregate; + m_nFormatEnumPropertyHandle = _nOriginalPropertyHandle; +#ifdef DBG_UTIL + if (m_xAggregate.is()) + { + try + { + m_xAggregate->getFastPropertyValue(m_nFormatEnumPropertyHandle); + } + catch(const Exception&) + { + OSL_ENSURE(sal_False, "OLimitedFormats::setAggregateSet: invalid handle!"); + } + } +#endif + } + + //--------------------------------------------------------------------- + void OLimitedFormats::getFormatKeyPropertyValue( Any& _rValue ) const + { + _rValue.clear(); + + OSL_ENSURE(m_xAggregate.is() && (-1 != m_nFormatEnumPropertyHandle), "OLimitedFormats::getFormatKeyPropertyValue: not initialized!"); + if (m_xAggregate.is()) + { + // get the aggregate's enum property value + Any aEnumPropertyValue = m_xAggregate->getFastPropertyValue(m_nFormatEnumPropertyHandle); + sal_Int32 nValue = -1; + ::cppu::enum2int(nValue, aEnumPropertyValue); + + // get the translation table + const FormatEntry* pFormats = lcl_getFormatTable(m_nTableId); + + // seek to the nValue'th entry + sal_Int32 nLookup = 0; + for ( ; + (NULL != pFormats->pDescription) && (nLookup < nValue); + ++pFormats, ++nLookup + ) + ; + OSL_ENSURE(NULL != pFormats->pDescription, "OLimitedFormats::getFormatKeyPropertyValue: did not find the value!"); + if (pFormats->pDescription) + _rValue <<= pFormats->nKey; + } + + // TODO: should use a standard format for the control type we're working for + } + + //--------------------------------------------------------------------- + sal_Bool OLimitedFormats::convertFormatKeyPropertyValue(Any& _rConvertedValue, Any& _rOldValue, const Any& _rNewValue) + { + OSL_ENSURE(m_xAggregate.is() && (-1 != m_nFormatEnumPropertyHandle), "OLimitedFormats::convertFormatKeyPropertyValue: not initialized!"); + + if (m_xAggregate.is()) + { + // the new format key to set + sal_Int32 nNewFormat = 0; + if (!(_rNewValue >>= nNewFormat)) + throw IllegalArgumentException(); + + // get the old (enum) value from the aggregate + Any aEnumPropertyValue = m_xAggregate->getFastPropertyValue(m_nFormatEnumPropertyHandle); + sal_Int32 nOldEnumValue = -1; + ::cppu::enum2int(nOldEnumValue, aEnumPropertyValue); + + // get the translation table + const FormatEntry* pFormats = lcl_getFormatTable(m_nTableId); + + _rOldValue.clear(); + _rConvertedValue.clear(); + + // look for the entry with the given format key + sal_Int32 nTablePosition = 0; + for ( ; + (NULL != pFormats->pDescription) && (nNewFormat != pFormats->nKey); + ++pFormats, ++nTablePosition + ) + { + if (nTablePosition == nOldEnumValue) + _rOldValue <<= pFormats->nKey; + } + + sal_Bool bFoundIt = (NULL != pFormats->pDescription); + sal_Bool bModified = sal_False; + if (bFoundIt) + { + _rConvertedValue <<= (sal_Int16)nTablePosition; + bModified = nTablePosition != nOldEnumValue; + } + + if (!_rOldValue.hasValue()) + { // did not reach the end of the table (means we found nNewFormat) + // -> go to the end to ensure that _rOldValue is set + while (pFormats->pDescription) + { + if (nTablePosition == nOldEnumValue) + { + _rOldValue <<= pFormats->nKey; + break; + } + + ++pFormats; + ++nTablePosition; + } + } + + OSL_ENSURE(_rOldValue.hasValue(), "OLimitedFormats::convertFormatKeyPropertyValue: did not find the old enum value in the table!"); + + if (!bFoundIt) + { // somebody gave us an format which we can't translate + ::rtl::OUString sMessage = ::rtl::OUString::createFromAscii("This control supports only a very limited number of formats."); + throw IllegalArgumentException(sMessage, NULL, 2); + } + + return bModified; + } + + return sal_False; + } + + //--------------------------------------------------------------------- + void OLimitedFormats::setFormatKeyPropertyValue( const Any& _rNewValue ) + { + OSL_ENSURE(m_xAggregate.is() && (-1 != m_nFormatEnumPropertyHandle), "OLimitedFormats::setFormatKeyPropertyValue: not initialized!"); + + if (m_xAggregate.is()) + { // this is to be called after convertFormatKeyPropertyValue, where + // we translated the format key into a enum value. + // So now we can simply forward this enum value to our aggreate + m_xAggregate->setFastPropertyValue(m_nFormatEnumPropertyHandle, _rNewValue); + } + } + + //--------------------------------------------------------------------- + void OLimitedFormats::acquireSupplier(const Reference< XMultiServiceFactory >& _rxORB) + { + ::osl::MutexGuard aGuard(s_aMutex); + if ((1 == ++s_nInstanceCount) && _rxORB.is()) + { // create the standard formatter + + Sequence< Any > aInit(1); + aInit[0] <<= getLocale(ltEnglishUS); + + Reference< XInterface > xSupplier = _rxORB->createInstanceWithArguments(FRM_NUMBER_FORMATS_SUPPLIER, aInit); + OSL_ENSURE(xSupplier.is(), "OLimitedFormats::OLimitedFormats: could not create a formats supplier!"); + + s_xStandardFormats = Reference< XNumberFormatsSupplier >(xSupplier, UNO_QUERY); + OSL_ENSURE(s_xStandardFormats.is() || !xSupplier.is(), "OLimitedFormats::OLimitedFormats: missing an interface!"); + } + } + + //--------------------------------------------------------------------- + void OLimitedFormats::releaseSupplier() + { + ::osl::MutexGuard aGuard(s_aMutex); + if (0 == --s_nInstanceCount) + { + ::comphelper::disposeComponent(s_xStandardFormats); + s_xStandardFormats = NULL; + + clearTable(FormComponentType::TIMEFIELD); + clearTable(FormComponentType::DATEFIELD); + } + } + +//......................................................................... +} // namespace frm +//......................................................................... + diff --git a/forms/source/misc/listenercontainers.cxx b/forms/source/misc/listenercontainers.cxx new file mode 100644 index 000000000000..db19ecacf866 --- /dev/null +++ b/forms/source/misc/listenercontainers.cxx @@ -0,0 +1,75 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: listenercontainers.cxx,v $ + * $Revision: 1.6 $ + * + * 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" + +#ifndef FORMS_SOURCE_MISC_LISTENERCONTAINERS_HXX +#include "listenercontainers.hxx" +#endif + +/** === begin UNO includes === **/ +/** === end UNO includes === **/ + +//........................................................................ +namespace frm +{ +//........................................................................ + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::form; + + //==================================================================== + //= ResetListeners + //==================================================================== + //--------------------------------------------------------------------- + bool ResetListeners::implTypedNotify( const Reference< XResetListener >& _rxListener, + const EventObject& _rEvent ) SAL_THROW( ( Exception ) ) + { + switch ( m_eCurrentNotificationType ) + { + case eApproval: + if ( !_rxListener->approveReset( _rEvent ) ) + return false; + return true; + case eFinal: + _rxListener->resetted( _rEvent ); + break; + default: + OSL_ENSURE( sal_False, "ResetListeners::implNotify: invalid notification type!" ); + } + return true; + } + +//........................................................................ +} // namespace frm +//........................................................................ + diff --git a/forms/source/misc/makefile.mk b/forms/source/misc/makefile.mk new file mode 100644 index 000000000000..b03109ba64d5 --- /dev/null +++ b/forms/source/misc/makefile.mk @@ -0,0 +1,64 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.10 $ +# +# 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=common + +ENABLE_EXCEPTIONS=TRUE +#TARGETTYPE=GUI + +# --- Settings ---------------------------------- + +.INCLUDE : settings.mk +.INCLUDE: $(PRJ)$/makefile.pmk + +# --- Types ------------------------------------- + +INCPRE+=$(SOLARINCDIR)$/offuh + +# --- Files ------------------------------------- + +SLOFILES= $(SLO)$/limitedformats.obj \ + $(SLO)$/property.obj \ + $(SLO)$/services.obj \ + $(SLO)$/InterfaceContainer.obj \ + $(SLO)$/ids.obj \ + $(SLO)$/frm_module.obj \ + $(SLO)$/frm_strings.obj \ + $(SLO)$/listenercontainers.obj \ + $(SLO)$/componenttools.obj \ + +# --- Targets ---------------------------------- + +.INCLUDE : target.mk + diff --git a/forms/source/misc/property.cxx b/forms/source/misc/property.cxx new file mode 100644 index 000000000000..12cc73e10264 --- /dev/null +++ b/forms/source/misc/property.cxx @@ -0,0 +1,260 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: property.cxx,v $ + * $Revision: 1.18 $ + * + * 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 "frm_strings.hxx" +#include "property.hxx" + +#ifndef _FRM_PROPERTY_HRC_ +#include "property.hrc" +#endif +#include <cppuhelper/queryinterface.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/beans/PropertyAttribute.hpp> + +#include <algorithm> + +//... namespace frm ....................................................... +namespace frm +{ +//......................................................................... + +//================================================================== +//= PropertyInfoService +//================================================================== +PropertyInfoService::PropertyMap PropertyInfoService::s_AllKnownProperties; +//------------------------------------------------------------------ +sal_Int32 PropertyInfoService::getPropertyId(const ::rtl::OUString& _rName) +{ + initialize(); + + PropertyAssignment aCompareName(_rName, -1); + + ::std::pair<PropertyMapIterator,PropertyMapIterator> aPair = equal_range( + s_AllKnownProperties.begin(), + s_AllKnownProperties.end(), + aCompareName, + PropertyAssignmentNameCompareLess()); + + sal_Int32 nHandle = -1; + if (aPair.first != aPair.second) + { // we found something _and_ we have an identity + nHandle = aPair.first->nHandle; + } + + return nHandle; +} + +//------------------------------------------------------------------ +sal_Int32 ConcreteInfoService::getPreferedPropertyId(const ::rtl::OUString& _rName) +{ + return PropertyInfoService::getPropertyId(_rName); +} + +//------------------------------------------------------------------ +#define ADD_PROP_ASSIGNMENT(varname) \ + s_AllKnownProperties.push_back(PropertyAssignment(PROPERTY_##varname, PROPERTY_ID_##varname)) +//.................................................................. +void PropertyInfoService::initialize() +{ + if (!s_AllKnownProperties.empty()) + return; + + s_AllKnownProperties.reserve(220); + + ADD_PROP_ASSIGNMENT(NAME); + ADD_PROP_ASSIGNMENT(TAG); + ADD_PROP_ASSIGNMENT(TABINDEX); + ADD_PROP_ASSIGNMENT(CLASSID); + ADD_PROP_ASSIGNMENT(ALIGN); + ADD_PROP_ASSIGNMENT(FETCHSIZE); + ADD_PROP_ASSIGNMENT(VALUE); + ADD_PROP_ASSIGNMENT(VALUEMIN); + ADD_PROP_ASSIGNMENT(VALUEMAX); + ADD_PROP_ASSIGNMENT(VALUESTEP); + ADD_PROP_ASSIGNMENT(TEXT); + ADD_PROP_ASSIGNMENT(LABEL); + ADD_PROP_ASSIGNMENT(NAVIGATION); + ADD_PROP_ASSIGNMENT(CYCLE); + ADD_PROP_ASSIGNMENT(CONTROLSOURCE); + ADD_PROP_ASSIGNMENT(ENABLED); + ADD_PROP_ASSIGNMENT(ENABLEVISIBLE); + ADD_PROP_ASSIGNMENT(SPIN); + ADD_PROP_ASSIGNMENT(READONLY); + ADD_PROP_ASSIGNMENT(FILTER); + ADD_PROP_ASSIGNMENT(WIDTH); + ADD_PROP_ASSIGNMENT(SEARCHABLE); + ADD_PROP_ASSIGNMENT(MULTILINE); + ADD_PROP_ASSIGNMENT(TARGET_URL); + ADD_PROP_ASSIGNMENT(DEFAULTCONTROL); + ADD_PROP_ASSIGNMENT(MAXTEXTLEN); + ADD_PROP_ASSIGNMENT(SIZE); + ADD_PROP_ASSIGNMENT(DATE); + ADD_PROP_ASSIGNMENT(TIME); + ADD_PROP_ASSIGNMENT(STATE); + ADD_PROP_ASSIGNMENT(TRISTATE); + ADD_PROP_ASSIGNMENT(HIDDEN_VALUE); + ADD_PROP_ASSIGNMENT(TARGET_FRAME); + ADD_PROP_ASSIGNMENT(BUTTONTYPE); + ADD_PROP_ASSIGNMENT(STRINGITEMLIST); + ADD_PROP_ASSIGNMENT(DEFAULT_TEXT); + ADD_PROP_ASSIGNMENT(DEFAULT_STATE); + ADD_PROP_ASSIGNMENT(DEFAULT_DATE); + ADD_PROP_ASSIGNMENT(DEFAULT_TIME); + ADD_PROP_ASSIGNMENT(DEFAULT_VALUE); + ADD_PROP_ASSIGNMENT(FORMATKEY); + ADD_PROP_ASSIGNMENT(FORMATSSUPPLIER); + ADD_PROP_ASSIGNMENT(SUBMIT_ACTION); + ADD_PROP_ASSIGNMENT(SUBMIT_TARGET); + ADD_PROP_ASSIGNMENT(SUBMIT_METHOD); + ADD_PROP_ASSIGNMENT(SUBMIT_ENCODING); + ADD_PROP_ASSIGNMENT(IMAGE_URL); + ADD_PROP_ASSIGNMENT(EMPTY_IS_NULL); + ADD_PROP_ASSIGNMENT(LISTSOURCETYPE); + ADD_PROP_ASSIGNMENT(LISTSOURCE); + ADD_PROP_ASSIGNMENT(SELECT_SEQ); + ADD_PROP_ASSIGNMENT(VALUE_SEQ); + ADD_PROP_ASSIGNMENT(DEFAULT_SELECT_SEQ); + ADD_PROP_ASSIGNMENT(MULTISELECTION); + ADD_PROP_ASSIGNMENT(DECIMAL_ACCURACY); + ADD_PROP_ASSIGNMENT(EDITMASK); + ADD_PROP_ASSIGNMENT(ISREADONLY); + ADD_PROP_ASSIGNMENT(FIELDTYPE); + ADD_PROP_ASSIGNMENT(DECIMALS); + ADD_PROP_ASSIGNMENT(REFVALUE); + ADD_PROP_ASSIGNMENT(STRICTFORMAT); + ADD_PROP_ASSIGNMENT(DATASOURCE); + ADD_PROP_ASSIGNMENT(ALLOWADDITIONS); + ADD_PROP_ASSIGNMENT(ALLOWEDITS); + ADD_PROP_ASSIGNMENT(ALLOWDELETIONS); + ADD_PROP_ASSIGNMENT(MASTERFIELDS); + ADD_PROP_ASSIGNMENT(ISPASSTHROUGH); + ADD_PROP_ASSIGNMENT(QUERY); + ADD_PROP_ASSIGNMENT(LITERALMASK); + ADD_PROP_ASSIGNMENT(SHOWTHOUSANDSEP); + ADD_PROP_ASSIGNMENT(CURRENCYSYMBOL); + ADD_PROP_ASSIGNMENT(DATEFORMAT); + ADD_PROP_ASSIGNMENT(DATEMIN); + ADD_PROP_ASSIGNMENT(DATEMAX); + ADD_PROP_ASSIGNMENT(DATE_SHOW_CENTURY); + ADD_PROP_ASSIGNMENT(TIMEFORMAT); + ADD_PROP_ASSIGNMENT(TIMEMIN); + ADD_PROP_ASSIGNMENT(TIMEMAX); + ADD_PROP_ASSIGNMENT(LINECOUNT); + ADD_PROP_ASSIGNMENT(BOUNDCOLUMN); + ADD_PROP_ASSIGNMENT(HASNAVIGATION); + ADD_PROP_ASSIGNMENT(FONT); + ADD_PROP_ASSIGNMENT(BACKGROUNDCOLOR); + ADD_PROP_ASSIGNMENT(FILLCOLOR); + ADD_PROP_ASSIGNMENT(TEXTCOLOR); + ADD_PROP_ASSIGNMENT(LINECOLOR); + ADD_PROP_ASSIGNMENT(BORDER); + ADD_PROP_ASSIGNMENT(DROPDOWN); + ADD_PROP_ASSIGNMENT(HSCROLL); + ADD_PROP_ASSIGNMENT(VSCROLL); + ADD_PROP_ASSIGNMENT(TABSTOP); + ADD_PROP_ASSIGNMENT(AUTOCOMPLETE); + ADD_PROP_ASSIGNMENT(HARDLINEBREAKS); + ADD_PROP_ASSIGNMENT(PRINTABLE); + ADD_PROP_ASSIGNMENT(ECHO_CHAR); + ADD_PROP_ASSIGNMENT(ROWHEIGHT); + ADD_PROP_ASSIGNMENT(HELPTEXT); + ADD_PROP_ASSIGNMENT(FONT_NAME); + ADD_PROP_ASSIGNMENT(FONT_STYLENAME); + ADD_PROP_ASSIGNMENT(FONT_FAMILY); + ADD_PROP_ASSIGNMENT(FONT_CHARSET); + ADD_PROP_ASSIGNMENT(FONT_HEIGHT); + ADD_PROP_ASSIGNMENT(FONT_WEIGHT); + ADD_PROP_ASSIGNMENT(FONT_SLANT); + ADD_PROP_ASSIGNMENT(FONT_UNDERLINE); + ADD_PROP_ASSIGNMENT(FONT_WORDLINEMODE); + ADD_PROP_ASSIGNMENT(FONT_STRIKEOUT); + ADD_PROP_ASSIGNMENT(TEXTLINECOLOR); + ADD_PROP_ASSIGNMENT(FONTEMPHASISMARK); + ADD_PROP_ASSIGNMENT(FONTRELIEF); + ADD_PROP_ASSIGNMENT(HELPURL); + ADD_PROP_ASSIGNMENT(RECORDMARKER); + ADD_PROP_ASSIGNMENT(BOUNDFIELD); + ADD_PROP_ASSIGNMENT(INPUT_REQUIRED); + ADD_PROP_ASSIGNMENT(TREATASNUMERIC); + ADD_PROP_ASSIGNMENT(EFFECTIVE_VALUE); + ADD_PROP_ASSIGNMENT(EFFECTIVE_DEFAULT); + ADD_PROP_ASSIGNMENT(EFFECTIVE_MIN); + ADD_PROP_ASSIGNMENT(EFFECTIVE_MAX); + ADD_PROP_ASSIGNMENT(HIDDEN); + ADD_PROP_ASSIGNMENT(FILTERPROPOSAL); + ADD_PROP_ASSIGNMENT(FIELDSOURCE); + ADD_PROP_ASSIGNMENT(TABLENAME); + ADD_PROP_ASSIGNMENT(CONTROLLABEL); + ADD_PROP_ASSIGNMENT(CURRSYM_POSITION); + ADD_PROP_ASSIGNMENT(CURSORCOLOR); + ADD_PROP_ASSIGNMENT(ALWAYSSHOWCURSOR); + ADD_PROP_ASSIGNMENT(DISPLAYSYNCHRON); + ADD_PROP_ASSIGNMENT(ISMODIFIED); + ADD_PROP_ASSIGNMENT(ISNEW); + ADD_PROP_ASSIGNMENT(PRIVILEGES); + ADD_PROP_ASSIGNMENT(DETAILFIELDS); + ADD_PROP_ASSIGNMENT(COMMAND); + ADD_PROP_ASSIGNMENT(COMMANDTYPE); + ADD_PROP_ASSIGNMENT(RESULTSET_CONCURRENCY); + ADD_PROP_ASSIGNMENT(INSERTONLY); + ADD_PROP_ASSIGNMENT(RESULTSET_TYPE); + ADD_PROP_ASSIGNMENT(ESCAPE_PROCESSING); + ADD_PROP_ASSIGNMENT(APPLYFILTER); + ADD_PROP_ASSIGNMENT(ISNULLABLE); + ADD_PROP_ASSIGNMENT(ACTIVECOMMAND); + ADD_PROP_ASSIGNMENT(ISCURRENCY); + ADD_PROP_ASSIGNMENT(URL); + ADD_PROP_ASSIGNMENT(TITLE); + ADD_PROP_ASSIGNMENT(ACTIVE_CONNECTION); + ADD_PROP_ASSIGNMENT(SCALE); + ADD_PROP_ASSIGNMENT(SORT); + ADD_PROP_ASSIGNMENT(PERSISTENCE_MAXTEXTLENGTH); + ADD_PROP_ASSIGNMENT(SCROLL_VALUE); + ADD_PROP_ASSIGNMENT(SPIN_VALUE); + ADD_PROP_ASSIGNMENT(DEFAULT_SCROLL_VALUE); + ADD_PROP_ASSIGNMENT(DEFAULT_SPIN_VALUE); + ADD_PROP_ASSIGNMENT( WRITING_MODE ); + ADD_PROP_ASSIGNMENT( CONTEXT_WRITING_MODE ); + + // now sort the array by name + + std::sort( + s_AllKnownProperties.begin(), + s_AllKnownProperties.end(), + PropertyAssignmentNameCompareLess() + ); +} + +//......................................................................... +} +//... namespace frm ....................................................... + diff --git a/forms/source/misc/services.cxx b/forms/source/misc/services.cxx new file mode 100644 index 000000000000..92c0ef90946b --- /dev/null +++ b/forms/source/misc/services.cxx @@ -0,0 +1,467 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: services.cxx,v $ + * $Revision: 1.29 $ + * + * 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 "services.hxx" +#include "frm_module.hxx" +#include <cppuhelper/factory.hxx> +#include <uno/lbnames.h> +#include <osl/diagnose.h> +#include <uno/mapping.hxx> + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::registry; + +//--------------------------------------------------------------------------------------- +//....................................................................................... +#define DECLARE_SERVICE_INFO(classImplName) \ + namespace frm { \ + extern ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> SAL_CALL classImplName##_CreateInstance(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory) throw (::com::sun::star::uno::RuntimeException); \ + } + +//--------------------------------------------------------------------------------------- +DECLARE_SERVICE_INFO(OFixedTextModel) +DECLARE_SERVICE_INFO(ORadioButtonModel) +DECLARE_SERVICE_INFO(ORadioButtonControl) +DECLARE_SERVICE_INFO(OCheckBoxModel) +DECLARE_SERVICE_INFO(OCheckBoxControl) +DECLARE_SERVICE_INFO(OHiddenModel) +DECLARE_SERVICE_INFO(OGroupBoxModel) +DECLARE_SERVICE_INFO(OGroupBoxControl) +DECLARE_SERVICE_INFO(OListBoxControl) +DECLARE_SERVICE_INFO(OListBoxModel) +DECLARE_SERVICE_INFO(OComboBoxControl) +DECLARE_SERVICE_INFO(OComboBoxModel) +DECLARE_SERVICE_INFO(OEditControl) +DECLARE_SERVICE_INFO(OEditModel) +DECLARE_SERVICE_INFO(ONumericControl) +DECLARE_SERVICE_INFO(ONumericModel) +DECLARE_SERVICE_INFO(OPatternControl) +DECLARE_SERVICE_INFO(OPatternModel) +DECLARE_SERVICE_INFO(OCurrencyControl) +DECLARE_SERVICE_INFO(OCurrencyModel) +DECLARE_SERVICE_INFO(ODateControl) +DECLARE_SERVICE_INFO(ODateModel) +DECLARE_SERVICE_INFO(OTimeControl) +DECLARE_SERVICE_INFO(OTimeModel) +DECLARE_SERVICE_INFO(OFormattedControl) +DECLARE_SERVICE_INFO(OFormattedModel) +DECLARE_SERVICE_INFO(OFileControlModel) +DECLARE_SERVICE_INFO(OButtonControl) +DECLARE_SERVICE_INFO(OButtonModel) +DECLARE_SERVICE_INFO(OImageButtonControl) +DECLARE_SERVICE_INFO(OImageButtonModel) + +DECLARE_SERVICE_INFO(OImageControlControl) +DECLARE_SERVICE_INFO(OImageControlModel) +DECLARE_SERVICE_INFO(OGridControlModel) + +// XForms objects +DECLARE_SERVICE_INFO(Binding) +DECLARE_SERVICE_INFO(Model) +DECLARE_SERVICE_INFO(XForms) + +// some special handling for the FormattedFieldWrapper which can act as FormattedModel or as EditModel +DECLARE_SERVICE_INFO(OFormattedFieldWrapper) + // this is for a service, which is instantiated through the EditModel service name + // and which acts mostly as Edit (mostly means : if somebody uses XPersistObject::read immediately after + // the object was instantiated and the stream contains a FormattedModel, it switches permanently to + // formatted.) +namespace frm { \ + extern Reference< XInterface > SAL_CALL OFormattedFieldWrapper_CreateInstance_ForceFormatted(const Reference<XMultiServiceFactory>& _rxFactory) throw (RuntimeException); \ +} + +DECLARE_SERVICE_INFO(OFormsCollection) +DECLARE_SERVICE_INFO(ImageProducer) + +//--------------------------------------------------------------------------------------- + +static Sequence< ::rtl::OUString > s_aClassImplementationNames; +static Sequence<Sequence< ::rtl::OUString > > s_aClassServiceNames; +static Sequence<sal_Int64> s_aFactories; + // need to use sal_Int64 instead of ComponentInstantiation, as ComponentInstantiation has no cppuType, so + // it can't be used with sequences + +//--------------------------------------------------------------------------------------- +void registerClassInfo( + ::rtl::OUString _rClassImplName, // the ImplName of the class + const Sequence< ::rtl::OUString >& _rServiceNames, // the services supported by this class + ::cppu::ComponentInstantiation _pCreateFunction // the method for instantiating such a class + ) +{ + sal_Int32 nCurrentLength = s_aClassImplementationNames.getLength(); + OSL_ENSURE((nCurrentLength == s_aClassServiceNames.getLength()) + && (nCurrentLength == s_aFactories.getLength()), + "forms::registerClassInfo : invalid class infos !"); + + s_aClassImplementationNames.realloc(nCurrentLength + 1); + s_aClassServiceNames.realloc(nCurrentLength + 1); + s_aFactories.realloc(nCurrentLength + 1); + + s_aClassImplementationNames.getArray()[nCurrentLength] = _rClassImplName; + s_aClassServiceNames.getArray()[nCurrentLength] = _rServiceNames; + s_aFactories.getArray()[nCurrentLength] = reinterpret_cast<sal_Int64>(_pCreateFunction); +} + +//--------------------------------------------------------------------------------------- +//....................................................................................... +#define REGISTER_CLASS_CORE(classImplName) \ + registerClassInfo( \ + ::rtl::OUString::createFromAscii("com.sun.star.form.") + ::rtl::OUString::createFromAscii(#classImplName), \ + aServices, \ + frm::classImplName##_CreateInstance) + +//....................................................................................... +#define REGISTER_CLASS1(classImplName, service1) \ + aServices.realloc(1); \ + aServices.getArray()[0] = frm::service1; \ + REGISTER_CLASS_CORE(classImplName) + +//....................................................................................... +#define REGISTER_CLASS2(classImplName, service1, service2) \ + aServices.realloc(2); \ + aServices.getArray()[0] = frm::service1; \ + aServices.getArray()[1] = frm::service2; \ + REGISTER_CLASS_CORE(classImplName) + +//....................................................................................... +#define REGISTER_CLASS3(classImplName, service1, service2, service3) \ + aServices.realloc(3); \ + aServices.getArray()[0] = frm::service1; \ + aServices.getArray()[1] = frm::service2; \ + aServices.getArray()[2] = frm::service3; \ + REGISTER_CLASS_CORE(classImplName) + +//....................................................................................... +#define REGISTER_CLASS4(classImplName, service1, service2, service3, service4) \ + aServices.realloc(4); \ + aServices.getArray()[0] = frm::service1; \ + aServices.getArray()[1] = frm::service2; \ + aServices.getArray()[2] = frm::service3; \ + aServices.getArray()[3] = frm::service4; \ + REGISTER_CLASS_CORE(classImplName) + +//--------------------------------------------------------------------------------------- +void ensureClassInfos() +{ + if (s_aClassImplementationNames.getLength()) + // nothing to do + return; + Sequence< ::rtl::OUString > aServices; + + // ======================================================================== + // = ControlModels + // ------------------------------------------------------------------------ + // - FixedText + REGISTER_CLASS2(OFixedTextModel, FRM_COMPONENT_FIXEDTEXT, FRM_SUN_COMPONENT_FIXEDTEXT); + // - Hidden + REGISTER_CLASS3(OHiddenModel, FRM_COMPONENT_HIDDENCONTROL, FRM_SUN_COMPONENT_HIDDENCONTROL, FRM_COMPONENT_HIDDEN); + // - FileControl + REGISTER_CLASS2(OFileControlModel, FRM_COMPONENT_FILECONTROL, FRM_SUN_COMPONENT_FILECONTROL); + // - ImageButton + REGISTER_CLASS2(OImageButtonModel, FRM_COMPONENT_IMAGEBUTTON, FRM_SUN_COMPONENT_IMAGEBUTTON); + // - GridControl + REGISTER_CLASS3(OGridControlModel, FRM_COMPONENT_GRID /* compatibility */, FRM_COMPONENT_GRIDCONTROL, FRM_SUN_COMPONENT_GRIDCONTROL); + // - GroupBox + REGISTER_CLASS2(OGroupBoxModel, FRM_COMPONENT_GROUPBOX, FRM_SUN_COMPONENT_GROUPBOX); + + // - RadioButton + REGISTER_CLASS4( ORadioButtonModel, FRM_COMPONENT_RADIOBUTTON, FRM_SUN_COMPONENT_RADIOBUTTON, FRM_SUN_COMPONENT_DATABASE_RADIOBUTTON, BINDABLE_DATABASE_RADIO_BUTTON ); + // - CheckBox + REGISTER_CLASS4( OCheckBoxModel, FRM_COMPONENT_CHECKBOX, FRM_SUN_COMPONENT_CHECKBOX, FRM_SUN_COMPONENT_DATABASE_CHECKBOX, BINDABLE_DATABASE_CHECK_BOX ); + // - ListBox + REGISTER_CLASS4( OListBoxModel, FRM_COMPONENT_LISTBOX, FRM_SUN_COMPONENT_LISTBOX, FRM_SUN_COMPONENT_DATABASE_LISTBOX, BINDABLE_DATABASE_LIST_BOX ); + // - ComboBox + REGISTER_CLASS4( OComboBoxModel, FRM_COMPONENT_COMBOBOX, FRM_SUN_COMPONENT_COMBOBOX, FRM_SUN_COMPONENT_DATABASE_COMBOBOX, BINDABLE_DATABASE_COMBO_BOX ); + // - EditControl + REGISTER_CLASS4( OEditModel, FRM_COMPONENT_TEXTFIELD, FRM_SUN_COMPONENT_TEXTFIELD, FRM_SUN_COMPONENT_DATABASE_TEXTFIELD, BINDABLE_DATABASE_TEXT_FIELD ); + // - DateControl + REGISTER_CLASS3( ODateModel, FRM_COMPONENT_DATEFIELD, FRM_SUN_COMPONENT_DATEFIELD, FRM_SUN_COMPONENT_DATABASE_DATEFIELD ); + // - TimeControl + REGISTER_CLASS3( OTimeModel, FRM_COMPONENT_TIMEFIELD, FRM_SUN_COMPONENT_TIMEFIELD, FRM_SUN_COMPONENT_DATABASE_TIMEFIELD ); + // - NumericField + REGISTER_CLASS4( ONumericModel, FRM_COMPONENT_NUMERICFIELD, FRM_SUN_COMPONENT_NUMERICFIELD, FRM_SUN_COMPONENT_DATABASE_NUMERICFIELD, BINDABLE_DATABASE_NUMERIC_FIELD ); + // - CurrencyField + REGISTER_CLASS3( OCurrencyModel, FRM_COMPONENT_CURRENCYFIELD, FRM_SUN_COMPONENT_CURRENCYFIELD, FRM_SUN_COMPONENT_DATABASE_CURRENCYFIELD ); + // - PatternField + REGISTER_CLASS3( OPatternModel, FRM_COMPONENT_PATTERNFIELD, FRM_SUN_COMPONENT_PATTERNFIELD, FRM_SUN_COMPONENT_DATABASE_PATTERNFIELD ); + // - Button + REGISTER_CLASS2( OButtonModel, FRM_COMPONENT_COMMANDBUTTON, FRM_SUN_COMPONENT_COMMANDBUTTON ); + // - ImageControl + REGISTER_CLASS2( OImageControlModel, FRM_COMPONENT_IMAGECONTROL, FRM_SUN_COMPONENT_IMAGECONTROL ); + + // - FormattedField + REGISTER_CLASS1(OFormattedFieldWrapper, FRM_COMPONENT_EDIT); + // since SRC568 both OFormattedModel and OEditModel use FRM_COMPONENT_EDIT for persistence, + // and while reading a wrapper determines which kind of model it is + // register the wrapper for the FormattedField, as it handles the XPersistObject::write + // so that version <= 5.1 are able to read it + aServices.realloc(4); + aServices.getArray()[0] = frm::FRM_COMPONENT_FORMATTEDFIELD; + aServices.getArray()[1] = frm::FRM_SUN_COMPONENT_FORMATTEDFIELD; + aServices.getArray()[2] = frm::FRM_SUN_COMPONENT_DATABASE_FORMATTEDFIELD; + aServices.getArray()[3] = frm::BINDABLE_DATABASE_FORMATTED_FIELD; + + registerClassInfo(::rtl::OUString::createFromAscii("com.sun.star.comp.forms.OFormattedFieldWrapper_ForcedFormatted"), + aServices, + frm::OFormattedFieldWrapper_CreateInstance_ForceFormatted); + + // ======================================================================== + // = Controls + // - RadioButton + REGISTER_CLASS2(ORadioButtonControl, STARDIV_ONE_FORM_CONTROL_RADIOBUTTON, FRM_SUN_CONTROL_RADIOBUTTON); + // - CheckBox + REGISTER_CLASS2(OCheckBoxControl, STARDIV_ONE_FORM_CONTROL_CHECKBOX, FRM_SUN_CONTROL_CHECKBOX); + // - GroupBox + REGISTER_CLASS2(OGroupBoxControl, STARDIV_ONE_FORM_CONTROL_GROUPBOX, FRM_SUN_CONTROL_GROUPBOX); + // - ListBox + REGISTER_CLASS2(OListBoxControl, STARDIV_ONE_FORM_CONTROL_LISTBOX, FRM_SUN_CONTROL_LISTBOX); + // - ComboBox + REGISTER_CLASS2(OComboBoxControl, STARDIV_ONE_FORM_CONTROL_COMBOBOX, FRM_SUN_CONTROL_COMBOBOX); + // - EditControl + REGISTER_CLASS3(OEditControl, STARDIV_ONE_FORM_CONTROL_TEXTFIELD, FRM_SUN_CONTROL_TEXTFIELD, STARDIV_ONE_FORM_CONTROL_EDIT); + // - DateControl + REGISTER_CLASS2(ODateControl, STARDIV_ONE_FORM_CONTROL_DATEFIELD, FRM_SUN_CONTROL_DATEFIELD); + // - TimeControl + REGISTER_CLASS2(OTimeControl, STARDIV_ONE_FORM_CONTROL_TIMEFIELD, FRM_SUN_CONTROL_TIMEFIELD); + // - NumericField + REGISTER_CLASS2(ONumericControl, STARDIV_ONE_FORM_CONTROL_NUMERICFIELD, FRM_SUN_CONTROL_NUMERICFIELD); + // - CurrencyField + REGISTER_CLASS2(OCurrencyControl, STARDIV_ONE_FORM_CONTROL_CURRENCYFIELD, FRM_SUN_CONTROL_CURRENCYFIELD); + // - PatternField + REGISTER_CLASS2(OPatternControl, STARDIV_ONE_FORM_CONTROL_PATTERNFIELD, FRM_SUN_CONTROL_PATTERNFIELD); + // - FormattedField + REGISTER_CLASS2(OFormattedControl, STARDIV_ONE_FORM_CONTROL_FORMATTEDFIELD, FRM_SUN_CONTROL_FORMATTEDFIELD); + // - Button + REGISTER_CLASS2(OButtonControl, STARDIV_ONE_FORM_CONTROL_COMMANDBUTTON, FRM_SUN_CONTROL_COMMANDBUTTON); + // - ImageButton + REGISTER_CLASS2(OImageButtonControl, STARDIV_ONE_FORM_CONTROL_IMAGEBUTTON, FRM_SUN_CONTROL_IMAGEBUTTON); + // - ImageControl + REGISTER_CLASS2(OImageControlControl, STARDIV_ONE_FORM_CONTROL_IMAGECONTROL, FRM_SUN_CONTROL_IMAGECONTROL); + + + // ======================================================================== + // = various + REGISTER_CLASS1(OFormsCollection, FRM_SUN_FORMS_COLLECTION); + REGISTER_CLASS1(ImageProducer, SRV_AWT_IMAGEPRODUCER); + + // ======================================================================== + // = XForms core +#define REGISTER_XFORMS_CLASS(name) \ + aServices.realloc(1); \ + aServices.getArray()[0] = rtl::OUString::createFromAscii( "com.sun.star.xforms." #name ); \ + REGISTER_CLASS_CORE(name) + + REGISTER_XFORMS_CLASS(Model); + REGISTER_XFORMS_CLASS(XForms); + +} + +//--------------------------------------------------------------------------------------- +void registerServiceProvider(const ::rtl::OUString& _rServiceImplName, const Sequence< ::rtl::OUString >& _rServices, XRegistryKey* _pKey) +{ + ::rtl::OUString sMainKeyName = ::rtl::OUString::createFromAscii("/"); + sMainKeyName += _rServiceImplName; + sMainKeyName += ::rtl::OUString::createFromAscii("/UNO/SERVICES"); + Reference< XRegistryKey > xNewKey = _pKey->createKey(sMainKeyName); + OSL_ENSURE(xNewKey.is(), "forms::registerProvider : could not create a registry key !"); + if (!xNewKey.is()) + return; + + const ::rtl::OUString* pSupportedServices = _rServices.getConstArray(); + for (sal_Int32 i=0; i<_rServices.getLength(); ++i, ++pSupportedServices) + xNewKey->createKey(*pSupportedServices); +} + +//======================================================================================= +extern "C" +{ + +//--------------------------------------------------------------------------------------- +void SAL_CALL createRegistryInfo_ODatabaseForm(); +void SAL_CALL createRegistryInfo_OFilterControl(); +void SAL_CALL createRegistryInfo_OScrollBarModel(); +void SAL_CALL createRegistryInfo_OSpinButtonModel(); +void SAL_CALL createRegistryInfo_ONavigationBarModel(); +void SAL_CALL createRegistryInfo_ONavigationBarControl(); +void SAL_CALL createRegistryInfo_ORichTextModel(); +void SAL_CALL createRegistryInfo_ORichTextControl(); +void SAL_CALL createRegistryInfo_CLibxml2XFormsExtension(); +void SAL_CALL createRegistryInfo_FormOperations(); + +//--------------------------------------------------------------------------------------- +void SAL_CALL createRegistryInfo_FORMS() +{ + static sal_Bool bInit = sal_False; + if (!bInit) + { + createRegistryInfo_ODatabaseForm(); + createRegistryInfo_OFilterControl(); + createRegistryInfo_OScrollBarModel(); + createRegistryInfo_OSpinButtonModel(); + createRegistryInfo_ONavigationBarModel(); + createRegistryInfo_ONavigationBarControl(); + createRegistryInfo_ORichTextModel(); + createRegistryInfo_ORichTextControl(); + createRegistryInfo_CLibxml2XFormsExtension(); + createRegistryInfo_FormOperations(); + bInit = sal_True; + } +} + +//--------------------------------------------------------------------------------------- +SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment(const sal_Char** _ppEnvTypeName, uno_Environment** /*_ppEnv*/) +{ + *_ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +//--------------------------------------------------------------------------------------- +SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo(void* _pServiceManager, XRegistryKey* _pRegistryKey) +{ + if (_pRegistryKey) + { + try + { + // ======================================================================== + // the real way - use the OModule + createRegistryInfo_FORMS(); + if ( !::frm::OFormsModule::writeComponentInfos( + static_cast<XMultiServiceFactory*>( _pServiceManager ), + static_cast<XRegistryKey*>( _pRegistryKey ) ) + ) + return sal_False; + + // ======================================================================== + // a lot of stuff which is implemented "manually" here in this file + + // collect the class infos + ensureClassInfos(); + + // both our static sequences should have the same length ... + sal_Int32 nClasses = s_aClassImplementationNames.getLength(); + OSL_ENSURE(s_aClassServiceNames.getLength() == nClasses, + "forms::component_writeInfo : invalid class infos !"); + + // loop through the sequences and register the service providers + const ::rtl::OUString* pClasses = s_aClassImplementationNames.getConstArray(); + const Sequence< ::rtl::OUString >* pServices = s_aClassServiceNames.getConstArray(); + + for (sal_Int32 i=0; i<nClasses; ++i, ++pClasses, ++pServices) + registerServiceProvider(*pClasses, *pServices, _pRegistryKey); + + s_aClassImplementationNames.realloc(0); + s_aClassServiceNames.realloc(0); + s_aFactories.realloc(0); + + return sal_True; + } + catch ( InvalidRegistryException& ) + { + OSL_ENSURE(sal_False, "forms::component_writeInfo : InvalidRegistryException !"); + } + } + s_aClassImplementationNames.realloc(0); + s_aClassServiceNames.realloc(0); + s_aFactories.realloc(0); + return sal_False; +} + +//--------------------------------------------------------------------------------------- +SAL_DLLPUBLIC_EXPORT void* SAL_CALL component_getFactory(const sal_Char* _pImplName, XMultiServiceFactory* _pServiceManager, void* /*_pRegistryKey*/) +{ + if (!_pServiceManager || !_pImplName) + return NULL; + + // ======================================================================== + // a lot of stuff which is implemented "manually" here in this file + void* pRet = NULL; + + // collect the class infos + ensureClassInfos(); + + // both our static sequences should have the same length ... + sal_Int32 nClasses = s_aClassImplementationNames.getLength(); + OSL_ENSURE((s_aClassServiceNames.getLength() == nClasses) && + (s_aFactories.getLength() == nClasses), + "forms::component_writeInfo : invalid class infos !"); + + // loop through the sequences and register the service providers + const ::rtl::OUString* pClasses = s_aClassImplementationNames.getConstArray(); + const Sequence< ::rtl::OUString >* pServices = s_aClassServiceNames.getConstArray(); + const sal_Int64* pFunctionsAsInts = s_aFactories.getConstArray(); + + for (sal_Int32 i=0; i<nClasses; ++i, ++pClasses, ++pServices, ++pFunctionsAsInts) + { + if (rtl_ustr_ascii_compare(*pClasses, _pImplName) == 0) + { + ::cppu::ComponentInstantiation aCurrentCreateFunction = + reinterpret_cast< ::cppu::ComponentInstantiation>(*pFunctionsAsInts); + + Reference<XSingleServiceFactory> xFactory( + ::cppu::createSingleFactory( + _pServiceManager, + *pClasses, + aCurrentCreateFunction, + *pServices + ) + ); + if (xFactory.is()) + { + xFactory->acquire(); + pRet = xFactory.get(); + break; + } + } + } + + // ======================================================================== + // the real way - use the OModule + if ( !pRet ) + { + createRegistryInfo_FORMS(); + { + // let the module look for the component + Reference< XInterface > xRet; + xRet = ::frm::OFormsModule::getComponentFactory( + ::rtl::OUString::createFromAscii( _pImplName ), + static_cast< XMultiServiceFactory* >( _pServiceManager ) ); + + if ( xRet.is() ) + xRet->acquire(); + pRet = xRet.get(); + } + } + + return pRet; +} + +} |