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