1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: navigatortreemodel.cxx,v $
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>
47 #include "fmresids.hrc"
48 #include "fmshimp.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 //............................................................................
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
)
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
);
101 pEntryData
= m_pNavModel
->FindData( xForm
, m_pNavModel
->GetRootList() );
102 else if( xFormComponent
.is() )
103 pEntryData
= m_pNavModel
->FindData( xFormComponent
, m_pNavModel
->GetRootList() );
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
)
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
);
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
;
150 Reference
< XFormComponent
> xFormComp(xIface
, UNO_QUERY
);
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
)
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
);
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
)
195 m_bCanUndo
= sal_False
;
197 //////////////////////////////////////////////////////////
198 // EntryData loeschen
199 FmEntryData
* pEntryData
= m_pNavModel
->FindData( _rxElement
, m_pNavModel
->GetRootList(), sal_True
);
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
;
215 //========================================================================
216 // class NavigatorTreeModel
217 //========================================================================
219 //------------------------------------------------------------------------
220 NavigatorTreeModel::NavigatorTreeModel( const ImageList
& _rNormalImages
, const ImageList
& _rHCImages
)
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
240 FmFormModel
* pFormModel
= m_pFormShell
->GetFormModel();
241 if( pFormModel
&& IsListening(*pFormModel
))
242 EndListening( *pFormModel
);
244 if (IsListening(*m_pFormShell
))
245 EndListening(*m_pFormShell
);
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
);
272 xContainer
->removeContainerListener((XContainerListener
*)m_pPropChangeList
);
274 //////////////////////////////////////////////////////////////////////
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
);
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())
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() );
315 if (pEntry
->ISA(FmFormData
))
316 aStr
= SVX_RES(RID_STR_FORM
);
318 aStr
= SVX_RES(RID_STR_CONTROL
);
320 Reference
< XIndexContainer
> xContainer
;
322 xContainer
= Reference
< XIndexContainer
> (pFolder
->GetFormIface(), UNO_QUERY
);
324 xContainer
= Reference
< XIndexContainer
> (GetForms(), UNO_QUERY
);
326 bool bUndo
= m_pFormModel
->IsUndoEnabled();
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();
339 if ( bUndo
&& m_pPropChangeList
->CanUndo())
341 m_pFormModel
->AddUndo(new FmUndoContainerAction(*m_pFormModel
,
342 FmUndoContainerAction::Inserted
,
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
));
365 DBG_ERROR("NavigatorTreeModel::Insert : the parent container needs an elementtype I don't know !");
369 m_pFormModel
->EndUndo();
372 //////////////////////////////////////////////////////////////////////
373 // Als PropertyChangeListener anmelden
374 Reference
< XPropertySet
> xSet(xElement
, UNO_QUERY
);
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
);
384 xContainer
->addContainerListener((XContainerListener
*)m_pPropChangeList
);
388 pFolder
->GetChildList()->Insert( pEntry
, nRelPos
);
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
)
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() );
422 if (pEntry
->ISA(FmFormData
))
423 aStr
= SVX_RES(RID_STR_FORM
);
425 aStr
= SVX_RES(RID_STR_CONTROL
);
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
);
439 RemoveFormComponent((FmControlData
*)pEntry
);
444 Reference
< XIndexContainer
> xContainer(xElement
->getParent(), UNO_QUERY
);
445 // aus dem Container entfernen
446 sal_Int32 nContainerIndex
= getElementPos(xContainer
.get(), xElement
);
448 if (nContainerIndex
>= 0)
450 if ( bUndo
&& m_pPropChangeList
->CanUndo())
452 m_pFormModel
->AddUndo(new FmUndoContainerAction(*m_pFormModel
,
453 FmUndoContainerAction::Removed
,
455 xElement
, nContainerIndex
));
457 else if( !m_pPropChangeList
->CanUndo() )
459 FmUndoContainerAction::DisposeElement( xElement
);
462 xContainer
->removeByIndex(nContainerIndex
);
466 m_pFormModel
->EndUndo();
469 // beim Vater austragen
471 pFolder
->GetChildList()->Remove(pEntry
);
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
);
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
)
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() );
520 xSet
->removePropertyChangeListener( FM_PROP_NAME
, m_pPropChangeList
);
522 Reference
< XContainer
> xContainer( pFormData
->GetContainer() );
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
536 //////////////////////////////////////////////////////////////////////
537 // Als PropertyChangeListener abmelden
538 Reference
< XPropertySet
> xSet( pControlData
->GetPropertySet() );
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
);
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
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
);
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
);
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() );
636 //////////////////////////////////////////////////////////
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 //////////////////////////////////////////////////////////
654 Reference
< XInterface
> xIFace( xComp
->getParent());
655 Reference
< XForm
> xForm(xIFace
, UNO_QUERY
);
659 FmFormData
* pParentData
= (FmFormData
*)FindData( xForm
, GetRootList() );
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" );
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() )
704 pEntryData
= FindData( xElement
, pEntryData
->GetChildList() );
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
;
718 pDataList
= GetRootList();
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
)
734 if( bRecurs
&& pEntryData
->ISA(FmFormData
) )
736 pChildData
= FindData( rText
, (FmFormData
*)pEntryData
);
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());
757 case HINT_OBJREMOVED
:
758 RemoveSdrObj(pSdrHint
->GetObject());
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
);
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
);
813 Reference
< XFormComponent
> xFormComponent( pFormObject
->GetUnoControlModel(), UNO_QUERY_THROW
);
814 FmEntryData
* pEntryData
= FindData( xFormComponent
, GetRootList(), sal_True
);
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
))
846 FmFormObj
* pFormObject
= FmFormObj::GetFormObject( pObject
);
852 Reference
< XFormComponent
> xFormViewControl( pFormObject
->GetUnoControlModel(), UNO_QUERY_THROW
);
853 FmEntryData
* pControlData
= FindData( xFormViewControl
, GetRootList() );
857 rHint
.AddItem( pControlData
);
860 catch( const Exception
& )
862 DBG_UNHANDLED_EXCEPTION();
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
901 Reference
< XContainer
> xFormContainer(xForms
, UNO_QUERY
);
902 if (xFormContainer
.is())
903 xFormContainer
->addContainerListener((XContainerListener
*)m_pPropChangeList
);
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
))
927 //////////////////////////////////////////////////////////////////////
928 // Als Listener abmelden
932 EndListening( *m_pFormModel
);
934 EndListening( *m_pFormShell
);
938 //////////////////////////////////////////////////////////////////////
940 m_pFormShell
= pShell
;
943 m_pFormPage
= pNewPage
;
944 UpdateContent(m_pFormPage
->GetForms());
948 //////////////////////////////////////////////////////////////////////
949 // Als Listener neu anmelden
952 StartListening( *m_pFormShell
);
953 m_pFormModel
= m_pFormShell
->GetFormModel();
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
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
;
984 pChildList
= GetRootList();
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
)
1007 aError
.Message
= String(SVX_RES(RID_ERR_CONTEXT_ADDFORM
));
1008 aError
.Details
= String(SVX_RES(RID_ERR_DUPLICATE_NAME
));
1009 displayException(aError
);
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 //////////////////////////////////////////////////////////////////////
1049 xSet
->setPropertyValue( FM_PROP_NAME
, makeAny(rNewText
) );
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 //////////////////////////////////////////////////////////////////////
1062 if (GetForms()->hasByName(rName
))
1066 //////////////////////////////////////////////////////////////////////
1067 // Restliche Components
1070 Reference
< XNameContainer
> xFormComponents(GetFormComponents(pParentData
), UNO_QUERY
);
1071 if (xFormComponents
.is() && xFormComponents
->hasByName(rName
))
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
)
1085 //////////////////////////////////////////////////////////////////////
1086 // In der Page das entsprechende SdrObj finden und selektieren
1087 Reference
< XFormComponent
> xFormComponent( pControlData
->GetFormComponent());
1088 if (!xFormComponent
.is())
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
);
1109 Reference
< XFormComponent
> xFormViewControl( pFormObject
->GetUnoControlModel(), UNO_QUERY
);
1110 if ( xFormViewControl
== xComp
)
1113 else if ( pObj
->IsGroupObject() )
1115 SdrObjListIter
aIter( *pObj
->GetSubList() );
1116 pObj
= Search( aIter
, xComp
);
1124 //............................................................................
1125 } // namespace svxform
1126 //............................................................................