summaryrefslogtreecommitdiff
path: root/svx/source/form/fmpgeimp.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svx/source/form/fmpgeimp.cxx')
-rw-r--r--svx/source/form/fmpgeimp.cxx739
1 files changed, 739 insertions, 0 deletions
diff --git a/svx/source/form/fmpgeimp.cxx b/svx/source/form/fmpgeimp.cxx
new file mode 100644
index 000000000000..3ade4bdd3091
--- /dev/null
+++ b/svx/source/form/fmpgeimp.cxx
@@ -0,0 +1,739 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include "svxerr.hxx"
+#include "fmpgeimp.hxx"
+#include "fmundo.hxx"
+#include "svx/fmtools.hxx"
+#include "fmprop.hrc"
+#include "fmservs.hxx"
+#include "fmobj.hxx"
+#include "formcontrolfactory.hxx"
+#include "svditer.hxx"
+#include "fmresids.hrc"
+#include "svx/dbtoolsclient.hxx"
+#include "treevisitor.hxx"
+
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/util/XCloneable.hpp>
+#include <com/sun/star/container/EnumerableMap.hpp>
+#include <com/sun/star/drawing/XControlShape.hpp>
+
+#include <sfx2/objsh.hxx>
+#include <svx/fmglob.hxx>
+#include <svx/fmpage.hxx>
+#include <svx/fmmodel.hxx>
+#include <tools/resid.hxx>
+#include <tools/diagnose_ex.h>
+#include <tools/shl.hxx>
+#include <vcl/stdtext.hxx>
+#include <svx/dialmgr.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/componentcontext.hxx>
+#include <comphelper/uno3.hxx>
+#include <comphelper/types.hxx>
+#include <unotools/streamwrap.hxx>
+#include <rtl/logfile.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::form;
+using ::com::sun::star::util::XCloneable;
+using ::com::sun::star::awt::XControlModel;
+using ::com::sun::star::container::XMap;
+using ::com::sun::star::container::EnumerableMap;
+using ::com::sun::star::drawing::XControlShape;
+using namespace ::svxform;
+
+DBG_NAME(FmFormPageImpl)
+//------------------------------------------------------------------------------
+FmFormPageImpl::FmFormPageImpl( FmFormPage& _rPage )
+ :m_rPage( _rPage )
+ ,m_bFirstActivation( sal_True )
+ ,m_bAttemptedFormCreation( false )
+ ,m_bInFind( false )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFormPageImpl::FmFormPageImpl" );
+ DBG_CTOR(FmFormPageImpl,NULL);
+}
+
+//------------------------------------------------------------------------------
+namespace
+{
+ typedef Reference< XInterface > FormComponent;
+
+ class FormComponentInfo
+ {
+ public:
+ size_t childCount( const FormComponent& _component ) const
+ {
+ Reference< XIndexAccess > xContainer( _component, UNO_QUERY );
+ if ( xContainer.is() )
+ return xContainer->getCount();
+ return 0;
+ }
+
+ FormComponent getChild( const FormComponent& _component, size_t _index ) const
+ {
+ Reference< XIndexAccess > xContainer( _component, UNO_QUERY_THROW );
+ return FormComponent( xContainer->getByIndex( _index ), UNO_QUERY );
+ }
+ };
+
+ typedef ::std::pair< FormComponent, FormComponent > FormComponentPair;
+
+ class FormHierarchyComparator
+ {
+ public:
+ FormHierarchyComparator()
+ {
+ }
+
+ size_t childCount( const FormComponentPair& _components ) const
+ {
+ size_t lhsCount = m_aComponentInfo.childCount( _components.first );
+ size_t rhsCount = m_aComponentInfo.childCount( _components.second );
+ if ( lhsCount != rhsCount )
+ throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Found inconsistent form component hierarchies (1)!" ) ), NULL );
+ return lhsCount;
+ }
+
+ FormComponentPair getChild( const FormComponentPair& _components, size_t _index ) const
+ {
+ return FormComponentPair(
+ m_aComponentInfo.getChild( _components.first, _index ),
+ m_aComponentInfo.getChild( _components.second, _index )
+ );
+ }
+ private:
+ FormComponentInfo m_aComponentInfo;
+ };
+
+ typedef ::std::map< Reference< XControlModel >, Reference< XControlModel >, ::comphelper::OInterfaceCompare< XControlModel > > MapControlModels;
+
+ class FormComponentAssignment
+ {
+ public:
+ FormComponentAssignment( MapControlModels& _out_controlModelMap )
+ :m_rControlModelMap( _out_controlModelMap )
+ {
+ }
+
+ void process( const FormComponentPair& _component )
+ {
+ Reference< XControlModel > lhsControlModel( _component.first, UNO_QUERY );
+ Reference< XControlModel > rhsControlModel( _component.second, UNO_QUERY );
+ if ( lhsControlModel.is() != rhsControlModel.is() )
+ throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Found inconsistent form component hierarchies (2)!" ) ), NULL );
+
+ if ( lhsControlModel.is() )
+ m_rControlModelMap[ lhsControlModel ] = rhsControlModel;
+ }
+
+ private:
+ MapControlModels& m_rControlModelMap;
+ };
+}
+
+//------------------------------------------------------------------------------
+FmFormPageImpl::FmFormPageImpl( FmFormPage& _rPage, const FmFormPageImpl& rImpl )
+ :m_rPage( _rPage )
+ ,m_bFirstActivation( sal_True )
+ ,m_bAttemptedFormCreation( false )
+{
+ DBG_CTOR(FmFormPageImpl,NULL);
+
+ // clone the Forms collection
+ Reference< XCloneable > xCloneable( const_cast< FmFormPageImpl& >( rImpl ).getForms( false ), UNO_QUERY );
+ if ( !xCloneable.is() )
+ {
+ // great, nothing to do
+ OSL_ENSURE( !const_cast< FmFormPageImpl& >( rImpl ).getForms( false ).is(), "FmFormPageImpl::FmFormPageImpl: a non-cloneable forms container!?" );
+ return;
+ }
+ try
+ {
+ m_xForms.set( xCloneable->createClone(), UNO_QUERY_THROW );
+
+ // create a mapping between the original control models and their clones
+ MapControlModels aModelAssignment;
+
+ typedef TreeVisitor< FormComponentPair, FormHierarchyComparator, FormComponentAssignment > FormComponentVisitor;
+ FormComponentVisitor aVisitor = FormComponentVisitor( FormHierarchyComparator() );
+
+ FormComponentAssignment aAssignmentProcessor( aModelAssignment );
+ aVisitor.process( FormComponentPair( xCloneable, m_xForms ), aAssignmentProcessor );
+
+ // assign the cloned models to their SdrObjects
+ SdrObjListIter aForeignIter( rImpl.m_rPage );
+ SdrObjListIter aOwnIter( m_rPage );
+
+ OSL_ENSURE( aForeignIter.IsMore() == aOwnIter.IsMore(), "FmFormPageImpl::FmFormPageImpl: inconsistent number of objects (1)!" );
+ while ( aForeignIter.IsMore() && aOwnIter.IsMore() )
+ {
+ FmFormObj* pForeignObj = dynamic_cast< FmFormObj* >( aForeignIter.Next() );
+ FmFormObj* pOwnObj = dynamic_cast< FmFormObj* >( aOwnIter.Next() );
+
+ bool bForeignIsForm = pForeignObj && ( pForeignObj->GetObjInventor() == FmFormInventor );
+ bool bOwnIsForm = pOwnObj && ( pOwnObj->GetObjInventor() == FmFormInventor );
+
+ if ( bForeignIsForm != bOwnIsForm )
+ {
+ OSL_ENSURE( false, "FmFormPageImpl::FmFormPageImpl: inconsistent ordering of objects!" );
+ // don't attempt to do further assignments, something's completely messed up
+ break;
+ }
+ if ( !bForeignIsForm )
+ // no form control -> next round
+ continue;
+
+ Reference< XControlModel > xForeignModel( pForeignObj->GetUnoControlModel() );
+ OSL_ENSURE( xForeignModel.is(), "FmFormPageImpl::FmFormPageImpl: control shape without control!" );
+ if ( !xForeignModel.is() )
+ // the SdrObject does not have a UNO Control Model. This is pathological, but well ... So the cloned
+ // SdrObject will also not have a UNO Control Model.
+ continue;
+
+ OSL_ENSURE( !pOwnObj->GetUnoControlModel().is(), "FmFormPageImpl::FmFormPageImpl: there already is a control model for the target object!" );
+
+ MapControlModels::const_iterator assignment = aModelAssignment.find( xForeignModel );
+ OSL_ENSURE( assignment != aModelAssignment.end(), "FmFormPageImpl::FmFormPageImpl: no clone found for this model!" );
+ if ( assignment == aModelAssignment.end() )
+ // the source SdrObject has a model, but it is not part of the model hierarchy in rImpl.getForms().
+ // Pathological, too ...
+ continue;
+
+ pOwnObj->SetUnoControlModel( assignment->second );
+ }
+ OSL_ENSURE( aForeignIter.IsMore() == aOwnIter.IsMore(), "FmFormPageImpl::FmFormPageImpl: inconsistent number of objects (2)!" );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+
+//------------------------------------------------------------------------------
+Reference< XMap > FmFormPageImpl::getControlToShapeMap()
+{
+ Reference< XMap > xControlShapeMap( m_aControlShapeMap.get(), UNO_QUERY );
+ if ( xControlShapeMap.is() )
+ return xControlShapeMap;
+
+ xControlShapeMap = impl_createControlShapeMap_nothrow();
+ m_aControlShapeMap = xControlShapeMap;
+ return xControlShapeMap;
+}
+
+//------------------------------------------------------------------------------
+namespace
+{
+ static void lcl_insertFormObject_throw( const FmFormObj& _object, const Reference< XMap >& _map )
+ {
+ // the control model
+ Reference< XControlModel > xControlModel( _object.GetUnoControlModel(), UNO_QUERY );
+ OSL_ENSURE( xControlModel.is(), "lcl_insertFormObject_throw: suspicious: no control model!" );
+ if ( !xControlModel.is() )
+ return;
+
+ Reference< XControlShape > xControlShape( const_cast< FmFormObj& >( _object ).getUnoShape(), UNO_QUERY );
+ OSL_ENSURE( xControlShape.is(), "lcl_insertFormObject_throw: suspicious: no control shape!" );
+ if ( !xControlShape.is() )
+ return;
+
+ _map->put( makeAny( xControlModel ), makeAny( xControlShape ) );
+ }
+
+ static void lcl_removeFormObject( const FmFormObj& _object, const Reference< XMap >& _map )
+ {
+ // the control model
+ Reference< XControlModel > xControlModel( _object.GetUnoControlModel(), UNO_QUERY );
+ OSL_ENSURE( xControlModel.is(), "lcl_removeFormObject: suspicious: no control model!" );
+ if ( !xControlModel.is() )
+ return;
+
+ #if OSL_DEBUG_LEVEL > 0
+ Any aOldAssignment =
+ #endif
+ _map->remove( makeAny( xControlModel ) );
+ OSL_ENSURE( aOldAssignment == makeAny( Reference< XControlShape >( const_cast< FmFormObj& >( _object ).getUnoShape(), UNO_QUERY ) ),
+ "lcl_removeFormObject: map was inconsistent!" );
+ }
+}
+
+//------------------------------------------------------------------------------
+Reference< XMap > FmFormPageImpl::impl_createControlShapeMap_nothrow()
+{
+ Reference< XMap > xMap;
+
+ try
+ {
+ ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
+ xMap.set( EnumerableMap::create( aContext.getUNOContext(),
+ ::cppu::UnoType< XControlModel >::get(),
+ ::cppu::UnoType< XControlShape >::get()
+ ).get(), UNO_SET_THROW );
+
+ SdrObjListIter aPageIter( m_rPage );
+ while ( aPageIter.IsMore() )
+ {
+ // only FmFormObjs are what we're interested in
+ FmFormObj* pCurrent = FmFormObj::GetFormObject( aPageIter.Next() );
+ if ( !pCurrent )
+ continue;
+
+ lcl_insertFormObject_throw( *pCurrent, xMap );
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return xMap;
+}
+
+//------------------------------------------------------------------------------
+const Reference< XNameContainer >& FmFormPageImpl::getForms( bool _bForceCreate )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFormPageImpl::getForms" );
+ if ( m_xForms.is() || !_bForceCreate )
+ return m_xForms;
+
+ if ( !m_bAttemptedFormCreation )
+ {
+ m_bAttemptedFormCreation = true;
+
+ const ::rtl::OUString sFormsCollectionServiceName = ::rtl::OUString::createFromAscii("com.sun.star.form.Forms");
+ m_xForms = Reference< XNameContainer > (
+ ::comphelper::getProcessServiceFactory()->createInstance( sFormsCollectionServiceName ),
+ UNO_QUERY
+ );
+ DBG_ASSERT( m_xForms.is(), "FmFormPageImpl::getForms: could not create a forms collection!" );
+
+ if ( m_aFormsCreationHdl.IsSet() )
+ {
+ m_aFormsCreationHdl.Call( this );
+ }
+
+ FmFormModel* pFormsModel = PTR_CAST( FmFormModel, m_rPage.GetModel() );
+
+ // give the newly created collection a place in the universe
+ Reference< XChild > xAsChild( m_xForms, UNO_QUERY );
+ if ( xAsChild.is() )
+ {
+ SfxObjectShell* pObjShell = pFormsModel ? pFormsModel->GetObjectShell() : NULL;
+ if ( pObjShell )
+ xAsChild->setParent( pObjShell->GetModel() );
+ }
+
+ // tell the UNDO environment that we have a new forms collection
+ if ( pFormsModel )
+ pFormsModel->GetUndoEnv().AddForms( m_xForms );
+ }
+ return m_xForms;
+}
+
+//------------------------------------------------------------------------------
+FmFormPageImpl::~FmFormPageImpl()
+{
+ xCurrentForm = NULL;
+
+ ::comphelper::disposeComponent( m_xForms );
+ DBG_DTOR(FmFormPageImpl,NULL);
+}
+
+//------------------------------------------------------------------------------
+bool FmFormPageImpl::validateCurForm()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFormPageImpl::validateCurForm" );
+ if ( !xCurrentForm.is() )
+ return false;
+
+ Reference< XChild > xAsChild( xCurrentForm, UNO_QUERY );
+ DBG_ASSERT( xAsChild.is(), "FmFormPageImpl::validateCurForm: a form which is no child??" );
+ if ( !xAsChild.is() || !xAsChild->getParent().is() )
+ xCurrentForm.clear();
+
+ return xCurrentForm.is();
+}
+
+//------------------------------------------------------------------------------
+void FmFormPageImpl::setCurForm(Reference< ::com::sun::star::form::XForm > xForm)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFormPageImpl::setCurForm" );
+ xCurrentForm = xForm;
+}
+
+//------------------------------------------------------------------------------
+Reference< XForm > FmFormPageImpl::getDefaultForm()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFormPageImpl::getDefaultForm" );
+ Reference< XForm > xForm;
+
+ Reference< XNameContainer > xForms( getForms() );
+
+ // by default, we use our "current form"
+ if ( !validateCurForm() )
+ {
+ // check whether there is a "standard" form
+ if ( xForms->hasElements() )
+ {
+ // suche die Standardform
+ ::rtl::OUString sStandardFormname = String( SVX_RES( RID_STR_STDFORMNAME ) );
+
+ try
+ {
+ if ( xForms->hasByName( sStandardFormname ) )
+ xForm.set( xForms->getByName( sStandardFormname ), UNO_QUERY_THROW );
+ else
+ {
+ Reference< XIndexAccess > xFormsByIndex( xForms, UNO_QUERY_THROW );
+ xForm.set( xFormsByIndex->getByIndex(0), UNO_QUERY_THROW );
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+ }
+ else
+ {
+ xForm = xCurrentForm;
+ }
+
+ // did not find an existing suitable form -> create a new one
+ if ( !xForm.is() )
+ {
+ SdrModel* pModel = m_rPage.GetModel();
+
+ if( pModel->IsUndoEnabled() )
+ {
+ XubString aStr(SVX_RES(RID_STR_FORM));
+ XubString aUndoStr(SVX_RES(RID_STR_UNDO_CONTAINER_INSERT));
+ aUndoStr.SearchAndReplace('#', aStr);
+ pModel->BegUndo(aUndoStr);
+ }
+
+ try
+ {
+ xForm.set( ::comphelper::getProcessServiceFactory()->createInstance( FM_SUN_COMPONENT_FORM ), UNO_QUERY );
+
+ // a form should always have the command type table as default
+ Reference< XPropertySet > xFormProps( xForm, UNO_QUERY_THROW );
+ xFormProps->setPropertyValue( FM_PROP_COMMANDTYPE, makeAny( sal_Int32( CommandType::TABLE ) ) );
+
+ // and the "Standard" name
+ ::rtl::OUString sName = String( SVX_RES( RID_STR_STDFORMNAME ) );
+ xFormProps->setPropertyValue( FM_PROP_NAME, makeAny( sName ) );
+
+ Reference< XIndexContainer > xContainer( xForms, UNO_QUERY );
+ if( pModel->IsUndoEnabled() )
+ {
+ pModel->AddUndo(new FmUndoContainerAction(*(FmFormModel*)pModel,
+ FmUndoContainerAction::Inserted,
+ xContainer,
+ xForm,
+ xContainer->getCount()));
+ }
+ xForms->insertByName( sName, makeAny( xForm ) );
+ xCurrentForm = xForm;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ xForm.clear();
+ }
+
+ if( pModel->IsUndoEnabled() )
+ pModel->EndUndo();
+ }
+
+ return xForm;
+}
+
+//------------------------------------------------------------------------------
+Reference< ::com::sun::star::form::XForm > FmFormPageImpl::findPlaceInFormComponentHierarchy(
+ const Reference< XFormComponent > & rContent, const Reference< XDataSource > & rDatabase,
+ const ::rtl::OUString& rDBTitle, const ::rtl::OUString& rCursorSource, sal_Int32 nCommandType )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFormPageImpl::findPlaceInFormComponentHierarchy" );
+ // if the control already is child of a form, don't do anything
+ if (!rContent.is() || rContent->getParent().is())
+ return NULL;
+
+ Reference< XForm > xForm;
+
+ // Wenn Datenbank und CursorSource gesetzt sind, dann wird
+ // die Form anhand dieser Kriterien gesucht, ansonsten nur aktuelle
+ // und die StandardForm
+ if (rDatabase.is() && rCursorSource.getLength())
+ {
+ validateCurForm();
+
+ // erst in der aktuellen form suchen
+ xForm = findFormForDataSource( xCurrentForm, rDatabase, rCursorSource, nCommandType );
+
+ Reference< ::com::sun::star::container::XIndexAccess > xFormsByIndex( getForms(), UNO_QUERY );
+ DBG_ASSERT(xFormsByIndex.is(), "FmFormPageImpl::findPlaceInFormComponentHierarchy : no index access for my forms collection !");
+ sal_Int32 nCount = xFormsByIndex->getCount();
+ for (sal_Int32 i = 0; !xForm.is() && i < nCount; i++)
+ {
+ Reference< ::com::sun::star::form::XForm > xToSearch;
+ xFormsByIndex->getByIndex(i) >>= xToSearch;
+ xForm = findFormForDataSource( xToSearch, rDatabase, rCursorSource, nCommandType );
+ }
+
+ // wenn keine ::com::sun::star::form gefunden, dann eine neue erzeugen
+ if (!xForm.is())
+ {
+ SdrModel* pModel = m_rPage.GetModel();
+
+ const bool bUndo = pModel->IsUndoEnabled();
+
+ if( bUndo )
+ {
+ XubString aStr(SVX_RES(RID_STR_FORM));
+ XubString aUndoStr(SVX_RES(RID_STR_UNDO_CONTAINER_INSERT));
+ aUndoStr.SearchAndReplace('#', aStr);
+ pModel->BegUndo(aUndoStr);
+ }
+
+ xForm = Reference< ::com::sun::star::form::XForm >(::comphelper::getProcessServiceFactory()->createInstance(FM_SUN_COMPONENT_FORM), UNO_QUERY);
+ // a form should always have the command type table as default
+ Reference< ::com::sun::star::beans::XPropertySet > xFormProps(xForm, UNO_QUERY);
+ try { xFormProps->setPropertyValue(FM_PROP_COMMANDTYPE, makeAny(sal_Int32(CommandType::TABLE))); }
+ catch(Exception&) { }
+
+ if (rDBTitle.getLength())
+ xFormProps->setPropertyValue(FM_PROP_DATASOURCE,makeAny(rDBTitle));
+ else
+ {
+ Reference< ::com::sun::star::beans::XPropertySet > xDatabaseProps(rDatabase, UNO_QUERY);
+ Any aDatabaseUrl = xDatabaseProps->getPropertyValue(FM_PROP_URL);
+ xFormProps->setPropertyValue(FM_PROP_DATASOURCE, aDatabaseUrl);
+ }
+
+ xFormProps->setPropertyValue(FM_PROP_COMMAND,makeAny(rCursorSource));
+ xFormProps->setPropertyValue(FM_PROP_COMMANDTYPE, makeAny(nCommandType));
+
+ Reference< ::com::sun::star::container::XNameAccess > xNamedSet( getForms(), UNO_QUERY );
+
+ const bool bTableOrQuery = ( CommandType::TABLE == nCommandType ) || ( CommandType::QUERY == nCommandType );
+ ::rtl::OUString sName = FormControlFactory::getUniqueName( xNamedSet,
+ bTableOrQuery ? rCursorSource : ::rtl::OUString( String( SVX_RES( RID_STR_STDFORMNAME ) ) ) );
+
+ xFormProps->setPropertyValue( FM_PROP_NAME, makeAny( sName ) );
+
+ if( bUndo )
+ {
+ Reference< ::com::sun::star::container::XIndexContainer > xContainer( getForms(), UNO_QUERY );
+ pModel->AddUndo(new FmUndoContainerAction(*(FmFormModel*)pModel,
+ FmUndoContainerAction::Inserted,
+ xContainer,
+ xForm,
+ xContainer->getCount()));
+ }
+
+ getForms()->insertByName( sName, makeAny( xForm ) );
+
+ if( bUndo )
+ pModel->EndUndo();
+ }
+ xCurrentForm = xForm;
+ }
+
+ xForm = getDefaultForm();
+ return xForm;
+}
+
+//------------------------------------------------------------------------------
+Reference< XForm > FmFormPageImpl::findFormForDataSource(
+ const Reference< XForm > & rForm, const Reference< XDataSource > & _rxDatabase,
+ const ::rtl::OUString& _rCursorSource, sal_Int32 nCommandType)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFormPageImpl::findFormForDataSource" );
+ Reference< XForm > xResultForm;
+ Reference< XRowSet > xDBForm(rForm, UNO_QUERY);
+ Reference< XPropertySet > xFormProps(rForm, UNO_QUERY);
+ if (!xDBForm.is() || !xFormProps.is())
+ return xResultForm;
+
+ OSL_ENSURE(_rxDatabase.is(), "FmFormPageImpl::findFormForDataSource: invalid data source!");
+ ::rtl::OUString sLookupName; // the name of the data source we're looking for
+ ::rtl::OUString sFormDataSourceName; // the name of the data source the current connection in the form is based on
+ try
+ {
+ Reference< XPropertySet > xDSProps(_rxDatabase, UNO_QUERY);
+ if (xDSProps.is())
+ xDSProps->getPropertyValue(FM_PROP_NAME) >>= sLookupName;
+
+ xFormProps->getPropertyValue(FM_PROP_DATASOURCE) >>= sFormDataSourceName;
+ // if there's no DataSourceName set at the form, check whether we can deduce one from its
+ // ActiveConnection
+ if (0 == sFormDataSourceName.getLength())
+ {
+ Reference< XConnection > xFormConnection;
+ xFormProps->getPropertyValue( FM_PROP_ACTIVE_CONNECTION ) >>= xFormConnection;
+ if ( !xFormConnection.is() )
+ OStaticDataAccessTools().isEmbeddedInDatabase( xFormProps, xFormConnection );
+ if (xFormConnection.is())
+ {
+ Reference< XChild > xConnAsChild(xFormConnection, UNO_QUERY);
+ if (xConnAsChild.is())
+ {
+ Reference< XDataSource > xFormDS(xConnAsChild->getParent(), UNO_QUERY);
+ if (xFormDS.is())
+ {
+ xDSProps = xDSProps.query(xFormDS);
+ if (xDSProps.is())
+ xDSProps->getPropertyValue(FM_PROP_NAME) >>= sFormDataSourceName;
+ }
+ }
+ }
+ }
+ }
+ catch(const Exception& e)
+ {
+ (void)e;
+ OSL_ENSURE(sal_False, "FmFormPageImpl::findFormForDataSource: caught an exception!");
+ }
+
+ if (sLookupName == sFormDataSourceName)
+ {
+ // jetzt noch ueberpruefen ob CursorSource und Type uebereinstimmen
+ ::rtl::OUString aCursorSource = ::comphelper::getString(xFormProps->getPropertyValue(FM_PROP_COMMAND));
+ sal_Int32 nType = ::comphelper::getINT32(xFormProps->getPropertyValue(FM_PROP_COMMANDTYPE));
+ if (!aCursorSource.getLength() || ((nType == nCommandType) && (aCursorSource == _rCursorSource))) // found the form
+ {
+ xResultForm = rForm;
+ // Ist noch keine Datenquelle gesetzt, wird dieses hier nachgeholt
+ if (!aCursorSource.getLength())
+ {
+ xFormProps->setPropertyValue(FM_PROP_COMMAND, makeAny(_rCursorSource));
+ xFormProps->setPropertyValue(FM_PROP_COMMANDTYPE, makeAny((sal_Int32)nCommandType));
+ }
+ }
+ }
+
+ // as long as xResultForm is NULL, search the child forms of rForm
+ Reference< XIndexAccess > xComponents(rForm, UNO_QUERY);
+ sal_Int32 nCount = xComponents->getCount();
+ for (sal_Int32 i = 0; !xResultForm.is() && i < nCount; ++i)
+ {
+ Reference< ::com::sun::star::form::XForm > xSearchForm;
+ xComponents->getByIndex(i) >>= xSearchForm;
+ // continue searching in the sub form
+ if (xSearchForm.is())
+ xResultForm = findFormForDataSource( xSearchForm, _rxDatabase, _rCursorSource, nCommandType );
+ }
+ return xResultForm;
+}
+
+//------------------------------------------------------------------------------
+::rtl::OUString FmFormPageImpl::setUniqueName(const Reference< XFormComponent > & xFormComponent, const Reference< XForm > & xControls)
+{
+#if OSL_DEBUG_LEVEL > 0
+ try
+ {
+ Reference< XChild > xChild( xFormComponent, UNO_QUERY_THROW );
+ OSL_ENSURE( !xChild->getParent().is(), "FmFormPageImpl::setUniqueName: to be called before insertion!" );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+#endif
+ ::rtl::OUString sName;
+ Reference< ::com::sun::star::beans::XPropertySet > xSet(xFormComponent, UNO_QUERY);
+ if (xSet.is())
+ {
+ sName = ::comphelper::getString( xSet->getPropertyValue( FM_PROP_NAME ) );
+ Reference< ::com::sun::star::container::XNameAccess > xNameAcc(xControls, UNO_QUERY);
+
+ if (!sName.getLength() || xNameAcc->hasByName(sName))
+ {
+ // setzen eines default Namens ueber die ClassId
+ sal_Int16 nClassId( FormComponentType::CONTROL );
+ xSet->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId;
+
+ ::rtl::OUString sDefaultName = FormControlFactory::getDefaultUniqueName_ByComponentType(
+ Reference< XNameAccess >( xControls, UNO_QUERY ), xSet );
+
+ // bei Radiobuttons, die einen Namen haben, diesen nicht ueberschreiben!
+ if (!sName.getLength() || nClassId != ::com::sun::star::form::FormComponentType::RADIOBUTTON)
+ {
+ xSet->setPropertyValue(FM_PROP_NAME, makeAny(sDefaultName));
+ }
+
+ sName = sDefaultName;
+ }
+ }
+ return sName;
+}
+
+//------------------------------------------------------------------
+void FmFormPageImpl::formObjectInserted( const FmFormObj& _object )
+{
+ Reference< XMap > xControlShapeMap( m_aControlShapeMap.get(), UNO_QUERY );
+ if ( !xControlShapeMap.is() )
+ // our map does not exist -> not interested in this event
+ return;
+
+ try
+ {
+ lcl_insertFormObject_throw( _object, xControlShapeMap );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+
+void FmFormPageImpl::formObjectRemoved( const FmFormObj& _object )
+{
+ Reference< XMap > xControlShapeMap( m_aControlShapeMap.get(), UNO_QUERY );
+ if ( !xControlShapeMap.is() )
+ // our map does not exist -> not interested in this event
+ return;
+
+ try
+ {
+ lcl_removeFormObject( _object, xControlShapeMap );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}