merge the formfield patch from ooo-build
[ooovba.git] / svx / source / form / fmpgeimp.cxx
blob9da374d24df11548d562c3ad71a4394f639d0e0f
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: fmpgeimp.cxx,v $
10 * $Revision: 1.38 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 #include "svxerr.hxx"
35 #include "fmpgeimp.hxx"
36 #include "fmundo.hxx"
37 #include "fmtools.hxx"
38 #include "fmprop.hrc"
39 #include "fmservs.hxx"
40 #include "fmobj.hxx"
41 #include "formcontrolfactory.hxx"
42 #include "svditer.hxx"
43 #include "fmresids.hrc"
44 #include "svx/dbtoolsclient.hxx"
45 #include "treevisitor.hxx"
47 #include <com/sun/star/sdb/CommandType.hpp>
48 #include <com/sun/star/util/XCloneable.hpp>
49 #include <com/sun/star/container/EnumerableMap.hpp>
50 #include <com/sun/star/drawing/XControlShape.hpp>
52 #include <sfx2/objsh.hxx>
53 #include <svx/fmglob.hxx>
54 #include <svx/fmpage.hxx>
55 #include <svx/fmmodel.hxx>
56 #include <tools/resid.hxx>
57 #include <tools/diagnose_ex.h>
58 #include <tools/shl.hxx>
59 #include <vcl/stdtext.hxx>
60 #include <svx/dialmgr.hxx>
61 #include <comphelper/processfactory.hxx>
62 #include <comphelper/componentcontext.hxx>
63 #include <comphelper/uno3.hxx>
64 #include <comphelper/types.hxx>
65 #include <unotools/streamwrap.hxx>
66 #include <rtl/logfile.hxx>
68 using namespace ::com::sun::star::uno;
69 using namespace ::com::sun::star::lang;
70 using namespace ::com::sun::star::sdbc;
71 using namespace ::com::sun::star::sdb;
72 using namespace ::com::sun::star::container;
73 using namespace ::com::sun::star::beans;
74 using namespace ::com::sun::star::form;
75 using ::com::sun::star::util::XCloneable;
76 using ::com::sun::star::awt::XControlModel;
77 using ::com::sun::star::container::XMap;
78 using ::com::sun::star::container::EnumerableMap;
79 using ::com::sun::star::drawing::XControlShape;
80 using namespace ::svxform;
82 DBG_NAME(FmFormPageImpl)
83 //------------------------------------------------------------------------------
84 FmFormPageImpl::FmFormPageImpl( FmFormPage& _rPage )
85 :m_rPage( _rPage )
86 ,m_bFirstActivation( sal_True )
87 ,m_bAttemptedFormCreation( false )
88 ,m_bInFind( false )
90 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFormPageImpl::FmFormPageImpl" );
91 DBG_CTOR(FmFormPageImpl,NULL);
94 //------------------------------------------------------------------------------
95 namespace
97 typedef Reference< XInterface > FormComponent;
99 class FormComponentInfo
101 public:
102 size_t childCount( const FormComponent& _component ) const
104 Reference< XIndexAccess > xContainer( _component, UNO_QUERY );
105 if ( xContainer.is() )
106 return xContainer->getCount();
107 return 0;
110 FormComponent getChild( const FormComponent& _component, size_t _index ) const
112 Reference< XIndexAccess > xContainer( _component, UNO_QUERY_THROW );
113 return FormComponent( xContainer->getByIndex( _index ), UNO_QUERY );
117 typedef ::std::pair< FormComponent, FormComponent > FormComponentPair;
119 class FormHierarchyComparator
121 public:
122 FormHierarchyComparator()
126 size_t childCount( const FormComponentPair& _components ) const
128 size_t lhsCount = m_aComponentInfo.childCount( _components.first );
129 size_t rhsCount = m_aComponentInfo.childCount( _components.second );
130 if ( lhsCount != rhsCount )
131 throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Found inconsistent form component hierarchies (1)!" ) ), NULL );
132 return lhsCount;
135 FormComponentPair getChild( const FormComponentPair& _components, size_t _index ) const
137 return FormComponentPair(
138 m_aComponentInfo.getChild( _components.first, _index ),
139 m_aComponentInfo.getChild( _components.second, _index )
142 private:
143 FormComponentInfo m_aComponentInfo;
146 typedef ::std::map< Reference< XControlModel >, Reference< XControlModel >, ::comphelper::OInterfaceCompare< XControlModel > > MapControlModels;
148 class FormComponentAssignment
150 public:
151 FormComponentAssignment( MapControlModels& _out_controlModelMap )
152 :m_rControlModelMap( _out_controlModelMap )
156 void process( const FormComponentPair& _component )
158 Reference< XControlModel > lhsControlModel( _component.first, UNO_QUERY );
159 Reference< XControlModel > rhsControlModel( _component.second, UNO_QUERY );
160 if ( lhsControlModel.is() != rhsControlModel.is() )
161 throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Found inconsistent form component hierarchies (2)!" ) ), NULL );
163 if ( lhsControlModel.is() )
164 m_rControlModelMap[ lhsControlModel ] = rhsControlModel;
167 private:
168 MapControlModels& m_rControlModelMap;
172 //------------------------------------------------------------------------------
173 FmFormPageImpl::FmFormPageImpl( FmFormPage& _rPage, const FmFormPageImpl& rImpl )
174 :m_rPage( _rPage )
175 ,m_bFirstActivation( sal_True )
176 ,m_bAttemptedFormCreation( false )
178 DBG_CTOR(FmFormPageImpl,NULL);
180 // clone the Forms collection
181 Reference< XCloneable > xCloneable( const_cast< FmFormPageImpl& >( rImpl ).getForms( false ), UNO_QUERY );
182 if ( !xCloneable.is() )
184 // great, nothing to do
185 OSL_ENSURE( !const_cast< FmFormPageImpl& >( rImpl ).getForms( false ).is(), "FmFormPageImpl::FmFormPageImpl: a non-cloneable forms container!?" );
186 return;
190 m_xForms.set( xCloneable->createClone(), UNO_QUERY_THROW );
192 // create a mapping between the original control models and their clones
193 MapControlModels aModelAssignment;
195 typedef TreeVisitor< FormComponentPair, FormHierarchyComparator, FormComponentAssignment > FormComponentVisitor;
196 FormComponentVisitor aVisitor = FormComponentVisitor( FormHierarchyComparator() );
198 FormComponentAssignment aAssignmentProcessor( aModelAssignment );
199 aVisitor.process( FormComponentPair( xCloneable, m_xForms ), aAssignmentProcessor );
201 // assign the cloned models to their SdrObjects
202 SdrObjListIter aForeignIter( rImpl.m_rPage );
203 SdrObjListIter aOwnIter( m_rPage );
205 OSL_ENSURE( aForeignIter.IsMore() == aOwnIter.IsMore(), "FmFormPageImpl::FmFormPageImpl: inconsistent number of objects (1)!" );
206 while ( aForeignIter.IsMore() && aOwnIter.IsMore() )
208 FmFormObj* pForeignObj = dynamic_cast< FmFormObj* >( aForeignIter.Next() );
209 FmFormObj* pOwnObj = dynamic_cast< FmFormObj* >( aOwnIter.Next() );
211 bool bForeignIsForm = pForeignObj && ( pForeignObj->GetObjInventor() == FmFormInventor );
212 bool bOwnIsForm = pOwnObj && ( pOwnObj->GetObjInventor() == FmFormInventor );
214 if ( bForeignIsForm != bOwnIsForm )
216 OSL_ENSURE( false, "FmFormPageImpl::FmFormPageImpl: inconsistent ordering of objects!" );
217 // don't attempt to do further assignments, something's completely messed up
218 break;
220 if ( !bForeignIsForm )
221 // no form control -> next round
222 continue;
224 Reference< XControlModel > xForeignModel( pForeignObj->GetUnoControlModel() );
225 OSL_ENSURE( xForeignModel.is(), "FmFormPageImpl::FmFormPageImpl: control shape without control!" );
226 if ( !xForeignModel.is() )
227 // the SdrObject does not have a UNO Control Model. This is pathological, but well ... So the cloned
228 // SdrObject will also not have a UNO Control Model.
229 continue;
231 OSL_ENSURE( !pOwnObj->GetUnoControlModel().is(), "FmFormPageImpl::FmFormPageImpl: there already is a control model for the target object!" );
233 MapControlModels::const_iterator assignment = aModelAssignment.find( xForeignModel );
234 OSL_ENSURE( assignment != aModelAssignment.end(), "FmFormPageImpl::FmFormPageImpl: no clone found for this model!" );
235 if ( assignment == aModelAssignment.end() )
236 // the source SdrObject has a model, but it is not part of the model hierarchy in rImpl.getForms().
237 // Pathological, too ...
238 continue;
240 pOwnObj->SetUnoControlModel( assignment->second );
242 OSL_ENSURE( aForeignIter.IsMore() == aOwnIter.IsMore(), "FmFormPageImpl::FmFormPageImpl: inconsistent number of objects (2)!" );
244 catch( const Exception& )
246 DBG_UNHANDLED_EXCEPTION();
250 //------------------------------------------------------------------------------
251 Reference< XMap > FmFormPageImpl::getControlToShapeMap()
253 Reference< XMap > xControlShapeMap( m_aControlShapeMap.get(), UNO_QUERY );
254 if ( xControlShapeMap.is() )
255 return xControlShapeMap;
257 xControlShapeMap = impl_createControlShapeMap_nothrow();
258 m_aControlShapeMap = xControlShapeMap;
259 return xControlShapeMap;
262 //------------------------------------------------------------------------------
263 namespace
265 static void lcl_insertFormObject_throw( const FmFormObj& _object, const Reference< XMap >& _map )
267 // the control model
268 Reference< XControlModel > xControlModel( _object.GetUnoControlModel(), UNO_QUERY );
269 OSL_ENSURE( xControlModel.is(), "lcl_insertFormObject_throw: suspicious: no control model!" );
270 if ( !xControlModel.is() )
271 return;
273 Reference< XControlShape > xControlShape( const_cast< FmFormObj& >( _object ).getUnoShape(), UNO_QUERY );
274 OSL_ENSURE( xControlShape.is(), "lcl_insertFormObject_throw: suspicious: no control shape!" );
275 if ( !xControlShape.is() )
276 return;
278 _map->put( makeAny( xControlModel ), makeAny( xControlShape ) );
281 static void lcl_removeFormObject( const FmFormObj& _object, const Reference< XMap >& _map )
283 // the control model
284 Reference< XControlModel > xControlModel( _object.GetUnoControlModel(), UNO_QUERY );
285 OSL_ENSURE( xControlModel.is(), "lcl_removeFormObject: suspicious: no control model!" );
286 if ( !xControlModel.is() )
287 return;
289 #if OSL_DEBUG_LEVEL > 0
290 Any aOldAssignment =
291 #endif
292 _map->remove( makeAny( xControlModel ) );
293 OSL_ENSURE( aOldAssignment == makeAny( Reference< XControlShape >( const_cast< FmFormObj& >( _object ).getUnoShape(), UNO_QUERY ) ),
294 "lcl_removeFormObject: map was inconsistent!" );
298 //------------------------------------------------------------------------------
299 Reference< XMap > FmFormPageImpl::impl_createControlShapeMap_nothrow()
301 Reference< XMap > xMap;
305 ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
306 xMap.set( EnumerableMap::create( aContext.getUNOContext(),
307 ::cppu::UnoType< XControlModel >::get(),
308 ::cppu::UnoType< XControlShape >::get()
309 ).get(), UNO_SET_THROW );
311 SdrObjListIter aPageIter( m_rPage );
312 while ( aPageIter.IsMore() )
314 // only FmFormObjs are what we're interested in
315 FmFormObj* pCurrent = FmFormObj::GetFormObject( aPageIter.Next() );
316 if ( !pCurrent )
317 continue;
319 lcl_insertFormObject_throw( *pCurrent, xMap );
322 catch( const Exception& )
324 DBG_UNHANDLED_EXCEPTION();
326 return xMap;
329 //------------------------------------------------------------------------------
330 const Reference< XNameContainer >& FmFormPageImpl::getForms( bool _bForceCreate )
332 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFormPageImpl::getForms" );
333 if ( m_xForms.is() || !_bForceCreate )
334 return m_xForms;
336 if ( !m_bAttemptedFormCreation )
338 m_bAttemptedFormCreation = true;
340 const ::rtl::OUString sFormsCollectionServiceName = ::rtl::OUString::createFromAscii("com.sun.star.form.Forms");
341 m_xForms = Reference< XNameContainer > (
342 ::comphelper::getProcessServiceFactory()->createInstance( sFormsCollectionServiceName ),
343 UNO_QUERY
345 DBG_ASSERT( m_xForms.is(), "FmFormPageImpl::getForms: could not create a forms collection!" );
347 if ( m_aFormsCreationHdl.IsSet() )
349 m_aFormsCreationHdl.Call( this );
352 FmFormModel* pFormsModel = PTR_CAST( FmFormModel, m_rPage.GetModel() );
354 // give the newly created collection a place in the universe
355 Reference< XChild > xAsChild( m_xForms, UNO_QUERY );
356 if ( xAsChild.is() )
358 SfxObjectShell* pObjShell = pFormsModel ? pFormsModel->GetObjectShell() : NULL;
359 if ( pObjShell )
360 xAsChild->setParent( pObjShell->GetModel() );
363 // tell the UNDO environment that we have a new forms collection
364 if ( pFormsModel )
365 pFormsModel->GetUndoEnv().AddForms( m_xForms );
367 return m_xForms;
370 //------------------------------------------------------------------------------
371 FmFormPageImpl::~FmFormPageImpl()
373 xCurrentForm = NULL;
375 ::comphelper::disposeComponent( m_xForms );
376 DBG_DTOR(FmFormPageImpl,NULL);
379 //------------------------------------------------------------------------------
380 bool FmFormPageImpl::validateCurForm()
382 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFormPageImpl::validateCurForm" );
383 if ( !xCurrentForm.is() )
384 return false;
386 Reference< XChild > xAsChild( xCurrentForm, UNO_QUERY );
387 DBG_ASSERT( xAsChild.is(), "FmFormPageImpl::validateCurForm: a form which is no child??" );
388 if ( !xAsChild.is() || !xAsChild->getParent().is() )
389 xCurrentForm.clear();
391 return xCurrentForm.is();
394 //------------------------------------------------------------------------------
395 void FmFormPageImpl::setCurForm(Reference< ::com::sun::star::form::XForm > xForm)
397 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFormPageImpl::setCurForm" );
398 xCurrentForm = xForm;
401 //------------------------------------------------------------------------------
402 Reference< XForm > FmFormPageImpl::getDefaultForm()
404 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFormPageImpl::getDefaultForm" );
405 Reference< XForm > xForm;
407 Reference< XNameContainer > xForms( getForms() );
409 // by default, we use our "current form"
410 if ( !validateCurForm() )
412 // check whether there is a "standard" form
413 if ( xForms->hasElements() )
415 // suche die Standardform
416 ::rtl::OUString sStandardFormname = String( SVX_RES( RID_STR_STDFORMNAME ) );
420 if ( xForms->hasByName( sStandardFormname ) )
421 xForm.set( xForms->getByName( sStandardFormname ), UNO_QUERY_THROW );
422 else
424 Reference< XIndexAccess > xFormsByIndex( xForms, UNO_QUERY_THROW );
425 xForm.set( xFormsByIndex->getByIndex(0), UNO_QUERY_THROW );
428 catch( const Exception& )
430 DBG_UNHANDLED_EXCEPTION();
434 else
436 xForm = xCurrentForm;
439 // did not find an existing suitable form -> create a new one
440 if ( !xForm.is() )
442 SdrModel* pModel = m_rPage.GetModel();
444 if( pModel->IsUndoEnabled() )
446 XubString aStr(SVX_RES(RID_STR_FORM));
447 XubString aUndoStr(SVX_RES(RID_STR_UNDO_CONTAINER_INSERT));
448 aUndoStr.SearchAndReplace('#', aStr);
449 pModel->BegUndo(aUndoStr);
454 xForm.set( ::comphelper::getProcessServiceFactory()->createInstance( FM_SUN_COMPONENT_FORM ), UNO_QUERY );
456 // a form should always have the command type table as default
457 Reference< XPropertySet > xFormProps( xForm, UNO_QUERY_THROW );
458 xFormProps->setPropertyValue( FM_PROP_COMMANDTYPE, makeAny( sal_Int32( CommandType::TABLE ) ) );
460 // and the "Standard" name
461 ::rtl::OUString sName = String( SVX_RES( RID_STR_STDFORMNAME ) );
462 xFormProps->setPropertyValue( FM_PROP_NAME, makeAny( sName ) );
464 Reference< XIndexContainer > xContainer( xForms, UNO_QUERY );
465 if( pModel->IsUndoEnabled() )
467 pModel->AddUndo(new FmUndoContainerAction(*(FmFormModel*)pModel,
468 FmUndoContainerAction::Inserted,
469 xContainer,
470 xForm,
471 xContainer->getCount()));
473 xForms->insertByName( sName, makeAny( xForm ) );
474 xCurrentForm = xForm;
476 catch( const Exception& )
478 DBG_UNHANDLED_EXCEPTION();
479 xForm.clear();
482 if( pModel->IsUndoEnabled() )
483 pModel->EndUndo();
486 return xForm;
489 //------------------------------------------------------------------------------
490 Reference< ::com::sun::star::form::XForm > FmFormPageImpl::findPlaceInFormComponentHierarchy(
491 const Reference< XFormComponent > & rContent, const Reference< XDataSource > & rDatabase,
492 const ::rtl::OUString& rDBTitle, const ::rtl::OUString& rCursorSource, sal_Int32 nCommandType )
494 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFormPageImpl::findPlaceInFormComponentHierarchy" );
495 // if the control already is child of a form, don't do anything
496 if (!rContent.is() || rContent->getParent().is())
497 return NULL;
499 Reference< XForm > xForm;
501 // Wenn Datenbank und CursorSource gesetzt sind, dann wird
502 // die Form anhand dieser Kriterien gesucht, ansonsten nur aktuelle
503 // und die StandardForm
504 if (rDatabase.is() && rCursorSource.getLength())
506 validateCurForm();
508 // erst in der aktuellen form suchen
509 xForm = findFormForDataSource( xCurrentForm, rDatabase, rCursorSource, nCommandType );
511 Reference< ::com::sun::star::container::XIndexAccess > xFormsByIndex( getForms(), UNO_QUERY );
512 DBG_ASSERT(xFormsByIndex.is(), "FmFormPageImpl::findPlaceInFormComponentHierarchy : no index access for my forms collection !");
513 sal_Int32 nCount = xFormsByIndex->getCount();
514 for (sal_Int32 i = 0; !xForm.is() && i < nCount; i++)
516 Reference< ::com::sun::star::form::XForm > xToSearch;
517 xFormsByIndex->getByIndex(i) >>= xToSearch;
518 xForm = findFormForDataSource( xToSearch, rDatabase, rCursorSource, nCommandType );
521 // wenn keine ::com::sun::star::form gefunden, dann eine neue erzeugen
522 if (!xForm.is())
524 SdrModel* pModel = m_rPage.GetModel();
526 const bool bUndo = pModel->IsUndoEnabled();
528 if( bUndo )
530 XubString aStr(SVX_RES(RID_STR_FORM));
531 XubString aUndoStr(SVX_RES(RID_STR_UNDO_CONTAINER_INSERT));
532 aUndoStr.SearchAndReplace('#', aStr);
533 pModel->BegUndo(aUndoStr);
536 xForm = Reference< ::com::sun::star::form::XForm >(::comphelper::getProcessServiceFactory()->createInstance(FM_SUN_COMPONENT_FORM), UNO_QUERY);
537 // a form should always have the command type table as default
538 Reference< ::com::sun::star::beans::XPropertySet > xFormProps(xForm, UNO_QUERY);
539 try { xFormProps->setPropertyValue(FM_PROP_COMMANDTYPE, makeAny(sal_Int32(CommandType::TABLE))); }
540 catch(Exception&) { }
542 if (rDBTitle.getLength())
543 xFormProps->setPropertyValue(FM_PROP_DATASOURCE,makeAny(rDBTitle));
544 else
546 Reference< ::com::sun::star::beans::XPropertySet > xDatabaseProps(rDatabase, UNO_QUERY);
547 Any aDatabaseUrl = xDatabaseProps->getPropertyValue(FM_PROP_URL);
548 xFormProps->setPropertyValue(FM_PROP_DATASOURCE, aDatabaseUrl);
551 xFormProps->setPropertyValue(FM_PROP_COMMAND,makeAny(rCursorSource));
552 xFormProps->setPropertyValue(FM_PROP_COMMANDTYPE, makeAny(nCommandType));
554 Reference< ::com::sun::star::container::XNameAccess > xNamedSet( getForms(), UNO_QUERY );
556 const bool bTableOrQuery = ( CommandType::TABLE == nCommandType ) || ( CommandType::QUERY == nCommandType );
557 ::rtl::OUString sName = FormControlFactory::getUniqueName( xNamedSet,
558 bTableOrQuery ? rCursorSource : ::rtl::OUString( String( SVX_RES( RID_STR_STDFORMNAME ) ) ) );
560 xFormProps->setPropertyValue( FM_PROP_NAME, makeAny( sName ) );
562 if( bUndo )
564 Reference< ::com::sun::star::container::XIndexContainer > xContainer( getForms(), UNO_QUERY );
565 pModel->AddUndo(new FmUndoContainerAction(*(FmFormModel*)pModel,
566 FmUndoContainerAction::Inserted,
567 xContainer,
568 xForm,
569 xContainer->getCount()));
572 getForms()->insertByName( sName, makeAny( xForm ) );
574 if( bUndo )
575 pModel->EndUndo();
577 xCurrentForm = xForm;
580 xForm = getDefaultForm();
581 return xForm;
584 //------------------------------------------------------------------------------
585 Reference< XForm > FmFormPageImpl::findFormForDataSource(
586 const Reference< XForm > & rForm, const Reference< XDataSource > & _rxDatabase,
587 const ::rtl::OUString& _rCursorSource, sal_Int32 nCommandType)
589 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFormPageImpl::findFormForDataSource" );
590 Reference< XForm > xResultForm;
591 Reference< XRowSet > xDBForm(rForm, UNO_QUERY);
592 Reference< XPropertySet > xFormProps(rForm, UNO_QUERY);
593 if (!xDBForm.is() || !xFormProps.is())
594 return xResultForm;
596 OSL_ENSURE(_rxDatabase.is(), "FmFormPageImpl::findFormForDataSource: invalid data source!");
597 ::rtl::OUString sLookupName; // the name of the data source we're looking for
598 ::rtl::OUString sFormDataSourceName; // the name of the data source the current connection in the form is based on
601 Reference< XPropertySet > xDSProps(_rxDatabase, UNO_QUERY);
602 if (xDSProps.is())
603 xDSProps->getPropertyValue(FM_PROP_NAME) >>= sLookupName;
605 xFormProps->getPropertyValue(FM_PROP_DATASOURCE) >>= sFormDataSourceName;
606 // if there's no DataSourceName set at the form, check whether we can deduce one from its
607 // ActiveConnection
608 if (0 == sFormDataSourceName.getLength())
610 Reference< XConnection > xFormConnection;
611 xFormProps->getPropertyValue( FM_PROP_ACTIVE_CONNECTION ) >>= xFormConnection;
612 if ( !xFormConnection.is() )
613 OStaticDataAccessTools().isEmbeddedInDatabase( xFormProps, xFormConnection );
614 if (xFormConnection.is())
616 Reference< XChild > xConnAsChild(xFormConnection, UNO_QUERY);
617 if (xConnAsChild.is())
619 Reference< XDataSource > xFormDS(xConnAsChild->getParent(), UNO_QUERY);
620 if (xFormDS.is())
622 xDSProps = xDSProps.query(xFormDS);
623 if (xDSProps.is())
624 xDSProps->getPropertyValue(FM_PROP_NAME) >>= sFormDataSourceName;
630 catch(const Exception& e)
632 (void)e;
633 OSL_ENSURE(sal_False, "FmFormPageImpl::findFormForDataSource: caught an exception!");
636 if (sLookupName == sFormDataSourceName)
638 // jetzt noch ueberpruefen ob CursorSource und Type uebereinstimmen
639 ::rtl::OUString aCursorSource = ::comphelper::getString(xFormProps->getPropertyValue(FM_PROP_COMMAND));
640 sal_Int32 nType = ::comphelper::getINT32(xFormProps->getPropertyValue(FM_PROP_COMMANDTYPE));
641 if (!aCursorSource.getLength() || ((nType == nCommandType) && (aCursorSource == _rCursorSource))) // found the form
643 xResultForm = rForm;
644 // Ist noch keine Datenquelle gesetzt, wird dieses hier nachgeholt
645 if (!aCursorSource.getLength())
647 xFormProps->setPropertyValue(FM_PROP_COMMAND, makeAny(_rCursorSource));
648 xFormProps->setPropertyValue(FM_PROP_COMMANDTYPE, makeAny((sal_Int32)nCommandType));
653 // as long as xResultForm is NULL, search the child forms of rForm
654 Reference< XIndexAccess > xComponents(rForm, UNO_QUERY);
655 sal_Int32 nCount = xComponents->getCount();
656 for (sal_Int32 i = 0; !xResultForm.is() && i < nCount; ++i)
658 Reference< ::com::sun::star::form::XForm > xSearchForm;
659 xComponents->getByIndex(i) >>= xSearchForm;
660 // continue searching in the sub form
661 if (xSearchForm.is())
662 xResultForm = findFormForDataSource( xSearchForm, _rxDatabase, _rCursorSource, nCommandType );
664 return xResultForm;
667 //------------------------------------------------------------------------------
668 ::rtl::OUString FmFormPageImpl::setUniqueName(const Reference< XFormComponent > & xFormComponent, const Reference< XForm > & xControls)
670 #if OSL_DEBUG_LEVEL > 0
673 Reference< XChild > xChild( xFormComponent, UNO_QUERY_THROW );
674 OSL_ENSURE( !xChild->getParent().is(), "FmFormPageImpl::setUniqueName: to be called before insertion!" );
676 catch( const Exception& )
678 DBG_UNHANDLED_EXCEPTION();
680 #endif
681 ::rtl::OUString sName;
682 Reference< ::com::sun::star::beans::XPropertySet > xSet(xFormComponent, UNO_QUERY);
683 if (xSet.is())
685 sName = ::comphelper::getString( xSet->getPropertyValue( FM_PROP_NAME ) );
686 Reference< ::com::sun::star::container::XNameAccess > xNameAcc(xControls, UNO_QUERY);
688 if (!sName.getLength() || xNameAcc->hasByName(sName))
690 // setzen eines default Namens ueber die ClassId
691 sal_Int16 nClassId( FormComponentType::CONTROL );
692 xSet->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId;
694 ::rtl::OUString sDefaultName = FormControlFactory::getDefaultUniqueName_ByComponentType(
695 Reference< XNameAccess >( xControls, UNO_QUERY ), xSet );
697 // bei Radiobuttons, die einen Namen haben, diesen nicht ueberschreiben!
698 if (!sName.getLength() || nClassId != ::com::sun::star::form::FormComponentType::RADIOBUTTON)
700 xSet->setPropertyValue(FM_PROP_NAME, makeAny(sDefaultName));
703 sName = sDefaultName;
706 return sName;
709 //------------------------------------------------------------------
710 void FmFormPageImpl::formObjectInserted( const FmFormObj& _object )
712 Reference< XMap > xControlShapeMap( m_aControlShapeMap.get(), UNO_QUERY );
713 if ( !xControlShapeMap.is() )
714 // our map does not exist -> not interested in this event
715 return;
719 lcl_insertFormObject_throw( _object, xControlShapeMap );
721 catch( const Exception& )
723 DBG_UNHANDLED_EXCEPTION();
727 void FmFormPageImpl::formObjectRemoved( const FmFormObj& _object )
729 Reference< XMap > xControlShapeMap( m_aControlShapeMap.get(), UNO_QUERY );
730 if ( !xControlShapeMap.is() )
731 // our map does not exist -> not interested in this event
732 return;
736 lcl_removeFormObject( _object, xControlShapeMap );
738 catch( const Exception& )
740 DBG_UNHANDLED_EXCEPTION();