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