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>
56 const OUString& rModelName)
59 ,m_pLastKnownRefDevice(nullptr)
63 impl_checkRefDevice_nothrow(
true );
66FmFormObj::FmFormObj(
SdrModel& rSdrModel)
69 ,m_pLastKnownRefDevice(nullptr)
72 impl_checkRefDevice_nothrow();
75FmFormObj::FmFormObj(
SdrModel& rSdrModel, FmFormObj
const & rSource)
78 ,m_pLastKnownRefDevice(nullptr)
81 impl_checkRefDevice_nothrow();
85 Reference< XFormComponent > xContent(rSource.xUnoControlModel, UNO_QUERY);
88 Reference< XEventAttacherManager > xManager(xContent->getParent(), UNO_QUERY);
89 Reference< XIndexAccess > xManagerAsIndex(xManager, UNO_QUERY);
90 if (xManagerAsIndex.is())
94 aEvts = xManager->getScriptEvents( nPos );
98 aEvts = rSource.aEvts;
100 Reference< XChild > xSourceAsChild(rSource.GetUnoControlModel(), UNO_QUERY);
101 if (!xSourceAsChild.is())
104 Reference< XInterface > xSourceContainer = xSourceAsChild->getParent();
108 ensureModelEnv(xSourceContainer, m_xEnvironmentHistory);
109 m_aEventsHistory = aEvts;
113FmFormObj::~FmFormObj()
116 if (m_xEnvironmentHistory.is())
117 m_xEnvironmentHistory->dispose();
119 m_xEnvironmentHistory =
nullptr;
120 m_aEventsHistory.realloc(0);
124void FmFormObj::SetObjEnv(
const Reference< XIndexContainer > & xForm,
const sal_Int32 nIdx,
125 const Sequence< ScriptEventDescriptor >& rEvts)
133void FmFormObj::ClearObjEnv()
141void FmFormObj::impl_checkRefDevice_nothrow(
bool _force )
148 if ( ( m_pLastKnownRefDevice.get() == pCurrentRefDevice ) && !_force )
151 Reference< XControlModel > xControlModel( GetUnoControlModel() );
152 if ( !xControlModel.is() )
155 m_pLastKnownRefDevice = pCurrentRefDevice;
156 if ( !m_pLastKnownRefDevice )
161 Reference< XPropertySet > xModelProps( GetUnoControlModel(), UNO_QUERY_THROW );
162 Reference< XPropertySetInfo > xPropertyInfo( xModelProps->getPropertySetInfo(), UNO_SET_THROW );
164 static constexpr OUStringLiteral sRefDevicePropName =
u"ReferenceDevice";
165 if ( xPropertyInfo->hasPropertyByName( sRefDevicePropName ) )
168 pUnoRefDevice->SetOutputDevice( m_pLastKnownRefDevice );
169 Reference< XDevice > xRefDevice( pUnoRefDevice );
170 xModelProps->setPropertyValue( sRefDevicePropName,
Any( xRefDevice ) );
173 catch(
const Exception& )
180void FmFormObj::impl_isolateControlModel_nothrow()
184 Reference< XChild > xControlModel( GetUnoControlModel(), UNO_QUERY );
185 if ( xControlModel.is() )
187 Reference< XIndexContainer> xParent( xControlModel->getParent(), UNO_QUERY );
191 xParent->removeByIndex( nPos );
195 catch(
const Exception& )
202void FmFormObj::handlePageChange(
SdrPage* pOldPage,
SdrPage* pNewPage)
206 pOldFormPage->GetImpl().formObjectRemoved( *
this );
215 impl_isolateControlModel_nothrow();
220 Reference< css::form::XForms > xNewPageForms = pNewFormPage->
GetForms();
221 Reference< XIndexContainer > xNewParent;
222 Sequence< ScriptEventDescriptor> aNewEvents;
226 if ( m_xEnvironmentHistory.is() )
230 Reference< XIndexContainer > xRightMostLeaf( m_xEnvironmentHistory, UNO_QUERY_THROW );
233 while ( xRightMostLeaf->getCount() )
236 xRightMostLeaf->getByIndex( xRightMostLeaf->getCount() - 1 ),
241 xNewParent.set( ensureModelEnv( xRightMostLeaf, xNewPageForms ), UNO_QUERY_THROW );
245 aNewEvents = m_aEventsHistory;
247 catch(
const Exception& )
253 if ( !xNewParent.is() )
256 Reference< XIndexContainer > xOldForms;
258 xOldForms.set( pOldFormPage->GetForms(), UNO_QUERY_THROW );
260 if ( xOldForms.is() )
263 Reference< XChild > xSearch( GetUnoControlModel(), UNO_QUERY );
266 if ( xSearch == xOldForms )
268 xSearch.set( xSearch->getParent(), UNO_QUERY );
272 Reference< XChild > xMeAsChild( GetUnoControlModel(), UNO_QUERY );
273 xNewParent.set( ensureModelEnv( xMeAsChild->getParent(), xNewPageForms ), UNO_QUERY );
275 if ( xNewParent.is() )
280 Reference< XEventAttacherManager > xEventManager(xMeAsChild->getParent(), UNO_QUERY);
281 Reference< XIndexAccess > xManagerAsIndex(xEventManager, UNO_QUERY);
282 if (xManagerAsIndex.is())
286 aNewEvents = xEventManager->getScriptEvents(nPos);
291 catch(
const Exception& )
306 Reference< XFormComponent > xMeAsFormComp(GetUnoControlModel(), UNO_QUERY);
307 if (xMeAsFormComp.is())
310 Reference< XIndexContainer > xOldParent(xMeAsFormComp->getParent(), UNO_QUERY);
315 xOldParent->removeByIndex(nPos);
319 xNewParent->insertByIndex(xNewParent->getCount(),
Any(xMeAsFormComp));
322 if (aNewEvents.hasElements())
326 Reference< XEventAttacherManager > xEventManager(xNewParent, UNO_QUERY);
327 Reference< XIndexAccess > xManagerAsIndex(xEventManager, UNO_QUERY);
328 if (xManagerAsIndex.is())
331 DBG_ASSERT(nPos >= 0,
"FmFormObj::SetPage : inserted but not present ?");
332 xEventManager->registerScriptEvents(nPos, aNewEvents);
335 catch(
const Exception& )
345 if (m_xEnvironmentHistory.is())
346 m_xEnvironmentHistory->dispose();
348 m_xEnvironmentHistory =
nullptr;
349 m_aEventsHistory.realloc(0);
366 return new FmFormObj(rTargetModel, *
this);
369void FmFormObj::NbcReformatText()
371 impl_checkRefDevice_nothrow();
378 OUString lcl_getFormComponentAccessPath(
const Reference< XInterface >& _xElement, Reference< XInterface >& _rTopLevelElement)
380 Reference< css::form::XFormComponent> xChild(_xElement, UNO_QUERY);
381 Reference< css::container::XIndexAccess> xParent;
383 xParent.set(xChild->getParent(), UNO_QUERY);
393 OUString sCurrentIndex = OUString::number(nPos);
394 if (!sReturn.isEmpty())
396 sCurrentIndex +=
"\\" + sReturn;
399 sReturn = sCurrentIndex;
402 xChild.set(xParent, css::uno::UNO_QUERY);
404 xParent.set(xChild->getParent(), UNO_QUERY);
407 _rTopLevelElement = xParent;
413Reference< XInterface > FmFormObj::ensureModelEnv(
const Reference< XInterface > & _rSourceContainer,
const Reference<css::form::XForms>& _rTopLevelDestContainer)
415 Reference< XInterface > xTopLevelSource;
416 OUString sAccessPath = lcl_getFormComponentAccessPath(_rSourceContainer, xTopLevelSource);
417 if (!xTopLevelSource.is())
419 return Reference< XInterface > ();
421 Reference< XIndexContainer > xDestContainer(_rTopLevelDestContainer, UNO_QUERY_THROW);
422 Reference< XIndexContainer > xSourceContainer(xTopLevelSource, UNO_QUERY);
423 DBG_ASSERT(xSourceContainer.is(),
"FmFormObj::ensureModelEnv : the top level source is invalid !");
425 sal_Int32 nTokIndex = 0;
428 std::u16string_view aToken =
o3tl::getToken(sAccessPath, 0,
'\\', nTokIndex );
432 DBG_ASSERT(nIndex<xSourceContainer->getCount(),
"FmFormObj::ensureModelEnv : invalid access path !");
433 Reference< XPropertySet > xSourceForm;
434 xSourceContainer->getByIndex(nIndex) >>= xSourceForm;
435 DBG_ASSERT(xSourceForm.is(),
"FmFormObj::ensureModelEnv : invalid source form !");
437 Any aSrcCursorSource, aSrcCursorSourceType, aSrcDataSource;
439 && ::comphelper::hasProperty(
FM_PROP_DATASOURCE, xSourceForm),
"FmFormObj::ensureModelEnv : invalid access path or invalid form (missing props) !");
449 OSL_FAIL(
"FmFormObj::ensureModelEnv : could not retrieve a source DSS !");
454 Reference< XPropertySet > xCurrentSourceForm, xCurrentDestForm;
455 sal_Int16 nCurrentSourceIndex = 0;
456 sal_Int32 nCurrentDestIndex = 0;
457 while (nCurrentSourceIndex <= nIndex)
459 bool bEqualDSS =
false;
462 xSourceContainer->getByIndex(nCurrentSourceIndex) >>= xCurrentSourceForm;
463 DBG_ASSERT(xCurrentSourceForm.is(),
"FmFormObj::ensureModelEnv : invalid form ancestor (2) !");
469 if ( xCurrentSourceForm->getPropertyValue(
FM_PROP_COMMAND) == aSrcCursorSource
480 "exception while getting a sibling's DSS !");
484 ++nCurrentSourceIndex;
487 DBG_ASSERT(bEqualDSS,
"FmFormObj::ensureModelEnv : found no source form !");
492 while (!bEqualDSS && (nCurrentDestIndex < xDestContainer->getCount()))
494 xDestContainer->getByIndex(nCurrentDestIndex) >>= xCurrentDestForm;
495 DBG_ASSERT(xCurrentDestForm.is(),
"FmFormObj::ensureModelEnv : invalid destination form !");
501 if ( xCurrentDestForm->getPropertyValue(
FM_PROP_COMMAND) == aSrcCursorSource
512 "exception while getting a destination DSS !");
525 xCurrentDestForm.set(
526 ::comphelper::getProcessServiceFactory()->
createInstance(
"com.sun.star.form.component.DataForm"),
528 ::comphelper::copyProperties( xCurrentSourceForm, xCurrentDestForm );
530 DBG_ASSERT(nCurrentDestIndex == xDestContainer->getCount(),
"FmFormObj::ensureModelEnv : something went wrong with the numbers !");
531 xDestContainer->insertByIndex(nCurrentDestIndex,
Any(xCurrentDestForm));
538 OSL_FAIL(
"FmFormObj::ensureModelEnv : something went seriously wrong while creating a new form !");
540 return Reference< XInterface > ();
550 xDestContainer.set(xCurrentDestForm, UNO_QUERY);
551 xSourceContainer.set(xSourceForm, UNO_QUERY);
552 DBG_ASSERT(xDestContainer.is() && xSourceContainer.is(),
"FmFormObj::ensureModelEnv : invalid container !");
554 while ( nTokIndex >= 0 );
556 return Reference<XInterface>( xDestContainer, UNO_QUERY );
559FmFormObj* FmFormObj::GetFormObject(
SdrObject* _pSdrObject )
561 FmFormObj* pFormObject =
dynamic_cast< FmFormObj*
>( _pSdrObject );
565 if ( pVirtualObject )
566 pFormObject =
dynamic_cast< FmFormObj*
>( &pVirtualObject->
ReferencedObj() );
572const FmFormObj* FmFormObj::GetFormObject(
const SdrObject* _pSdrObject )
574 const FmFormObj* pFormObject =
dynamic_cast< const FmFormObj*
>( _pSdrObject );
578 if ( pVirtualObject )
579 pFormObject =
dynamic_cast< const FmFormObj*
>( &pVirtualObject->
GetReferencedObj() );
585void FmFormObj::SetUnoControlModel(
const Reference< css::awt::XControlModel >& _rxModel )
591 pFormPage->GetImpl().formModelAssigned( *
this );
593 impl_checkRefDevice_nothrow(
true );
604 if (
nullptr != pFormPage)
608 Reference< XFormComponent > xContent( xUnoControlModel, UNO_QUERY_THROW );
609 Reference< XForm > xParentForm( xContent->getParent(), UNO_QUERY );
611 Reference< XIndexContainer > xFormToInsertInto;
613 if ( !xParentForm.is() )
615 xParentForm.set( pFormPage->GetImpl().findPlaceInFormComponentHierarchy( xContent ), UNO_SET_THROW );
616 xFormToInsertInto.set( xParentForm, UNO_QUERY_THROW );
621 if ( xFormToInsertInto.is() )
622 xFormToInsertInto->insertByIndex( xFormToInsertInto->getCount(),
Any( xContent ) );
624 catch(
const Exception& )
631 FmXFormView* pViewImpl = pView ? pView->GetImpl() :
nullptr;
632 OSL_ENSURE( pViewImpl,
"FmFormObj::EndCreate: no view!?" );
643 impl_isolateControlModel_nothrow();
646 FmXFormView* pViewImpl = pView ? pView->GetImpl() :
nullptr;
647 OSL_ENSURE( pViewImpl,
"FmFormObj::EndCreate: no view!?" );
HRESULT createInstance(REFIID iid, Ifc **ppIfc)
void formObjectInserted(const FmFormObj &_object)
static OUString setUniqueName(const css::uno::Reference< css::form::XFormComponent > &xFormComponent, const css::uno::Reference< css::form::XForm > &xControls)
const css::uno::Reference< css::form::XForms > & GetForms(bool _bForceCreate=true) const
FmFormPageImpl & GetImpl() const
SdrView * GetView() const
OutputDevice * GetRefDevice() const
A SdrPage contains exactly one SdrObjList and a description of the physical page dimensions (size / m...
virtual void NbcReformatText() override
virtual void BrkCreate(SdrDragStat &rStat) override
virtual void handlePageChange(SdrPage *pOldPage, SdrPage *pNewPage) override
virtual bool EndCreate(SdrDragStat &rStat, SdrCreateCmd eCmd) override
virtual void SetUnoControlModel(const css::uno::Reference< css::awt::XControlModel > &xModel)
FIXME: The virtual object is not yet fully implemented and tested.
const SdrObject & GetReferencedObj() const
SdrObject & ReferencedObj()
#define DBG_ASSERT(sCon, aError)
#define TOOLS_WARN_EXCEPTION(area, stream)
#define DBG_UNHANDLED_EXCEPTION(...)
constexpr OUStringLiteral FM_PROP_COMMAND
constexpr OUStringLiteral FM_PROP_COMMANDTYPE
constexpr OUStringLiteral FM_PROP_DATASOURCE
Reference< XComponentContext > getProcessComponentContext()
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
@ UNO
continuously activated OLE (PlugIn-Frame or similar)