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