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