| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the 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 "svx/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 necessary) |
| 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 ); |
| |
| FmFormPage* pFormPage = PTR_CAST( FmFormPage, GetPage() ); |
| if ( pFormPage ) |
| pFormPage->GetImpl().formModelAssigned( *this ); |
| |
| 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 hierarchy |
| 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 |