sd: keep a non-owning pointer to the OverridingShell
[LibreOffice.git] / svx / source / form / fmobj.cxx
blob0e9850914685e79427c3b35e67f938909598bac8
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.hxx>
22 #include <fmvwimp.hxx>
23 #include <fmpgeimp.hxx>
24 #include <o3tl/string_view.hxx>
25 #include <svx/fmview.hxx>
26 #include <svx/fmpage.hxx>
27 #include <svx/svdovirt.hxx>
28 #include <svx/fmmodel.hxx>
30 #include <com/sun/star/awt/XDevice.hpp>
31 #include <com/sun/star/beans/XPropertySet.hpp>
32 #include <com/sun/star/form/Forms.hpp>
33 #include <com/sun/star/script/XEventAttacherManager.hpp>
34 #include <svx/fmtools.hxx>
36 #include <comphelper/property.hxx>
37 #include <comphelper/processfactory.hxx>
38 #include <toolkit/awt/vclxdevice.hxx>
39 #include <tools/debug.hxx>
40 #include <comphelper/diagnose_ex.hxx>
42 using namespace ::com::sun::star::uno;
43 using namespace ::com::sun::star::awt;
44 using namespace ::com::sun::star::lang;
45 using namespace ::com::sun::star::form;
46 using namespace ::com::sun::star::beans;
47 using namespace ::com::sun::star::script;
48 using namespace ::com::sun::star::container;
49 using namespace ::svxform;
52 FmFormObj::FmFormObj(
53 SdrModel& rSdrModel,
54 const OUString& rModelName)
55 : SdrUnoObj(rSdrModel, rModelName)
56 ,m_nPos(-1)
57 ,m_pLastKnownRefDevice(nullptr)
59 // normally, this is done in SetUnoControlModel, but if the call happened in the base class ctor,
60 // then our incarnation of it was not called (since we were not constructed at this time).
61 impl_checkRefDevice_nothrow( true );
64 FmFormObj::FmFormObj(SdrModel& rSdrModel)
65 : SdrUnoObj(rSdrModel, u""_ustr)
66 ,m_nPos(-1)
67 ,m_pLastKnownRefDevice(nullptr)
69 // Stuff that old SetModel also did:
70 impl_checkRefDevice_nothrow();
73 FmFormObj::FmFormObj(SdrModel& rSdrModel, FmFormObj const & rSource)
74 : SdrUnoObj(rSdrModel, rSource)
75 ,m_nPos(-1)
76 ,m_pLastKnownRefDevice(nullptr)
78 // Stuff that old SetModel also did:
79 impl_checkRefDevice_nothrow();
81 // If UnoControlModel is part of an event environment,
82 // events may assigned to it.
83 Reference< XFormComponent > xContent(rSource.xUnoControlModel, UNO_QUERY);
84 if (xContent.is())
86 Reference< XEventAttacherManager > xManager(xContent->getParent(), UNO_QUERY);
87 Reference< XIndexAccess > xManagerAsIndex(xManager, UNO_QUERY);
88 if (xManagerAsIndex.is())
90 sal_Int32 nPos = getElementPos( xManagerAsIndex, xContent );
91 if ( nPos >= 0 )
92 aEvts = xManager->getScriptEvents( nPos );
95 else
96 aEvts = rSource.aEvts;
98 Reference< XChild > xSourceAsChild(rSource.GetUnoControlModel(), UNO_QUERY);
99 if (!xSourceAsChild.is())
100 return;
102 Reference< XInterface > xSourceContainer = xSourceAsChild->getParent();
104 m_xEnvironmentHistory = css::form::Forms::create( comphelper::getProcessComponentContext() );
106 ensureModelEnv(xSourceContainer, m_xEnvironmentHistory);
107 m_aEventsHistory = aEvts;
108 // if we were clone there was a call to operator=, so aEvts are exactly the events we need here...
111 FmFormObj::~FmFormObj()
114 if (m_xEnvironmentHistory.is())
115 m_xEnvironmentHistory->dispose();
117 m_xEnvironmentHistory = nullptr;
118 m_aEventsHistory.realloc(0);
122 void FmFormObj::SetObjEnv(const Reference< XIndexContainer > & xForm, const sal_Int32 nIdx,
123 const Sequence< ScriptEventDescriptor >& rEvts)
125 m_xParent = xForm;
126 aEvts = rEvts;
127 m_nPos = nIdx;
131 void FmFormObj::ClearObjEnv()
133 m_xParent.clear();
134 aEvts.realloc( 0 );
135 m_nPos = -1;
139 void FmFormObj::impl_checkRefDevice_nothrow( bool _force )
141 const FmFormModel* pFormModel = dynamic_cast<FmFormModel*>(&getSdrModelFromSdrObject());
142 if ( !pFormModel || !pFormModel->ControlsUseRefDevice() )
143 return;
145 OutputDevice* pCurrentRefDevice = pFormModel->GetRefDevice();
146 if ( ( m_pLastKnownRefDevice.get() == pCurrentRefDevice ) && !_force )
147 return;
149 Reference< XControlModel > xControlModel( GetUnoControlModel() );
150 if ( !xControlModel.is() )
151 return;
153 m_pLastKnownRefDevice = pCurrentRefDevice;
154 if ( !m_pLastKnownRefDevice )
155 return;
159 Reference< XPropertySet > xModelProps( GetUnoControlModel(), UNO_QUERY_THROW );
160 Reference< XPropertySetInfo > xPropertyInfo( xModelProps->getPropertySetInfo(), UNO_SET_THROW );
162 static constexpr OUString sRefDevicePropName = u"ReferenceDevice"_ustr;
163 if ( xPropertyInfo->hasPropertyByName( sRefDevicePropName ) )
165 rtl::Reference<VCLXDevice> pUnoRefDevice = new VCLXDevice;
166 pUnoRefDevice->SetOutputDevice( m_pLastKnownRefDevice );
167 Reference< XDevice > xRefDevice( pUnoRefDevice );
168 xModelProps->setPropertyValue( sRefDevicePropName, Any( xRefDevice ) );
171 catch( const Exception& )
173 DBG_UNHANDLED_EXCEPTION("svx");
178 void FmFormObj::impl_isolateControlModel_nothrow()
182 Reference< XChild > xControlModel( GetUnoControlModel(), UNO_QUERY );
183 if ( xControlModel.is() )
185 Reference< XIndexContainer> xParent( xControlModel->getParent(), UNO_QUERY );
186 if ( xParent.is() )
188 sal_Int32 nPos = getElementPos( xParent, xControlModel );
189 xParent->removeByIndex( nPos );
193 catch( const Exception& )
195 DBG_UNHANDLED_EXCEPTION("svx");
200 void FmFormObj::handlePageChange(SdrPage* pOldPage, SdrPage* pNewPage)
202 FmFormPage* pOldFormPage(dynamic_cast< FmFormPage* >(getSdrPageFromSdrObject()));
203 if ( pOldFormPage )
204 pOldFormPage->GetImpl().formObjectRemoved( *this );
206 FmFormPage* pNewFormPage = dynamic_cast<FmFormPage*>( pNewPage );
207 if ( !pNewFormPage )
209 // 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,
210 // me may want to remember our place within the old page. For this we could create a new m_xEnvironmentHistory to store it.
211 // So the next SetPage with a valid new page would restore that environment within the new page.
212 // But for the original Bug (#57300#) we don't need that, so I omit it here. Maybe this will be implemented later.
213 impl_isolateControlModel_nothrow();
214 SdrUnoObj::handlePageChange(pOldPage, pNewPage);
215 return;
218 Reference< css::form::XForms > xNewPageForms = pNewFormPage->GetForms();
219 Reference< XIndexContainer > xNewParent;
220 Sequence< ScriptEventDescriptor> aNewEvents;
222 // calc the new parent for my model (within the new page's forms hierarchy)
223 // do we have a history ? (from :Clone)
224 if ( m_xEnvironmentHistory.is() )
226 // the element in m_xEnvironmentHistory which is equivalent to my new parent (which (perhaps) has to be created within pNewPage->GetForms)
227 // is the right-most element in the tree.
228 Reference< XIndexContainer > xRightMostLeaf( m_xEnvironmentHistory, UNO_QUERY_THROW );
231 while ( xRightMostLeaf->getCount() )
233 xRightMostLeaf.set(
234 xRightMostLeaf->getByIndex( xRightMostLeaf->getCount() - 1 ),
235 UNO_QUERY_THROW
239 xNewParent.set( ensureModelEnv( xRightMostLeaf, xNewPageForms ), UNO_QUERY_THROW );
241 // we successfully cloned the environment in m_xEnvironmentHistory, so we can use m_aEventsHistory
242 // (which describes the events of our model at the moment m_xEnvironmentHistory was created)
243 aNewEvents = m_aEventsHistory;
245 catch( const Exception& )
247 DBG_UNHANDLED_EXCEPTION("svx");
251 if ( !xNewParent.is() )
253 // are we a valid part of our current page forms ?
254 Reference< XIndexContainer > xOldForms;
255 if ( pOldFormPage )
256 xOldForms.set( pOldFormPage->GetForms(), UNO_QUERY_THROW );
258 if ( xOldForms.is() )
260 // search (upward from our model) for xOldForms
261 Reference< XChild > xSearch( GetUnoControlModel(), UNO_QUERY );
262 while (xSearch.is())
264 if ( xSearch == xOldForms )
265 break;
266 xSearch.set( xSearch->getParent(), UNO_QUERY );
268 if ( xSearch.is() ) // implies xSearch == xOldForms, which means we're a valid part of our current page forms hierarchy
270 Reference< XChild > xMeAsChild( GetUnoControlModel(), UNO_QUERY );
271 xNewParent.set( ensureModelEnv( xMeAsChild->getParent(), xNewPageForms ), UNO_QUERY );
273 if ( xNewParent.is() )
277 // transfer the events from our (model's) parent to the new (model's) parent, too
278 Reference< XEventAttacherManager > xEventManager(xMeAsChild->getParent(), UNO_QUERY);
279 Reference< XIndexAccess > xManagerAsIndex(xEventManager, UNO_QUERY);
280 if (xManagerAsIndex.is())
282 sal_Int32 nPos = getElementPos(xManagerAsIndex, xMeAsChild);
283 if (nPos >= 0)
284 aNewEvents = xEventManager->getScriptEvents(nPos);
286 else
287 aNewEvents = aEvts;
289 catch( const Exception& )
291 DBG_UNHANDLED_EXCEPTION("svx");
298 // now set the page
299 SdrUnoObj::handlePageChange(pOldPage, pNewPage);
301 // place my model within the new parent container
302 if (xNewParent.is())
304 Reference< XFormComponent > xMeAsFormComp(GetUnoControlModel(), UNO_QUERY);
305 if (xMeAsFormComp.is())
307 // check if I have another parent (and remove me, if necessary)
308 Reference< XIndexContainer > xOldParent(xMeAsFormComp->getParent(), UNO_QUERY);
309 if (xOldParent.is())
311 sal_Int32 nPos = getElementPos(xOldParent, xMeAsFormComp);
312 if (nPos > -1)
313 xOldParent->removeByIndex(nPos);
316 // and insert into the new container
317 xNewParent->insertByIndex(xNewParent->getCount(), Any(xMeAsFormComp));
319 // transfer the events
320 if (aNewEvents.hasElements())
324 Reference< XEventAttacherManager > xEventManager(xNewParent, UNO_QUERY);
325 Reference< XIndexAccess > xManagerAsIndex(xEventManager, UNO_QUERY);
326 if (xManagerAsIndex.is())
328 sal_Int32 nPos = getElementPos(xManagerAsIndex, xMeAsFormComp);
329 DBG_ASSERT(nPos >= 0, "FmFormObj::SetPage : inserted but not present ?");
330 xEventManager->registerScriptEvents(nPos, aNewEvents);
333 catch( const Exception& )
335 DBG_UNHANDLED_EXCEPTION("svx");
342 // delete my history
343 if (m_xEnvironmentHistory.is())
344 m_xEnvironmentHistory->dispose();
346 m_xEnvironmentHistory = nullptr;
347 m_aEventsHistory.realloc(0);
349 pNewFormPage->GetImpl().formObjectInserted( *this );
352 SdrInventor FmFormObj::GetObjInventor() const
354 return SdrInventor::FmForm;
357 SdrObjKind FmFormObj::GetObjIdentifier() const
359 return SdrObjKind::UNO;
362 rtl::Reference<SdrObject> FmFormObj::CloneSdrObject(SdrModel& rTargetModel) const
364 return new FmFormObj(rTargetModel, *this);
367 void FmFormObj::NbcReformatText()
369 impl_checkRefDevice_nothrow();
370 SdrUnoObj::NbcReformatText();
374 namespace
376 OUString lcl_getFormComponentAccessPath(const Reference< XInterface >& _xElement, Reference< XInterface >& _rTopLevelElement)
378 Reference< css::form::XFormComponent> xChild(_xElement, UNO_QUERY);
379 Reference< css::container::XIndexAccess> xParent;
380 if (xChild.is())
381 xParent.set(xChild->getParent(), UNO_QUERY);
383 // while the current content is a form
384 OUString sReturn;
385 while (xChild.is())
387 // get the content's relative pos within its parent container
388 sal_Int32 nPos = getElementPos(xParent, xChild);
390 // prepend this current relative pos
391 OUString sCurrentIndex = OUString::number(nPos);
392 if (!sReturn.isEmpty())
394 sCurrentIndex += "\\" + sReturn;
397 sReturn = sCurrentIndex;
399 // travel up
400 xChild.set(xParent, css::uno::UNO_QUERY);
401 if (xChild.is())
402 xParent.set(xChild->getParent(), UNO_QUERY);
405 _rTopLevelElement = xParent;
406 return sReturn;
411 Reference< XInterface > FmFormObj::ensureModelEnv(const Reference< XInterface > & _rSourceContainer, const Reference<css::form::XForms>& _rTopLevelDestContainer)
413 Reference< XInterface > xTopLevelSource;
414 OUString sAccessPath = lcl_getFormComponentAccessPath(_rSourceContainer, xTopLevelSource);
415 if (!xTopLevelSource.is())
416 // something went wrong, maybe _rSourceContainer isn't part of a valid forms hierarchy
417 return Reference< XInterface > ();
419 Reference< XIndexContainer > xDestContainer(_rTopLevelDestContainer, UNO_QUERY_THROW);
420 Reference< XIndexContainer > xSourceContainer(xTopLevelSource, UNO_QUERY);
421 DBG_ASSERT(xSourceContainer.is(), "FmFormObj::ensureModelEnv : the top level source is invalid !");
423 sal_Int32 nTokIndex = 0;
426 std::u16string_view aToken = o3tl::getToken(sAccessPath, 0, '\\', nTokIndex );
427 sal_uInt16 nIndex = static_cast<sal_uInt16>(o3tl::toInt32(aToken));
429 // get the DSS of the source form (we have to find an equivalent for)
430 DBG_ASSERT(nIndex<xSourceContainer->getCount(), "FmFormObj::ensureModelEnv : invalid access path !");
431 Reference< XPropertySet > xSourceForm;
432 xSourceContainer->getByIndex(nIndex) >>= xSourceForm;
433 DBG_ASSERT(xSourceForm.is(), "FmFormObj::ensureModelEnv : invalid source form !");
435 Any aSrcCursorSource, aSrcCursorSourceType, aSrcDataSource;
436 DBG_ASSERT(::comphelper::hasProperty(FM_PROP_COMMAND, xSourceForm) && ::comphelper::hasProperty(FM_PROP_COMMANDTYPE, xSourceForm)
437 && ::comphelper::hasProperty(FM_PROP_DATASOURCE, xSourceForm), "FmFormObj::ensureModelEnv : invalid access path or invalid form (missing props) !");
438 // the parent access path should refer to a row set
441 aSrcCursorSource = xSourceForm->getPropertyValue(FM_PROP_COMMAND);
442 aSrcCursorSourceType = xSourceForm->getPropertyValue(FM_PROP_COMMANDTYPE);
443 aSrcDataSource = xSourceForm->getPropertyValue(FM_PROP_DATASOURCE);
445 catch(Exception&)
447 OSL_FAIL("FmFormObj::ensureModelEnv : could not retrieve a source DSS !");
451 // calc the number of (source) form siblings with the same DSS
452 Reference< XPropertySet > xCurrentSourceForm, xCurrentDestForm;
453 sal_Int16 nCurrentSourceIndex = 0;
454 sal_Int32 nCurrentDestIndex = 0;
455 while (nCurrentSourceIndex <= nIndex)
457 bool bEqualDSS = false;
458 while (!bEqualDSS) // (we don't have to check nCurrentSourceIndex here : it's bound by nIndex)
460 xSourceContainer->getByIndex(nCurrentSourceIndex) >>= xCurrentSourceForm;
461 DBG_ASSERT(xCurrentSourceForm.is(), "FmFormObj::ensureModelEnv : invalid form ancestor (2) !");
462 bEqualDSS = false;
463 if (::comphelper::hasProperty(FM_PROP_DATASOURCE, xCurrentSourceForm))
464 { // it is a form
467 if ( xCurrentSourceForm->getPropertyValue(FM_PROP_COMMAND) == aSrcCursorSource
468 && xCurrentSourceForm->getPropertyValue(FM_PROP_COMMANDTYPE) == aSrcCursorSourceType
469 && xCurrentSourceForm->getPropertyValue(FM_PROP_DATASOURCE) == aSrcDataSource
472 bEqualDSS = true;
475 catch(Exception&)
477 TOOLS_WARN_EXCEPTION("svx.form",
478 "exception while getting a sibling's DSS !");
482 ++nCurrentSourceIndex;
485 DBG_ASSERT(bEqualDSS, "FmFormObj::ensureModelEnv : found no source form !");
486 // ??? at least the nIndex-th one should have been found ???
488 // now search the next one with the given DSS (within the destination container)
489 bEqualDSS = false;
490 while (!bEqualDSS && (nCurrentDestIndex < xDestContainer->getCount()))
492 xDestContainer->getByIndex(nCurrentDestIndex) >>= xCurrentDestForm;
493 DBG_ASSERT(xCurrentDestForm.is(), "FmFormObj::ensureModelEnv : invalid destination form !");
494 bEqualDSS = false;
495 if (::comphelper::hasProperty(FM_PROP_DATASOURCE, xCurrentDestForm))
496 { // it is a form
499 if ( xCurrentDestForm->getPropertyValue(FM_PROP_COMMAND) == aSrcCursorSource
500 && xCurrentDestForm->getPropertyValue(FM_PROP_COMMANDTYPE) == aSrcCursorSourceType
501 && xCurrentDestForm->getPropertyValue(FM_PROP_DATASOURCE) == aSrcDataSource
504 bEqualDSS = true;
507 catch(Exception&)
509 TOOLS_WARN_EXCEPTION("svx.form",
510 "exception while getting a destination DSS !");
514 ++nCurrentDestIndex;
517 if (!bEqualDSS)
518 { // There is at least one more source form with the given DSS than destination forms are.
519 // correct this ...
522 // create and insert (into the destination) a copy of the form
523 xCurrentDestForm.set(
524 ::comphelper::getProcessServiceFactory()->createInstance(u"com.sun.star.form.component.DataForm"_ustr),
525 UNO_QUERY_THROW );
526 ::comphelper::copyProperties( xCurrentSourceForm, xCurrentDestForm );
528 DBG_ASSERT(nCurrentDestIndex == xDestContainer->getCount(), "FmFormObj::ensureModelEnv : something went wrong with the numbers !");
529 xDestContainer->insertByIndex(nCurrentDestIndex, Any(xCurrentDestForm));
531 ++nCurrentDestIndex;
532 // like nCurrentSourceIndex, nCurrentDestIndex now points 'behind' the form it actually means
534 catch(Exception&)
536 OSL_FAIL("FmFormObj::ensureModelEnv : something went seriously wrong while creating a new form !");
537 // no more options anymore ...
538 return Reference< XInterface > ();
544 // now xCurrentDestForm is a form equivalent to xSourceForm (which means they have the same DSS and the same number
545 // of left siblings with the same DSS, which counts for all their ancestors, too)
547 // go down
548 xDestContainer.set(xCurrentDestForm, UNO_QUERY);
549 xSourceContainer.set(xSourceForm, UNO_QUERY);
550 DBG_ASSERT(xDestContainer.is() && xSourceContainer.is(), "FmFormObj::ensureModelEnv : invalid container !");
552 while ( nTokIndex >= 0 );
554 return Reference<XInterface>( xDestContainer, UNO_QUERY );
557 FmFormObj* FmFormObj::GetFormObject( SdrObject* _pSdrObject )
559 FmFormObj* pFormObject = dynamic_cast< FmFormObj* >( _pSdrObject );
560 if ( !pFormObject )
562 SdrVirtObj* pVirtualObject = dynamic_cast< SdrVirtObj* >( _pSdrObject );
563 if ( pVirtualObject )
564 pFormObject = dynamic_cast< FmFormObj* >( &pVirtualObject->ReferencedObj() );
566 return pFormObject;
570 const FmFormObj* FmFormObj::GetFormObject( const SdrObject* _pSdrObject )
572 const FmFormObj* pFormObject = dynamic_cast< const FmFormObj* >( _pSdrObject );
573 if ( !pFormObject )
575 const SdrVirtObj* pVirtualObject = dynamic_cast< const SdrVirtObj* >( _pSdrObject );
576 if ( pVirtualObject )
577 pFormObject = dynamic_cast< const FmFormObj* >( &pVirtualObject->GetReferencedObj() );
579 return pFormObject;
583 void FmFormObj::SetUnoControlModel( const Reference< css::awt::XControlModel >& _rxModel )
585 SdrUnoObj::SetUnoControlModel( _rxModel );
587 FmFormPage* pFormPage(dynamic_cast< FmFormPage* >(getSdrPageFromSdrObject()));
588 if ( pFormPage )
589 pFormPage->GetImpl().formModelAssigned( *this );
591 impl_checkRefDevice_nothrow( true );
595 bool FmFormObj::EndCreate( SdrDragStat& rStat, SdrCreateCmd eCmd )
597 bool bResult = SdrUnoObj::EndCreate(rStat, eCmd);
598 if ( bResult && SdrCreateCmd::ForceEnd == eCmd && rStat.GetView() )
600 FmFormPage* pFormPage(dynamic_cast< FmFormPage* >(getSdrPageFromSdrObject()));
602 if (nullptr != pFormPage)
606 Reference< XFormComponent > xContent( xUnoControlModel, UNO_QUERY_THROW );
607 Reference< XForm > xParentForm( xContent->getParent(), UNO_QUERY );
609 Reference< XIndexContainer > xFormToInsertInto;
611 if ( !xParentForm.is() )
612 { // model is not yet part of a form component hierarchy
613 xParentForm.set( pFormPage->GetImpl().findPlaceInFormComponentHierarchy( xContent ), UNO_SET_THROW );
614 xFormToInsertInto.set( xParentForm, UNO_QUERY_THROW );
617 FmFormPageImpl::setUniqueName( xContent, xParentForm );
619 if ( xFormToInsertInto.is() )
620 xFormToInsertInto->insertByIndex( xFormToInsertInto->getCount(), Any( xContent ) );
622 catch( const Exception& )
624 DBG_UNHANDLED_EXCEPTION("svx");
628 FmFormView* pView( dynamic_cast< FmFormView* >( rStat.GetView() ) );
629 FmXFormView* pViewImpl = pView ? pView->GetImpl() : nullptr;
630 OSL_ENSURE( pViewImpl, "FmFormObj::EndCreate: no view!?" );
631 if ( pViewImpl )
632 pViewImpl->onCreatedFormObject( *this );
634 return bResult;
638 void FmFormObj::BrkCreate( SdrDragStat& rStat )
640 SdrUnoObj::BrkCreate( rStat );
641 impl_isolateControlModel_nothrow();
643 FmFormView* pView( dynamic_cast< FmFormView* >( rStat.GetView() ) );
644 FmXFormView* pViewImpl = pView ? pView->GetImpl() : nullptr;
645 OSL_ENSURE( pViewImpl, "FmFormObj::EndCreate: no view!?" );
646 if ( pViewImpl )
647 pViewImpl->breakCreateFormObject();
651 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */