update dev300-m58
[ooovba.git] / svx / source / form / navigatortreemodel.cxx
blobd19e75f923a80cbcfc836937a2e896fdd536a18d
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: navigatortreemodel.cxx,v $
10 * $Revision: 1.15 $
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"
33 #include <svx/dialmgr.hxx>
34 #include <svx/fmshell.hxx>
35 #include <svx/fmmodel.hxx>
36 #include <svx/fmpage.hxx>
37 #include <svx/fmglob.hxx>
38 #include "svditer.hxx"
39 #include <svx/svdogrp.hxx>
40 #include <svx/svdpagv.hxx>
43 #include "fmundo.hxx"
44 #include "fmhelp.hrc"
45 #include "fmexpl.hrc"
46 #include "fmexpl.hxx"
47 #include "fmresids.hrc"
48 #include "fmshimp.hxx"
49 #include "fmobj.hxx"
50 #include <sfx2/objsh.hxx>
51 #include <tools/diagnose_ex.h>
52 #include <rtl/logfile.hxx>
53 #include <com/sun/star/container/XContainer.hpp>
55 //............................................................................
56 namespace svxform
58 //............................................................................
60 using namespace ::com::sun::star::uno;
61 using namespace ::com::sun::star::lang;
62 using namespace ::com::sun::star::beans;
63 using namespace ::com::sun::star::form;
64 using namespace ::com::sun::star::awt;
65 using namespace ::com::sun::star::container;
66 using namespace ::com::sun::star::script;
67 using namespace ::com::sun::star::sdb;
69 //========================================================================
70 // class OFormComponentObserver
71 //========================================================================
72 //------------------------------------------------------------------------
73 OFormComponentObserver::OFormComponentObserver(NavigatorTreeModel* _pModel)
74 :m_pNavModel(_pModel)
75 ,m_nLocks(0)
76 ,m_bCanUndo(sal_True)
78 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::OFormComponentObserver" );
81 // XPropertyChangeListener
82 //------------------------------------------------------------------------
83 void SAL_CALL OFormComponentObserver::disposing(const EventObject& Source) throw( RuntimeException )
85 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::disposing" );
86 Remove( Source.Source );
89 //------------------------------------------------------------------------
90 void SAL_CALL OFormComponentObserver::propertyChange(const PropertyChangeEvent& evt) throw(RuntimeException)
92 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::propertyChange" );
93 if( !m_pNavModel ) return;
94 if( evt.PropertyName != FM_PROP_NAME ) return;
96 Reference< XFormComponent > xFormComponent(evt.Source, UNO_QUERY);
97 Reference< XForm > xForm(evt.Source, UNO_QUERY);
99 FmEntryData* pEntryData( NULL );
100 if( xForm.is() )
101 pEntryData = m_pNavModel->FindData( xForm, m_pNavModel->GetRootList() );
102 else if( xFormComponent.is() )
103 pEntryData = m_pNavModel->FindData( xFormComponent, m_pNavModel->GetRootList() );
105 if( pEntryData )
107 ::rtl::OUString aNewName = ::comphelper::getString(evt.NewValue);
108 pEntryData->SetText( aNewName );
109 FmNavNameChangedHint aNameChangedHint( pEntryData, aNewName );
110 m_pNavModel->Broadcast( aNameChangedHint );
114 // XContainerListener
115 //------------------------------------------------------------------------------
116 void SAL_CALL OFormComponentObserver::elementInserted(const ContainerEvent& evt) throw(RuntimeException)
118 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::elementInserted" );
119 if (IsLocked() || !m_pNavModel)
120 return;
122 // keine Undoaction einfuegen
123 m_bCanUndo = sal_False;
125 Reference< XInterface > xTemp;
126 evt.Element >>= xTemp;
127 Insert(xTemp, ::comphelper::getINT32(evt.Accessor));
129 m_bCanUndo = sal_True;
132 //------------------------------------------------------------------------------
133 void OFormComponentObserver::Insert(const Reference< XInterface > & xIface, sal_Int32 nIndex)
135 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::Insert" );
136 Reference< XForm > xForm(xIface, UNO_QUERY);
137 if (xForm.is())
139 m_pNavModel->InsertForm(xForm, sal_uInt32(nIndex));
140 Reference< XIndexContainer > xContainer(xForm, UNO_QUERY);
141 Reference< XInterface > xTemp;
142 for (sal_Int32 i = 0; i < xContainer->getCount(); i++)
144 xContainer->getByIndex(i) >>= xTemp;
145 Insert(xTemp, i);
148 else
150 Reference< XFormComponent > xFormComp(xIface, UNO_QUERY);
151 if (xFormComp.is())
152 m_pNavModel->InsertFormComponent(xFormComp, sal_uInt32(nIndex));
156 //------------------------------------------------------------------------------
157 void SAL_CALL OFormComponentObserver::elementReplaced(const ContainerEvent& evt) throw(RuntimeException)
159 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::elementReplaced" );
160 if (IsLocked() || !m_pNavModel)
161 return;
163 m_bCanUndo = sal_False;
165 // EntryData loeschen
166 Reference< XFormComponent > xReplaced;
167 evt.ReplacedElement >>= xReplaced;
168 FmEntryData* pEntryData = m_pNavModel->FindData(xReplaced, m_pNavModel->GetRootList(), sal_True);
169 if (pEntryData)
171 if (pEntryData->ISA(FmControlData))
173 Reference< XFormComponent > xComp;
174 evt.Element >>= xComp;
175 DBG_ASSERT(xComp.is(), "OFormComponentObserver::elementReplaced : invalid argument !");
176 // an einer FmControlData sollte eine XFormComponent haengen
177 m_pNavModel->ReplaceFormComponent(xReplaced, xComp);
179 else if (pEntryData->ISA(FmFormData))
181 DBG_ERROR("replacing forms not implemented yet !");
185 m_bCanUndo = sal_True;
188 //------------------------------------------------------------------------------
189 void OFormComponentObserver::Remove( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxElement )
191 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::Remove" );
192 if (IsLocked() || !m_pNavModel)
193 return;
195 m_bCanUndo = sal_False;
197 //////////////////////////////////////////////////////////
198 // EntryData loeschen
199 FmEntryData* pEntryData = m_pNavModel->FindData( _rxElement, m_pNavModel->GetRootList(), sal_True );
200 if (pEntryData)
201 m_pNavModel->Remove(pEntryData);
203 m_bCanUndo = sal_True;
206 //------------------------------------------------------------------------------
207 void SAL_CALL OFormComponentObserver::elementRemoved(const ContainerEvent& evt) throw(RuntimeException)
209 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::elementRemoved" );
210 Reference< XInterface > xElement;
211 evt.Element >>= xElement;
212 Remove( xElement );
215 //========================================================================
216 // class NavigatorTreeModel
217 //========================================================================
219 //------------------------------------------------------------------------
220 NavigatorTreeModel::NavigatorTreeModel( const ImageList& _rNormalImages, const ImageList& _rHCImages )
221 :m_pFormShell(NULL)
222 ,m_pFormPage(NULL)
223 ,m_pFormModel(NULL)
224 ,m_aNormalImages( _rNormalImages )
225 ,m_aHCImages( _rHCImages )
227 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::NavigatorTreeModel" );
228 m_pPropChangeList = new OFormComponentObserver(this);
229 m_pPropChangeList->acquire();
230 m_pRootList = new FmEntryDataList();
233 //------------------------------------------------------------------------
234 NavigatorTreeModel::~NavigatorTreeModel()
236 //////////////////////////////////////////////////////////////////////
237 // Als Listener abmelden
238 if( m_pFormShell)
240 FmFormModel* pFormModel = m_pFormShell->GetFormModel();
241 if( pFormModel && IsListening(*pFormModel))
242 EndListening( *pFormModel );
244 if (IsListening(*m_pFormShell))
245 EndListening(*m_pFormShell);
248 Clear();
249 delete m_pRootList;
250 m_pPropChangeList->ReleaseModel();
251 m_pPropChangeList->release();
255 //------------------------------------------------------------------------
256 void NavigatorTreeModel::SetModified( sal_Bool bMod )
258 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::SetModified" );
259 if( !m_pFormShell ) return;
260 SfxObjectShell* pObjShell = m_pFormShell->GetFormModel()->GetObjectShell();
261 if( !pObjShell ) return;
262 pObjShell->SetModified( bMod );
265 //------------------------------------------------------------------------
266 void NavigatorTreeModel::Clear()
268 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Clear" );
269 Reference< XNameContainer > xForms( GetForms());
270 Reference< XContainer > xContainer(xForms, UNO_QUERY);
271 if (xContainer.is())
272 xContainer->removeContainerListener((XContainerListener*)m_pPropChangeList);
274 //////////////////////////////////////////////////////////////////////
275 // RootList loeschen
276 FmEntryData* pChildData;
277 FmEntryDataList* pRootList = GetRootList();
279 for( sal_uInt32 i=pRootList->Count(); i>0; i-- )
281 pChildData = pRootList->GetObject(i-1);
282 pRootList->Remove( pChildData );
283 delete pChildData;
286 //////////////////////////////////////////////////////////////////////
287 // UI benachrichtigen
288 FmNavClearedHint aClearedHint;
289 Broadcast( aClearedHint );
292 //------------------------------------------------------------------------
293 Reference< XNameContainer > NavigatorTreeModel::GetForms() const
295 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::GetForms" );
296 if( !m_pFormShell || !m_pFormShell->GetCurPage())
297 return NULL;
298 else
299 return m_pFormShell->GetCurPage()->GetForms();
302 //------------------------------------------------------------------------
303 void NavigatorTreeModel::Insert(FmEntryData* pEntry, ULONG nRelPos, sal_Bool bAlterModel)
305 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Insert" );
306 if (IsListening(*m_pFormModel))
307 EndListening(*m_pFormModel);
309 m_pPropChangeList->Lock();
310 FmFormData* pFolder = (FmFormData*) pEntry->GetParent();
311 Reference< XChild > xElement( pEntry->GetChildIFace() );
312 if (bAlterModel)
314 XubString aStr;
315 if (pEntry->ISA(FmFormData))
316 aStr = SVX_RES(RID_STR_FORM);
317 else
318 aStr = SVX_RES(RID_STR_CONTROL);
320 Reference< XIndexContainer > xContainer;
321 if (pFolder)
322 xContainer = Reference< XIndexContainer > (pFolder->GetFormIface(), UNO_QUERY);
323 else
324 xContainer = Reference< XIndexContainer > (GetForms(), UNO_QUERY);
326 bool bUndo = m_pFormModel->IsUndoEnabled();
328 if( bUndo )
330 XubString aUndoStr(SVX_RES(RID_STR_UNDO_CONTAINER_INSERT));
331 aUndoStr.SearchAndReplace('#', aStr);
332 m_pFormModel->BegUndo(aUndoStr);
335 if (nRelPos >= (sal_uInt32)xContainer->getCount())
336 nRelPos = (sal_uInt32)xContainer->getCount();
338 // UndoAction
339 if ( bUndo && m_pPropChangeList->CanUndo())
341 m_pFormModel->AddUndo(new FmUndoContainerAction(*m_pFormModel,
342 FmUndoContainerAction::Inserted,
343 xContainer,
344 xElement,
345 nRelPos));
348 // das Element muss den Typ haben, den der Container erwartet
349 if (xContainer->getElementType() ==
350 ::getCppuType((const Reference< XForm>*)0))
353 Reference< XForm > xElementAsForm(xElement, UNO_QUERY);
354 xContainer->insertByIndex(nRelPos, makeAny(xElementAsForm));
356 else if (xContainer->getElementType() ==
357 ::getCppuType((const Reference< XFormComponent>*)0))
360 Reference< XFormComponent > xElementAsComponent(xElement, UNO_QUERY);
361 xContainer->insertByIndex(nRelPos, makeAny(xElementAsComponent));
363 else
365 DBG_ERROR("NavigatorTreeModel::Insert : the parent container needs an elementtype I don't know !");
368 if( bUndo )
369 m_pFormModel->EndUndo();
372 //////////////////////////////////////////////////////////////////////
373 // Als PropertyChangeListener anmelden
374 Reference< XPropertySet > xSet(xElement, UNO_QUERY);
375 if( xSet.is() )
376 xSet->addPropertyChangeListener( FM_PROP_NAME, m_pPropChangeList );
378 //////////////////////////////////////////////////////////////////////
379 // Daten aus Model entfernen
380 if (pEntry->ISA(FmFormData))
382 Reference< XContainer > xContainer(xElement, UNO_QUERY);
383 if (xContainer.is())
384 xContainer->addContainerListener((XContainerListener*)m_pPropChangeList);
387 if (pFolder)
388 pFolder->GetChildList()->Insert( pEntry, nRelPos );
389 else
390 GetRootList()->Insert( pEntry, nRelPos );
392 //////////////////////////////////////////////////////////////////////
393 // UI benachrichtigen
394 FmNavInsertedHint aInsertedHint( pEntry, nRelPos );
395 Broadcast( aInsertedHint );
397 m_pPropChangeList->UnLock();
398 if (IsListening(*m_pFormModel))
399 StartListening(*m_pFormModel);
402 //------------------------------------------------------------------------
403 void NavigatorTreeModel::Remove(FmEntryData* pEntry, sal_Bool bAlterModel)
405 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Remove" );
406 //////////////////////////////////////////////////////////////////////
407 // Form und Parent holen
408 if (!pEntry || !m_pFormModel)
409 return;
411 if (IsListening(*m_pFormModel))
412 EndListening(*m_pFormModel);
414 const bool bUndo = m_pFormModel->IsUndoEnabled();
416 m_pPropChangeList->Lock();
417 FmFormData* pFolder = (FmFormData*) pEntry->GetParent();
418 Reference< XChild > xElement ( pEntry->GetChildIFace() );
419 if (bAlterModel)
421 XubString aStr;
422 if (pEntry->ISA(FmFormData))
423 aStr = SVX_RES(RID_STR_FORM);
424 else
425 aStr = SVX_RES(RID_STR_CONTROL);
427 if( bUndo )
429 XubString aUndoStr(SVX_RES(RID_STR_UNDO_CONTAINER_REMOVE));
430 aUndoStr.SearchAndReplace('#', aStr);
431 m_pFormModel->BegUndo(aUndoStr);
435 // jetzt die eigentliche Entfernung der Daten aus dem Model
436 if (pEntry->ISA(FmFormData))
437 RemoveForm((FmFormData*)pEntry);
438 else
439 RemoveFormComponent((FmControlData*)pEntry);
442 if (bAlterModel)
444 Reference< XIndexContainer > xContainer(xElement->getParent(), UNO_QUERY);
445 // aus dem Container entfernen
446 sal_Int32 nContainerIndex = getElementPos(xContainer.get(), xElement);
447 // UndoAction
448 if (nContainerIndex >= 0)
450 if ( bUndo && m_pPropChangeList->CanUndo())
452 m_pFormModel->AddUndo(new FmUndoContainerAction(*m_pFormModel,
453 FmUndoContainerAction::Removed,
454 xContainer,
455 xElement, nContainerIndex ));
457 else if( !m_pPropChangeList->CanUndo() )
459 FmUndoContainerAction::DisposeElement( xElement );
462 xContainer->removeByIndex(nContainerIndex );
465 if( bUndo )
466 m_pFormModel->EndUndo();
469 // beim Vater austragen
470 if (pFolder)
471 pFolder->GetChildList()->Remove(pEntry);
472 else
474 GetRootList()->Remove(pEntry);
475 //////////////////////////////////////////////////////////////////////
476 // Wenn keine Form mehr in der Root, an der Shell CurForm zuruecksetzen
477 if (!GetRootList()->Count())
478 m_pFormShell->GetImpl()->forgetCurrentForm();
481 //////////////////////////////////////////////////////////////////////
482 // UI benachrichtigen
483 FmNavRemovedHint aRemovedHint( pEntry );
484 Broadcast( aRemovedHint );
486 // Eintrag loeschen
487 delete pEntry;
489 m_pPropChangeList->UnLock();
490 StartListening(*m_pFormModel);
493 //------------------------------------------------------------------------
494 void NavigatorTreeModel::RemoveForm(FmFormData* pFormData)
496 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::RemoveForm" );
497 //////////////////////////////////////////////////////////////////////
498 // Form und Parent holen
499 if (!pFormData || !m_pFormModel)
500 return;
502 FmEntryDataList* pChildList = pFormData->GetChildList();
503 sal_uInt32 nCount = pChildList->Count();
504 for (sal_uInt32 i = nCount; i > 0; i--)
506 FmEntryData* pEntryData = pChildList->GetObject(i - 1);
508 //////////////////////////////////////////////////////////////////////
509 // Child ist Form -> rekursiver Aufruf
510 if( pEntryData->ISA(FmFormData) )
511 RemoveForm( (FmFormData*)pEntryData);
512 else if( pEntryData->ISA(FmControlData) )
513 RemoveFormComponent((FmControlData*) pEntryData);
516 //////////////////////////////////////////////////////////////////////
517 // Als PropertyChangeListener abmelden
518 Reference< XPropertySet > xSet( pFormData->GetPropertySet() );
519 if ( xSet.is() )
520 xSet->removePropertyChangeListener( FM_PROP_NAME, m_pPropChangeList );
522 Reference< XContainer > xContainer( pFormData->GetContainer() );
523 if (xContainer.is())
524 xContainer->removeContainerListener((XContainerListener*)m_pPropChangeList);
527 //------------------------------------------------------------------------
528 void NavigatorTreeModel::RemoveFormComponent(FmControlData* pControlData)
530 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::RemoveFormComponent" );
531 //////////////////////////////////////////////////////////////////////
532 // Control und Parent holen
533 if (!pControlData)
534 return;
536 //////////////////////////////////////////////////////////////////////
537 // Als PropertyChangeListener abmelden
538 Reference< XPropertySet > xSet( pControlData->GetPropertySet() );
539 if (xSet.is())
540 xSet->removePropertyChangeListener( FM_PROP_NAME, m_pPropChangeList);
543 //------------------------------------------------------------------------
544 void NavigatorTreeModel::ClearBranch( FmFormData* pParentData )
546 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::ClearBranch" );
547 //////////////////////////////////////////////////////////////////////
548 // Alle Eintraege dieses Zweiges loeschen
549 FmEntryDataList* pChildList = pParentData->GetChildList();
550 FmEntryData* pChildData;
552 for( sal_uInt32 i=pChildList->Count(); i>0; i-- )
554 pChildData = pChildList->GetObject(i-1);
555 if( pChildData->ISA(FmFormData) )
556 ClearBranch( (FmFormData*)pChildData );
558 pChildList->Remove( pChildData );
562 //------------------------------------------------------------------------
563 void NavigatorTreeModel::FillBranch( FmFormData* pFormData )
565 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::FillBranch" );
566 //////////////////////////////////////////////////////////////
567 // Forms aus der Root einfuegen
568 if( pFormData == NULL )
570 Reference< XIndexContainer > xForms(GetForms(), UNO_QUERY);
571 if (!xForms.is())
572 return;
574 Reference< XForm > xSubForm;
575 FmFormData* pSubFormData;
576 for (sal_Int32 i=0; i<xForms->getCount(); ++i)
578 DBG_ASSERT( xForms->getByIndex(i).getValueType() == ::getCppuType((const Reference< XForm>*)NULL),
579 "NavigatorTreeModel::FillBranch : the root container should supply only elements of type XForm");
581 xForms->getByIndex(i) >>= xSubForm;
582 pSubFormData = new FmFormData( xSubForm, m_aNormalImages, m_aHCImages, pFormData );
583 Insert( pSubFormData, LIST_APPEND );
585 //////////////////////////////////////////////////////////////
586 // Neuer Branch, wenn SubForm wiederum Subforms enthaelt
587 FillBranch( pSubFormData );
591 //////////////////////////////////////////////////////////////
592 // Componenten einfuegen
593 else
595 Reference< XIndexContainer > xComponents( GetFormComponents(pFormData));
596 if( !xComponents.is() ) return;
598 ::rtl::OUString aControlName;
599 Reference< XInterface > xInterface;
600 Reference< XPropertySet > xSet;
601 FmControlData* pNewControlData;
602 FmFormData* pSubFormData;
604 Reference< XFormComponent > xCurrentComponent;
605 for (sal_Int32 j=0; j<xComponents->getCount(); ++j)
607 xComponents->getByIndex(j) >>= xCurrentComponent;
608 Reference< XForm > xSubForm(xCurrentComponent, UNO_QUERY);
610 if (xSubForm.is())
611 { // die aktuelle Component ist eine Form
612 pSubFormData = new FmFormData(xSubForm, m_aNormalImages, m_aHCImages, pFormData);
613 Insert(pSubFormData, LIST_APPEND);
615 //////////////////////////////////////////////////////////////
616 // Neuer Branch, wenn SubForm wiederum Subforms enthaelt
617 FillBranch(pSubFormData);
619 else
621 pNewControlData = new FmControlData(xCurrentComponent, m_aNormalImages, m_aHCImages, pFormData);
622 Insert(pNewControlData, LIST_APPEND);
628 //------------------------------------------------------------------------
629 void NavigatorTreeModel::InsertForm(const Reference< XForm > & xForm, sal_uInt32 nRelPos)
631 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::InsertForm" );
632 FmFormData* pFormData = (FmFormData*)FindData( xForm, GetRootList() );
633 if (pFormData)
634 return;
636 //////////////////////////////////////////////////////////
637 // ParentData setzen
638 Reference< XInterface > xIFace( xForm->getParent());
639 Reference< XForm > xParentForm(xIFace, UNO_QUERY);
640 FmFormData* pParentData = NULL;
641 if (xParentForm.is())
642 pParentData = (FmFormData*)FindData( xParentForm, GetRootList() );
644 pFormData = new FmFormData( xForm, m_aNormalImages, m_aHCImages, pParentData );
645 Insert( pFormData, nRelPos );
648 //------------------------------------------------------------------------
649 void NavigatorTreeModel::InsertFormComponent(const Reference< XFormComponent > & xComp, sal_uInt32 nRelPos)
651 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::InsertFormComponent" );
652 //////////////////////////////////////////////////////////
653 // ParentData setzen
654 Reference< XInterface > xIFace( xComp->getParent());
655 Reference< XForm > xForm(xIFace, UNO_QUERY);
656 if (!xForm.is())
657 return;
659 FmFormData* pParentData = (FmFormData*)FindData( xForm, GetRootList() );
660 if( !pParentData )
662 pParentData = new FmFormData( xForm, m_aNormalImages, m_aHCImages, NULL );
663 Insert( pParentData, LIST_APPEND );
666 if (!FindData(xComp, pParentData->GetChildList(),sal_False))
668 //////////////////////////////////////////////////////////
669 // Neue EntryData setzen
670 FmEntryData* pNewEntryData = new FmControlData( xComp, m_aNormalImages, m_aHCImages, pParentData );
672 //////////////////////////////////////////////////////////
673 // Neue EntryData einfuegen
674 Insert( pNewEntryData, nRelPos );
678 //------------------------------------------------------------------------
679 void NavigatorTreeModel::ReplaceFormComponent(const Reference< XFormComponent > & xOld, const Reference< XFormComponent > & xNew)
681 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::ReplaceFormComponent" );
682 FmEntryData* pData = FindData(xOld, GetRootList(), sal_True);
683 DBG_ASSERT(pData && pData->ISA(FmControlData), "NavigatorTreeModel::ReplaceFormComponent : invalid argument !");
684 ((FmControlData*)pData)->ModelReplaced( xNew, m_aNormalImages, m_aHCImages );
686 FmNavModelReplacedHint aReplacedHint( pData );
687 Broadcast( aReplacedHint );
690 //------------------------------------------------------------------------
691 FmEntryData* NavigatorTreeModel::FindData(const Reference< XInterface > & xElement, FmEntryDataList* pDataList, sal_Bool bRecurs)
693 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::FindData" );
694 // normalize
695 Reference< XInterface > xIFace( xElement, UNO_QUERY );
697 for (sal_uInt16 i=0; i < pDataList->Count(); i++)
699 FmEntryData* pEntryData = pDataList->GetObject(i);
700 if ( pEntryData->GetElement().get() == xIFace.get() )
701 return pEntryData;
702 else if (bRecurs)
704 pEntryData = FindData( xElement, pEntryData->GetChildList() );
705 if (pEntryData)
706 return pEntryData;
709 return NULL;
712 //------------------------------------------------------------------------
713 FmEntryData* NavigatorTreeModel::FindData( const ::rtl::OUString& rText, FmFormData* pParentData, sal_Bool bRecurs )
715 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::FindData" );
716 FmEntryDataList* pDataList;
717 if( !pParentData )
718 pDataList = GetRootList();
719 else
720 pDataList = pParentData->GetChildList();
722 ::rtl::OUString aEntryText;
723 FmEntryData* pEntryData;
724 FmEntryData* pChildData;
726 for( sal_uInt16 i=0; i<pDataList->Count(); i++ )
728 pEntryData = pDataList->GetObject(i);
729 aEntryText = pEntryData->GetText();
731 if (rText == aEntryText)
732 return pEntryData;
734 if( bRecurs && pEntryData->ISA(FmFormData) )
736 pChildData = FindData( rText, (FmFormData*)pEntryData );
737 if( pChildData )
738 return pChildData;
742 return NULL;
745 //------------------------------------------------------------------------
746 void NavigatorTreeModel::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
748 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Notify" );
749 if( rHint.ISA(SdrHint) )
751 SdrHint* pSdrHint = (SdrHint*)&rHint;
752 switch( pSdrHint->GetKind() )
754 case HINT_OBJINSERTED:
755 InsertSdrObj(pSdrHint->GetObject());
756 break;
757 case HINT_OBJREMOVED:
758 RemoveSdrObj(pSdrHint->GetObject());
759 break;
760 default:
761 break;
764 // hat sich die shell verabschiedet?
765 else if ( rHint.ISA(SfxSimpleHint) && ((SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING)
766 UpdateContent((FmFormShell*)NULL);
768 // hat sich die Markierung der Controls veraendert ?
769 else if (rHint.ISA(FmNavViewMarksChanged))
771 FmNavViewMarksChanged* pvmcHint = (FmNavViewMarksChanged*)&rHint;
772 BroadcastMarkedObjects( pvmcHint->GetAffectedView()->GetMarkedObjectList() );
776 //------------------------------------------------------------------------
777 void NavigatorTreeModel::InsertSdrObj( const SdrObject* pObj )
779 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::InsertSdrObj" );
780 const FmFormObj* pFormObject = FmFormObj::GetFormObject( pObj );
781 if ( pFormObject )
785 Reference< XFormComponent > xFormComponent( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW );
786 Reference< XIndexAccess > xContainer( xFormComponent->getParent(), UNO_QUERY_THROW );
788 sal_Int32 nPos = getElementPos( xContainer, xFormComponent );
789 InsertFormComponent( xFormComponent, nPos );
791 catch( const Exception& )
793 DBG_UNHANDLED_EXCEPTION();
796 else if ( pObj->IsGroupObject() )
798 SdrObjListIter aIter( *pObj->GetSubList() );
799 while ( aIter.IsMore() )
800 InsertSdrObj( aIter.Next() );
804 //------------------------------------------------------------------------
805 void NavigatorTreeModel::RemoveSdrObj( const SdrObject* pObj )
807 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::RemoveSdrObj" );
808 const FmFormObj* pFormObject = FmFormObj::GetFormObject( pObj );
809 if ( pFormObject )
813 Reference< XFormComponent > xFormComponent( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW );
814 FmEntryData* pEntryData = FindData( xFormComponent, GetRootList(), sal_True );
815 if ( pEntryData )
816 Remove( pEntryData );
818 catch( const Exception& )
820 DBG_UNHANDLED_EXCEPTION();
823 else if ( pObj->IsGroupObject() )
825 SdrObjListIter aIter( *pObj->GetSubList() );
826 while ( aIter.IsMore() )
827 RemoveSdrObj( aIter.Next() );
831 sal_Bool NavigatorTreeModel::InsertFormComponent(FmNavRequestSelectHint& rHint, SdrObject* pObject)
833 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::InsertFormComponent" );
834 if ( pObject->ISA(SdrObjGroup) )
835 { // rekursiv absteigen
836 const SdrObjList *pChilds = ((SdrObjGroup*)pObject)->GetSubList();
837 for ( sal_uInt16 i=0; i<pChilds->GetObjCount(); ++i )
839 SdrObject* pCurrent = pChilds->GetObj(i);
840 if (!InsertFormComponent(rHint, pCurrent))
841 return sal_False;
844 else
846 FmFormObj* pFormObject = FmFormObj::GetFormObject( pObject );
847 if ( !pFormObject )
848 return sal_False;
852 Reference< XFormComponent > xFormViewControl( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW );
853 FmEntryData* pControlData = FindData( xFormViewControl, GetRootList() );
854 if ( !pControlData )
855 return sal_False;
857 rHint.AddItem( pControlData );
858 return sal_True;
860 catch( const Exception& )
862 DBG_UNHANDLED_EXCEPTION();
863 return sal_False;
867 return sal_True;
870 void NavigatorTreeModel::BroadcastMarkedObjects(const SdrMarkList& mlMarked)
872 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::BroadcastMarkedObjects" );
873 // gehen wir durch alle markierten Objekte und suchen wir die raus, mit denen ich was anfangen kann
874 FmNavRequestSelectHint rshRequestSelection;
875 sal_Bool bIsMixedSelection = sal_False;
877 for (ULONG i=0; (i<mlMarked.GetMarkCount()) && !bIsMixedSelection; i++)
879 SdrObject* pobjCurrent = mlMarked.GetMark(i)->GetMarkedSdrObj();
880 bIsMixedSelection |= !InsertFormComponent(rshRequestSelection, pobjCurrent);
881 // bei einem Nicht-Form-Control liefert InsertFormComponent sal_False !
884 rshRequestSelection.SetMixedSelection(bIsMixedSelection);
885 if (bIsMixedSelection)
886 rshRequestSelection.ClearItems();
888 Broadcast(rshRequestSelection);
889 // eine leere Liste interpretiert der NavigatorTree so, dass er seine Selektion komplett rausnimmt
892 //------------------------------------------------------------------------
893 void NavigatorTreeModel::UpdateContent( const Reference< XNameContainer > & xForms )
895 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::UpdateContent" );
896 //////////////////////////////////////////////////////////////////////
897 // Model von der Root aufwaerts neu fuellen
898 Clear();
899 if (xForms.is())
901 Reference< XContainer > xFormContainer(xForms, UNO_QUERY);
902 if (xFormContainer.is())
903 xFormContainer->addContainerListener((XContainerListener*)m_pPropChangeList);
905 FillBranch(NULL);
907 // jetzt in meinem Tree genau die das in meiner View markierte Control selektieren
908 // (bzw alle solchen), falls es eines gibt ...
909 if(!m_pFormShell) return; // keine Shell -> wech
911 FmFormView* pFormView = m_pFormShell->GetFormView();
912 DBG_ASSERT(pFormView != NULL, "NavigatorTreeModel::UpdateContent : keine FormView");
913 BroadcastMarkedObjects(pFormView->GetMarkedObjectList());
917 //------------------------------------------------------------------------
918 void NavigatorTreeModel::UpdateContent( FmFormShell* pShell )
920 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::UpdateContent" );
921 //////////////////////////////////////////////////////////////////////
922 // Wenn Shell sich nicht veraendert hat, nichts machen
923 FmFormPage* pNewPage = pShell ? pShell->GetCurPage() : NULL;
924 if ((pShell == m_pFormShell) && (m_pFormPage == pNewPage))
925 return;
927 //////////////////////////////////////////////////////////////////////
928 // Als Listener abmelden
929 if( m_pFormShell )
931 if (m_pFormModel)
932 EndListening( *m_pFormModel );
933 m_pFormModel = NULL;
934 EndListening( *m_pFormShell );
935 Clear();
938 //////////////////////////////////////////////////////////////////////
939 // Vollupdate
940 m_pFormShell = pShell;
941 if (m_pFormShell)
943 m_pFormPage = pNewPage;
944 UpdateContent(m_pFormPage->GetForms());
945 } else
946 m_pFormPage = NULL;
948 //////////////////////////////////////////////////////////////////////
949 // Als Listener neu anmelden
950 if( m_pFormShell )
952 StartListening( *m_pFormShell );
953 m_pFormModel = m_pFormShell->GetFormModel();
954 if( m_pFormModel )
955 StartListening( *m_pFormModel );
959 //------------------------------------------------------------------------
960 Reference< XIndexContainer > NavigatorTreeModel::GetFormComponents( FmFormData* pFormData )
962 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::GetFormComponents" );
963 //////////////////////////////////////////////////////////////////////
964 // Von der Form Components holen
965 if (pFormData)
966 return Reference< XIndexContainer > (pFormData->GetFormIface(), UNO_QUERY);
968 return Reference< XIndexContainer > ();
971 //------------------------------------------------------------------------
972 sal_Bool NavigatorTreeModel::CheckEntry( FmEntryData* pEntryData )
974 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::CheckEntry" );
975 //////////////////////////////////////////////////////////////////////
976 // Nur Forms duerfen auf Doppeldeutigkeit untersucht werden
977 if( !pEntryData->ISA(FmFormData) ) return sal_True;
979 //////////////////////////////////////////////////////////////////////
980 // ChildListe des Parents holen
981 FmFormData* pParentData = (FmFormData*)pEntryData->GetParent();
982 FmEntryDataList* pChildList;
983 if( !pParentData )
984 pChildList = GetRootList();
985 else
986 pChildList = pParentData->GetChildList();
988 //////////////////////////////////////////////////////////////////////
989 // In ChildListe nach doppelten Namen suchen
990 ::rtl::OUString aChildText;
991 FmEntryData* pChildData;
993 for( sal_uInt16 i=0; i<pChildList->Count(); i++ )
995 pChildData = pChildList->GetObject(i);
996 aChildText = pChildData->GetText();
998 //////////////////////////////////////////////////////////////////////
999 // Gleichen Eintrag gefunden
1000 if ( (aChildText == pEntryData->GetText())
1001 && (pEntryData!=pChildData)
1006 SQLContext aError;
1007 aError.Message = String(SVX_RES(RID_ERR_CONTEXT_ADDFORM));
1008 aError.Details = String(SVX_RES(RID_ERR_DUPLICATE_NAME));
1009 displayException(aError);
1011 return sal_False;
1015 return sal_True;
1018 //------------------------------------------------------------------------
1019 sal_Bool NavigatorTreeModel::Rename( FmEntryData* pEntryData, const ::rtl::OUString& rNewText )
1021 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Rename" );
1022 //////////////////////////////////////////////////////////////////////
1023 // Wenn Name schon vorhanden, Fehlermeldung
1024 pEntryData->SetText( rNewText );
1026 //////////////////////////////////////////////////////////////////////
1027 // PropertySet besorgen
1028 Reference< XFormComponent > xFormComponent;
1030 if( pEntryData->ISA(FmFormData) )
1032 FmFormData* pFormData = (FmFormData*)pEntryData;
1033 Reference< XForm > xForm( pFormData->GetFormIface());
1034 xFormComponent = Reference< XFormComponent > (xForm, UNO_QUERY);
1037 if( pEntryData->ISA(FmControlData) )
1039 FmControlData* pControlData = (FmControlData*)pEntryData;
1040 xFormComponent = pControlData->GetFormComponent();
1043 if( !xFormComponent.is() ) return sal_False;
1044 Reference< XPropertySet > xSet(xFormComponent, UNO_QUERY);
1045 if( !xSet.is() ) return sal_False;
1047 //////////////////////////////////////////////////////////////////////
1048 // Namen setzen
1049 xSet->setPropertyValue( FM_PROP_NAME, makeAny(rNewText) );
1051 return sal_True;
1054 //------------------------------------------------------------------------
1055 sal_Bool NavigatorTreeModel::IsNameAlreadyDefined( const ::rtl::OUString& rName, FmFormData* pParentData )
1057 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::IsNameAlreadyDefined" );
1058 //////////////////////////////////////////////////////////////////////
1059 // Form in der Root
1060 if( !pParentData )
1062 if (GetForms()->hasByName(rName))
1063 return sal_True;
1066 //////////////////////////////////////////////////////////////////////
1067 // Restliche Components
1068 else
1070 Reference< XNameContainer > xFormComponents(GetFormComponents(pParentData), UNO_QUERY);
1071 if (xFormComponents.is() && xFormComponents->hasByName(rName))
1072 return sal_True;
1075 return sal_False;
1078 //------------------------------------------------------------------------
1079 SdrObject* NavigatorTreeModel::GetSdrObj( FmControlData* pControlData )
1081 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::GetSdrObj" );
1082 if (!pControlData || !m_pFormShell)
1083 return NULL;
1085 //////////////////////////////////////////////////////////////////////
1086 // In der Page das entsprechende SdrObj finden und selektieren
1087 Reference< XFormComponent > xFormComponent( pControlData->GetFormComponent());
1088 if (!xFormComponent.is())
1089 return NULL;
1091 FmFormView* pFormView = m_pFormShell->GetFormView();
1092 SdrPageView* pPageView = pFormView->GetSdrPageView();
1093 SdrPage* pPage = pPageView->GetPage();
1095 SdrObjListIter aIter( *pPage );
1096 return Search(aIter, xFormComponent);
1099 //------------------------------------------------------------------
1100 SdrObject* NavigatorTreeModel::Search(SdrObjListIter& rIter, const Reference< XFormComponent > & xComp)
1102 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Search" );
1103 while (rIter.IsMore())
1105 SdrObject* pObj = rIter.Next();
1106 FmFormObj* pFormObject = FmFormObj::GetFormObject( pObj );
1107 if ( pFormObject )
1109 Reference< XFormComponent > xFormViewControl( pFormObject->GetUnoControlModel(), UNO_QUERY );
1110 if ( xFormViewControl == xComp )
1111 return pObj;
1113 else if ( pObj->IsGroupObject() )
1115 SdrObjListIter aIter( *pObj->GetSubList() );
1116 pObj = Search( aIter, xComp );
1117 if ( pObj )
1118 return pObj;
1121 return NULL;
1124 //............................................................................
1125 } // namespace svxform
1126 //............................................................................