Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
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"
32 :
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"
40 :
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>
47 :
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;
58 :
59 0 : TYPEINIT1(FmFormObj, SdrUnoObj);
60 :
61 0 : FmFormObj::FmFormObj(const OUString& rModelName)
62 : :SdrUnoObj ( rModelName )
63 : ,m_nPos ( -1 )
64 0 : ,m_pLastKnownRefDevice ( NULL )
65 : {
66 :
67 : // normally, this is done in SetUnoControlModel, but if the call happened in the base class ctor,
68 : // then our incarnation of it was not called (since we were not constructed at this time).
69 0 : impl_checkRefDevice_nothrow( true );
70 0 : }
71 :
72 :
73 0 : FmFormObj::FmFormObj()
74 : :SdrUnoObj ( "" )
75 : ,m_nPos ( -1 )
76 0 : ,m_pLastKnownRefDevice ( NULL )
77 : {
78 0 : }
79 :
80 :
81 0 : FmFormObj::~FmFormObj()
82 : {
83 :
84 0 : if (m_xEnvironmentHistory.is())
85 0 : m_xEnvironmentHistory->dispose();
86 :
87 0 : m_xEnvironmentHistory = NULL;
88 0 : m_aEventsHistory.realloc(0);
89 0 : }
90 :
91 :
92 0 : void FmFormObj::SetObjEnv(const Reference< XIndexContainer > & xForm, const sal_Int32 nIdx,
93 : const Sequence< ScriptEventDescriptor >& rEvts)
94 : {
95 0 : m_xParent = xForm;
96 0 : aEvts = rEvts;
97 0 : m_nPos = nIdx;
98 0 : }
99 :
100 :
101 0 : void FmFormObj::ClearObjEnv()
102 : {
103 0 : m_xParent.clear();
104 0 : aEvts.realloc( 0 );
105 0 : m_nPos = -1;
106 0 : }
107 :
108 :
109 0 : void FmFormObj::impl_checkRefDevice_nothrow( bool _force )
110 : {
111 0 : const FmFormModel* pFormModel = PTR_CAST( FmFormModel, GetModel() );
112 0 : if ( !pFormModel || !pFormModel->ControlsUseRefDevice() )
113 0 : return;
114 :
115 0 : OutputDevice* pCurrentRefDevice = pFormModel ? pFormModel->GetRefDevice() : NULL;
116 0 : if ( ( m_pLastKnownRefDevice == pCurrentRefDevice ) && !_force )
117 0 : return;
118 :
119 0 : Reference< XControlModel > xControlModel( GetUnoControlModel() );
120 0 : if ( !xControlModel.is() )
121 0 : return;
122 :
123 0 : m_pLastKnownRefDevice = pCurrentRefDevice;
124 0 : if ( m_pLastKnownRefDevice == NULL )
125 0 : return;
126 :
127 : try
128 : {
129 0 : Reference< XPropertySet > xModelProps( GetUnoControlModel(), UNO_QUERY_THROW );
130 0 : Reference< XPropertySetInfo > xPropertyInfo( xModelProps->getPropertySetInfo(), UNO_SET_THROW );
131 :
132 0 : static const OUString sRefDevicePropName( "ReferenceDevice" );
133 0 : if ( xPropertyInfo->hasPropertyByName( sRefDevicePropName ) )
134 : {
135 0 : VCLXDevice* pUnoRefDevice = new VCLXDevice;
136 0 : pUnoRefDevice->SetOutputDevice( m_pLastKnownRefDevice );
137 0 : Reference< XDevice > xRefDevice( pUnoRefDevice );
138 0 : xModelProps->setPropertyValue( sRefDevicePropName, makeAny( xRefDevice ) );
139 0 : }
140 : }
141 0 : catch( const Exception& )
142 : {
143 : DBG_UNHANDLED_EXCEPTION();
144 0 : }
145 : }
146 :
147 :
148 0 : void FmFormObj::impl_isolateControlModel_nothrow()
149 : {
150 : try
151 : {
152 0 : Reference< XChild > xControlModel( GetUnoControlModel(), UNO_QUERY );
153 0 : if ( xControlModel.is() )
154 : {
155 0 : Reference< XIndexContainer> xParent( xControlModel->getParent(), UNO_QUERY );
156 0 : if ( xParent.is() )
157 : {
158 0 : sal_Int32 nPos = getElementPos( xParent.get(), xControlModel );
159 0 : xParent->removeByIndex( nPos );
160 0 : }
161 0 : }
162 : }
163 0 : catch( const Exception& )
164 : {
165 : DBG_UNHANDLED_EXCEPTION();
166 : }
167 0 : }
168 :
169 :
170 0 : void FmFormObj::SetPage(SdrPage* _pNewPage)
171 : {
172 0 : if ( GetPage() == _pNewPage )
173 : {
174 0 : SdrUnoObj::SetPage(_pNewPage);
175 0 : return;
176 : }
177 :
178 0 : FmFormPage* pOldFormPage = PTR_CAST( FmFormPage, GetPage() );
179 0 : if ( pOldFormPage )
180 0 : pOldFormPage->GetImpl().formObjectRemoved( *this );
181 :
182 0 : FmFormPage* pNewFormPage = PTR_CAST( FmFormPage, _pNewPage );
183 0 : if ( !pNewFormPage )
184 : { // 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,
185 : // me may want to remember our place within the old page. For this we could create a new m_xEnvironmentHistory to store it.
186 : // So the next SetPage with a valid new page would restore that environment within the new page.
187 : // But for the original Bug (#57300#) we don't need that, so I omit it here. Maybe this will be implemented later.
188 0 : impl_isolateControlModel_nothrow();
189 0 : SdrUnoObj::SetPage(_pNewPage);
190 0 : return;
191 : }
192 :
193 0 : Reference< css::form::XForms > xNewPageForms = pNewFormPage->GetForms( true );
194 0 : Reference< XIndexContainer > xNewParent;
195 0 : Sequence< ScriptEventDescriptor> aNewEvents;
196 :
197 : // calc the new parent for my model (within the new page's forms hierarchy)
198 : // do we have a history ? (from :Clone)
199 0 : if ( m_xEnvironmentHistory.is() )
200 : {
201 : // the element in m_xEnvironmentHistory which is equivalent to my new parent (which (perhaps) has to be created within _pNewPage->GetForms)
202 : // is the right-most element in the tree.
203 0 : Reference< XIndexContainer > xRightMostLeaf( m_xEnvironmentHistory, UNO_QUERY_THROW );
204 : try
205 : {
206 0 : while ( xRightMostLeaf->getCount() )
207 : {
208 : xRightMostLeaf.set(
209 0 : xRightMostLeaf->getByIndex( xRightMostLeaf->getCount() - 1 ),
210 : UNO_QUERY_THROW
211 0 : );
212 : }
213 :
214 0 : xNewParent.set( ensureModelEnv( xRightMostLeaf, xNewPageForms ), UNO_QUERY_THROW );
215 :
216 : // we successfully cloned the environment in m_xEnvironmentHistory, so we can use m_aEventsHistory
217 : // (which describes the events of our model at the moment m_xEnvironmentHistory was created)
218 0 : aNewEvents = m_aEventsHistory;
219 : }
220 0 : catch( const Exception& )
221 : {
222 : DBG_UNHANDLED_EXCEPTION();
223 0 : }
224 : }
225 :
226 0 : if ( !xNewParent.is() )
227 : {
228 : // are we a valid part of our current page forms ?
229 0 : Reference< XIndexContainer > xOldForms;
230 0 : if ( pOldFormPage )
231 0 : xOldForms.set( pOldFormPage->GetForms(), UNO_QUERY_THROW );
232 :
233 0 : if ( xOldForms.is() )
234 : {
235 : // search (upward from our model) for xOldForms
236 0 : Reference< XChild > xSearch( GetUnoControlModel(), UNO_QUERY );
237 0 : while (xSearch.is())
238 : {
239 0 : if ( xSearch == xOldForms )
240 0 : break;
241 0 : xSearch = Reference< XChild >( xSearch->getParent(), UNO_QUERY );
242 : }
243 0 : if ( xSearch.is() ) // implies xSearch == xOldForms, which means we're a valid part of our current page forms hierarchy
244 : {
245 0 : Reference< XChild > xMeAsChild( GetUnoControlModel(), UNO_QUERY );
246 0 : xNewParent.set( ensureModelEnv( xMeAsChild->getParent(), xNewPageForms ), UNO_QUERY );
247 :
248 0 : if ( xNewParent.is() )
249 : {
250 : try
251 : {
252 : // transfer the events from our (model's) parent to the new (model's) parent, too
253 0 : Reference< XEventAttacherManager > xEventManager(xMeAsChild->getParent(), UNO_QUERY);
254 0 : Reference< XIndexAccess > xManagerAsIndex(xEventManager, UNO_QUERY);
255 0 : if (xManagerAsIndex.is())
256 : {
257 0 : sal_Int32 nPos = getElementPos(xManagerAsIndex, xMeAsChild);
258 0 : if (nPos >= 0)
259 0 : aNewEvents = xEventManager->getScriptEvents(nPos);
260 : }
261 : else
262 0 : aNewEvents = aEvts;
263 : }
264 0 : catch( const Exception& )
265 : {
266 : DBG_UNHANDLED_EXCEPTION();
267 : }
268 0 : }
269 0 : }
270 0 : }
271 : }
272 :
273 : // now set the page
274 0 : SdrUnoObj::SetPage(_pNewPage);
275 :
276 : // place my model within the new parent container
277 0 : if (xNewParent.is())
278 : {
279 0 : Reference< XFormComponent > xMeAsFormComp(GetUnoControlModel(), UNO_QUERY);
280 0 : if (xMeAsFormComp.is())
281 : {
282 : // check if I have another parent (and remove me, if necessary)
283 0 : Reference< XIndexContainer > xOldParent(xMeAsFormComp->getParent(), UNO_QUERY);
284 0 : if (xOldParent.is())
285 : {
286 0 : sal_Int32 nPos = getElementPos(xOldParent, xMeAsFormComp);
287 0 : if (nPos > -1)
288 0 : xOldParent->removeByIndex(nPos);
289 : }
290 : // and insert into the new container
291 0 : xNewParent->insertByIndex(xNewParent->getCount(), makeAny(xMeAsFormComp));
292 :
293 : // transfer the events
294 0 : if (aNewEvents.getLength())
295 : {
296 : try
297 : {
298 0 : Reference< XEventAttacherManager > xEventManager(xNewParent, UNO_QUERY);
299 0 : Reference< XIndexAccess > xManagerAsIndex(xEventManager, UNO_QUERY);
300 0 : if (xManagerAsIndex.is())
301 : {
302 0 : sal_Int32 nPos = getElementPos(xManagerAsIndex, xMeAsFormComp);
303 : DBG_ASSERT(nPos >= 0, "FmFormObj::SetPage : inserted but not present ?");
304 0 : xEventManager->registerScriptEvents(nPos, aNewEvents);
305 0 : }
306 : }
307 0 : catch( const Exception& )
308 : {
309 : DBG_UNHANDLED_EXCEPTION();
310 : }
311 :
312 0 : }
313 0 : }
314 : }
315 :
316 : // delete my history
317 0 : if (m_xEnvironmentHistory.is())
318 0 : m_xEnvironmentHistory->dispose();
319 :
320 0 : m_xEnvironmentHistory = NULL;
321 0 : m_aEventsHistory.realloc(0);
322 :
323 0 : if ( pNewFormPage )
324 0 : pNewFormPage->GetImpl().formObjectInserted( *this );
325 : }
326 :
327 :
328 0 : sal_uInt32 FmFormObj::GetObjInventor() const
329 : {
330 0 : return FmFormInventor;
331 : }
332 :
333 :
334 0 : sal_uInt16 FmFormObj::GetObjIdentifier() const
335 : {
336 0 : return OBJ_UNO;
337 : }
338 :
339 :
340 0 : void FmFormObj::clonedFrom(const FmFormObj* _pSource)
341 : {
342 : DBG_ASSERT(_pSource != NULL, "FmFormObj::clonedFrom : invalid source !");
343 0 : if (m_xEnvironmentHistory.is())
344 0 : m_xEnvironmentHistory->dispose();
345 :
346 0 : m_xEnvironmentHistory = NULL;
347 0 : m_aEventsHistory.realloc(0);
348 :
349 0 : Reference< XChild > xSourceAsChild(_pSource->GetUnoControlModel(), UNO_QUERY);
350 0 : if (!xSourceAsChild.is())
351 0 : return;
352 :
353 0 : Reference< XInterface > xSourceContainer = xSourceAsChild->getParent();
354 :
355 0 : m_xEnvironmentHistory = css::form::Forms::create( comphelper::getProcessComponentContext() );
356 :
357 0 : ensureModelEnv(xSourceContainer, m_xEnvironmentHistory);
358 0 : m_aEventsHistory = aEvts;
359 : // if we we're clone there was a call to operator=, so aEvts are excatly the events we need here ...
360 : }
361 :
362 :
363 0 : FmFormObj* FmFormObj::Clone() const
364 : {
365 0 : FmFormObj* pFormObject = CloneHelper< FmFormObj >();
366 : DBG_ASSERT(pFormObject != NULL, "FmFormObj::Clone : invalid clone !");
367 0 : if (pFormObject)
368 0 : pFormObject->clonedFrom(this);
369 :
370 0 : return pFormObject;
371 : }
372 :
373 :
374 0 : void FmFormObj::NbcReformatText()
375 : {
376 0 : impl_checkRefDevice_nothrow( false );
377 0 : SdrUnoObj::NbcReformatText();
378 0 : }
379 :
380 :
381 0 : FmFormObj& FmFormObj::operator= (const FmFormObj& rObj)
382 : {
383 0 : if( this == &rObj )
384 0 : return *this;
385 0 : SdrUnoObj::operator= (rObj);
386 :
387 : // liegt das UnoControlModel in einer Eventumgebung,
388 : // dann koennen noch Events zugeordnet sein
389 0 : Reference< XFormComponent > xContent(rObj.xUnoControlModel, UNO_QUERY);
390 0 : if (xContent.is())
391 : {
392 0 : Reference< XEventAttacherManager > xManager(xContent->getParent(), UNO_QUERY);
393 0 : Reference< XIndexAccess > xManagerAsIndex(xManager, UNO_QUERY);
394 0 : if (xManagerAsIndex.is())
395 : {
396 0 : sal_Int32 nPos = getElementPos( xManagerAsIndex, xContent );
397 0 : if ( nPos >= 0 )
398 0 : aEvts = xManager->getScriptEvents( nPos );
399 0 : }
400 : }
401 : else
402 0 : aEvts = rObj.aEvts;
403 0 : return *this;
404 : }
405 :
406 :
407 : namespace
408 : {
409 0 : OUString lcl_getFormComponentAccessPath(const Reference< XInterface >& _xElement, Reference< XInterface >& _rTopLevelElement)
410 : {
411 0 : Reference< ::com::sun::star::form::XFormComponent> xChild(_xElement, UNO_QUERY);
412 0 : Reference< ::com::sun::star::container::XIndexAccess> xParent;
413 0 : if (xChild.is())
414 0 : xParent = Reference< ::com::sun::star::container::XIndexAccess>(xChild->getParent(), UNO_QUERY);
415 :
416 : // while the current content is a form
417 0 : OUString sReturn;
418 0 : OUString sCurrentIndex;
419 0 : while (xChild.is())
420 : {
421 : // get the content's relative pos within its parent container
422 0 : sal_Int32 nPos = getElementPos(xParent, xChild);
423 :
424 : // prepend this current relaive pos
425 0 : sCurrentIndex = OUString::number(nPos);
426 0 : if (!sReturn.isEmpty())
427 : {
428 0 : sCurrentIndex += "\\";
429 0 : sCurrentIndex += sReturn;
430 : }
431 :
432 0 : sReturn = sCurrentIndex;
433 :
434 : // travel up
435 0 : if (::comphelper::query_interface((Reference< XInterface >)xParent,xChild))
436 0 : xParent = Reference< ::com::sun::star::container::XIndexAccess>(xChild->getParent(), UNO_QUERY);
437 : }
438 :
439 0 : _rTopLevelElement = xParent;
440 0 : return sReturn;
441 : }
442 : }
443 :
444 :
445 0 : Reference< XInterface > FmFormObj::ensureModelEnv(const Reference< XInterface > & _rSourceContainer, const Reference<css::form::XForms>& _rTopLevelDestContainer)
446 : {
447 0 : Reference< XInterface > xTopLevelSouce;
448 0 : OUString sAccessPath = lcl_getFormComponentAccessPath(_rSourceContainer, xTopLevelSouce);
449 0 : if (!xTopLevelSouce.is())
450 : // something went wrong, maybe _rSourceContainer isn't part of a valid forms hierarchy
451 0 : return Reference< XInterface > ();
452 :
453 0 : Reference< XIndexContainer > xDestContainer(_rTopLevelDestContainer, UNO_QUERY_THROW);
454 0 : Reference< XIndexContainer > xSourceContainer(xTopLevelSouce, UNO_QUERY);
455 : DBG_ASSERT(xSourceContainer.is(), "FmFormObj::ensureModelEnv : the top level source is invalid !");
456 :
457 0 : sal_Int32 nTokIndex = 0;
458 0 : do
459 : {
460 0 : OUString aToken = sAccessPath.getToken( 0, '\\', nTokIndex );
461 0 : sal_uInt16 nIndex = (sal_uInt16)aToken.toInt32();
462 :
463 : // get the DSS of the source form (we have to find an aquivalent for)
464 : DBG_ASSERT(nIndex<xSourceContainer->getCount(), "FmFormObj::ensureModelEnv : invalid access path !");
465 0 : Reference< XPropertySet > xSourceForm;
466 0 : xSourceContainer->getByIndex(nIndex) >>= xSourceForm;
467 : DBG_ASSERT(xSourceForm.is(), "FmFormObj::ensureModelEnv : invalid source form !");
468 :
469 0 : Any aSrcCursorSource, aSrcCursorSourceType, aSrcDataSource;
470 : DBG_ASSERT(::comphelper::hasProperty(FM_PROP_COMMAND, xSourceForm) && ::comphelper::hasProperty(FM_PROP_COMMANDTYPE, xSourceForm)
471 : && ::comphelper::hasProperty(FM_PROP_DATASOURCE, xSourceForm), "FmFormObj::ensureModelEnv : invalid access path or invalid form (missing props) !");
472 : // the parent access path should refer to a row set
473 : try
474 : {
475 0 : aSrcCursorSource = xSourceForm->getPropertyValue(FM_PROP_COMMAND);
476 0 : aSrcCursorSourceType = xSourceForm->getPropertyValue(FM_PROP_COMMANDTYPE);
477 0 : aSrcDataSource = xSourceForm->getPropertyValue(FM_PROP_DATASOURCE);
478 : }
479 0 : catch(Exception&)
480 : {
481 : OSL_FAIL("FmFormObj::ensureModelEnv : could not retrieve a source DSS !");
482 : }
483 :
484 :
485 : // calc the number of (source) form siblings with the same DSS
486 0 : Reference< XPropertySet > xCurrentSourceForm, xCurrentDestForm;
487 0 : sal_Int16 nCurrentSourceIndex = 0, nCurrentDestIndex = 0;
488 0 : while (nCurrentSourceIndex <= nIndex)
489 : {
490 0 : sal_Bool bEqualDSS = sal_False;
491 0 : while (!bEqualDSS) // (we don't have to check nCurrentSourceIndex here : it's bound by nIndex)
492 : {
493 0 : xSourceContainer->getByIndex(nCurrentSourceIndex) >>= xCurrentSourceForm;
494 : DBG_ASSERT(xCurrentSourceForm.is(), "FmFormObj::ensureModelEnv : invalid form ancestor (2) !");
495 0 : bEqualDSS = sal_False;
496 0 : if (::comphelper::hasProperty(FM_PROP_DATASOURCE, xCurrentSourceForm))
497 : { // it is a form
498 : try
499 : {
500 0 : if ( ::comphelper::compare(xCurrentSourceForm->getPropertyValue(FM_PROP_COMMAND), aSrcCursorSource)
501 0 : && ::comphelper::compare(xCurrentSourceForm->getPropertyValue(FM_PROP_COMMANDTYPE), aSrcCursorSourceType)
502 0 : && ::comphelper::compare(xCurrentSourceForm->getPropertyValue(FM_PROP_DATASOURCE), aSrcDataSource)
503 : )
504 : {
505 0 : bEqualDSS = sal_True;
506 : }
507 : }
508 0 : catch(Exception&)
509 : {
510 : OSL_FAIL("FmFormObj::ensureModelEnv : exception while getting a sibling's DSS !");
511 : }
512 :
513 : }
514 0 : ++nCurrentSourceIndex;
515 : }
516 :
517 : DBG_ASSERT(bEqualDSS, "FmFormObj::ensureModelEnv : found no source form !");
518 : // ??? at least the nIndex-th one should have been found ???
519 :
520 : // now search the next one with the given DSS (within the destination container)
521 0 : bEqualDSS = sal_False;
522 0 : while (!bEqualDSS && (nCurrentDestIndex < xDestContainer->getCount()))
523 : {
524 0 : xDestContainer->getByIndex(nCurrentDestIndex) >>= xCurrentDestForm;
525 : DBG_ASSERT(xCurrentDestForm.is(), "FmFormObj::ensureModelEnv : invalid destination form !");
526 0 : bEqualDSS = sal_False;
527 0 : if (::comphelper::hasProperty(FM_PROP_DATASOURCE, xCurrentDestForm))
528 : { // it is a form
529 : try
530 : {
531 0 : if ( ::comphelper::compare(xCurrentDestForm->getPropertyValue(FM_PROP_COMMAND), aSrcCursorSource)
532 0 : && ::comphelper::compare(xCurrentDestForm->getPropertyValue(FM_PROP_COMMANDTYPE), aSrcCursorSourceType)
533 0 : && ::comphelper::compare(xCurrentDestForm->getPropertyValue(FM_PROP_DATASOURCE), aSrcDataSource)
534 : )
535 : {
536 0 : bEqualDSS = sal_True;
537 : }
538 : }
539 0 : catch(Exception&)
540 : {
541 : OSL_FAIL("FmFormObj::ensureModelEnv : exception while getting a destination DSS !");
542 : }
543 :
544 : }
545 0 : ++nCurrentDestIndex;
546 : }
547 :
548 0 : if (!bEqualDSS)
549 : { // There is at least one more source form with the given DSS than destination forms are.
550 : // correct this ...
551 : try
552 : {
553 : // create and insert (into the destination) a copy of the form
554 : xCurrentDestForm.set(
555 0 : ::comphelper::getProcessServiceFactory()->createInstance("com.sun.star.form.component.DataForm"),
556 0 : UNO_QUERY_THROW );
557 0 : ::comphelper::copyProperties( xCurrentSourceForm, xCurrentDestForm );
558 :
559 : DBG_ASSERT(nCurrentDestIndex == xDestContainer->getCount(), "FmFormObj::ensureModelEnv : something went wrong with the numbers !");
560 0 : xDestContainer->insertByIndex(nCurrentDestIndex, makeAny(xCurrentDestForm));
561 :
562 0 : ++nCurrentDestIndex;
563 : // like nCurrentSourceIndex, nCurrentDestIndex now points 'behind' the form it actally means
564 : }
565 0 : catch(Exception&)
566 : {
567 : OSL_FAIL("FmFormObj::ensureModelEnv : something went seriously wrong while creating a new form !");
568 : // no more options anymore ...
569 0 : return Reference< XInterface > ();
570 : }
571 :
572 : }
573 : }
574 :
575 : // now xCurrentDestForm is a form equivalent to xSourceForm (which means they have the same DSS and the same number
576 : // of left siblings with the same DSS, which counts for all their ancestors, too)
577 :
578 : // go down
579 0 : xDestContainer = Reference< XIndexContainer > (xCurrentDestForm, UNO_QUERY);
580 0 : xSourceContainer = Reference< XIndexContainer > (xSourceForm, UNO_QUERY);
581 0 : DBG_ASSERT(xDestContainer.is() && xSourceContainer.is(), "FmFormObj::ensureModelEnv : invalid container !");
582 : }
583 0 : while ( nTokIndex >= 0 );
584 :
585 0 : return xDestContainer;
586 : }
587 :
588 :
589 0 : void FmFormObj::SetModel( SdrModel* _pNewModel )
590 : {
591 0 : SdrUnoObj::SetModel( _pNewModel );
592 0 : impl_checkRefDevice_nothrow();
593 0 : }
594 :
595 :
596 0 : FmFormObj* FmFormObj::GetFormObject( SdrObject* _pSdrObject )
597 : {
598 0 : FmFormObj* pFormObject = dynamic_cast< FmFormObj* >( _pSdrObject );
599 0 : if ( !pFormObject )
600 : {
601 0 : SdrVirtObj* pVirtualObject = dynamic_cast< SdrVirtObj* >( _pSdrObject );
602 0 : if ( pVirtualObject )
603 0 : pFormObject = dynamic_cast< FmFormObj* >( &pVirtualObject->ReferencedObj() );
604 : }
605 0 : return pFormObject;
606 : }
607 :
608 :
609 0 : const FmFormObj* FmFormObj::GetFormObject( const SdrObject* _pSdrObject )
610 : {
611 0 : const FmFormObj* pFormObject = dynamic_cast< const FmFormObj* >( _pSdrObject );
612 0 : if ( !pFormObject )
613 : {
614 0 : const SdrVirtObj* pVirtualObject = dynamic_cast< const SdrVirtObj* >( _pSdrObject );
615 0 : if ( pVirtualObject )
616 0 : pFormObject = dynamic_cast< const FmFormObj* >( &pVirtualObject->GetReferencedObj() );
617 : }
618 0 : return pFormObject;
619 : }
620 :
621 :
622 0 : void FmFormObj::SetUnoControlModel( const Reference< com::sun::star::awt::XControlModel >& _rxModel )
623 : {
624 0 : SdrUnoObj::SetUnoControlModel( _rxModel );
625 :
626 0 : FmFormPage* pFormPage = PTR_CAST( FmFormPage, GetPage() );
627 0 : if ( pFormPage )
628 0 : pFormPage->GetImpl().formModelAssigned( *this );
629 :
630 0 : impl_checkRefDevice_nothrow( true );
631 0 : }
632 :
633 :
634 0 : bool FmFormObj::EndCreate( SdrDragStat& rStat, SdrCreateCmd eCmd )
635 : {
636 0 : bool bResult = SdrUnoObj::EndCreate(rStat, eCmd);
637 0 : if ( bResult && SDRCREATE_FORCEEND == eCmd && rStat.GetView() )
638 : {
639 0 : if ( pPage )
640 : {
641 0 : FmFormPage& rPage = dynamic_cast< FmFormPage& >( *pPage );
642 :
643 : try
644 : {
645 0 : Reference< XFormComponent > xContent( xUnoControlModel, UNO_QUERY_THROW );
646 0 : Reference< XForm > xParentForm( xContent->getParent(), UNO_QUERY );
647 :
648 0 : Reference< XIndexContainer > xFormToInsertInto;
649 :
650 0 : if ( !xParentForm.is() )
651 : { // model is not yet part of a form component hierachy
652 0 : xParentForm.set( rPage.GetImpl().findPlaceInFormComponentHierarchy( xContent ), UNO_SET_THROW );
653 0 : xFormToInsertInto.set( xParentForm, UNO_QUERY_THROW );
654 : }
655 :
656 0 : rPage.GetImpl().setUniqueName( xContent, xParentForm );
657 :
658 0 : if ( xFormToInsertInto.is() )
659 0 : xFormToInsertInto->insertByIndex( xFormToInsertInto->getCount(), makeAny( xContent ) );
660 : }
661 0 : catch( const Exception& )
662 : {
663 : DBG_UNHANDLED_EXCEPTION();
664 : }
665 : }
666 :
667 0 : FmFormView* pView( dynamic_cast< FmFormView* >( rStat.GetView() ) );
668 0 : FmXFormView* pViewImpl = pView ? pView->GetImpl() : NULL;
669 : OSL_ENSURE( pViewImpl, "FmFormObj::EndCreate: no view!?" );
670 0 : if ( pViewImpl )
671 0 : pViewImpl->onCreatedFormObject( *this );
672 : }
673 0 : return bResult;
674 : }
675 :
676 :
677 0 : void FmFormObj::BrkCreate( SdrDragStat& rStat )
678 : {
679 0 : SdrUnoObj::BrkCreate( rStat );
680 0 : impl_isolateControlModel_nothrow();
681 0 : }
682 :
683 :
684 : // #i70852# overload Layer interface to force to FormColtrol layer
685 :
686 0 : SdrLayerID FmFormObj::GetLayer() const
687 : {
688 : // #i72535#
689 : // i70852 was too radical, in SW obects (and thus, FormControls, too)
690 : // get moved to invisible layers to hide them (e.g. in hidden sections).
691 : // This means that form controls ARE allowed to be on other layers than
692 : // the form control layer ATM and that being member of form control layer
693 : // is no criteria to find all FormControls of a document.
694 : // To fix, use parent functionality
695 0 : return SdrUnoObj::GetLayer();
696 : }
697 :
698 0 : void FmFormObj::NbcSetLayer(SdrLayerID nLayer)
699 : {
700 : // #i72535#
701 : // See above. To fix, use parent functionality
702 0 : return SdrUnoObj::NbcSetLayer(nLayer);
703 : }
704 :
705 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|