update credits
[LibreOffice.git] / svx / source / form / fmobj.cxx
blob34949302dc9fd151b03ef80d4bd572a866307213
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "fmobj.hxx"
21 #include "fmprop.hrc"
22 #include "fmvwimp.hxx"
23 #include "fmpgeimp.hxx"
24 #include "svx/fmresids.hrc"
25 #include "svx/fmview.hxx"
26 #include "svx/fmglob.hxx"
27 #include "svx/fmpage.hxx"
28 #include "editeng/editeng.hxx"
29 #include "svx/svdovirt.hxx"
30 #include "svx/fmmodel.hxx"
31 #include "svx/dialmgr.hxx"
33 #include <com/sun/star/awt/XDevice.hpp>
34 #include <com/sun/star/awt/XControlContainer.hpp>
35 #include <com/sun/star/form/Forms.hpp>
36 #include <com/sun/star/io/XPersistObject.hpp>
37 #include <com/sun/star/script/XEventAttacherManager.hpp>
38 #include <com/sun/star/util/XCloneable.hpp>
39 #include "svx/fmtools.hxx"
41 #include <tools/shl.hxx>
42 #include <comphelper/property.hxx>
43 #include <comphelper/processfactory.hxx>
44 #include <toolkit/awt/vclxdevice.hxx>
45 #include <vcl/svapp.hxx>
46 #include <tools/diagnose_ex.h>
48 using namespace ::com::sun::star::io;
49 using namespace ::com::sun::star::uno;
50 using namespace ::com::sun::star::awt;
51 using namespace ::com::sun::star::lang;
52 using namespace ::com::sun::star::util;
53 using namespace ::com::sun::star::form;
54 using namespace ::com::sun::star::beans;
55 using namespace ::com::sun::star::script;
56 using namespace ::com::sun::star::container;
57 using namespace ::svxform;
59 TYPEINIT1(FmFormObj, SdrUnoObj);
60 DBG_NAME(FmFormObj);
61 //------------------------------------------------------------------
62 FmFormObj::FmFormObj(const OUString& rModelName)
63 :SdrUnoObj ( rModelName )
64 ,m_nPos ( -1 )
65 ,m_pLastKnownRefDevice ( NULL )
67 DBG_CTOR(FmFormObj, NULL);
69 // normally, this is done in SetUnoControlModel, but if the call happened in the base class ctor,
70 // then our incarnation of it was not called (since we were not constructed at this time).
71 impl_checkRefDevice_nothrow( true );
74 //------------------------------------------------------------------
75 FmFormObj::FmFormObj()
76 :SdrUnoObj ( String() )
77 ,m_nPos ( -1 )
78 ,m_pLastKnownRefDevice ( NULL )
80 DBG_CTOR(FmFormObj, NULL);
83 //------------------------------------------------------------------
84 FmFormObj::~FmFormObj()
86 DBG_DTOR(FmFormObj, NULL);
88 if (m_xEnvironmentHistory.is())
89 m_xEnvironmentHistory->dispose();
91 m_xEnvironmentHistory = NULL;
92 m_aEventsHistory.realloc(0);
95 //------------------------------------------------------------------
96 void FmFormObj::SetObjEnv(const Reference< XIndexContainer > & xForm, const sal_Int32 nIdx,
97 const Sequence< ScriptEventDescriptor >& rEvts)
99 m_xParent = xForm;
100 aEvts = rEvts;
101 m_nPos = nIdx;
104 //------------------------------------------------------------------
105 void FmFormObj::ClearObjEnv()
107 m_xParent.clear();
108 aEvts.realloc( 0 );
109 m_nPos = -1;
112 //------------------------------------------------------------------
113 void FmFormObj::impl_checkRefDevice_nothrow( bool _force )
115 const FmFormModel* pFormModel = PTR_CAST( FmFormModel, GetModel() );
116 if ( !pFormModel || !pFormModel->ControlsUseRefDevice() )
117 return;
119 OutputDevice* pCurrentRefDevice = pFormModel ? pFormModel->GetRefDevice() : NULL;
120 if ( ( m_pLastKnownRefDevice == pCurrentRefDevice ) && !_force )
121 return;
123 Reference< XControlModel > xControlModel( GetUnoControlModel() );
124 if ( !xControlModel.is() )
125 return;
127 m_pLastKnownRefDevice = pCurrentRefDevice;
128 if ( m_pLastKnownRefDevice == NULL )
129 return;
133 Reference< XPropertySet > xModelProps( GetUnoControlModel(), UNO_QUERY_THROW );
134 Reference< XPropertySetInfo > xPropertyInfo( xModelProps->getPropertySetInfo(), UNO_SET_THROW );
136 static const OUString sRefDevicePropName( "ReferenceDevice" );
137 if ( xPropertyInfo->hasPropertyByName( sRefDevicePropName ) )
139 VCLXDevice* pUnoRefDevice = new VCLXDevice;
140 pUnoRefDevice->SetOutputDevice( m_pLastKnownRefDevice );
141 Reference< XDevice > xRefDevice( pUnoRefDevice );
142 xModelProps->setPropertyValue( sRefDevicePropName, makeAny( xRefDevice ) );
145 catch( const Exception& )
147 DBG_UNHANDLED_EXCEPTION();
151 //------------------------------------------------------------------
152 void FmFormObj::impl_isolateControlModel_nothrow()
156 Reference< XChild > xControlModel( GetUnoControlModel(), UNO_QUERY );
157 if ( xControlModel.is() )
159 Reference< XIndexContainer> xParent( xControlModel->getParent(), UNO_QUERY );
160 if ( xParent.is() )
162 sal_Int32 nPos = getElementPos( xParent.get(), xControlModel );
163 xParent->removeByIndex( nPos );
167 catch( const Exception& )
169 DBG_UNHANDLED_EXCEPTION();
173 //------------------------------------------------------------------
174 void FmFormObj::SetPage(SdrPage* _pNewPage)
176 if ( GetPage() == _pNewPage )
178 SdrUnoObj::SetPage(_pNewPage);
179 return;
182 FmFormPage* pOldFormPage = PTR_CAST( FmFormPage, GetPage() );
183 if ( pOldFormPage )
184 pOldFormPage->GetImpl().formObjectRemoved( *this );
186 FmFormPage* pNewFormPage = PTR_CAST( FmFormPage, _pNewPage );
187 if ( !pNewFormPage )
188 { // 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,
189 // me may want to remember our place within the old page. For this we could create a new m_xEnvironmentHistory to store it.
190 // So the next SetPage with a valid new page would restore that environment within the new page.
191 // But for the original Bug (#57300#) we don't need that, so I omit it here. Maybe this will be implemented later.
192 impl_isolateControlModel_nothrow();
193 SdrUnoObj::SetPage(_pNewPage);
194 return;
197 Reference< css::form::XForms > xNewPageForms = pNewFormPage->GetForms( true );
198 Reference< XIndexContainer > xNewParent;
199 Sequence< ScriptEventDescriptor> aNewEvents;
201 // calc the new parent for my model (within the new page's forms hierarchy)
202 // do we have a history ? (from :Clone)
203 if ( m_xEnvironmentHistory.is() )
205 // the element in m_xEnvironmentHistory which is equivalent to my new parent (which (perhaps) has to be created within _pNewPage->GetForms)
206 // is the right-most element in the tree.
207 Reference< XIndexContainer > xRightMostLeaf( m_xEnvironmentHistory, UNO_QUERY_THROW );
210 while ( xRightMostLeaf->getCount() )
212 xRightMostLeaf.set(
213 xRightMostLeaf->getByIndex( xRightMostLeaf->getCount() - 1 ),
214 UNO_QUERY_THROW
218 xNewParent.set( ensureModelEnv( xRightMostLeaf, xNewPageForms ), UNO_QUERY_THROW );
220 // we successfully cloned the environment in m_xEnvironmentHistory, so we can use m_aEventsHistory
221 // (which describes the events of our model at the moment m_xEnvironmentHistory was created)
222 aNewEvents = m_aEventsHistory;
224 catch( const Exception& )
226 DBG_UNHANDLED_EXCEPTION();
230 if ( !xNewParent.is() )
232 // are we a valid part of our current page forms ?
233 Reference< XIndexContainer > xOldForms;
234 if ( pOldFormPage )
235 xOldForms.set( pOldFormPage->GetForms(), UNO_QUERY_THROW );
237 if ( xOldForms.is() )
239 // search (upward from our model) for xOldForms
240 Reference< XChild > xSearch( GetUnoControlModel(), UNO_QUERY );
241 while (xSearch.is())
243 if ( xSearch == xOldForms )
244 break;
245 xSearch = Reference< XChild >( xSearch->getParent(), UNO_QUERY );
247 if ( xSearch.is() ) // implies xSearch == xOldForms, which means we're a valid part of our current page forms hierarchy
249 Reference< XChild > xMeAsChild( GetUnoControlModel(), UNO_QUERY );
250 xNewParent.set( ensureModelEnv( xMeAsChild->getParent(), xNewPageForms ), UNO_QUERY );
252 if ( xNewParent.is() )
256 // transfer the events from our (model's) parent to the new (model's) parent, too
257 Reference< XEventAttacherManager > xEventManager(xMeAsChild->getParent(), UNO_QUERY);
258 Reference< XIndexAccess > xManagerAsIndex(xEventManager, UNO_QUERY);
259 if (xManagerAsIndex.is())
261 sal_Int32 nPos = getElementPos(xManagerAsIndex, xMeAsChild);
262 if (nPos >= 0)
263 aNewEvents = xEventManager->getScriptEvents(nPos);
265 else
266 aNewEvents = aEvts;
268 catch( const Exception& )
270 DBG_UNHANDLED_EXCEPTION();
277 // now set the page
278 SdrUnoObj::SetPage(_pNewPage);
280 // place my model within the new parent container
281 if (xNewParent.is())
283 Reference< XFormComponent > xMeAsFormComp(GetUnoControlModel(), UNO_QUERY);
284 if (xMeAsFormComp.is())
286 // check if I have another parent (and remove me, if necessary)
287 Reference< XIndexContainer > xOldParent(xMeAsFormComp->getParent(), UNO_QUERY);
288 if (xOldParent.is())
290 sal_Int32 nPos = getElementPos(Reference< XIndexAccess > (xOldParent, UNO_QUERY), xMeAsFormComp);
291 if (nPos > -1)
292 xOldParent->removeByIndex(nPos);
294 // and insert into the new container
295 xNewParent->insertByIndex(xNewParent->getCount(), makeAny(xMeAsFormComp));
297 // transfer the events
298 if (aNewEvents.getLength())
302 Reference< XEventAttacherManager > xEventManager(xNewParent, UNO_QUERY);
303 Reference< XIndexAccess > xManagerAsIndex(xEventManager, UNO_QUERY);
304 if (xManagerAsIndex.is())
306 sal_Int32 nPos = getElementPos(xManagerAsIndex, xMeAsFormComp);
307 DBG_ASSERT(nPos >= 0, "FmFormObj::SetPage : inserted but not present ?");
308 xEventManager->registerScriptEvents(nPos, aNewEvents);
311 catch( const Exception& )
313 DBG_UNHANDLED_EXCEPTION();
320 // delete my history
321 if (m_xEnvironmentHistory.is())
322 m_xEnvironmentHistory->dispose();
324 m_xEnvironmentHistory = NULL;
325 m_aEventsHistory.realloc(0);
327 if ( pNewFormPage )
328 pNewFormPage->GetImpl().formObjectInserted( *this );
331 //------------------------------------------------------------------
332 sal_uInt32 FmFormObj::GetObjInventor() const
334 return FmFormInventor;
337 //------------------------------------------------------------------
338 sal_uInt16 FmFormObj::GetObjIdentifier() const
340 return OBJ_UNO;
343 //------------------------------------------------------------------
344 void FmFormObj::clonedFrom(const FmFormObj* _pSource)
346 DBG_ASSERT(_pSource != NULL, "FmFormObj::clonedFrom : invalid source !");
347 if (m_xEnvironmentHistory.is())
348 m_xEnvironmentHistory->dispose();
350 m_xEnvironmentHistory = NULL;
351 m_aEventsHistory.realloc(0);
353 Reference< XChild > xSourceAsChild(_pSource->GetUnoControlModel(), UNO_QUERY);
354 if (!xSourceAsChild.is())
355 return;
357 Reference< XInterface > xSourceContainer = xSourceAsChild->getParent();
359 m_xEnvironmentHistory = css::form::Forms::create( comphelper::getProcessComponentContext() );
361 ensureModelEnv(xSourceContainer, m_xEnvironmentHistory);
362 m_aEventsHistory = aEvts;
363 // if we we're clone there was a call to operator=, so aEvts are excatly the events we need here ...
366 //------------------------------------------------------------------
367 FmFormObj* FmFormObj::Clone() const
369 FmFormObj* pFormObject = CloneHelper< FmFormObj >();
370 DBG_ASSERT(pFormObject != NULL, "FmFormObj::Clone : invalid clone !");
371 if (pFormObject)
372 pFormObject->clonedFrom(this);
374 return pFormObject;
377 //------------------------------------------------------------------
378 void FmFormObj::NbcReformatText()
380 impl_checkRefDevice_nothrow( false );
381 SdrUnoObj::NbcReformatText();
384 //------------------------------------------------------------------
385 FmFormObj& FmFormObj::operator= (const FmFormObj& rObj)
387 if( this == &rObj )
388 return *this;
389 SdrUnoObj::operator= (rObj);
391 // liegt das UnoControlModel in einer Eventumgebung,
392 // dann koennen noch Events zugeordnet sein
393 Reference< XFormComponent > xContent(rObj.xUnoControlModel, UNO_QUERY);
394 if (xContent.is())
396 Reference< XEventAttacherManager > xManager(xContent->getParent(), UNO_QUERY);
397 Reference< XIndexAccess > xManagerAsIndex(xManager, UNO_QUERY);
398 if (xManagerAsIndex.is())
400 sal_Int32 nPos = getElementPos( xManagerAsIndex, xContent );
401 if ( nPos >= 0 )
402 aEvts = xManager->getScriptEvents( nPos );
405 else
406 aEvts = rObj.aEvts;
407 return *this;
410 //------------------------------------------------------------------
411 namespace
413 OUString lcl_getFormComponentAccessPath(const Reference< XInterface >& _xElement, Reference< XInterface >& _rTopLevelElement)
415 Reference< ::com::sun::star::form::XFormComponent> xChild(_xElement, UNO_QUERY);
416 Reference< ::com::sun::star::container::XIndexAccess> xParent;
417 if (xChild.is())
418 xParent = Reference< ::com::sun::star::container::XIndexAccess>(xChild->getParent(), UNO_QUERY);
420 // while the current content is a form
421 String sReturn;
422 String sCurrentIndex;
423 while (xChild.is())
425 // get the content's relative pos within it's parent container
426 sal_Int32 nPos = getElementPos(xParent, xChild);
428 // prepend this current relaive pos
429 sCurrentIndex = OUString::number(nPos);
430 if (sReturn.Len() != 0)
432 sCurrentIndex += '\\';
433 sCurrentIndex += sReturn;
436 sReturn = sCurrentIndex;
438 // travel up
439 if (::comphelper::query_interface((Reference< XInterface >)xParent,xChild))
440 xParent = Reference< ::com::sun::star::container::XIndexAccess>(xChild->getParent(), UNO_QUERY);
443 _rTopLevelElement = xParent;
444 return sReturn;
448 //------------------------------------------------------------------
449 Reference< XInterface > FmFormObj::ensureModelEnv(const Reference< XInterface > & _rSourceContainer, const Reference<css::form::XForms>& _rTopLevelDestContainer)
451 Reference< XInterface > xTopLevelSouce;
452 OUString sAccessPath = lcl_getFormComponentAccessPath(_rSourceContainer, xTopLevelSouce);
453 if (!xTopLevelSouce.is())
454 // something went wrong, maybe _rSourceContainer isn't part of a valid forms hierarchy
455 return Reference< XInterface > ();
457 Reference< XIndexContainer > xDestContainer(_rTopLevelDestContainer, UNO_QUERY_THROW);
458 Reference< XIndexContainer > xSourceContainer(xTopLevelSouce, UNO_QUERY);
459 DBG_ASSERT(xSourceContainer.is(), "FmFormObj::ensureModelEnv : the top level source is invalid !");
461 sal_Int32 nTokIndex = 0;
464 OUString aToken = sAccessPath.getToken( 0, '\\', nTokIndex );
465 sal_uInt16 nIndex = (sal_uInt16)aToken.toInt32();
467 // get the DSS of the source form (we have to find an aquivalent for)
468 DBG_ASSERT(nIndex<xSourceContainer->getCount(), "FmFormObj::ensureModelEnv : invalid access path !");
469 Reference< XPropertySet > xSourceForm;
470 xSourceContainer->getByIndex(nIndex) >>= xSourceForm;
471 DBG_ASSERT(xSourceForm.is(), "FmFormObj::ensureModelEnv : invalid source form !");
473 Any aSrcCursorSource, aSrcCursorSourceType, aSrcDataSource;
474 DBG_ASSERT(::comphelper::hasProperty(FM_PROP_COMMAND, xSourceForm) && ::comphelper::hasProperty(FM_PROP_COMMANDTYPE, xSourceForm)
475 && ::comphelper::hasProperty(FM_PROP_DATASOURCE, xSourceForm), "FmFormObj::ensureModelEnv : invalid access path or invalid form (missing props) !");
476 // the parent access path should refer to a row set
479 aSrcCursorSource = xSourceForm->getPropertyValue(FM_PROP_COMMAND);
480 aSrcCursorSourceType = xSourceForm->getPropertyValue(FM_PROP_COMMANDTYPE);
481 aSrcDataSource = xSourceForm->getPropertyValue(FM_PROP_DATASOURCE);
483 catch(Exception&)
485 OSL_FAIL("FmFormObj::ensureModelEnv : could not retrieve a source DSS !");
489 // calc the number of (source) form siblings with the same DSS
490 Reference< XPropertySet > xCurrentSourceForm, xCurrentDestForm;
491 sal_Int16 nCurrentSourceIndex = 0, nCurrentDestIndex = 0;
492 while (nCurrentSourceIndex <= nIndex)
494 sal_Bool bEqualDSS = sal_False;
495 while (!bEqualDSS) // (we don't have to check nCurrentSourceIndex here : it's bound by nIndex)
497 xSourceContainer->getByIndex(nCurrentSourceIndex) >>= xCurrentSourceForm;
498 DBG_ASSERT(xCurrentSourceForm.is(), "FmFormObj::ensureModelEnv : invalid form ancestor (2) !");
499 bEqualDSS = sal_False;
500 if (::comphelper::hasProperty(FM_PROP_DATASOURCE, xCurrentSourceForm))
501 { // it is a form
504 if ( ::comphelper::compare(xCurrentSourceForm->getPropertyValue(FM_PROP_COMMAND), aSrcCursorSource)
505 && ::comphelper::compare(xCurrentSourceForm->getPropertyValue(FM_PROP_COMMANDTYPE), aSrcCursorSourceType)
506 && ::comphelper::compare(xCurrentSourceForm->getPropertyValue(FM_PROP_DATASOURCE), aSrcDataSource)
509 bEqualDSS = sal_True;
512 catch(Exception&)
514 OSL_FAIL("FmFormObj::ensureModelEnv : exception while getting a sibling's DSS !");
518 ++nCurrentSourceIndex;
521 DBG_ASSERT(bEqualDSS, "FmFormObj::ensureModelEnv : found no source form !");
522 // ??? at least the nIndex-th one should have been found ???
524 // now search the next one with the given DSS (within the destination container)
525 bEqualDSS = sal_False;
526 while (!bEqualDSS && (nCurrentDestIndex < xDestContainer->getCount()))
528 xDestContainer->getByIndex(nCurrentDestIndex) >>= xCurrentDestForm;
529 DBG_ASSERT(xCurrentDestForm.is(), "FmFormObj::ensureModelEnv : invalid destination form !");
530 bEqualDSS = sal_False;
531 if (::comphelper::hasProperty(FM_PROP_DATASOURCE, xCurrentDestForm))
532 { // it is a form
535 if ( ::comphelper::compare(xCurrentDestForm->getPropertyValue(FM_PROP_COMMAND), aSrcCursorSource)
536 && ::comphelper::compare(xCurrentDestForm->getPropertyValue(FM_PROP_COMMANDTYPE), aSrcCursorSourceType)
537 && ::comphelper::compare(xCurrentDestForm->getPropertyValue(FM_PROP_DATASOURCE), aSrcDataSource)
540 bEqualDSS = sal_True;
543 catch(Exception&)
545 OSL_FAIL("FmFormObj::ensureModelEnv : exception while getting a destination DSS !");
549 ++nCurrentDestIndex;
552 if (!bEqualDSS)
553 { // There is at least one more source form with the given DSS than destination forms are.
554 // correct this ...
557 // create and insert (into the destination) a copy of the form
558 xCurrentDestForm.set(
559 ::comphelper::getProcessServiceFactory()->createInstance(OUString( "com.sun.star.form.component.DataForm" ) ),
560 UNO_QUERY_THROW );
561 ::comphelper::copyProperties( xCurrentSourceForm, xCurrentDestForm );
563 DBG_ASSERT(nCurrentDestIndex == xDestContainer->getCount(), "FmFormObj::ensureModelEnv : something went wrong with the numbers !");
564 xDestContainer->insertByIndex(nCurrentDestIndex, makeAny(xCurrentDestForm));
566 ++nCurrentDestIndex;
567 // like nCurrentSourceIndex, nCurrentDestIndex now points 'behind' the form it actally means
569 catch(Exception&)
571 OSL_FAIL("FmFormObj::ensureModelEnv : something went seriously wrong while creating a new form !");
572 // no more options anymore ...
573 return Reference< XInterface > ();
579 // now xCurrentDestForm is a form equivalent to xSourceForm (which means they have the same DSS and the same number
580 // of left siblings with the same DSS, which counts for all their ancestors, too)
582 // go down
583 xDestContainer = Reference< XIndexContainer > (xCurrentDestForm, UNO_QUERY);
584 xSourceContainer = Reference< XIndexContainer > (xSourceForm, UNO_QUERY);
585 DBG_ASSERT(xDestContainer.is() && xSourceContainer.is(), "FmFormObj::ensureModelEnv : invalid container !");
587 while ( nTokIndex >= 0 );
589 return Reference< XInterface > (xDestContainer, UNO_QUERY);
592 //------------------------------------------------------------------
593 void FmFormObj::SetModel( SdrModel* _pNewModel )
595 SdrUnoObj::SetModel( _pNewModel );
596 impl_checkRefDevice_nothrow();
599 //------------------------------------------------------------------
600 FmFormObj* FmFormObj::GetFormObject( SdrObject* _pSdrObject )
602 FmFormObj* pFormObject = dynamic_cast< FmFormObj* >( _pSdrObject );
603 if ( !pFormObject )
605 SdrVirtObj* pVirtualObject = dynamic_cast< SdrVirtObj* >( _pSdrObject );
606 if ( pVirtualObject )
607 pFormObject = dynamic_cast< FmFormObj* >( &pVirtualObject->ReferencedObj() );
609 return pFormObject;
612 //------------------------------------------------------------------
613 const FmFormObj* FmFormObj::GetFormObject( const SdrObject* _pSdrObject )
615 const FmFormObj* pFormObject = dynamic_cast< const FmFormObj* >( _pSdrObject );
616 if ( !pFormObject )
618 const SdrVirtObj* pVirtualObject = dynamic_cast< const SdrVirtObj* >( _pSdrObject );
619 if ( pVirtualObject )
620 pFormObject = dynamic_cast< const FmFormObj* >( &pVirtualObject->GetReferencedObj() );
622 return pFormObject;
625 //------------------------------------------------------------------
626 void FmFormObj::SetUnoControlModel( const Reference< com::sun::star::awt::XControlModel >& _rxModel )
628 SdrUnoObj::SetUnoControlModel( _rxModel );
630 FmFormPage* pFormPage = PTR_CAST( FmFormPage, GetPage() );
631 if ( pFormPage )
632 pFormPage->GetImpl().formModelAssigned( *this );
634 impl_checkRefDevice_nothrow( true );
637 //------------------------------------------------------------------
638 bool FmFormObj::EndCreate( SdrDragStat& rStat, SdrCreateCmd eCmd )
640 bool bResult = SdrUnoObj::EndCreate(rStat, eCmd);
641 if ( bResult && SDRCREATE_FORCEEND == eCmd && rStat.GetView() )
643 if ( pPage )
645 FmFormPage& rPage = dynamic_cast< FmFormPage& >( *pPage );
649 Reference< XFormComponent > xContent( xUnoControlModel, UNO_QUERY_THROW );
650 Reference< XForm > xParentForm( xContent->getParent(), UNO_QUERY );
652 Reference< XIndexContainer > xFormToInsertInto;
654 if ( !xParentForm.is() )
655 { // model is not yet part of a form component hierachy
656 xParentForm.set( rPage.GetImpl().findPlaceInFormComponentHierarchy( xContent ), UNO_SET_THROW );
657 xFormToInsertInto.set( xParentForm, UNO_QUERY_THROW );
660 rPage.GetImpl().setUniqueName( xContent, xParentForm );
662 if ( xFormToInsertInto.is() )
663 xFormToInsertInto->insertByIndex( xFormToInsertInto->getCount(), makeAny( xContent ) );
665 catch( const Exception& )
667 DBG_UNHANDLED_EXCEPTION();
671 FmFormView* pView( dynamic_cast< FmFormView* >( rStat.GetView() ) );
672 FmXFormView* pViewImpl = pView ? pView->GetImpl() : NULL;
673 OSL_ENSURE( pViewImpl, "FmFormObj::EndCreate: no view!?" );
674 if ( pViewImpl )
675 pViewImpl->onCreatedFormObject( *this );
677 return bResult;
680 //------------------------------------------------------------------------------
681 void FmFormObj::BrkCreate( SdrDragStat& rStat )
683 SdrUnoObj::BrkCreate( rStat );
684 impl_isolateControlModel_nothrow();
687 // -----------------------------------------------------------------------------
688 // #i70852# overload Layer interface to force to FormColtrol layer
690 SdrLayerID FmFormObj::GetLayer() const
692 // #i72535#
693 // i70852 was too radical, in SW obects (and thus, FormControls, too)
694 // get moved to invisible layers to hide them (e.g. in hidden sections).
695 // This means that form controls ARE allowed to be on other layers than
696 // the form control layer ATM and that being member of form control layer
697 // is no criteria to find all FormControls of a document.
698 // To fix, use parent functionality
699 return SdrUnoObj::GetLayer();
702 void FmFormObj::NbcSetLayer(SdrLayerID nLayer)
704 // #i72535#
705 // See above. To fix, use parent functionality
706 return SdrUnoObj::NbcSetLayer(nLayer);
709 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */