xref: /AOO41X/main/svx/source/form/navigatortreemodel.cxx (revision f6e50924346d0b8c0b07c91832a97665dd718b0c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26 #include <svx/dialmgr.hxx>
27 #include <svx/fmshell.hxx>
28 #include <svx/fmmodel.hxx>
29 #include <svx/fmpage.hxx>
30 #include <svx/fmglob.hxx>
31 #include "svx/svditer.hxx"
32 #include <svx/svdogrp.hxx>
33 #include <svx/svdpagv.hxx>
34 
35 #include "fmprop.hrc"
36 
37 #include "fmundo.hxx"
38 #include "fmhelp.hrc"
39 #include "fmexpl.hrc"
40 #include "fmexpl.hxx"
41 #include "svx/fmresids.hrc"
42 #include "fmshimp.hxx"
43 #include "fmobj.hxx"
44 #include <sfx2/objsh.hxx>
45 #include <tools/diagnose_ex.h>
46 #include <rtl/logfile.hxx>
47 #include <com/sun/star/container/XContainer.hpp>
48 
49 //............................................................................
50 namespace svxform
51 {
52 //............................................................................
53 
54     using namespace ::com::sun::star::uno;
55     using namespace ::com::sun::star::lang;
56     using namespace ::com::sun::star::beans;
57     using namespace ::com::sun::star::form;
58     using namespace ::com::sun::star::awt;
59     using namespace ::com::sun::star::container;
60     using namespace ::com::sun::star::script;
61     using namespace ::com::sun::star::sdb;
62 
63     //========================================================================
64     // class OFormComponentObserver
65     //========================================================================
66     //------------------------------------------------------------------------
OFormComponentObserver(NavigatorTreeModel * _pModel)67     OFormComponentObserver::OFormComponentObserver(NavigatorTreeModel* _pModel)
68         :m_pNavModel(_pModel)
69         ,m_nLocks(0)
70         ,m_bCanUndo(sal_True)
71     {
72         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::OFormComponentObserver" );
73     }
74 
75     // XPropertyChangeListener
76     //------------------------------------------------------------------------
disposing(const EventObject & Source)77     void SAL_CALL OFormComponentObserver::disposing(const EventObject& Source) throw( RuntimeException )
78     {
79         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::disposing" );
80         Remove( Source.Source );
81     }
82 
83     //------------------------------------------------------------------------
propertyChange(const PropertyChangeEvent & evt)84     void SAL_CALL OFormComponentObserver::propertyChange(const PropertyChangeEvent& evt) throw(RuntimeException)
85     {
86         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::propertyChange" );
87         if( !m_pNavModel ) return;
88         if( evt.PropertyName != FM_PROP_NAME ) return;
89 
90         Reference< XFormComponent >  xFormComponent(evt.Source, UNO_QUERY);
91         Reference< XForm >  xForm(evt.Source, UNO_QUERY);
92 
93         FmEntryData* pEntryData( NULL );
94         if( xForm.is() )
95             pEntryData = m_pNavModel->FindData( xForm, m_pNavModel->GetRootList() );
96         else if( xFormComponent.is() )
97             pEntryData = m_pNavModel->FindData( xFormComponent, m_pNavModel->GetRootList() );
98 
99         if( pEntryData )
100         {
101             ::rtl::OUString aNewName =  ::comphelper::getString(evt.NewValue);
102             pEntryData->SetText( aNewName );
103             FmNavNameChangedHint aNameChangedHint( pEntryData, aNewName );
104             m_pNavModel->Broadcast( aNameChangedHint );
105         }
106     }
107 
108     // XContainerListener
109     //------------------------------------------------------------------------------
elementInserted(const ContainerEvent & evt)110     void SAL_CALL OFormComponentObserver::elementInserted(const ContainerEvent& evt) throw(RuntimeException)
111     {
112         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::elementInserted" );
113         if (IsLocked() || !m_pNavModel)
114             return;
115 
116         // keine Undoaction einfuegen
117         m_bCanUndo = sal_False;
118 
119         Reference< XInterface > xTemp;
120         evt.Element >>= xTemp;
121         Insert(xTemp, ::comphelper::getINT32(evt.Accessor));
122 
123         m_bCanUndo = sal_True;
124     }
125 
126     //------------------------------------------------------------------------------
Insert(const Reference<XInterface> & xIface,sal_Int32 nIndex)127     void OFormComponentObserver::Insert(const Reference< XInterface > & xIface, sal_Int32 nIndex)
128     {
129         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::Insert" );
130         Reference< XForm >  xForm(xIface, UNO_QUERY);
131         if (xForm.is())
132         {
133             m_pNavModel->InsertForm(xForm, sal_uInt32(nIndex));
134             Reference< XIndexContainer >  xContainer(xForm, UNO_QUERY);
135             Reference< XInterface > xTemp;
136             for (sal_Int32 i = 0; i < xContainer->getCount(); i++)
137             {
138                 xContainer->getByIndex(i) >>= xTemp;
139                 Insert(xTemp, i);
140             }
141         }
142         else
143         {
144             Reference< XFormComponent >  xFormComp(xIface, UNO_QUERY);
145             if (xFormComp.is())
146                 m_pNavModel->InsertFormComponent(xFormComp, sal_uInt32(nIndex));
147         }
148     }
149 
150     //------------------------------------------------------------------------------
elementReplaced(const ContainerEvent & evt)151     void SAL_CALL OFormComponentObserver::elementReplaced(const ContainerEvent& evt) throw(RuntimeException)
152     {
153         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::elementReplaced" );
154         if (IsLocked() || !m_pNavModel)
155             return;
156 
157         m_bCanUndo = sal_False;
158 
159         // EntryData loeschen
160         Reference< XFormComponent >  xReplaced;
161         evt.ReplacedElement >>= xReplaced;
162         FmEntryData* pEntryData = m_pNavModel->FindData(xReplaced, m_pNavModel->GetRootList(), sal_True);
163         if (pEntryData)
164         {
165             if (pEntryData->ISA(FmControlData))
166             {
167                 Reference< XFormComponent >  xComp;
168                 evt.Element >>= xComp;
169                 DBG_ASSERT(xComp.is(), "OFormComponentObserver::elementReplaced : invalid argument !");
170                     // an einer FmControlData sollte eine XFormComponent haengen
171                 m_pNavModel->ReplaceFormComponent(xReplaced, xComp);
172             }
173             else if (pEntryData->ISA(FmFormData))
174             {
175                 DBG_ERROR("replacing forms not implemented yet !");
176             }
177         }
178 
179         m_bCanUndo = sal_True;
180     }
181 
182     //------------------------------------------------------------------------------
Remove(const::com::sun::star::uno::Reference<::com::sun::star::uno::XInterface> & _rxElement)183     void OFormComponentObserver::Remove( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxElement )
184     {
185         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::Remove" );
186         if (IsLocked() || !m_pNavModel)
187             return;
188 
189         m_bCanUndo = sal_False;
190 
191         //////////////////////////////////////////////////////////
192         // EntryData loeschen
193         FmEntryData* pEntryData = m_pNavModel->FindData( _rxElement, m_pNavModel->GetRootList(), sal_True );
194         if (pEntryData)
195             m_pNavModel->Remove(pEntryData);
196 
197         m_bCanUndo = sal_True;
198     }
199 
200     //------------------------------------------------------------------------------
elementRemoved(const ContainerEvent & evt)201     void SAL_CALL OFormComponentObserver::elementRemoved(const ContainerEvent& evt) throw(RuntimeException)
202     {
203         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::elementRemoved" );
204         Reference< XInterface > xElement;
205         evt.Element >>= xElement;
206         Remove( xElement );
207     }
208 
209     //========================================================================
210     // class NavigatorTreeModel
211     //========================================================================
212 
213     //------------------------------------------------------------------------
NavigatorTreeModel(const ImageList & _rNormalImages,const ImageList & _rHCImages)214     NavigatorTreeModel::NavigatorTreeModel( const ImageList& _rNormalImages, const ImageList& _rHCImages )
215                     :m_pFormShell(NULL)
216                     ,m_pFormPage(NULL)
217                     ,m_pFormModel(NULL)
218                     ,m_aNormalImages( _rNormalImages )
219                     ,m_aHCImages( _rHCImages )
220     {
221         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::NavigatorTreeModel" );
222         m_pPropChangeList = new OFormComponentObserver(this);
223         m_pPropChangeList->acquire();
224         m_pRootList = new FmEntryDataList();
225     }
226 
227     //------------------------------------------------------------------------
~NavigatorTreeModel()228     NavigatorTreeModel::~NavigatorTreeModel()
229     {
230         //////////////////////////////////////////////////////////////////////
231         // Als Listener abmelden
232         if( m_pFormShell)
233         {
234             FmFormModel* pFormModel = m_pFormShell->GetFormModel();
235             if( pFormModel && IsListening(*pFormModel))
236                 EndListening( *pFormModel );
237 
238             if (IsListening(*m_pFormShell))
239                 EndListening(*m_pFormShell);
240         }
241 
242         Clear();
243         delete m_pRootList;
244         m_pPropChangeList->ReleaseModel();
245         m_pPropChangeList->release();
246     }
247 
248 
249     //------------------------------------------------------------------------
SetModified(sal_Bool bMod)250     void NavigatorTreeModel::SetModified( sal_Bool bMod )
251     {
252         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::SetModified" );
253         if( !m_pFormShell ) return;
254         SfxObjectShell* pObjShell = m_pFormShell->GetFormModel()->GetObjectShell();
255         if( !pObjShell ) return;
256         pObjShell->SetModified( bMod );
257     }
258 
259     //------------------------------------------------------------------------
Clear()260     void NavigatorTreeModel::Clear()
261     {
262         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Clear" );
263         Reference< XNameContainer >  xForms( GetForms());
264         Reference< XContainer >  xContainer(xForms, UNO_QUERY);
265         if (xContainer.is())
266             xContainer->removeContainerListener((XContainerListener*)m_pPropChangeList);
267 
268         //////////////////////////////////////////////////////////////////////
269         // RootList loeschen
270         FmEntryData* pChildData;
271         FmEntryDataList* pRootList = GetRootList();
272 
273         for( sal_uInt32 i=pRootList->Count(); i>0; i-- )
274         {
275             pChildData = pRootList->GetObject(i-1);
276             pRootList->Remove( pChildData );
277             delete pChildData;
278         }
279 
280         //////////////////////////////////////////////////////////////////////
281         // UI benachrichtigen
282         FmNavClearedHint aClearedHint;
283         Broadcast( aClearedHint );
284     }
285 
286     //------------------------------------------------------------------------
GetForms() const287     Reference< XNameContainer >  NavigatorTreeModel::GetForms() const
288     {
289         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::GetForms" );
290         if( !m_pFormShell || !m_pFormShell->GetCurPage())
291             return NULL;
292         else
293             return m_pFormShell->GetCurPage()->GetForms();
294     }
295 
296     //------------------------------------------------------------------------
Insert(FmEntryData * pEntry,sal_uLong nRelPos,sal_Bool bAlterModel)297     void NavigatorTreeModel::Insert(FmEntryData* pEntry, sal_uLong nRelPos, sal_Bool bAlterModel)
298     {
299         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Insert" );
300         if (IsListening(*m_pFormModel))
301             EndListening(*m_pFormModel);
302 
303         m_pPropChangeList->Lock();
304         FmFormData* pFolder     = (FmFormData*) pEntry->GetParent();
305         Reference< XChild > xElement( pEntry->GetChildIFace() );
306         if (bAlterModel)
307         {
308             XubString aStr;
309             if (pEntry->ISA(FmFormData))
310                 aStr = SVX_RES(RID_STR_FORM);
311             else
312                 aStr = SVX_RES(RID_STR_CONTROL);
313 
314             Reference< XIndexContainer >  xContainer;
315             if (pFolder)
316                 xContainer = Reference< XIndexContainer > (pFolder->GetFormIface(), UNO_QUERY);
317             else
318                 xContainer = Reference< XIndexContainer > (GetForms(), UNO_QUERY);
319 
320             bool bUndo = m_pFormModel->IsUndoEnabled();
321 
322             if( bUndo )
323             {
324                 XubString aUndoStr(SVX_RES(RID_STR_UNDO_CONTAINER_INSERT));
325                 aUndoStr.SearchAndReplace('#', aStr);
326                 m_pFormModel->BegUndo(aUndoStr);
327             }
328 
329             if (nRelPos >= (sal_uInt32)xContainer->getCount())
330                 nRelPos = (sal_uInt32)xContainer->getCount();
331 
332             // UndoAction
333             if ( bUndo && m_pPropChangeList->CanUndo())
334             {
335                 m_pFormModel->AddUndo(new FmUndoContainerAction(*m_pFormModel,
336                                                          FmUndoContainerAction::Inserted,
337                                                          xContainer,
338                                                          xElement,
339                                                          nRelPos));
340             }
341 
342             // das Element muss den Typ haben, den der Container erwartet
343             if (xContainer->getElementType() ==
344                 ::getCppuType((const Reference< XForm>*)0))
345 
346             {
347                 Reference< XForm >  xElementAsForm(xElement, UNO_QUERY);
348                 xContainer->insertByIndex(nRelPos, makeAny(xElementAsForm));
349             }
350             else if (xContainer->getElementType() ==
351                 ::getCppuType((const Reference< XFormComponent>*)0))
352 
353             {
354                 Reference< XFormComponent >  xElementAsComponent(xElement, UNO_QUERY);
355                 xContainer->insertByIndex(nRelPos, makeAny(xElementAsComponent));
356             }
357             else
358             {
359                 DBG_ERROR("NavigatorTreeModel::Insert : the parent container needs an elementtype I don't know !");
360             }
361 
362             if( bUndo )
363                 m_pFormModel->EndUndo();
364         }
365 
366         //////////////////////////////////////////////////////////////////////
367         // Als PropertyChangeListener anmelden
368         Reference< XPropertySet >  xSet(xElement, UNO_QUERY);
369         if( xSet.is() )
370             xSet->addPropertyChangeListener( FM_PROP_NAME, m_pPropChangeList );
371 
372         //////////////////////////////////////////////////////////////////////
373         // Daten aus Model entfernen
374         if (pEntry->ISA(FmFormData))
375         {
376             Reference< XContainer >  xContainer(xElement, UNO_QUERY);
377             if (xContainer.is())
378                 xContainer->addContainerListener((XContainerListener*)m_pPropChangeList);
379         }
380 
381         if (pFolder)
382             pFolder->GetChildList()->Insert( pEntry, nRelPos );
383         else
384             GetRootList()->Insert( pEntry, nRelPos );
385 
386         //////////////////////////////////////////////////////////////////////
387         // UI benachrichtigen
388         FmNavInsertedHint aInsertedHint( pEntry, nRelPos );
389         Broadcast( aInsertedHint );
390 
391         m_pPropChangeList->UnLock();
392         if (IsListening(*m_pFormModel))
393             StartListening(*m_pFormModel);
394     }
395 
396     //------------------------------------------------------------------------
Remove(FmEntryData * pEntry,sal_Bool bAlterModel)397     void NavigatorTreeModel::Remove(FmEntryData* pEntry, sal_Bool bAlterModel)
398     {
399         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Remove" );
400         //////////////////////////////////////////////////////////////////////
401         // Form und Parent holen
402         if (!pEntry || !m_pFormModel)
403             return;
404 
405         if (IsListening(*m_pFormModel))
406             EndListening(*m_pFormModel);
407 
408         const bool bUndo = m_pFormModel->IsUndoEnabled();
409 
410         m_pPropChangeList->Lock();
411         FmFormData*     pFolder     = (FmFormData*) pEntry->GetParent();
412         Reference< XChild > xElement ( pEntry->GetChildIFace() );
413         if (bAlterModel)
414         {
415             XubString        aStr;
416             if (pEntry->ISA(FmFormData))
417                 aStr = SVX_RES(RID_STR_FORM);
418             else
419                 aStr = SVX_RES(RID_STR_CONTROL);
420 
421             if( bUndo )
422             {
423                 XubString aUndoStr(SVX_RES(RID_STR_UNDO_CONTAINER_REMOVE));
424                 aUndoStr.SearchAndReplace('#', aStr);
425                 m_pFormModel->BegUndo(aUndoStr);
426             }
427         }
428 
429         // jetzt die eigentliche Entfernung der Daten aus dem Model
430         if (pEntry->ISA(FmFormData))
431             RemoveForm((FmFormData*)pEntry);
432         else
433             RemoveFormComponent((FmControlData*)pEntry);
434 
435 
436         if (bAlterModel)
437         {
438             Reference< XIndexContainer >  xContainer(xElement->getParent(), UNO_QUERY);
439             // aus dem Container entfernen
440             sal_Int32 nContainerIndex = getElementPos(xContainer.get(), xElement);
441             // UndoAction
442             if (nContainerIndex >= 0)
443             {
444                 if ( bUndo && m_pPropChangeList->CanUndo())
445                 {
446                     m_pFormModel->AddUndo(new FmUndoContainerAction(*m_pFormModel,
447                                                           FmUndoContainerAction::Removed,
448                                                           xContainer,
449                                                           xElement, nContainerIndex ));
450                 }
451                 else if( !m_pPropChangeList->CanUndo() )
452                 {
453                     FmUndoContainerAction::DisposeElement( xElement );
454                 }
455 
456                 xContainer->removeByIndex(nContainerIndex );
457             }
458 
459             if( bUndo )
460                 m_pFormModel->EndUndo();
461         }
462 
463         // beim Vater austragen
464         if (pFolder)
465             pFolder->GetChildList()->Remove(pEntry);
466         else
467         {
468             GetRootList()->Remove(pEntry);
469             //////////////////////////////////////////////////////////////////////
470             // Wenn keine Form mehr in der Root, an der Shell CurForm zuruecksetzen
471             if (!GetRootList()->Count())
472                 m_pFormShell->GetImpl()->forgetCurrentForm();
473         }
474 
475         //////////////////////////////////////////////////////////////////////
476         // UI benachrichtigen
477         FmNavRemovedHint aRemovedHint( pEntry );
478         Broadcast( aRemovedHint );
479 
480         // Eintrag loeschen
481         delete pEntry;
482 
483         m_pPropChangeList->UnLock();
484         StartListening(*m_pFormModel);
485     }
486 
487     //------------------------------------------------------------------------
RemoveForm(FmFormData * pFormData)488     void NavigatorTreeModel::RemoveForm(FmFormData* pFormData)
489     {
490         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::RemoveForm" );
491         //////////////////////////////////////////////////////////////////////
492         // Form und Parent holen
493         if (!pFormData || !m_pFormModel)
494             return;
495 
496         FmEntryDataList*    pChildList = pFormData->GetChildList();
497         sal_uInt32 nCount = pChildList->Count();
498         for (sal_uInt32 i = nCount; i > 0; i--)
499         {
500             FmEntryData* pEntryData = pChildList->GetObject(i - 1);
501 
502             //////////////////////////////////////////////////////////////////////
503             // Child ist Form -> rekursiver Aufruf
504             if( pEntryData->ISA(FmFormData) )
505                 RemoveForm( (FmFormData*)pEntryData);
506             else if( pEntryData->ISA(FmControlData) )
507                 RemoveFormComponent((FmControlData*) pEntryData);
508         }
509 
510         //////////////////////////////////////////////////////////////////////
511         // Als PropertyChangeListener abmelden
512         Reference< XPropertySet > xSet( pFormData->GetPropertySet() );
513         if ( xSet.is() )
514             xSet->removePropertyChangeListener( FM_PROP_NAME, m_pPropChangeList );
515 
516         Reference< XContainer >  xContainer( pFormData->GetContainer() );
517         if (xContainer.is())
518             xContainer->removeContainerListener((XContainerListener*)m_pPropChangeList);
519     }
520 
521     //------------------------------------------------------------------------
RemoveFormComponent(FmControlData * pControlData)522     void NavigatorTreeModel::RemoveFormComponent(FmControlData* pControlData)
523     {
524         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::RemoveFormComponent" );
525         //////////////////////////////////////////////////////////////////////
526         // Control und Parent holen
527         if (!pControlData)
528             return;
529 
530         //////////////////////////////////////////////////////////////////////
531         // Als PropertyChangeListener abmelden
532         Reference< XPropertySet >  xSet( pControlData->GetPropertySet() );
533         if (xSet.is())
534             xSet->removePropertyChangeListener( FM_PROP_NAME, m_pPropChangeList);
535     }
536 
537     //------------------------------------------------------------------------
ClearBranch(FmFormData * pParentData)538     void NavigatorTreeModel::ClearBranch( FmFormData* pParentData )
539     {
540         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::ClearBranch" );
541         //////////////////////////////////////////////////////////////////////
542         // Alle Eintraege dieses Zweiges loeschen
543         FmEntryDataList* pChildList = pParentData->GetChildList();
544         FmEntryData* pChildData;
545 
546         for( sal_uInt32 i=pChildList->Count(); i>0; i-- )
547         {
548             pChildData = pChildList->GetObject(i-1);
549             if( pChildData->ISA(FmFormData) )
550                 ClearBranch( (FmFormData*)pChildData );
551 
552             pChildList->Remove( pChildData );
553         }
554     }
555 
556     //------------------------------------------------------------------------
FillBranch(FmFormData * pFormData)557     void NavigatorTreeModel::FillBranch( FmFormData* pFormData )
558     {
559         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::FillBranch" );
560         //////////////////////////////////////////////////////////////
561         // Forms aus der Root einfuegen
562         if( pFormData == NULL )
563         {
564             Reference< XIndexContainer >   xForms(GetForms(), UNO_QUERY);
565             if (!xForms.is())
566                 return;
567 
568             Reference< XForm >     xSubForm;
569             FmFormData* pSubFormData;
570             for (sal_Int32 i=0; i<xForms->getCount(); ++i)
571             {
572                 DBG_ASSERT( xForms->getByIndex(i).getValueType() == ::getCppuType((const Reference< XForm>*)NULL),
573                     "NavigatorTreeModel::FillBranch : the root container should supply only elements of type XForm");
574 
575                 xForms->getByIndex(i) >>= xSubForm;
576                 pSubFormData = new FmFormData( xSubForm, m_aNormalImages, m_aHCImages, pFormData );
577                 Insert( pSubFormData, LIST_APPEND );
578 
579                 //////////////////////////////////////////////////////////////
580                 // Neuer Branch, wenn SubForm wiederum Subforms enthaelt
581                 FillBranch( pSubFormData );
582             }
583         }
584 
585         //////////////////////////////////////////////////////////////
586         // Componenten einfuegen
587         else
588         {
589             Reference< XIndexContainer >  xComponents( GetFormComponents(pFormData));
590             if( !xComponents.is() ) return;
591 
592             ::rtl::OUString aControlName;
593             Reference< XInterface >  xInterface;
594             Reference< XPropertySet >  xSet;
595             FmControlData* pNewControlData;
596             FmFormData* pSubFormData;
597 
598             Reference< XFormComponent >  xCurrentComponent;
599             for (sal_Int32 j=0; j<xComponents->getCount(); ++j)
600             {
601                 xComponents->getByIndex(j) >>= xCurrentComponent;
602                 Reference< XForm >  xSubForm(xCurrentComponent, UNO_QUERY);
603 
604                 if (xSubForm.is())
605                 {   // die aktuelle Component ist eine Form
606                     pSubFormData = new FmFormData(xSubForm, m_aNormalImages, m_aHCImages, pFormData);
607                     Insert(pSubFormData, LIST_APPEND);
608 
609                     //////////////////////////////////////////////////////////////
610                     // Neuer Branch, wenn SubForm wiederum Subforms enthaelt
611                     FillBranch(pSubFormData);
612                 }
613                 else
614                 {
615                     pNewControlData = new FmControlData(xCurrentComponent, m_aNormalImages, m_aHCImages, pFormData);
616                     Insert(pNewControlData, LIST_APPEND);
617                 }
618             }
619         }
620     }
621 
622     //------------------------------------------------------------------------
InsertForm(const Reference<XForm> & xForm,sal_uInt32 nRelPos)623     void NavigatorTreeModel::InsertForm(const Reference< XForm > & xForm, sal_uInt32 nRelPos)
624     {
625         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::InsertForm" );
626         FmFormData* pFormData = (FmFormData*)FindData( xForm, GetRootList() );
627         if (pFormData)
628             return;
629 
630         //////////////////////////////////////////////////////////
631         // ParentData setzen
632         Reference< XInterface >  xIFace( xForm->getParent());
633         Reference< XForm >  xParentForm(xIFace, UNO_QUERY);
634         FmFormData* pParentData = NULL;
635         if (xParentForm.is())
636             pParentData = (FmFormData*)FindData( xParentForm, GetRootList() );
637 
638         pFormData = new FmFormData( xForm, m_aNormalImages, m_aHCImages, pParentData );
639         Insert( pFormData, nRelPos );
640     }
641 
642     //------------------------------------------------------------------------
InsertFormComponent(const Reference<XFormComponent> & xComp,sal_uInt32 nRelPos)643     void NavigatorTreeModel::InsertFormComponent(const Reference< XFormComponent > & xComp, sal_uInt32 nRelPos)
644     {
645         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::InsertFormComponent" );
646         //////////////////////////////////////////////////////////
647         // ParentData setzen
648         Reference< XInterface >  xIFace( xComp->getParent());
649         Reference< XForm >  xForm(xIFace, UNO_QUERY);
650         if (!xForm.is())
651             return;
652 
653         FmFormData* pParentData = (FmFormData*)FindData( xForm, GetRootList() );
654         if( !pParentData )
655         {
656             pParentData = new FmFormData( xForm, m_aNormalImages, m_aHCImages, NULL );
657             Insert( pParentData, LIST_APPEND );
658         }
659 
660         if (!FindData(xComp, pParentData->GetChildList(),sal_False))
661         {
662             //////////////////////////////////////////////////////////
663             // Neue EntryData setzen
664             FmEntryData* pNewEntryData = new FmControlData( xComp, m_aNormalImages, m_aHCImages, pParentData );
665 
666             //////////////////////////////////////////////////////////
667             // Neue EntryData einfuegen
668             Insert( pNewEntryData, nRelPos );
669         }
670     }
671 
672     //------------------------------------------------------------------------
ReplaceFormComponent(const Reference<XFormComponent> & xOld,const Reference<XFormComponent> & xNew)673     void NavigatorTreeModel::ReplaceFormComponent(const Reference< XFormComponent > & xOld, const Reference< XFormComponent > & xNew)
674     {
675         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::ReplaceFormComponent" );
676         FmEntryData* pData = FindData(xOld, GetRootList(), sal_True);
677         DBG_ASSERT(pData && pData->ISA(FmControlData), "NavigatorTreeModel::ReplaceFormComponent : invalid argument !");
678         ((FmControlData*)pData)->ModelReplaced( xNew, m_aNormalImages, m_aHCImages );
679 
680         FmNavModelReplacedHint aReplacedHint( pData );
681         Broadcast( aReplacedHint );
682     }
683 
684     //------------------------------------------------------------------------
FindData(const Reference<XInterface> & xElement,FmEntryDataList * pDataList,sal_Bool bRecurs)685     FmEntryData* NavigatorTreeModel::FindData(const Reference< XInterface > & xElement, FmEntryDataList* pDataList, sal_Bool bRecurs)
686     {
687         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::FindData" );
688         // normalize
689         Reference< XInterface > xIFace( xElement, UNO_QUERY );
690 
691         for (sal_uInt16 i=0; i < pDataList->Count(); i++)
692         {
693             FmEntryData* pEntryData = pDataList->GetObject(i);
694             if ( pEntryData->GetElement().get() == xIFace.get() )
695                 return pEntryData;
696             else if (bRecurs)
697             {
698                 pEntryData = FindData( xElement, pEntryData->GetChildList() );
699                 if (pEntryData)
700                     return pEntryData;
701             }
702         }
703         return NULL;
704     }
705 
706     //------------------------------------------------------------------------
FindData(const::rtl::OUString & rText,FmFormData * pParentData,sal_Bool bRecurs)707     FmEntryData* NavigatorTreeModel::FindData( const ::rtl::OUString& rText, FmFormData* pParentData, sal_Bool bRecurs )
708     {
709         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::FindData" );
710         FmEntryDataList* pDataList;
711         if( !pParentData )
712             pDataList = GetRootList();
713         else
714             pDataList = pParentData->GetChildList();
715 
716         ::rtl::OUString aEntryText;
717         FmEntryData* pEntryData;
718         FmEntryData* pChildData;
719 
720         for( sal_uInt16 i=0; i<pDataList->Count(); i++ )
721         {
722             pEntryData = pDataList->GetObject(i);
723             aEntryText = pEntryData->GetText();
724 
725             if (rText == aEntryText)
726                 return pEntryData;
727 
728             if( bRecurs && pEntryData->ISA(FmFormData) )
729             {
730                 pChildData = FindData( rText, (FmFormData*)pEntryData );
731                 if( pChildData )
732                     return pChildData;
733             }
734         }
735 
736         return NULL;
737     }
738 
739     //------------------------------------------------------------------------
Notify(SfxBroadcaster &,const SfxHint & rHint)740     void NavigatorTreeModel::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
741     {
742         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Notify" );
743         if( rHint.ISA(SdrHint) )
744         {
745             SdrHint* pSdrHint = (SdrHint*)&rHint;
746             switch( pSdrHint->GetKind() )
747             {
748                 case HINT_OBJINSERTED:
749                     InsertSdrObj(pSdrHint->GetObject());
750                     break;
751                 case HINT_OBJREMOVED:
752                     RemoveSdrObj(pSdrHint->GetObject());
753                     break;
754                 default:
755                     break;
756             }
757         }
758         // hat sich die shell verabschiedet?
759         else if ( rHint.ISA(SfxSimpleHint) && ((SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING)
760             UpdateContent((FmFormShell*)NULL);
761 
762         // hat sich die Markierung der Controls veraendert ?
763         else if (rHint.ISA(FmNavViewMarksChanged))
764         {
765             FmNavViewMarksChanged* pvmcHint = (FmNavViewMarksChanged*)&rHint;
766             BroadcastMarkedObjects( pvmcHint->GetAffectedView()->GetMarkedObjectList() );
767         }
768     }
769 
770     //------------------------------------------------------------------------
InsertSdrObj(const SdrObject * pObj)771     void NavigatorTreeModel::InsertSdrObj( const SdrObject* pObj )
772     {
773         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::InsertSdrObj" );
774         const FmFormObj* pFormObject = FmFormObj::GetFormObject( pObj );
775         if ( pFormObject )
776         {
777             try
778             {
779                 Reference< XFormComponent > xFormComponent( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW );
780                 Reference< XIndexAccess > xContainer( xFormComponent->getParent(), UNO_QUERY_THROW );
781 
782                 sal_Int32 nPos = getElementPos( xContainer, xFormComponent );
783                 InsertFormComponent( xFormComponent, nPos );
784             }
785             catch( const Exception& )
786             {
787                 DBG_UNHANDLED_EXCEPTION();
788             }
789         }
790         else if ( pObj->IsGroupObject() )
791         {
792             SdrObjListIter aIter( *pObj->GetSubList() );
793             while ( aIter.IsMore() )
794                 InsertSdrObj( aIter.Next() );
795         }
796     }
797 
798     //------------------------------------------------------------------------
RemoveSdrObj(const SdrObject * pObj)799     void NavigatorTreeModel::RemoveSdrObj( const SdrObject* pObj )
800     {
801         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::RemoveSdrObj" );
802         const FmFormObj* pFormObject = FmFormObj::GetFormObject( pObj );
803         if ( pFormObject )
804         {
805             try
806             {
807                 Reference< XFormComponent > xFormComponent( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW );
808                 FmEntryData* pEntryData = FindData( xFormComponent, GetRootList(), sal_True );
809                 if ( pEntryData )
810                     Remove( pEntryData );
811             }
812             catch( const Exception& )
813             {
814                 DBG_UNHANDLED_EXCEPTION();
815             }
816         }
817         else if ( pObj->IsGroupObject() )
818         {
819             SdrObjListIter aIter( *pObj->GetSubList() );
820             while ( aIter.IsMore() )
821                 RemoveSdrObj( aIter.Next() );
822         }
823     }
824 
InsertFormComponent(FmNavRequestSelectHint & rHint,SdrObject * pObject)825     sal_Bool NavigatorTreeModel::InsertFormComponent(FmNavRequestSelectHint& rHint, SdrObject* pObject)
826     {
827         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::InsertFormComponent" );
828         if ( pObject->ISA(SdrObjGroup) )
829         {   // rekursiv absteigen
830             const SdrObjList *pChilds = ((SdrObjGroup*)pObject)->GetSubList();
831             for ( sal_uInt16 i=0; i<pChilds->GetObjCount(); ++i )
832             {
833                 SdrObject* pCurrent = pChilds->GetObj(i);
834                 if (!InsertFormComponent(rHint, pCurrent))
835                     return sal_False;
836             }
837         }
838         else
839         {
840             FmFormObj* pFormObject = FmFormObj::GetFormObject( pObject );
841             if ( !pFormObject )
842                 return sal_False;
843 
844             try
845             {
846                 Reference< XFormComponent > xFormViewControl( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW );
847                 FmEntryData* pControlData = FindData( xFormViewControl, GetRootList() );
848                 if ( !pControlData )
849                     return sal_False;
850 
851                 rHint.AddItem( pControlData );
852                 return sal_True;
853             }
854             catch( const Exception& )
855             {
856                 DBG_UNHANDLED_EXCEPTION();
857                 return sal_False;
858             }
859         }
860 
861         return sal_True;
862     }
863 
BroadcastMarkedObjects(const SdrMarkList & mlMarked)864     void NavigatorTreeModel::BroadcastMarkedObjects(const SdrMarkList& mlMarked)
865     {
866         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::BroadcastMarkedObjects" );
867         // gehen wir durch alle markierten Objekte und suchen wir die raus, mit denen ich was anfangen kann
868         FmNavRequestSelectHint rshRequestSelection;
869         sal_Bool bIsMixedSelection = sal_False;
870 
871         for (sal_uLong i=0; (i<mlMarked.GetMarkCount()) && !bIsMixedSelection; i++)
872         {
873             SdrObject* pobjCurrent = mlMarked.GetMark(i)->GetMarkedSdrObj();
874             bIsMixedSelection |= !InsertFormComponent(rshRequestSelection, pobjCurrent);
875                 // bei einem Nicht-Form-Control liefert InsertFormComponent sal_False !
876         }
877 
878         rshRequestSelection.SetMixedSelection(bIsMixedSelection);
879         if (bIsMixedSelection)
880             rshRequestSelection.ClearItems();
881 
882         Broadcast(rshRequestSelection);
883             // eine leere Liste interpretiert der NavigatorTree so, dass er seine Selektion komplett rausnimmt
884     }
885 
886     //------------------------------------------------------------------------
UpdateContent(const Reference<XNameContainer> & xForms)887     void NavigatorTreeModel::UpdateContent( const Reference< XNameContainer > & xForms )
888     {
889         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::UpdateContent" );
890         //////////////////////////////////////////////////////////////////////
891         // Model von der Root aufwaerts neu fuellen
892         Clear();
893         if (xForms.is())
894         {
895             Reference< XContainer >  xFormContainer(xForms, UNO_QUERY);
896             if (xFormContainer.is())
897                 xFormContainer->addContainerListener((XContainerListener*)m_pPropChangeList);
898 
899             FillBranch(NULL);
900 
901             // jetzt in meinem Tree genau die das in meiner View markierte Control selektieren
902             // (bzw alle solchen), falls es eines gibt ...
903             if(!m_pFormShell) return;       // keine Shell -> wech
904 
905             FmFormView* pFormView = m_pFormShell->GetFormView();
906             DBG_ASSERT(pFormView != NULL, "NavigatorTreeModel::UpdateContent : keine FormView");
907             BroadcastMarkedObjects(pFormView->GetMarkedObjectList());
908         }
909     }
910 
911     //------------------------------------------------------------------------
UpdateContent(FmFormShell * pShell)912     void NavigatorTreeModel::UpdateContent( FmFormShell* pShell )
913     {
914         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::UpdateContent" );
915         //////////////////////////////////////////////////////////////////////
916         // Wenn Shell sich nicht veraendert hat, nichts machen
917         FmFormPage* pNewPage = pShell ? pShell->GetCurPage() : NULL;
918         if ((pShell == m_pFormShell) && (m_pFormPage == pNewPage))
919             return;
920 
921         //////////////////////////////////////////////////////////////////////
922         // Als Listener abmelden
923         if( m_pFormShell )
924         {
925             if (m_pFormModel)
926                 EndListening( *m_pFormModel );
927             m_pFormModel = NULL;
928             EndListening( *m_pFormShell );
929             Clear();
930         }
931 
932         //////////////////////////////////////////////////////////////////////
933         // Vollupdate
934         m_pFormShell = pShell;
935         if (m_pFormShell)
936         {
937             m_pFormPage = pNewPage;
938             UpdateContent(m_pFormPage->GetForms());
939         } else
940             m_pFormPage = NULL;
941 
942         //////////////////////////////////////////////////////////////////////
943         // Als Listener neu anmelden
944         if( m_pFormShell )
945         {
946             StartListening( *m_pFormShell );
947             m_pFormModel = m_pFormShell->GetFormModel();
948             if( m_pFormModel )
949                 StartListening( *m_pFormModel );
950         }
951     }
952 
953     //------------------------------------------------------------------------
GetFormComponents(FmFormData * pFormData)954     Reference< XIndexContainer >  NavigatorTreeModel::GetFormComponents( FmFormData* pFormData )
955     {
956         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::GetFormComponents" );
957         //////////////////////////////////////////////////////////////////////
958         // Von der Form Components holen
959         if (pFormData)
960             return Reference< XIndexContainer > (pFormData->GetFormIface(), UNO_QUERY);
961 
962         return Reference< XIndexContainer > ();
963     }
964 
965     //------------------------------------------------------------------------
CheckEntry(FmEntryData * pEntryData)966     sal_Bool NavigatorTreeModel::CheckEntry( FmEntryData* pEntryData )
967     {
968         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::CheckEntry" );
969         //////////////////////////////////////////////////////////////////////
970         // Nur Forms duerfen auf Doppeldeutigkeit untersucht werden
971         if( !pEntryData->ISA(FmFormData) ) return sal_True;
972 
973         //////////////////////////////////////////////////////////////////////
974         // ChildListe des Parents holen
975         FmFormData* pParentData = (FmFormData*)pEntryData->GetParent();
976         FmEntryDataList* pChildList;
977         if( !pParentData )
978             pChildList = GetRootList();
979         else
980             pChildList = pParentData->GetChildList();
981 
982         //////////////////////////////////////////////////////////////////////
983         // In ChildListe nach doppelten Namen suchen
984         ::rtl::OUString aChildText;
985         FmEntryData* pChildData;
986 
987         for( sal_uInt16 i=0; i<pChildList->Count(); i++ )
988         {
989             pChildData = pChildList->GetObject(i);
990             aChildText = pChildData->GetText();
991 
992             //////////////////////////////////////////////////////////////////////
993             // Gleichen Eintrag gefunden
994             if  (   (aChildText == pEntryData->GetText())
995                 &&  (pEntryData!=pChildData)
996                 )
997             {
998 
999 
1000                 SQLContext aError;
1001                 aError.Message = String(SVX_RES(RID_ERR_CONTEXT_ADDFORM));
1002                 aError.Details = String(SVX_RES(RID_ERR_DUPLICATE_NAME));
1003                 displayException(aError);
1004 
1005                 return sal_False;
1006             }
1007         }
1008 
1009         return sal_True;
1010     }
1011 
1012     //------------------------------------------------------------------------
Rename(FmEntryData * pEntryData,const::rtl::OUString & rNewText)1013     sal_Bool NavigatorTreeModel::Rename( FmEntryData* pEntryData, const ::rtl::OUString& rNewText )
1014     {
1015         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Rename" );
1016         //////////////////////////////////////////////////////////////////////
1017         // Wenn Name schon vorhanden, Fehlermeldung
1018         pEntryData->SetText( rNewText );
1019 
1020         //////////////////////////////////////////////////////////////////////
1021         // PropertySet besorgen
1022         Reference< XFormComponent >  xFormComponent;
1023 
1024         if( pEntryData->ISA(FmFormData) )
1025         {
1026             FmFormData* pFormData = (FmFormData*)pEntryData;
1027             Reference< XForm >  xForm( pFormData->GetFormIface());
1028             xFormComponent = Reference< XFormComponent > (xForm, UNO_QUERY);
1029         }
1030 
1031         if( pEntryData->ISA(FmControlData) )
1032         {
1033             FmControlData* pControlData = (FmControlData*)pEntryData;
1034             xFormComponent = pControlData->GetFormComponent();
1035         }
1036 
1037         if( !xFormComponent.is() ) return sal_False;
1038         Reference< XPropertySet >  xSet(xFormComponent, UNO_QUERY);
1039         if( !xSet.is() ) return sal_False;
1040 
1041         //////////////////////////////////////////////////////////////////////
1042         // Namen setzen
1043         xSet->setPropertyValue( FM_PROP_NAME, makeAny(rNewText) );
1044 
1045         return sal_True;
1046     }
1047 
1048     //------------------------------------------------------------------------
IsNameAlreadyDefined(const::rtl::OUString & rName,FmFormData * pParentData)1049     sal_Bool NavigatorTreeModel::IsNameAlreadyDefined( const ::rtl::OUString& rName, FmFormData* pParentData )
1050     {
1051         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::IsNameAlreadyDefined" );
1052         //////////////////////////////////////////////////////////////////////
1053         // Form in der Root
1054         if( !pParentData )
1055         {
1056             if (GetForms()->hasByName(rName))
1057                 return sal_True;
1058         }
1059 
1060         //////////////////////////////////////////////////////////////////////
1061         // Restliche Components
1062         else
1063         {
1064             Reference< XNameContainer >  xFormComponents(GetFormComponents(pParentData), UNO_QUERY);
1065             if (xFormComponents.is() && xFormComponents->hasByName(rName))
1066                 return sal_True;
1067         }
1068 
1069         return sal_False;
1070     }
1071 
1072     //------------------------------------------------------------------------
GetSdrObj(FmControlData * pControlData)1073     SdrObject* NavigatorTreeModel::GetSdrObj( FmControlData* pControlData )
1074     {
1075         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::GetSdrObj" );
1076         if (!pControlData || !m_pFormShell)
1077             return NULL;
1078 
1079         //////////////////////////////////////////////////////////////////////
1080         // In der Page das entsprechende SdrObj finden und selektieren
1081         Reference< XFormComponent >  xFormComponent( pControlData->GetFormComponent());
1082         if (!xFormComponent.is())
1083             return NULL;
1084 
1085         FmFormView*     pFormView       = m_pFormShell->GetFormView();
1086         SdrPageView*    pPageView       = pFormView->GetSdrPageView();
1087         SdrPage*        pPage           = pPageView->GetPage();
1088 
1089         SdrObjListIter  aIter( *pPage );
1090         return Search(aIter, xFormComponent);
1091     }
1092 
1093     //------------------------------------------------------------------
Search(SdrObjListIter & rIter,const Reference<XFormComponent> & xComp)1094     SdrObject* NavigatorTreeModel::Search(SdrObjListIter& rIter, const Reference< XFormComponent > & xComp)
1095     {
1096         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Search" );
1097         while (rIter.IsMore())
1098         {
1099             SdrObject* pObj = rIter.Next();
1100             FmFormObj* pFormObject = FmFormObj::GetFormObject( pObj );
1101             if ( pFormObject )
1102             {
1103                 Reference< XFormComponent > xFormViewControl( pFormObject->GetUnoControlModel(), UNO_QUERY );
1104                 if ( xFormViewControl == xComp )
1105                     return pObj;
1106             }
1107             else if ( pObj->IsGroupObject() )
1108             {
1109                 SdrObjListIter aIter( *pObj->GetSubList() );
1110                 pObj = Search( aIter, xComp );
1111                 if ( pObj )
1112                     return pObj;
1113             }
1114         }
1115         return NULL;
1116     }
1117 
1118 //............................................................................
1119 }   // namespace svxform
1120 //............................................................................
1121 
1122 
1123