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 : :
30 : : #include "svx/svxerr.hxx"
31 : : #include "fmpgeimp.hxx"
32 : : #include "fmundo.hxx"
33 : : #include "svx/fmtools.hxx"
34 : : #include "fmprop.hrc"
35 : : #include "fmservs.hxx"
36 : : #include "fmobj.hxx"
37 : : #include "formcontrolfactory.hxx"
38 : : #include "svx/svditer.hxx"
39 : : #include "svx/fmresids.hrc"
40 : : #include "svx/dbtoolsclient.hxx"
41 : : #include "treevisitor.hxx"
42 : :
43 : : #include <com/sun/star/sdb/CommandType.hpp>
44 : : #include <com/sun/star/util/XCloneable.hpp>
45 : : #include <com/sun/star/container/EnumerableMap.hpp>
46 : : #include <com/sun/star/drawing/XControlShape.hpp>
47 : :
48 : : #include <sfx2/objsh.hxx>
49 : : #include <svx/fmglob.hxx>
50 : : #include <svx/fmpage.hxx>
51 : : #include <svx/fmmodel.hxx>
52 : : #include <tools/resid.hxx>
53 : : #include <tools/diagnose_ex.h>
54 : : #include <tools/shl.hxx>
55 : : #include <vcl/stdtext.hxx>
56 : : #include <svx/dialmgr.hxx>
57 : : #include <comphelper/processfactory.hxx>
58 : : #include <comphelper/componentcontext.hxx>
59 : : #include <comphelper/uno3.hxx>
60 : : #include <comphelper/types.hxx>
61 : : #include <unotools/streamwrap.hxx>
62 : : #include <rtl/logfile.hxx>
63 : :
64 : : using namespace ::com::sun::star::uno;
65 : : using namespace ::com::sun::star::lang;
66 : : using namespace ::com::sun::star::sdbc;
67 : : using namespace ::com::sun::star::sdb;
68 : : using namespace ::com::sun::star::container;
69 : : using namespace ::com::sun::star::beans;
70 : : using namespace ::com::sun::star::form;
71 : : using ::com::sun::star::util::XCloneable;
72 : : using ::com::sun::star::awt::XControlModel;
73 : : using ::com::sun::star::container::XMap;
74 : : using ::com::sun::star::container::EnumerableMap;
75 : : using ::com::sun::star::drawing::XControlShape;
76 : : using namespace ::svxform;
77 : :
78 : : DBG_NAME(FmFormPageImpl)
79 : : //------------------------------------------------------------------------------
80 : 2994 : FmFormPageImpl::FmFormPageImpl( FmFormPage& _rPage )
81 : : :m_rPage( _rPage )
82 : : ,m_bFirstActivation( sal_True )
83 : : ,m_bAttemptedFormCreation( false )
84 [ + - ][ + - ]: 2994 : ,m_bInFind( false )
85 : : {
86 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFormPageImpl::FmFormPageImpl" );
87 : : DBG_CTOR(FmFormPageImpl,NULL);
88 : 2994 : }
89 : :
90 : : //------------------------------------------------------------------------------
91 : : namespace
92 : : {
93 : : typedef Reference< XInterface > FormComponent;
94 : :
95 : : class FormComponentInfo
96 : : {
97 : : public:
98 : 0 : size_t childCount( const FormComponent& _component ) const
99 : : {
100 [ # # ]: 0 : Reference< XIndexAccess > xContainer( _component, UNO_QUERY );
101 [ # # ]: 0 : if ( xContainer.is() )
102 [ # # ][ # # ]: 0 : return xContainer->getCount();
103 : 0 : return 0;
104 : : }
105 : :
106 : 0 : FormComponent getChild( const FormComponent& _component, size_t _index ) const
107 : : {
108 [ # # ]: 0 : Reference< XIndexAccess > xContainer( _component, UNO_QUERY_THROW );
109 [ # # ][ # # ]: 0 : return FormComponent( xContainer->getByIndex( _index ), UNO_QUERY );
[ # # ]
110 : : }
111 : : };
112 : :
113 : : typedef ::std::pair< FormComponent, FormComponent > FormComponentPair;
114 : :
115 : : class FormHierarchyComparator
116 : : {
117 : : public:
118 : 0 : FormHierarchyComparator()
119 : : {
120 : 0 : }
121 : :
122 : 0 : size_t childCount( const FormComponentPair& _components ) const
123 : : {
124 : 0 : size_t lhsCount = m_aComponentInfo.childCount( _components.first );
125 : 0 : size_t rhsCount = m_aComponentInfo.childCount( _components.second );
126 [ # # ]: 0 : if ( lhsCount != rhsCount )
127 [ # # ][ # # ]: 0 : throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Found inconsistent form component hierarchies (1)!" ) ), NULL );
[ # # ]
128 : 0 : return lhsCount;
129 : : }
130 : :
131 : 0 : FormComponentPair getChild( const FormComponentPair& _components, size_t _index ) const
132 : : {
133 : : return FormComponentPair(
134 : : m_aComponentInfo.getChild( _components.first, _index ),
135 : : m_aComponentInfo.getChild( _components.second, _index )
136 [ # # ][ # # ]: 0 : );
137 : : }
138 : : private:
139 : : FormComponentInfo m_aComponentInfo;
140 : : };
141 : :
142 : : typedef ::std::map< Reference< XControlModel >, Reference< XControlModel >, ::comphelper::OInterfaceCompare< XControlModel > > MapControlModels;
143 : :
144 : : class FormComponentAssignment
145 : : {
146 : : public:
147 : 0 : FormComponentAssignment( MapControlModels& _out_controlModelMap )
148 : 0 : :m_rControlModelMap( _out_controlModelMap )
149 : : {
150 : 0 : }
151 : :
152 : 0 : void process( const FormComponentPair& _component )
153 : : {
154 [ # # ]: 0 : Reference< XControlModel > lhsControlModel( _component.first, UNO_QUERY );
155 [ # # ]: 0 : Reference< XControlModel > rhsControlModel( _component.second, UNO_QUERY );
156 [ # # ]: 0 : if ( lhsControlModel.is() != rhsControlModel.is() )
157 [ # # ][ # # ]: 0 : throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Found inconsistent form component hierarchies (2)!" ) ), NULL );
[ # # ]
158 : :
159 [ # # ]: 0 : if ( lhsControlModel.is() )
160 [ # # ][ # # ]: 0 : m_rControlModelMap[ lhsControlModel ] = rhsControlModel;
161 : 0 : }
162 : :
163 : : private:
164 : : MapControlModels& m_rControlModelMap;
165 : : };
166 : : }
167 : :
168 : : //------------------------------------------------------------------------------
169 : 0 : void FmFormPageImpl::initFrom( FmFormPageImpl& i_foreignImpl )
170 : : {
171 : : // clone the Forms collection
172 [ # # ]: 0 : const Reference< XNameContainer > xForeignForms( const_cast< FmFormPageImpl& >( i_foreignImpl ).getForms( false ) );
173 [ # # ]: 0 : const Reference< XCloneable > xCloneable( xForeignForms, UNO_QUERY );
174 [ # # ]: 0 : if ( !xCloneable.is() )
175 : : {
176 : : // great, nothing to do
177 : : OSL_ENSURE( !xForeignForms.is(), "FmFormPageImpl::FmFormPageImpl: a non-cloneable forms container!?" );
178 : 0 : return;
179 : : }
180 : :
181 : : try
182 : : {
183 [ # # ][ # # ]: 0 : m_xForms.set( xCloneable->createClone(), UNO_QUERY_THROW );
[ # # ]
184 : :
185 : : // create a mapping between the original control models and their clones
186 [ # # ]: 0 : MapControlModels aModelAssignment;
187 : :
188 : : typedef TreeVisitor< FormComponentPair, FormHierarchyComparator, FormComponentAssignment > FormComponentVisitor;
189 [ # # ]: 0 : FormComponentVisitor aVisitor = FormComponentVisitor( FormHierarchyComparator() );
190 : :
191 : 0 : FormComponentAssignment aAssignmentProcessor( aModelAssignment );
192 [ # # ][ # # ]: 0 : aVisitor.process( FormComponentPair( xCloneable, m_xForms ), aAssignmentProcessor );
[ # # ]
193 : :
194 : : // assign the cloned models to their SdrObjects
195 [ # # ]: 0 : SdrObjListIter aForeignIter( i_foreignImpl.m_rPage );
196 [ # # ]: 0 : SdrObjListIter aOwnIter( m_rPage );
197 : :
198 : : OSL_ENSURE( aForeignIter.IsMore() == aOwnIter.IsMore(), "FmFormPageImpl::FmFormPageImpl: inconsistent number of objects (1)!" );
199 [ # # ][ # # ]: 0 : while ( aForeignIter.IsMore() && aOwnIter.IsMore() )
[ # # ]
200 : : {
201 [ # # ][ # # ]: 0 : FmFormObj* pForeignObj = dynamic_cast< FmFormObj* >( aForeignIter.Next() );
202 [ # # ][ # # ]: 0 : FmFormObj* pOwnObj = dynamic_cast< FmFormObj* >( aOwnIter.Next() );
203 : :
204 [ # # ][ # # ]: 0 : bool bForeignIsForm = pForeignObj && ( pForeignObj->GetObjInventor() == FmFormInventor );
[ # # ]
205 [ # # ][ # # ]: 0 : bool bOwnIsForm = pOwnObj && ( pOwnObj->GetObjInventor() == FmFormInventor );
[ # # ]
206 : :
207 [ # # ]: 0 : if ( bForeignIsForm != bOwnIsForm )
208 : : {
209 : : // if this fires, don't attempt to do further assignments, something's completely messed up
210 : : SAL_WARN( "svx.form", "FmFormPageImpl::FmFormPageImpl: inconsistent ordering of objects!" );
211 : : break;
212 : : }
213 : :
214 [ # # ]: 0 : if ( !bForeignIsForm )
215 : : // no form control -> next round
216 : 0 : continue;
217 : :
218 [ # # ]: 0 : Reference< XControlModel > xForeignModel( pForeignObj->GetUnoControlModel() );
219 [ # # ]: 0 : if ( !xForeignModel.is() )
220 : : {
221 : : // if this fires, the SdrObject does not have a UNO Control Model. This is pathological, but well ...
222 : : // So the cloned SdrObject will also not have a UNO Control Model.
223 : : SAL_WARN( "svx.form", "FmFormPageImpl::FmFormPageImpl: control shape without control!" );
224 : 0 : continue;
225 : : }
226 : :
227 [ # # ]: 0 : MapControlModels::const_iterator assignment = aModelAssignment.find( xForeignModel );
228 [ # # ]: 0 : if ( assignment == aModelAssignment.end() )
229 : : {
230 : : // if this fires, the source SdrObject has a model, but it is not part of the model hierarchy in
231 : : // i_foreignImpl.getForms().
232 : : // Pathological, too ...
233 : : SAL_WARN( "svx.form", "FmFormPageImpl::FmFormPageImpl: no clone found for this model!" );
234 : 0 : continue;
235 : : }
236 : :
237 [ # # ][ # # ]: 0 : pOwnObj->SetUnoControlModel( assignment->second );
238 : 0 : }
239 [ # # ][ # # ]: 0 : OSL_ENSURE( aForeignIter.IsMore() == aOwnIter.IsMore(), "FmFormPageImpl::FmFormPageImpl: inconsistent number of objects (2)!" );
240 : : }
241 [ # # ]: 0 : catch( const Exception& )
242 : : {
243 : : DBG_UNHANDLED_EXCEPTION();
244 [ # # ][ # # ]: 0 : }
245 : : }
246 : :
247 : : //------------------------------------------------------------------------------
248 : 0 : Reference< XMap > FmFormPageImpl::getControlToShapeMap()
249 : : {
250 [ # # ]: 0 : Reference< XMap > xControlShapeMap( m_aControlShapeMap.get(), UNO_QUERY );
251 [ # # ]: 0 : if ( xControlShapeMap.is() )
252 : 0 : return xControlShapeMap;
253 : :
254 [ # # ][ # # ]: 0 : xControlShapeMap = impl_createControlShapeMap_nothrow();
255 [ # # ]: 0 : m_aControlShapeMap = xControlShapeMap;
256 : 0 : return xControlShapeMap;
257 : : }
258 : :
259 : : //------------------------------------------------------------------------------
260 : : namespace
261 : : {
262 : 0 : static void lcl_insertFormObject_throw( const FmFormObj& _object, const Reference< XMap >& _map )
263 : : {
264 : : // the control model
265 [ # # ][ # # ]: 0 : Reference< XControlModel > xControlModel( _object.GetUnoControlModel(), UNO_QUERY );
266 : : OSL_ENSURE( xControlModel.is(), "lcl_insertFormObject_throw: suspicious: no control model!" );
267 [ # # ]: 0 : if ( !xControlModel.is() )
268 : : return;
269 : :
270 [ # # ][ # # ]: 0 : Reference< XControlShape > xControlShape( const_cast< FmFormObj& >( _object ).getUnoShape(), UNO_QUERY );
271 : : OSL_ENSURE( xControlShape.is(), "lcl_insertFormObject_throw: suspicious: no control shape!" );
272 [ # # ]: 0 : if ( !xControlShape.is() )
273 : : return;
274 : :
275 [ # # ][ # # ]: 0 : _map->put( makeAny( xControlModel ), makeAny( xControlShape ) );
[ # # ][ # # ]
[ # # ][ # # ]
276 : : }
277 : :
278 : 0 : static void lcl_removeFormObject_throw( const FmFormObj& _object, const Reference< XMap >& _map, bool i_ignoreNonExistence = false )
279 : : {
280 : : // the control model
281 [ # # ][ # # ]: 0 : Reference< XControlModel > xControlModel( _object.GetUnoControlModel(), UNO_QUERY );
282 : : OSL_ENSURE( xControlModel.is(), "lcl_removeFormObject: suspicious: no control model!" );
283 [ # # ]: 0 : if ( !xControlModel.is() )
284 : 0 : return;
285 : :
286 : : #if OSL_DEBUG_LEVEL > 0
287 : : Any aOldAssignment =
288 : : #endif
289 [ # # ][ # # ]: 0 : _map->remove( makeAny( xControlModel ) );
[ # # ][ # # ]
290 : : #if OSL_DEBUG_LEVEL > 0
291 : : (void)aOldAssignment;
292 : : #endif
293 : : OSL_ENSURE( !i_ignoreNonExistence ||
294 : : ( aOldAssignment == makeAny( Reference< XControlShape >( const_cast< FmFormObj& >( _object ).getUnoShape(), UNO_QUERY ) ) ),
295 : : "lcl_removeFormObject: map was inconsistent!" );
296 : 0 : (void)i_ignoreNonExistence;
297 : : }
298 : : }
299 : :
300 : : //------------------------------------------------------------------------------
301 : 0 : Reference< XMap > FmFormPageImpl::impl_createControlShapeMap_nothrow()
302 : : {
303 : 0 : Reference< XMap > xMap;
304 : :
305 : : try
306 : : {
307 [ # # ][ # # ]: 0 : ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
308 : : xMap.set( EnumerableMap::create( aContext.getUNOContext(),
309 : 0 : ::cppu::UnoType< XControlModel >::get(),
310 : 0 : ::cppu::UnoType< XControlShape >::get()
311 [ # # ][ # # ]: 0 : ).get(), UNO_SET_THROW );
[ # # ][ # # ]
312 : :
313 [ # # ]: 0 : SdrObjListIter aPageIter( m_rPage );
314 [ # # ]: 0 : while ( aPageIter.IsMore() )
315 : : {
316 : : // only FmFormObjs are what we're interested in
317 [ # # ][ # # ]: 0 : FmFormObj* pCurrent = FmFormObj::GetFormObject( aPageIter.Next() );
318 [ # # ]: 0 : if ( !pCurrent )
319 : 0 : continue;
320 : :
321 [ # # ]: 0 : lcl_insertFormObject_throw( *pCurrent, xMap );
322 [ # # ][ # # ]: 0 : }
323 : : }
324 [ # # ]: 0 : catch( const Exception& )
325 : : {
326 : : DBG_UNHANDLED_EXCEPTION();
327 : : }
328 : 0 : return xMap;
329 : : }
330 : :
331 : : //------------------------------------------------------------------------------
332 : 14751 : const Reference< XNameContainer >& FmFormPageImpl::getForms( bool _bForceCreate )
333 : : {
334 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFormPageImpl::getForms" );
335 [ + + ][ + + ]: 14751 : if ( m_xForms.is() || !_bForceCreate )
[ + + ]
336 : 14415 : return m_xForms;
337 : :
338 [ + - ]: 336 : if ( !m_bAttemptedFormCreation )
339 : : {
340 : 336 : m_bAttemptedFormCreation = true;
341 : :
342 [ + - ]: 336 : const ::rtl::OUString sFormsCollectionServiceName( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.form.Forms") );
343 : : m_xForms = Reference< XNameContainer > (
344 [ + - ][ + - ]: 672 : ::comphelper::getProcessServiceFactory()->createInstance( sFormsCollectionServiceName ),
345 : : UNO_QUERY
346 [ + - ][ + - ]: 336 : );
[ + - ]
347 : : DBG_ASSERT( m_xForms.is(), "FmFormPageImpl::getForms: could not create a forms collection!" );
348 : :
349 [ + + ][ + - ]: 336 : if ( m_aFormsCreationHdl.IsSet() )
350 : : {
351 [ + - ]: 246 : m_aFormsCreationHdl.Call( this );
352 : : }
353 : :
354 [ + - ][ + - ]: 336 : FmFormModel* pFormsModel = PTR_CAST( FmFormModel, m_rPage.GetModel() );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
355 : :
356 : : // give the newly created collection a place in the universe
357 [ + - ]: 336 : Reference< XChild > xAsChild( m_xForms, UNO_QUERY );
358 [ + + ]: 336 : if ( xAsChild.is() )
359 : : {
360 [ + - ]: 333 : SfxObjectShell* pObjShell = pFormsModel ? pFormsModel->GetObjectShell() : NULL;
361 [ + + ]: 333 : if ( pObjShell )
362 [ + - ][ + - ]: 330 : xAsChild->setParent( pObjShell->GetModel() );
[ + - ]
363 : : }
364 : :
365 : : // tell the UNDO environment that we have a new forms collection
366 [ + - ]: 336 : if ( pFormsModel )
367 [ + - ][ + - ]: 336 : pFormsModel->GetUndoEnv().AddForms( m_xForms );
368 : : }
369 : 14751 : return m_xForms;
370 : : }
371 : :
372 : : //------------------------------------------------------------------------------
373 [ + - ]: 2860 : FmFormPageImpl::~FmFormPageImpl()
374 : : {
375 [ + - ]: 2860 : xCurrentForm = NULL;
376 : :
377 [ + - ]: 2860 : ::comphelper::disposeComponent( m_xForms );
378 : : DBG_DTOR(FmFormPageImpl,NULL);
379 : 2860 : }
380 : :
381 : : //------------------------------------------------------------------------------
382 : 460 : bool FmFormPageImpl::validateCurForm()
383 : : {
384 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFormPageImpl::validateCurForm" );
385 [ + + ]: 460 : if ( !xCurrentForm.is() )
386 : 248 : return false;
387 : :
388 [ + - ]: 212 : Reference< XChild > xAsChild( xCurrentForm, UNO_QUERY );
389 : : DBG_ASSERT( xAsChild.is(), "FmFormPageImpl::validateCurForm: a form which is no child??" );
390 [ + - ][ + - ]: 212 : if ( !xAsChild.is() || !xAsChild->getParent().is() )
[ + - ][ - + ]
[ + - ]
[ - + # # ]
391 : 0 : xCurrentForm.clear();
392 : :
393 : 460 : return xCurrentForm.is();
394 : : }
395 : :
396 : : //------------------------------------------------------------------------------
397 : 18 : void FmFormPageImpl::setCurForm(Reference< ::com::sun::star::form::XForm > xForm)
398 : : {
399 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFormPageImpl::setCurForm" );
400 : 18 : xCurrentForm = xForm;
401 : 18 : }
402 : :
403 : : //------------------------------------------------------------------------------
404 : 460 : Reference< XForm > FmFormPageImpl::getDefaultForm()
405 : : {
406 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFormPageImpl::getDefaultForm" );
407 : 460 : Reference< XForm > xForm;
408 : :
409 [ + - ]: 460 : Reference< XNameContainer > xForms( getForms() );
410 : :
411 : : // by default, we use our "current form"
412 [ + + ][ + - ]: 460 : if ( !validateCurForm() )
413 : : {
414 : : // check whether there is a "standard" form
415 [ + - ][ + - ]: 248 : if ( xForms->hasElements() )
[ + + ]
416 : : {
417 : : // suche die Standardform
418 [ + - ][ + - ]: 2 : ::rtl::OUString sStandardFormname = String( SVX_RES( RID_STR_STDFORMNAME ) );
[ + - ][ + - ]
419 : :
420 : : try
421 : : {
422 [ + - ][ + - ]: 2 : if ( xForms->hasByName( sStandardFormname ) )
[ - + ]
423 [ # # ][ # # ]: 0 : xForm.set( xForms->getByName( sStandardFormname ), UNO_QUERY_THROW );
[ # # ]
424 : : else
425 : : {
426 [ + - ]: 2 : Reference< XIndexAccess > xFormsByIndex( xForms, UNO_QUERY_THROW );
427 [ + - ][ + - ]: 2 : xForm.set( xFormsByIndex->getByIndex(0), UNO_QUERY_THROW );
[ + - ][ # # ]
428 : : }
429 : : }
430 [ # # ]: 0 : catch( const Exception& )
431 : : {
432 : : DBG_UNHANDLED_EXCEPTION();
433 : 2 : }
434 : : }
435 : : }
436 : : else
437 : : {
438 [ + - ]: 212 : xForm = xCurrentForm;
439 : : }
440 : :
441 : : // did not find an existing suitable form -> create a new one
442 [ + + ]: 460 : if ( !xForm.is() )
443 : : {
444 [ + - ]: 246 : SdrModel* pModel = m_rPage.GetModel();
445 : :
446 [ + - ][ + - ]: 246 : if( pModel->IsUndoEnabled() )
447 : : {
448 [ + - ][ + - ]: 246 : XubString aStr(SVX_RES(RID_STR_FORM));
449 [ + - ][ + - ]: 246 : XubString aUndoStr(SVX_RES(RID_STR_UNDO_CONTAINER_INSERT));
450 [ + - ][ + - ]: 246 : aUndoStr.SearchAndReplace(rtl::OUString('#'), aStr);
[ + - ]
451 [ + - ][ + - ]: 246 : pModel->BegUndo(aUndoStr);
[ + - ]
452 : : }
453 : :
454 : : try
455 : : {
456 [ + - ][ + - ]: 246 : xForm.set( ::comphelper::getProcessServiceFactory()->createInstance( FM_SUN_COMPONENT_FORM ), UNO_QUERY );
[ + - ][ + - ]
[ + - ]
457 : :
458 : : // a form should always have the command type table as default
459 [ + - ]: 246 : Reference< XPropertySet > xFormProps( xForm, UNO_QUERY_THROW );
460 [ + - ][ + - ]: 246 : xFormProps->setPropertyValue( FM_PROP_COMMANDTYPE, makeAny( sal_Int32( CommandType::TABLE ) ) );
[ + - ][ + - ]
461 : :
462 : : // and the "Standard" name
463 [ + - ][ + - ]: 246 : ::rtl::OUString sName = String( SVX_RES( RID_STR_STDFORMNAME ) );
[ + - ][ + - ]
464 [ + - ][ + - ]: 246 : xFormProps->setPropertyValue( FM_PROP_NAME, makeAny( sName ) );
[ + - ][ + - ]
465 : :
466 [ + - ]: 246 : Reference< XIndexContainer > xContainer( xForms, UNO_QUERY );
467 [ + - ][ + - ]: 246 : if( pModel->IsUndoEnabled() )
468 : : {
469 : : pModel->AddUndo(new FmUndoContainerAction(*(FmFormModel*)pModel,
470 : : FmUndoContainerAction::Inserted,
471 : : xContainer,
472 : : xForm,
473 [ + - ][ + - ]: 246 : xContainer->getCount()));
[ + - ][ + - ]
[ + - ]
474 : : }
475 [ + - ][ + - ]: 246 : xForms->insertByName( sName, makeAny( xForm ) );
[ + - ]
476 [ # # ][ + - ]: 246 : xCurrentForm = xForm;
477 : : }
478 [ # # ]: 0 : catch( const Exception& )
479 : : {
480 : : DBG_UNHANDLED_EXCEPTION();
481 : 0 : xForm.clear();
482 : : }
483 : :
484 [ + - ][ + - ]: 246 : if( pModel->IsUndoEnabled() )
485 [ + - ]: 246 : pModel->EndUndo();
486 : : }
487 : :
488 : 460 : return xForm;
489 : : }
490 : :
491 : : //------------------------------------------------------------------------------
492 : 460 : Reference< ::com::sun::star::form::XForm > FmFormPageImpl::findPlaceInFormComponentHierarchy(
493 : : const Reference< XFormComponent > & rContent, const Reference< XDataSource > & rDatabase,
494 : : const ::rtl::OUString& rDBTitle, const ::rtl::OUString& rCursorSource, sal_Int32 nCommandType )
495 : : {
496 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFormPageImpl::findPlaceInFormComponentHierarchy" );
497 : : // if the control already is child of a form, don't do anything
498 [ + - ][ + - ]: 460 : if (!rContent.is() || rContent->getParent().is())
[ + - ][ - + ]
[ + - ]
[ - + # # ]
499 [ # # ]: 0 : return NULL;
500 : :
501 : 460 : Reference< XForm > xForm;
502 : :
503 : : // Wenn Datenbank und CursorSource gesetzt sind, dann wird
504 : : // die Form anhand dieser Kriterien gesucht, ansonsten nur aktuelle
505 : : // und die StandardForm
506 [ # # ][ - + ]: 460 : if (rDatabase.is() && !rCursorSource.isEmpty())
[ - + ]
507 : : {
508 [ # # ]: 0 : validateCurForm();
509 : :
510 : : // erst in der aktuellen form suchen
511 [ # # ][ # # ]: 0 : xForm = findFormForDataSource( xCurrentForm, rDatabase, rCursorSource, nCommandType );
512 : :
513 [ # # ][ # # ]: 0 : Reference< ::com::sun::star::container::XIndexAccess > xFormsByIndex( getForms(), UNO_QUERY );
514 : : DBG_ASSERT(xFormsByIndex.is(), "FmFormPageImpl::findPlaceInFormComponentHierarchy : no index access for my forms collection !");
515 [ # # ][ # # ]: 0 : sal_Int32 nCount = xFormsByIndex->getCount();
516 [ # # ][ # # ]: 0 : for (sal_Int32 i = 0; !xForm.is() && i < nCount; i++)
[ # # ]
517 : : {
518 : 0 : Reference< ::com::sun::star::form::XForm > xToSearch;
519 [ # # ][ # # ]: 0 : xFormsByIndex->getByIndex(i) >>= xToSearch;
[ # # ]
520 [ # # ][ # # ]: 0 : xForm = findFormForDataSource( xToSearch, rDatabase, rCursorSource, nCommandType );
521 : 0 : }
522 : :
523 : : // wenn keine ::com::sun::star::form gefunden, dann eine neue erzeugen
524 [ # # ]: 0 : if (!xForm.is())
525 : : {
526 [ # # ]: 0 : SdrModel* pModel = m_rPage.GetModel();
527 : :
528 [ # # ]: 0 : const bool bUndo = pModel->IsUndoEnabled();
529 : :
530 [ # # ]: 0 : if( bUndo )
531 : : {
532 [ # # ][ # # ]: 0 : XubString aStr(SVX_RES(RID_STR_FORM));
533 [ # # ][ # # ]: 0 : XubString aUndoStr(SVX_RES(RID_STR_UNDO_CONTAINER_INSERT));
534 [ # # ][ # # ]: 0 : aUndoStr.SearchAndReplace(rtl::OUString('#'), aStr);
[ # # ]
535 [ # # ][ # # ]: 0 : pModel->BegUndo(aUndoStr);
[ # # ]
536 : : }
537 : :
538 [ # # ][ # # ]: 0 : xForm = Reference< ::com::sun::star::form::XForm >(::comphelper::getProcessServiceFactory()->createInstance(FM_SUN_COMPONENT_FORM), UNO_QUERY);
[ # # ][ # # ]
[ # # ][ # # ]
539 : : // a form should always have the command type table as default
540 [ # # ]: 0 : Reference< ::com::sun::star::beans::XPropertySet > xFormProps(xForm, UNO_QUERY);
541 [ # # ][ # # ]: 0 : try { xFormProps->setPropertyValue(FM_PROP_COMMANDTYPE, makeAny(sal_Int32(CommandType::TABLE))); }
[ # # ][ # # ]
[ # # ]
542 [ # # ]: 0 : catch(Exception&) { }
543 : :
544 [ # # ]: 0 : if (!rDBTitle.isEmpty())
545 [ # # ][ # # ]: 0 : xFormProps->setPropertyValue(FM_PROP_DATASOURCE,makeAny(rDBTitle));
[ # # ][ # # ]
546 : : else
547 : : {
548 [ # # ]: 0 : Reference< ::com::sun::star::beans::XPropertySet > xDatabaseProps(rDatabase, UNO_QUERY);
549 [ # # ][ # # ]: 0 : Any aDatabaseUrl = xDatabaseProps->getPropertyValue(FM_PROP_URL);
[ # # ]
550 [ # # ][ # # ]: 0 : xFormProps->setPropertyValue(FM_PROP_DATASOURCE, aDatabaseUrl);
[ # # ]
551 : : }
552 : :
553 [ # # ][ # # ]: 0 : xFormProps->setPropertyValue(FM_PROP_COMMAND,makeAny(rCursorSource));
[ # # ][ # # ]
554 [ # # ][ # # ]: 0 : xFormProps->setPropertyValue(FM_PROP_COMMANDTYPE, makeAny(nCommandType));
[ # # ][ # # ]
555 : :
556 [ # # ][ # # ]: 0 : Reference< ::com::sun::star::container::XNameAccess > xNamedSet( getForms(), UNO_QUERY );
557 : :
558 [ # # ][ # # ]: 0 : const bool bTableOrQuery = ( CommandType::TABLE == nCommandType ) || ( CommandType::QUERY == nCommandType );
559 : : ::rtl::OUString sName = FormControlFactory::getUniqueName( xNamedSet,
560 [ # # ][ # # ]: 0 : bTableOrQuery ? rCursorSource : ::rtl::OUString( String( SVX_RES( RID_STR_STDFORMNAME ) ) ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
561 : :
562 [ # # ][ # # ]: 0 : xFormProps->setPropertyValue( FM_PROP_NAME, makeAny( sName ) );
[ # # ][ # # ]
563 : :
564 [ # # ]: 0 : if( bUndo )
565 : : {
566 [ # # ][ # # ]: 0 : Reference< ::com::sun::star::container::XIndexContainer > xContainer( getForms(), UNO_QUERY );
567 : : pModel->AddUndo(new FmUndoContainerAction(*(FmFormModel*)pModel,
568 : : FmUndoContainerAction::Inserted,
569 : : xContainer,
570 : : xForm,
571 [ # # ][ # # ]: 0 : xContainer->getCount()));
[ # # ][ # # ]
[ # # ]
572 : : }
573 : :
574 [ # # ][ # # ]: 0 : getForms()->insertByName( sName, makeAny( xForm ) );
[ # # ][ # # ]
575 : :
576 [ # # ]: 0 : if( bUndo )
577 [ # # ]: 0 : pModel->EndUndo();
578 : : }
579 [ # # ]: 0 : xCurrentForm = xForm;
580 : : }
581 : :
582 [ + - ][ + - ]: 460 : xForm = getDefaultForm();
583 : 460 : return xForm;
584 : : }
585 : :
586 : : //------------------------------------------------------------------------------
587 : 0 : Reference< XForm > FmFormPageImpl::findFormForDataSource(
588 : : const Reference< XForm > & rForm, const Reference< XDataSource > & _rxDatabase,
589 : : const ::rtl::OUString& _rCursorSource, sal_Int32 nCommandType)
590 : : {
591 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFormPageImpl::findFormForDataSource" );
592 : 0 : Reference< XForm > xResultForm;
593 [ # # ]: 0 : Reference< XRowSet > xDBForm(rForm, UNO_QUERY);
594 [ # # ]: 0 : Reference< XPropertySet > xFormProps(rForm, UNO_QUERY);
595 [ # # ][ # # ]: 0 : if (!xDBForm.is() || !xFormProps.is())
[ # # ]
596 : : return xResultForm;
597 : :
598 : : OSL_ENSURE(_rxDatabase.is(), "FmFormPageImpl::findFormForDataSource: invalid data source!");
599 : 0 : ::rtl::OUString sLookupName; // the name of the data source we're looking for
600 : 0 : ::rtl::OUString sFormDataSourceName; // the name of the data source the current connection in the form is based on
601 : : try
602 : : {
603 [ # # ]: 0 : Reference< XPropertySet > xDSProps(_rxDatabase, UNO_QUERY);
604 [ # # ]: 0 : if (xDSProps.is())
605 [ # # ][ # # ]: 0 : xDSProps->getPropertyValue(FM_PROP_NAME) >>= sLookupName;
[ # # ]
606 : :
607 [ # # ][ # # ]: 0 : xFormProps->getPropertyValue(FM_PROP_DATASOURCE) >>= sFormDataSourceName;
[ # # ]
608 : : // if there's no DataSourceName set at the form, check whether we can deduce one from its
609 : : // ActiveConnection
610 [ # # ]: 0 : if (sFormDataSourceName.isEmpty())
611 : : {
612 : 0 : Reference< XConnection > xFormConnection;
613 [ # # ][ # # ]: 0 : xFormProps->getPropertyValue( FM_PROP_ACTIVE_CONNECTION ) >>= xFormConnection;
[ # # ][ # # ]
614 [ # # ]: 0 : if ( !xFormConnection.is() )
615 [ # # ][ # # ]: 0 : OStaticDataAccessTools().isEmbeddedInDatabase( xFormProps, xFormConnection );
[ # # ]
616 [ # # ]: 0 : if (xFormConnection.is())
617 : : {
618 [ # # ]: 0 : Reference< XChild > xConnAsChild(xFormConnection, UNO_QUERY);
619 [ # # ]: 0 : if (xConnAsChild.is())
620 : : {
621 [ # # ][ # # ]: 0 : Reference< XDataSource > xFormDS(xConnAsChild->getParent(), UNO_QUERY);
[ # # ]
622 [ # # ]: 0 : if (xFormDS.is())
623 : : {
624 [ # # ][ # # ]: 0 : xDSProps = xDSProps.query(xFormDS);
625 [ # # ]: 0 : if (xDSProps.is())
626 [ # # ][ # # ]: 0 : xDSProps->getPropertyValue(FM_PROP_NAME) >>= sFormDataSourceName;
[ # # ]
627 : 0 : }
628 : 0 : }
629 : 0 : }
630 [ # # ]: 0 : }
631 : : }
632 [ # # ]: 0 : catch(const Exception& e)
633 : : {
634 : : (void)e;
635 : : OSL_FAIL("FmFormPageImpl::findFormForDataSource: caught an exception!");
636 : : }
637 : :
638 [ # # ]: 0 : if (sLookupName == sFormDataSourceName)
639 : : {
640 : : // jetzt noch ueberpruefen ob CursorSource und Type uebereinstimmen
641 [ # # ][ # # ]: 0 : ::rtl::OUString aCursorSource = ::comphelper::getString(xFormProps->getPropertyValue(FM_PROP_COMMAND));
[ # # ][ # # ]
642 [ # # ][ # # ]: 0 : sal_Int32 nType = ::comphelper::getINT32(xFormProps->getPropertyValue(FM_PROP_COMMANDTYPE));
[ # # ][ # # ]
643 [ # # ][ # # ]: 0 : if (aCursorSource.isEmpty() || ((nType == nCommandType) && (aCursorSource == _rCursorSource))) // found the form
[ # # ][ # # ]
644 : : {
645 [ # # ]: 0 : xResultForm = rForm;
646 : : // Ist noch keine Datenquelle gesetzt, wird dieses hier nachgeholt
647 [ # # ]: 0 : if (aCursorSource.isEmpty())
648 : : {
649 [ # # ][ # # ]: 0 : xFormProps->setPropertyValue(FM_PROP_COMMAND, makeAny(_rCursorSource));
[ # # ][ # # ]
650 [ # # ][ # # ]: 0 : xFormProps->setPropertyValue(FM_PROP_COMMANDTYPE, makeAny((sal_Int32)nCommandType));
[ # # ][ # # ]
651 : : }
652 : 0 : }
653 : : }
654 : :
655 : : // as long as xResultForm is NULL, search the child forms of rForm
656 [ # # ]: 0 : Reference< XIndexAccess > xComponents(rForm, UNO_QUERY);
657 [ # # ][ # # ]: 0 : sal_Int32 nCount = xComponents->getCount();
658 [ # # ][ # # ]: 0 : for (sal_Int32 i = 0; !xResultForm.is() && i < nCount; ++i)
[ # # ]
659 : : {
660 : 0 : Reference< ::com::sun::star::form::XForm > xSearchForm;
661 [ # # ][ # # ]: 0 : xComponents->getByIndex(i) >>= xSearchForm;
[ # # ]
662 : : // continue searching in the sub form
663 [ # # ]: 0 : if (xSearchForm.is())
664 [ # # ][ # # ]: 0 : xResultForm = findFormForDataSource( xSearchForm, _rxDatabase, _rCursorSource, nCommandType );
665 : 0 : }
666 : 0 : return xResultForm;
667 : : }
668 : :
669 : : //------------------------------------------------------------------------------
670 : 468 : ::rtl::OUString FmFormPageImpl::setUniqueName(const Reference< XFormComponent > & xFormComponent, const Reference< XForm > & xControls)
671 : : {
672 : : #if OSL_DEBUG_LEVEL > 0
673 : : try
674 : : {
675 : : Reference< XChild > xChild( xFormComponent, UNO_QUERY_THROW );
676 : : OSL_ENSURE( !xChild->getParent().is(), "FmFormPageImpl::setUniqueName: to be called before insertion!" );
677 : : }
678 : : catch( const Exception& )
679 : : {
680 : : DBG_UNHANDLED_EXCEPTION();
681 : : }
682 : : #endif
683 : 468 : ::rtl::OUString sName;
684 [ + - ]: 468 : Reference< ::com::sun::star::beans::XPropertySet > xSet(xFormComponent, UNO_QUERY);
685 [ + - ]: 468 : if (xSet.is())
686 : : {
687 [ + - ][ + - ]: 468 : sName = ::comphelper::getString( xSet->getPropertyValue( FM_PROP_NAME ) );
[ + - ][ + - ]
688 [ + - ]: 468 : Reference< ::com::sun::star::container::XNameAccess > xNameAcc(xControls, UNO_QUERY);
689 : :
690 [ + + ][ + - ]: 468 : if (sName.isEmpty() || xNameAcc->hasByName(sName))
[ + - ][ - + ]
[ + + ]
691 : : {
692 : : // setzen eines default Namens ueber die ClassId
693 : 460 : sal_Int16 nClassId( FormComponentType::CONTROL );
694 [ + - ][ + - ]: 460 : xSet->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId;
[ + - ]
695 : :
696 : : ::rtl::OUString sDefaultName = FormControlFactory::getDefaultUniqueName_ByComponentType(
697 [ + - ][ + - ]: 460 : Reference< XNameAccess >( xControls, UNO_QUERY ), xSet );
698 : :
699 : : // bei Radiobuttons, die einen Namen haben, diesen nicht ueberschreiben!
700 [ # # ][ + - ]: 460 : if (sName.isEmpty() || nClassId != ::com::sun::star::form::FormComponentType::RADIOBUTTON)
[ - + ]
701 : : {
702 [ + - ][ + - ]: 460 : xSet->setPropertyValue(FM_PROP_NAME, makeAny(sDefaultName));
[ + - ][ + - ]
703 : : }
704 : :
705 : 460 : sName = sDefaultName;
706 : 468 : }
707 : : }
708 : 468 : return sName;
709 : : }
710 : :
711 : : //----------------------------------------------------------------------------------------------------------------------
712 : 40 : void FmFormPageImpl::formModelAssigned( const FmFormObj& _object )
713 : : {
714 [ + - ][ + - ]: 40 : Reference< XMap > xControlShapeMap( m_aControlShapeMap.get(), UNO_QUERY );
[ # # ]
715 [ + - ]: 40 : if ( !xControlShapeMap.is() )
716 : : // our map does not exist -> not interested in this event
717 : 40 : return;
718 : :
719 : : try
720 : : {
721 [ # # ]: 0 : lcl_removeFormObject_throw( _object, xControlShapeMap, false );
722 [ # # ]: 0 : lcl_insertFormObject_throw( _object, xControlShapeMap );
723 : : }
724 [ # # ]: 0 : catch( const Exception& )
725 : : {
726 : : DBG_UNHANDLED_EXCEPTION();
727 [ - + ]: 40 : }
728 : : }
729 : :
730 : : //----------------------------------------------------------------------------------------------------------------------
731 : 537 : void FmFormPageImpl::formObjectInserted( const FmFormObj& _object )
732 : : {
733 [ + - ][ + - ]: 537 : Reference< XMap > xControlShapeMap( m_aControlShapeMap.get(), UNO_QUERY );
[ # # ]
734 [ + - ]: 537 : if ( !xControlShapeMap.is() )
735 : : // our map does not exist -> not interested in this event
736 : 537 : return;
737 : :
738 : : try
739 : : {
740 [ # # ]: 0 : lcl_insertFormObject_throw( _object, xControlShapeMap );
741 : : }
742 [ # # ]: 0 : catch( const Exception& )
743 : : {
744 : : DBG_UNHANDLED_EXCEPTION();
745 [ - + ]: 537 : }
746 : : }
747 : :
748 : : //----------------------------------------------------------------------------------------------------------------------
749 : 477 : void FmFormPageImpl::formObjectRemoved( const FmFormObj& _object )
750 : : {
751 [ + - ][ + - ]: 477 : Reference< XMap > xControlShapeMap( m_aControlShapeMap.get(), UNO_QUERY );
[ # # ]
752 [ + - ]: 477 : if ( !xControlShapeMap.is() )
753 : : // our map does not exist -> not interested in this event
754 : 477 : return;
755 : :
756 : : try
757 : : {
758 [ # # ]: 0 : lcl_removeFormObject_throw( _object, xControlShapeMap );
759 : : }
760 [ # # ]: 0 : catch( const Exception& )
761 : : {
762 : : DBG_UNHANDLED_EXCEPTION();
763 [ - + ]: 477 : }
764 : : }
765 : :
766 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|