summaryrefslogtreecommitdiff
path: root/svx/source/form/fmobj.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svx/source/form/fmobj.cxx')
-rw-r--r--svx/source/form/fmobj.cxx736
1 files changed, 736 insertions, 0 deletions
diff --git a/svx/source/form/fmobj.cxx b/svx/source/form/fmobj.cxx
new file mode 100644
index 000000000000..e679779887a2
--- /dev/null
+++ b/svx/source/form/fmobj.cxx
@@ -0,0 +1,736 @@
+/*************************************************************************
+ *
+ * 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 "fmobj.hxx"
+#include "fmprop.hrc"
+#include "fmvwimp.hxx"
+#include "fmpgeimp.hxx"
+#include "fmresids.hrc"
+#include "svx/fmview.hxx"
+#include "svx/fmglob.hxx"
+#include "svx/fmpage.hxx"
+#include "editeng/editeng.hxx"
+#include "svx/svdovirt.hxx"
+#include "svx/fmmodel.hxx"
+#include "svx/dialmgr.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/script/XEventAttacherManager.hpp>
+#include <com/sun/star/io/XPersistObject.hpp>
+#include <com/sun/star/awt/XControlContainer.hpp>
+#include <com/sun/star/util/XCloneable.hpp>
+/** === end UNO includes === **/
+#include "svx/fmtools.hxx"
+
+#include <tools/shl.hxx>
+#include <comphelper/property.hxx>
+#include <comphelper/processfactory.hxx>
+#include <toolkit/awt/vclxdevice.hxx>
+#include <vcl/svapp.hxx>
+#include <tools/resmgr.hxx>
+#include <tools/diagnose_ex.h>
+
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::form;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::script;
+using namespace ::com::sun::star::container;
+using namespace ::svxform;
+
+TYPEINIT1(FmFormObj, SdrUnoObj);
+DBG_NAME(FmFormObj);
+//------------------------------------------------------------------
+FmFormObj::FmFormObj(const ::rtl::OUString& rModelName,sal_Int32 _nType)
+ :SdrUnoObj ( rModelName )
+ ,m_nPos ( -1 )
+ ,m_nType ( _nType )
+ ,m_pLastKnownRefDevice ( NULL )
+{
+ DBG_CTOR(FmFormObj, NULL);
+
+ // normally, this is done in SetUnoControlModel, but if the call happened in the base class ctor,
+ // then our incarnation of it was not called (since we were not constructed at this time).
+ impl_checkRefDevice_nothrow( true );
+}
+
+//------------------------------------------------------------------
+FmFormObj::FmFormObj( sal_Int32 _nType )
+ :SdrUnoObj ( String() )
+ ,m_nPos ( -1 )
+ ,m_nType ( _nType )
+ ,m_pLastKnownRefDevice ( NULL )
+{
+ DBG_CTOR(FmFormObj, NULL);
+}
+
+//------------------------------------------------------------------
+FmFormObj::~FmFormObj()
+{
+ DBG_DTOR(FmFormObj, NULL);
+
+ Reference< XComponent> xHistory(m_xEnvironmentHistory, UNO_QUERY);
+ if (xHistory.is())
+ xHistory->dispose();
+
+ m_xEnvironmentHistory = NULL;
+ m_aEventsHistory.realloc(0);
+}
+
+//------------------------------------------------------------------
+void FmFormObj::SetObjEnv(const Reference< XIndexContainer > & xForm, const sal_Int32 nIdx,
+ const Sequence< ScriptEventDescriptor >& rEvts)
+{
+ m_xParent = xForm;
+ aEvts = rEvts;
+ m_nPos = nIdx;
+}
+
+//------------------------------------------------------------------
+void FmFormObj::ClearObjEnv()
+{
+ m_xParent.clear();
+ aEvts.realloc( 0 );
+ m_nPos = -1;
+}
+
+//------------------------------------------------------------------
+void FmFormObj::impl_checkRefDevice_nothrow( bool _force )
+{
+ const FmFormModel* pFormModel = PTR_CAST( FmFormModel, GetModel() );
+ if ( !pFormModel || !pFormModel->ControlsUseRefDevice() )
+ return;
+
+ OutputDevice* pCurrentRefDevice = pFormModel ? pFormModel->GetRefDevice() : NULL;
+ if ( ( m_pLastKnownRefDevice == pCurrentRefDevice ) && !_force )
+ return;
+
+ Reference< XControlModel > xControlModel( GetUnoControlModel() );
+ if ( !xControlModel.is() )
+ return;
+
+ m_pLastKnownRefDevice = pCurrentRefDevice;
+ if ( m_pLastKnownRefDevice == NULL )
+ return;
+
+ try
+ {
+ Reference< XPropertySet > xModelProps( GetUnoControlModel(), UNO_QUERY_THROW );
+ Reference< XPropertySetInfo > xPropertyInfo( xModelProps->getPropertySetInfo(), UNO_SET_THROW );
+
+ static const ::rtl::OUString sRefDevicePropName( RTL_CONSTASCII_USTRINGPARAM( "ReferenceDevice" ) );
+ if ( xPropertyInfo->hasPropertyByName( sRefDevicePropName ) )
+ {
+ VCLXDevice* pUnoRefDevice = new VCLXDevice;
+ pUnoRefDevice->SetOutputDevice( m_pLastKnownRefDevice );
+ Reference< XDevice > xRefDevice( pUnoRefDevice );
+ xModelProps->setPropertyValue( sRefDevicePropName, makeAny( xRefDevice ) );
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+
+//------------------------------------------------------------------
+void FmFormObj::impl_isolateControlModel_nothrow()
+{
+ try
+ {
+ Reference< XChild > xControlModel( GetUnoControlModel(), UNO_QUERY );
+ if ( xControlModel.is() )
+ {
+ Reference< XIndexContainer> xParent( xControlModel->getParent(), UNO_QUERY );
+ if ( xParent.is() )
+ {
+ sal_Int32 nPos = getElementPos( xParent.get(), xControlModel );
+ xParent->removeByIndex( nPos );
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+
+//------------------------------------------------------------------
+void FmFormObj::SetPage(SdrPage* _pNewPage)
+{
+ if ( GetPage() == _pNewPage )
+ {
+ SdrUnoObj::SetPage(_pNewPage);
+ return;
+ }
+
+ FmFormPage* pOldFormPage = PTR_CAST( FmFormPage, GetPage() );
+ if ( pOldFormPage )
+ pOldFormPage->GetImpl().formObjectRemoved( *this );
+
+ FmFormPage* pNewFormPage = PTR_CAST( FmFormPage, _pNewPage );
+ if ( !pNewFormPage )
+ { // Maybe it makes sense to create an environment history here : if somebody set's our page to NULL, and we have a valid page before,
+ // me may want to remember our place within the old page. For this we could create a new m_xEnvironmentHistory to store it.
+ // So the next SetPage with a valid new page would restore that environment within the new page.
+ // But for the original Bug (#57300#) we don't need that, so I omit it here. Maybe this will be implemented later.
+ impl_isolateControlModel_nothrow();
+ SdrUnoObj::SetPage(_pNewPage);
+ return;
+ }
+
+ Reference< XIndexContainer > xNewPageForms( pNewFormPage->GetForms( true ), UNO_QUERY );
+ Reference< XIndexContainer > xNewParent;
+ Sequence< ScriptEventDescriptor> aNewEvents;
+
+ // calc the new parent for my model (within the new page's forms hierarchy)
+ // do we have a history ? (from :Clone)
+ if ( m_xEnvironmentHistory.is() )
+ {
+ // the element in m_xEnvironmentHistory which is equivalent to my new parent (which (perhaps) has to be created within _pNewPage->GetForms)
+ // is the right-most element in the tree.
+ Reference< XIndexContainer > xRightMostLeaf = m_xEnvironmentHistory;
+ try
+ {
+ while ( xRightMostLeaf->getCount() )
+ {
+ xRightMostLeaf.set(
+ xRightMostLeaf->getByIndex( xRightMostLeaf->getCount() - 1 ),
+ UNO_QUERY_THROW
+ );
+ }
+
+ xNewParent.set( ensureModelEnv( xRightMostLeaf, xNewPageForms ), UNO_QUERY_THROW );
+
+ // we successfully cloned the environment in m_xEnvironmentHistory, so we can use m_aEventsHistory
+ // (which describes the events of our model at the moment m_xEnvironmentHistory was created)
+ aNewEvents = m_aEventsHistory;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ if ( !xNewParent.is() )
+ {
+ // are we a valid part of our current page forms ?
+ Reference< XIndexContainer > xOldForms;
+ if ( pOldFormPage )
+ xOldForms.set( pOldFormPage->GetForms(), UNO_QUERY_THROW );
+
+ if ( xOldForms.is() )
+ {
+ // search (upward from our model) for xOldForms
+ Reference< XChild > xSearch( GetUnoControlModel(), UNO_QUERY );
+ while (xSearch.is())
+ {
+ if ( xSearch == xOldForms )
+ break;
+ xSearch = Reference< XChild >( xSearch->getParent(), UNO_QUERY );
+ }
+ if ( xSearch.is() ) // implies xSearch == xOldForms, which means we're a valid part of our current page forms hierarchy
+ {
+ Reference< XChild > xMeAsChild( GetUnoControlModel(), UNO_QUERY );
+ xNewParent.set( ensureModelEnv( xMeAsChild->getParent(), xNewPageForms ), UNO_QUERY );
+
+ if ( xNewParent.is() )
+ {
+ try
+ {
+ // transfer the events from our (model's) parent to the new (model's) parent, too
+ Reference< XEventAttacherManager > xEventManager(xMeAsChild->getParent(), UNO_QUERY);
+ Reference< XIndexAccess > xManagerAsIndex(xEventManager, UNO_QUERY);
+ if (xManagerAsIndex.is())
+ {
+ sal_Int32 nPos = getElementPos(xManagerAsIndex, xMeAsChild);
+ if (nPos >= 0)
+ aNewEvents = xEventManager->getScriptEvents(nPos);
+ }
+ else
+ aNewEvents = aEvts;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+ }
+ }
+ }
+
+ // now set the page
+ SdrUnoObj::SetPage(_pNewPage);
+
+ // place my model within the new parent container
+ if (xNewParent.is())
+ {
+ Reference< XFormComponent > xMeAsFormComp(GetUnoControlModel(), UNO_QUERY);
+ if (xMeAsFormComp.is())
+ {
+ // check if I have another parent (and remove me, if neccessary)
+ Reference< XIndexContainer > xOldParent(xMeAsFormComp->getParent(), UNO_QUERY);
+ if (xOldParent.is())
+ {
+ sal_Int32 nPos = getElementPos(Reference< XIndexAccess > (xOldParent, UNO_QUERY), xMeAsFormComp);
+ if (nPos > -1)
+ xOldParent->removeByIndex(nPos);
+ }
+ // and insert into the new container
+ xNewParent->insertByIndex(xNewParent->getCount(), makeAny(xMeAsFormComp));
+
+ // transfer the events
+ if (aNewEvents.getLength())
+ {
+ try
+ {
+ Reference< XEventAttacherManager > xEventManager(xNewParent, UNO_QUERY);
+ Reference< XIndexAccess > xManagerAsIndex(xEventManager, UNO_QUERY);
+ if (xManagerAsIndex.is())
+ {
+ sal_Int32 nPos = getElementPos(xManagerAsIndex, xMeAsFormComp);
+ DBG_ASSERT(nPos >= 0, "FmFormObj::SetPage : inserted but not present ?");
+ xEventManager->registerScriptEvents(nPos, aNewEvents);
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ }
+ }
+ }
+
+ // delete my history
+ Reference< XComponent> xHistory(m_xEnvironmentHistory, UNO_QUERY);
+ if (xHistory.is())
+ xHistory->dispose();
+
+ m_xEnvironmentHistory = NULL;
+ m_aEventsHistory.realloc(0);
+
+ if ( pNewFormPage )
+ pNewFormPage->GetImpl().formObjectInserted( *this );
+}
+
+//------------------------------------------------------------------
+sal_uInt32 FmFormObj::GetObjInventor() const
+{
+ return FmFormInventor;
+}
+
+//------------------------------------------------------------------
+sal_uInt16 FmFormObj::GetObjIdentifier() const
+{
+ return OBJ_UNO;
+}
+
+//------------------------------------------------------------------
+void FmFormObj::clonedFrom(const FmFormObj* _pSource)
+{
+ DBG_ASSERT(_pSource != NULL, "FmFormObj::clonedFrom : invalid source !");
+ Reference< XComponent> xHistory(m_xEnvironmentHistory, UNO_QUERY);
+ if (xHistory.is())
+ xHistory->dispose();
+
+ m_xEnvironmentHistory = NULL;
+ m_aEventsHistory.realloc(0);
+
+ Reference< XChild > xSourceAsChild(_pSource->GetUnoControlModel(), UNO_QUERY);
+ if (!xSourceAsChild.is())
+ return;
+
+ Reference< XInterface > xSourceContainer = xSourceAsChild->getParent();
+
+ m_xEnvironmentHistory = Reference< XIndexContainer >(
+ ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.form.Forms")),
+ UNO_QUERY);
+ DBG_ASSERT(m_xEnvironmentHistory.is(), "FmFormObj::clonedFrom : could not create a forms collection !");
+
+ if (m_xEnvironmentHistory.is())
+ {
+ ensureModelEnv(xSourceContainer, m_xEnvironmentHistory);
+ m_aEventsHistory = aEvts;
+ // if we we're clone there was a call to operator=, so aEvts are excatly the events we need here ...
+ }
+}
+
+//------------------------------------------------------------------
+SdrObject* FmFormObj::Clone() const
+{
+ SdrObject* pReturn = SdrUnoObj::Clone();
+
+ FmFormObj* pFormObject = PTR_CAST(FmFormObj, pReturn);
+ DBG_ASSERT(pFormObject != NULL, "FmFormObj::Clone : invalid clone !");
+ if (pFormObject)
+ pFormObject->clonedFrom(this);
+
+ return pReturn;
+}
+
+//------------------------------------------------------------------
+void FmFormObj::NbcReformatText()
+{
+ impl_checkRefDevice_nothrow( false );
+ SdrUnoObj::NbcReformatText();
+}
+
+//------------------------------------------------------------------
+void FmFormObj::operator= (const SdrObject& rObj)
+{
+ SdrUnoObj::operator= (rObj);
+
+ FmFormObj* pFormObj = PTR_CAST(FmFormObj, &rObj);
+ if (pFormObj)
+ {
+ // liegt das UnoControlModel in einer Eventumgebung,
+ // dann koennen noch Events zugeordnet sein
+ Reference< XFormComponent > xContent(pFormObj->xUnoControlModel, UNO_QUERY);
+ if (xContent.is())
+ {
+ Reference< XEventAttacherManager > xManager(xContent->getParent(), UNO_QUERY);
+ Reference< XIndexAccess > xManagerAsIndex(xManager, UNO_QUERY);
+ if (xManagerAsIndex.is())
+ {
+ sal_Int32 nPos = getElementPos( xManagerAsIndex, xContent );
+ if ( nPos >= 0 )
+ aEvts = xManager->getScriptEvents( nPos );
+ }
+ }
+ else
+ aEvts = pFormObj->aEvts;
+ }
+}
+
+//------------------------------------------------------------------
+namespace
+{
+ String lcl_getFormComponentAccessPath(const Reference< XInterface >& _xElement, Reference< XInterface >& _rTopLevelElement)
+ {
+ Reference< ::com::sun::star::form::XFormComponent> xChild(_xElement, UNO_QUERY);
+ Reference< ::com::sun::star::container::XIndexAccess> xParent;
+ if (xChild.is())
+ xParent = Reference< ::com::sun::star::container::XIndexAccess>(xChild->getParent(), UNO_QUERY);
+
+ // while the current content is a form
+ String sReturn;
+ String sCurrentIndex;
+ while (xChild.is())
+ {
+ // get the content's relative pos within it's parent container
+ sal_Int32 nPos = getElementPos(xParent, xChild);
+
+ // prepend this current relaive pos
+ sCurrentIndex = String::CreateFromInt32(nPos);
+ if (sReturn.Len() != 0)
+ {
+ sCurrentIndex += '\\';
+ sCurrentIndex += sReturn;
+ }
+
+ sReturn = sCurrentIndex;
+
+ // travel up
+ if (::comphelper::query_interface((Reference< XInterface >)xParent,xChild))
+ xParent = Reference< ::com::sun::star::container::XIndexAccess>(xChild->getParent(), UNO_QUERY);
+ }
+
+ _rTopLevelElement = xParent;
+ return sReturn;
+ }
+}
+
+//------------------------------------------------------------------
+Reference< XInterface > FmFormObj::ensureModelEnv(const Reference< XInterface > & _rSourceContainer, const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer > _rTopLevelDestContainer)
+{
+ Reference< XInterface > xTopLevelSouce;
+ String sAccessPath = lcl_getFormComponentAccessPath(_rSourceContainer, xTopLevelSouce);
+ if (!xTopLevelSouce.is())
+ // somthing went wrong, maybe _rSourceContainer isn't part of a valid forms hierarchy
+ return Reference< XInterface > ();
+
+ Reference< XIndexContainer > xDestContainer(_rTopLevelDestContainer);
+ Reference< XIndexContainer > xSourceContainer(xTopLevelSouce, UNO_QUERY);
+ DBG_ASSERT(xSourceContainer.is(), "FmFormObj::ensureModelEnv : the top level source is invalid !");
+
+ for (xub_StrLen i=0; i<sAccessPath.GetTokenCount('\\'); ++i)
+ {
+ sal_uInt16 nIndex = (sal_uInt16)sAccessPath.GetToken(i, '\\').ToInt32();
+
+ // get the DSS of the source form (we have to find an aquivalent for)
+ DBG_ASSERT(nIndex<xSourceContainer->getCount(), "FmFormObj::ensureModelEnv : invalid access path !");
+ Reference< XPropertySet > xSourceForm;
+ xSourceContainer->getByIndex(nIndex) >>= xSourceForm;
+ DBG_ASSERT(xSourceForm.is(), "FmFormObj::ensureModelEnv : invalid source form !");
+
+ Any aSrcCursorSource, aSrcCursorSourceType, aSrcDataSource;
+ DBG_ASSERT(::comphelper::hasProperty(FM_PROP_COMMAND, xSourceForm) && ::comphelper::hasProperty(FM_PROP_COMMANDTYPE, xSourceForm)
+ && ::comphelper::hasProperty(FM_PROP_DATASOURCE, xSourceForm), "FmFormObj::ensureModelEnv : invalid access path or invalid form (missing props) !");
+ // the parent access path should refer to a row set
+ try
+ {
+ aSrcCursorSource = xSourceForm->getPropertyValue(FM_PROP_COMMAND);
+ aSrcCursorSourceType = xSourceForm->getPropertyValue(FM_PROP_COMMANDTYPE);
+ aSrcDataSource = xSourceForm->getPropertyValue(FM_PROP_DATASOURCE);
+ }
+ catch(Exception&)
+ {
+ DBG_ERROR("FmFormObj::ensureModelEnv : could not retrieve a source DSS !");
+ }
+
+
+ // calc the number of (source) form siblings with the same DSS
+ Reference< XPropertySet > xCurrentSourceForm, xCurrentDestForm;
+ sal_Int16 nCurrentSourceIndex = 0, nCurrentDestIndex = 0;
+ while (nCurrentSourceIndex <= nIndex)
+ {
+ sal_Bool bEqualDSS = sal_False;
+ while (!bEqualDSS) // (we don't have to check nCurrentSourceIndex here : it's bound by nIndex)
+ {
+ xSourceContainer->getByIndex(nCurrentSourceIndex) >>= xCurrentSourceForm;
+ DBG_ASSERT(xCurrentSourceForm.is(), "FmFormObj::ensureModelEnv : invalid form ancestor (2) !");
+ bEqualDSS = sal_False;
+ if (::comphelper::hasProperty(FM_PROP_DATASOURCE, xCurrentSourceForm))
+ { // it is a form
+ try
+ {
+ if ( ::comphelper::compare(xCurrentSourceForm->getPropertyValue(FM_PROP_COMMAND), aSrcCursorSource)
+ && ::comphelper::compare(xCurrentSourceForm->getPropertyValue(FM_PROP_COMMANDTYPE), aSrcCursorSourceType)
+ && ::comphelper::compare(xCurrentSourceForm->getPropertyValue(FM_PROP_DATASOURCE), aSrcDataSource)
+ )
+ {
+ bEqualDSS = sal_True;
+ }
+ }
+ catch(Exception&)
+ {
+ DBG_ERROR("FmFormObj::ensureModelEnv : exception while getting a sibling's DSS !");
+ }
+
+ }
+ ++nCurrentSourceIndex;
+ }
+
+ DBG_ASSERT(bEqualDSS, "FmFormObj::ensureModelEnv : found no source form !");
+ // ??? at least the nIndex-th one should have been found ???
+
+ // now search the next one with the given DSS (within the destination container)
+ bEqualDSS = sal_False;
+ while (!bEqualDSS && (nCurrentDestIndex < xDestContainer->getCount()))
+ {
+ xDestContainer->getByIndex(nCurrentDestIndex) >>= xCurrentDestForm;
+ DBG_ASSERT(xCurrentDestForm.is(), "FmFormObj::ensureModelEnv : invalid destination form !");
+ bEqualDSS = sal_False;
+ if (::comphelper::hasProperty(FM_PROP_DATASOURCE, xCurrentDestForm))
+ { // it is a form
+ try
+ {
+ if ( ::comphelper::compare(xCurrentDestForm->getPropertyValue(FM_PROP_COMMAND), aSrcCursorSource)
+ && ::comphelper::compare(xCurrentDestForm->getPropertyValue(FM_PROP_COMMANDTYPE), aSrcCursorSourceType)
+ && ::comphelper::compare(xCurrentDestForm->getPropertyValue(FM_PROP_DATASOURCE), aSrcDataSource)
+ )
+ {
+ bEqualDSS = sal_True;
+ }
+ }
+ catch(Exception&)
+ {
+ DBG_ERROR("FmFormObj::ensureModelEnv : exception while getting a destination DSS !");
+ }
+
+ }
+ ++nCurrentDestIndex;
+ }
+
+ if (!bEqualDSS)
+ { // There is at least one more source form with the given DSS than destination forms are.
+ // correct this ...
+ try
+ {
+ // create and insert (into the destination) a copy of the form
+ xCurrentDestForm.set(
+ ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii( "com.sun.star.form.component.DataForm" ) ),
+ UNO_QUERY_THROW );
+ ::comphelper::copyProperties( xCurrentSourceForm, xCurrentDestForm );
+
+ DBG_ASSERT(nCurrentDestIndex == xDestContainer->getCount(), "FmFormObj::ensureModelEnv : something went wrong with the numbers !");
+ xDestContainer->insertByIndex(nCurrentDestIndex, makeAny(xCurrentDestForm));
+
+ ++nCurrentDestIndex;
+ // like nCurrentSourceIndex, nCurrentDestIndex now points 'behind' the form it actally means
+ }
+ catch(Exception&)
+ {
+ DBG_ERROR("FmFormObj::ensureModelEnv : something went seriously wrong while creating a new form !");
+ // no more options anymore ...
+ return Reference< XInterface > ();
+ }
+
+ }
+ }
+
+ // now xCurrentDestForm is a form equivalent to xSourceForm (which means they have the same DSS and the same number
+ // of left siblings with the same DSS, which counts for all their ancestors, too)
+
+ // go down
+ xDestContainer = Reference< XIndexContainer > (xCurrentDestForm, UNO_QUERY);
+ xSourceContainer = Reference< XIndexContainer > (xSourceForm, UNO_QUERY);
+ DBG_ASSERT(xDestContainer.is() && xSourceContainer.is(), "FmFormObj::ensureModelEnv : invalid container !");
+ }
+
+ return Reference< XInterface > (xDestContainer, UNO_QUERY);
+}
+
+//------------------------------------------------------------------
+void FmFormObj::SetModel( SdrModel* _pNewModel )
+{
+ SdrUnoObj::SetModel( _pNewModel );
+ impl_checkRefDevice_nothrow();
+}
+
+//------------------------------------------------------------------
+FmFormObj* FmFormObj::GetFormObject( SdrObject* _pSdrObject )
+{
+ FmFormObj* pFormObject = dynamic_cast< FmFormObj* >( _pSdrObject );
+ if ( !pFormObject )
+ {
+ SdrVirtObj* pVirtualObject = dynamic_cast< SdrVirtObj* >( _pSdrObject );
+ if ( pVirtualObject )
+ pFormObject = dynamic_cast< FmFormObj* >( &pVirtualObject->ReferencedObj() );
+ }
+ return pFormObject;
+}
+
+//------------------------------------------------------------------
+const FmFormObj* FmFormObj::GetFormObject( const SdrObject* _pSdrObject )
+{
+ const FmFormObj* pFormObject = dynamic_cast< const FmFormObj* >( _pSdrObject );
+ if ( !pFormObject )
+ {
+ const SdrVirtObj* pVirtualObject = dynamic_cast< const SdrVirtObj* >( _pSdrObject );
+ if ( pVirtualObject )
+ pFormObject = dynamic_cast< const FmFormObj* >( &pVirtualObject->GetReferencedObj() );
+ }
+ return pFormObject;
+}
+
+//------------------------------------------------------------------
+void FmFormObj::SetUnoControlModel( const Reference< com::sun::star::awt::XControlModel >& _rxModel )
+{
+ SdrUnoObj::SetUnoControlModel( _rxModel );
+
+ // TODO: call something like formObjectInserted at the form page, to tell it the new model
+
+ impl_checkRefDevice_nothrow( true );
+}
+
+//------------------------------------------------------------------
+FASTBOOL FmFormObj::EndCreate( SdrDragStat& rStat, SdrCreateCmd eCmd )
+{
+ bool bResult = SdrUnoObj::EndCreate(rStat, eCmd);
+ if ( bResult && SDRCREATE_FORCEEND == eCmd && rStat.GetView() )
+ {
+ if ( pPage )
+ {
+ FmFormPage& rPage = dynamic_cast< FmFormPage& >( *pPage );
+
+ try
+ {
+ Reference< XFormComponent > xContent( xUnoControlModel, UNO_QUERY_THROW );
+ Reference< XForm > xParentForm( xContent->getParent(), UNO_QUERY );
+
+ Reference< XIndexContainer > xFormToInsertInto;
+
+ if ( !xParentForm.is() )
+ { // model is not yet part of a form component hierachy
+ xParentForm.set( rPage.GetImpl().findPlaceInFormComponentHierarchy( xContent ), UNO_SET_THROW );
+ xFormToInsertInto.set( xParentForm, UNO_QUERY_THROW );
+ }
+
+ rPage.GetImpl().setUniqueName( xContent, xParentForm );
+
+ if ( xFormToInsertInto.is() )
+ xFormToInsertInto->insertByIndex( xFormToInsertInto->getCount(), makeAny( xContent ) );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ FmFormView* pView( dynamic_cast< FmFormView* >( rStat.GetView() ) );
+ FmXFormView* pViewImpl = pView ? pView->GetImpl() : NULL;
+ OSL_ENSURE( pViewImpl, "FmFormObj::EndCreate: no view!?" );
+ if ( pViewImpl )
+ pViewImpl->onCreatedFormObject( *this );
+ }
+ return bResult;
+}
+
+//------------------------------------------------------------------------------
+void FmFormObj::BrkCreate( SdrDragStat& rStat )
+{
+ SdrUnoObj::BrkCreate( rStat );
+ impl_isolateControlModel_nothrow();
+}
+
+// -----------------------------------------------------------------------------
+sal_Int32 FmFormObj::getType() const
+{
+ return m_nType;
+}
+
+// -----------------------------------------------------------------------------
+// #i70852# overload Layer interface to force to FormColtrol layer
+
+SdrLayerID FmFormObj::GetLayer() const
+{
+ // #i72535#
+ // i70852 was too radical, in SW obects (and thus, FormControls, too)
+ // get moved to invisible layers to hide them (e.g. in hidden sections).
+ // This means that form controls ARE allowed to be on other layers than
+ // the form control layer ATM and that being member of form control layer
+ // is no criteria to find all FormControls of a document.
+ // To fix, use parent functionality
+ return SdrUnoObj::GetLayer();
+}
+
+void FmFormObj::NbcSetLayer(SdrLayerID nLayer)
+{
+ // #i72535#
+ // See above. To fix, use parent functionality
+ return SdrUnoObj::NbcSetLayer(nLayer);
+}
+
+// eof