Version 4.3.0.0.beta1, tag libreoffice-4.3.0.0.beta1
[LibreOffice.git] / svx / source / form / navigatortreemodel.cxx
blob9df5153eb98d5bc87113aa725ea40fea2397bdd9
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <svx/dialmgr.hxx>
21 #include <svx/fmshell.hxx>
22 #include <svx/fmmodel.hxx>
23 #include <svx/fmpage.hxx>
24 #include <svx/fmglob.hxx>
25 #include "svx/svditer.hxx"
26 #include <svx/svdogrp.hxx>
27 #include <svx/svdpagv.hxx>
29 #include "fmprop.hrc"
31 #include "fmundo.hxx"
32 #include "fmhelp.hrc"
33 #include "fmexpl.hxx"
34 #include "svx/fmresids.hrc"
35 #include "fmshimp.hxx"
36 #include "fmobj.hxx"
37 #include <sfx2/objsh.hxx>
38 #include <tools/diagnose_ex.h>
39 #include <com/sun/star/container/XContainer.hpp>
42 namespace svxform
46 using namespace ::com::sun::star::uno;
47 using namespace ::com::sun::star::lang;
48 using namespace ::com::sun::star::beans;
49 using namespace ::com::sun::star::form;
50 using namespace ::com::sun::star::awt;
51 using namespace ::com::sun::star::container;
52 using namespace ::com::sun::star::script;
53 using namespace ::com::sun::star::sdb;
56 // class OFormComponentObserver
59 OFormComponentObserver::OFormComponentObserver(NavigatorTreeModel* _pModel)
60 :m_pNavModel(_pModel)
61 ,m_nLocks(0)
62 ,m_bCanUndo(true)
66 // XPropertyChangeListener
68 void SAL_CALL OFormComponentObserver::disposing(const EventObject& Source) throw( RuntimeException, std::exception )
70 Remove( Source.Source );
74 void SAL_CALL OFormComponentObserver::propertyChange(const PropertyChangeEvent& evt) throw(RuntimeException, std::exception)
76 if( !m_pNavModel ) return;
77 if( evt.PropertyName != FM_PROP_NAME ) return;
79 Reference< XFormComponent > xFormComponent(evt.Source, UNO_QUERY);
80 Reference< XForm > xForm(evt.Source, UNO_QUERY);
82 FmEntryData* pEntryData( NULL );
83 if( xForm.is() )
84 pEntryData = m_pNavModel->FindData( xForm, m_pNavModel->GetRootList() );
85 else if( xFormComponent.is() )
86 pEntryData = m_pNavModel->FindData( xFormComponent, m_pNavModel->GetRootList() );
88 if( pEntryData )
90 OUString aNewName = ::comphelper::getString(evt.NewValue);
91 pEntryData->SetText( aNewName );
92 FmNavNameChangedHint aNameChangedHint( pEntryData, aNewName );
93 m_pNavModel->Broadcast( aNameChangedHint );
97 // XContainerListener
99 void SAL_CALL OFormComponentObserver::elementInserted(const ContainerEvent& evt) throw(RuntimeException, std::exception)
101 if (IsLocked() || !m_pNavModel)
102 return;
104 // keine Undoaction einfuegen
105 m_bCanUndo = false;
107 Reference< XInterface > xTemp;
108 evt.Element >>= xTemp;
109 Insert(xTemp, ::comphelper::getINT32(evt.Accessor));
111 m_bCanUndo = true;
115 void OFormComponentObserver::Insert(const Reference< XInterface > & xIface, sal_Int32 nIndex)
117 Reference< XForm > xForm(xIface, UNO_QUERY);
118 if (xForm.is())
120 m_pNavModel->InsertForm(xForm, sal_uInt32(nIndex));
121 Reference< XIndexContainer > xContainer(xForm, UNO_QUERY);
122 Reference< XInterface > xTemp;
123 for (sal_Int32 i = 0; i < xContainer->getCount(); i++)
125 xContainer->getByIndex(i) >>= xTemp;
126 Insert(xTemp, i);
129 else
131 Reference< XFormComponent > xFormComp(xIface, UNO_QUERY);
132 if (xFormComp.is())
133 m_pNavModel->InsertFormComponent(xFormComp, sal_uInt32(nIndex));
138 void SAL_CALL OFormComponentObserver::elementReplaced(const ContainerEvent& evt) throw(RuntimeException, std::exception)
140 if (IsLocked() || !m_pNavModel)
141 return;
143 m_bCanUndo = false;
145 // EntryData loeschen
146 Reference< XFormComponent > xReplaced;
147 evt.ReplacedElement >>= xReplaced;
148 FmEntryData* pEntryData = m_pNavModel->FindData(xReplaced, m_pNavModel->GetRootList(), true);
149 if (pEntryData)
151 if (pEntryData->ISA(FmControlData))
153 Reference< XFormComponent > xComp;
154 evt.Element >>= xComp;
155 DBG_ASSERT(xComp.is(), "OFormComponentObserver::elementReplaced : invalid argument !");
156 // an einer FmControlData sollte eine XFormComponent haengen
157 m_pNavModel->ReplaceFormComponent(xReplaced, xComp);
159 else if (pEntryData->ISA(FmFormData))
161 OSL_FAIL("replacing forms not implemented yet !");
165 m_bCanUndo = true;
169 void OFormComponentObserver::Remove( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxElement )
171 if (IsLocked() || !m_pNavModel)
172 return;
174 m_bCanUndo = false;
177 // EntryData loeschen
178 FmEntryData* pEntryData = m_pNavModel->FindData( _rxElement, m_pNavModel->GetRootList(), true );
179 if (pEntryData)
180 m_pNavModel->Remove(pEntryData);
182 m_bCanUndo = true;
186 void SAL_CALL OFormComponentObserver::elementRemoved(const ContainerEvent& evt) throw(RuntimeException, std::exception)
188 Reference< XInterface > xElement;
189 evt.Element >>= xElement;
190 Remove( xElement );
194 // class NavigatorTreeModel
198 NavigatorTreeModel::NavigatorTreeModel( const ImageList& _rNormalImages )
199 :m_pFormShell(NULL)
200 ,m_pFormPage(NULL)
201 ,m_pFormModel(NULL)
202 ,m_aNormalImages( _rNormalImages )
204 m_pPropChangeList = new OFormComponentObserver(this);
205 m_pPropChangeList->acquire();
206 m_pRootList = new FmEntryDataList();
210 NavigatorTreeModel::~NavigatorTreeModel()
213 // Als Listener abmelden
214 if( m_pFormShell)
216 FmFormModel* pFormModel = m_pFormShell->GetFormModel();
217 if( pFormModel && IsListening(*pFormModel))
218 EndListening( *pFormModel );
220 if (IsListening(*m_pFormShell))
221 EndListening(*m_pFormShell);
224 Clear();
225 delete m_pRootList;
226 m_pPropChangeList->ReleaseModel();
227 m_pPropChangeList->release();
232 void NavigatorTreeModel::SetModified( bool bMod )
234 if( !m_pFormShell ) return;
235 SfxObjectShell* pObjShell = m_pFormShell->GetFormModel()->GetObjectShell();
236 if( !pObjShell ) return;
237 pObjShell->SetModified( bMod );
241 void NavigatorTreeModel::Clear()
243 Reference< css::form::XForms > xForms( GetForms());
244 if(xForms.is())
245 xForms->removeContainerListener((XContainerListener*)m_pPropChangeList);
248 // RootList loeschen
249 GetRootList()->clear();
252 // UI benachrichtigen
253 FmNavClearedHint aClearedHint;
254 Broadcast( aClearedHint );
258 Reference< css::form::XForms > NavigatorTreeModel::GetForms() const
260 if( !m_pFormShell || !m_pFormShell->GetCurPage())
261 return NULL;
262 else
263 return m_pFormShell->GetCurPage()->GetForms();
267 void NavigatorTreeModel::Insert(FmEntryData* pEntry, sal_uLong nRelPos, bool bAlterModel)
269 if (IsListening(*m_pFormModel))
270 EndListening(*m_pFormModel);
272 m_pPropChangeList->Lock();
273 FmFormData* pFolder = (FmFormData*) pEntry->GetParent();
274 Reference< XChild > xElement( pEntry->GetChildIFace() );
275 if (bAlterModel)
277 OUString aStr;
278 if (pEntry->ISA(FmFormData))
279 aStr = SVX_RESSTR(RID_STR_FORM);
280 else
281 aStr = SVX_RESSTR(RID_STR_CONTROL);
283 Reference< XIndexContainer > xContainer;
284 if (pFolder)
285 xContainer = Reference< XIndexContainer > (pFolder->GetFormIface(), UNO_QUERY);
286 else
287 xContainer = Reference< XIndexContainer > (GetForms(), UNO_QUERY);
289 bool bUndo = m_pFormModel->IsUndoEnabled();
291 if( bUndo )
293 OUString aUndoStr(SVX_RESSTR(RID_STR_UNDO_CONTAINER_INSERT));
294 aUndoStr = aUndoStr.replaceFirst("#", aStr);
295 m_pFormModel->BegUndo(aUndoStr);
298 if (nRelPos >= (sal_uInt32)xContainer->getCount())
299 nRelPos = (sal_uInt32)xContainer->getCount();
301 // UndoAction
302 if ( bUndo && m_pPropChangeList->CanUndo())
304 m_pFormModel->AddUndo(new FmUndoContainerAction(*m_pFormModel,
305 FmUndoContainerAction::Inserted,
306 xContainer,
307 xElement,
308 nRelPos));
311 // das Element muss den Typ haben, den der Container erwartet
312 if (xContainer->getElementType() ==
313 cppu::UnoType<XForm>::get())
316 Reference< XForm > xElementAsForm(xElement, UNO_QUERY);
317 xContainer->insertByIndex(nRelPos, makeAny(xElementAsForm));
319 else if (xContainer->getElementType() ==
320 cppu::UnoType<XFormComponent>::get())
323 Reference< XFormComponent > xElementAsComponent(xElement, UNO_QUERY);
324 xContainer->insertByIndex(nRelPos, makeAny(xElementAsComponent));
326 else
328 OSL_FAIL("NavigatorTreeModel::Insert : the parent container needs an elementtype I don't know !");
331 if( bUndo )
332 m_pFormModel->EndUndo();
336 // Als PropertyChangeListener anmelden
337 Reference< XPropertySet > xSet(xElement, UNO_QUERY);
338 if( xSet.is() )
339 xSet->addPropertyChangeListener( FM_PROP_NAME, m_pPropChangeList );
342 // Daten aus Model entfernen
343 if (pEntry->ISA(FmFormData))
345 Reference< XContainer > xContainer(xElement, UNO_QUERY);
346 if (xContainer.is())
347 xContainer->addContainerListener((XContainerListener*)m_pPropChangeList);
350 if (pFolder)
351 pFolder->GetChildList()->insert( pEntry, nRelPos );
352 else
353 GetRootList()->insert( pEntry, nRelPos );
356 // UI benachrichtigen
357 FmNavInsertedHint aInsertedHint( pEntry, nRelPos );
358 Broadcast( aInsertedHint );
360 m_pPropChangeList->UnLock();
361 if (IsListening(*m_pFormModel))
362 StartListening(*m_pFormModel);
366 void NavigatorTreeModel::Remove(FmEntryData* pEntry, bool bAlterModel)
369 // Form und Parent holen
370 if (!pEntry || !m_pFormModel)
371 return;
373 if (IsListening(*m_pFormModel))
374 EndListening(*m_pFormModel);
376 const bool bUndo = m_pFormModel->IsUndoEnabled();
378 m_pPropChangeList->Lock();
379 FmFormData* pFolder = (FmFormData*) pEntry->GetParent();
380 Reference< XChild > xElement ( pEntry->GetChildIFace() );
381 if (bAlterModel)
383 OUString aStr;
384 if (pEntry->ISA(FmFormData))
385 aStr = SVX_RESSTR(RID_STR_FORM);
386 else
387 aStr = SVX_RESSTR(RID_STR_CONTROL);
389 if( bUndo )
391 OUString aUndoStr(SVX_RESSTR(RID_STR_UNDO_CONTAINER_REMOVE));
392 aUndoStr = aUndoStr.replaceFirst("#", aStr);
393 m_pFormModel->BegUndo(aUndoStr);
397 // jetzt die eigentliche Entfernung der Daten aus dem Model
398 if (pEntry->ISA(FmFormData))
399 RemoveForm((FmFormData*)pEntry);
400 else
401 RemoveFormComponent((FmControlData*)pEntry);
404 if (bAlterModel)
406 Reference< XIndexContainer > xContainer(xElement->getParent(), UNO_QUERY);
407 // aus dem Container entfernen
408 sal_Int32 nContainerIndex = getElementPos(xContainer.get(), xElement);
409 // UndoAction
410 if (nContainerIndex >= 0)
412 if ( bUndo && m_pPropChangeList->CanUndo())
414 m_pFormModel->AddUndo(new FmUndoContainerAction(*m_pFormModel,
415 FmUndoContainerAction::Removed,
416 xContainer,
417 xElement, nContainerIndex ));
419 else if( !m_pPropChangeList->CanUndo() )
421 FmUndoContainerAction::DisposeElement( xElement );
424 xContainer->removeByIndex(nContainerIndex );
427 if( bUndo )
428 m_pFormModel->EndUndo();
431 // beim Vater austragen
432 if (pFolder)
433 pFolder->GetChildList()->remove( pEntry );
434 else
436 GetRootList()->remove( pEntry );
438 // Wenn keine Form mehr in der Root, an der Shell CurForm zuruecksetzen
439 if ( !GetRootList()->size() )
440 m_pFormShell->GetImpl()->forgetCurrentForm();
444 // UI benachrichtigen
445 FmNavRemovedHint aRemovedHint( pEntry );
446 Broadcast( aRemovedHint );
448 // Eintrag loeschen
449 delete pEntry;
451 m_pPropChangeList->UnLock();
452 StartListening(*m_pFormModel);
456 void NavigatorTreeModel::RemoveForm(FmFormData* pFormData)
459 // Form und Parent holen
460 if (!pFormData || !m_pFormModel)
461 return;
463 FmEntryDataList* pChildList = pFormData->GetChildList();
464 for ( size_t i = pChildList->size(); i > 0; )
466 FmEntryData* pEntryData = pChildList->at( --i );
469 // Child ist Form -> rekursiver Aufruf
470 if( pEntryData->ISA(FmFormData) )
471 RemoveForm( (FmFormData*)pEntryData);
472 else if( pEntryData->ISA(FmControlData) )
473 RemoveFormComponent((FmControlData*) pEntryData);
477 // Als PropertyChangeListener abmelden
478 Reference< XPropertySet > xSet( pFormData->GetPropertySet() );
479 if ( xSet.is() )
480 xSet->removePropertyChangeListener( FM_PROP_NAME, m_pPropChangeList );
482 Reference< XContainer > xContainer( pFormData->GetContainer() );
483 if (xContainer.is())
484 xContainer->removeContainerListener((XContainerListener*)m_pPropChangeList);
488 void NavigatorTreeModel::RemoveFormComponent(FmControlData* pControlData)
491 // Control und Parent holen
492 if (!pControlData)
493 return;
496 // Als PropertyChangeListener abmelden
497 Reference< XPropertySet > xSet( pControlData->GetPropertySet() );
498 if (xSet.is())
499 xSet->removePropertyChangeListener( FM_PROP_NAME, m_pPropChangeList);
503 void NavigatorTreeModel::ClearBranch( FmFormData* pParentData )
506 // Alle Eintraege dieses Zweiges loeschen
507 FmEntryDataList* pChildList = pParentData->GetChildList();
509 for( size_t i = pChildList->size(); i > 0; )
511 FmEntryData* pChildData = pChildList->at( --i );
512 if( pChildData->ISA(FmFormData) )
513 ClearBranch( (FmFormData*)pChildData );
515 pChildList->remove( pChildData );
520 void NavigatorTreeModel::FillBranch( FmFormData* pFormData )
523 // Forms aus der Root einfuegen
524 if( pFormData == NULL )
526 Reference< XIndexContainer > xForms(GetForms(), UNO_QUERY);
527 if (!xForms.is())
528 return;
530 Reference< XForm > xSubForm;
531 FmFormData* pSubFormData;
532 for (sal_Int32 i=0; i<xForms->getCount(); ++i)
534 DBG_ASSERT( xForms->getByIndex(i).getValueType() == cppu::UnoType<XForm>::get(),
535 "NavigatorTreeModel::FillBranch : the root container should supply only elements of type XForm");
537 xForms->getByIndex(i) >>= xSubForm;
538 pSubFormData = new FmFormData( xSubForm, m_aNormalImages, pFormData );
539 Insert( pSubFormData, CONTAINER_APPEND );
542 // Neuer Branch, wenn SubForm wiederum Subforms enthaelt
543 FillBranch( pSubFormData );
548 // Componenten einfuegen
549 else
551 Reference< XIndexContainer > xComponents( GetFormComponents(pFormData));
552 if( !xComponents.is() ) return;
554 Reference< XInterface > xInterface;
555 Reference< XPropertySet > xSet;
556 FmControlData* pNewControlData;
557 FmFormData* pSubFormData;
559 Reference< XFormComponent > xCurrentComponent;
560 for (sal_Int32 j=0; j<xComponents->getCount(); ++j)
562 xComponents->getByIndex(j) >>= xCurrentComponent;
563 Reference< XForm > xSubForm(xCurrentComponent, UNO_QUERY);
565 if (xSubForm.is())
566 { // die aktuelle Component ist eine Form
567 pSubFormData = new FmFormData(xSubForm, m_aNormalImages, pFormData);
568 Insert(pSubFormData, CONTAINER_APPEND);
571 // Neuer Branch, wenn SubForm wiederum Subforms enthaelt
572 FillBranch(pSubFormData);
574 else
576 pNewControlData = new FmControlData(xCurrentComponent, m_aNormalImages, pFormData);
577 Insert(pNewControlData, CONTAINER_APPEND);
584 void NavigatorTreeModel::InsertForm(const Reference< XForm > & xForm, sal_uInt32 nRelPos)
586 FmFormData* pFormData = (FmFormData*)FindData( xForm, GetRootList() );
587 if (pFormData)
588 return;
591 // ParentData setzen
592 Reference< XInterface > xIFace( xForm->getParent());
593 Reference< XForm > xParentForm(xIFace, UNO_QUERY);
594 FmFormData* pParentData = NULL;
595 if (xParentForm.is())
596 pParentData = (FmFormData*)FindData( xParentForm, GetRootList() );
598 pFormData = new FmFormData( xForm, m_aNormalImages, pParentData );
599 Insert( pFormData, nRelPos );
603 void NavigatorTreeModel::InsertFormComponent(const Reference< XFormComponent > & xComp, sal_uInt32 nRelPos)
606 // ParentData setzen
607 Reference< XInterface > xIFace( xComp->getParent());
608 Reference< XForm > xForm(xIFace, UNO_QUERY);
609 if (!xForm.is())
610 return;
612 FmFormData* pParentData = (FmFormData*)FindData( xForm, GetRootList() );
613 if( !pParentData )
615 pParentData = new FmFormData( xForm, m_aNormalImages, NULL );
616 Insert( pParentData, CONTAINER_APPEND );
619 if (!FindData(xComp, pParentData->GetChildList(),false))
622 // Neue EntryData setzen
623 FmEntryData* pNewEntryData = new FmControlData( xComp, m_aNormalImages, pParentData );
626 // Neue EntryData einfuegen
627 Insert( pNewEntryData, nRelPos );
632 void NavigatorTreeModel::ReplaceFormComponent(
633 const Reference< XFormComponent > & xOld,
634 const Reference< XFormComponent > & xNew
637 FmEntryData* pData = FindData(xOld, GetRootList(), true);
638 assert(pData && pData->ISA(FmControlData)); //NavigatorTreeModel::ReplaceFormComponent : invalid argument
639 if (!pData || !pData->ISA(FmControlData))
640 return;
641 ((FmControlData*)pData)->ModelReplaced( xNew, m_aNormalImages );
643 FmNavModelReplacedHint aReplacedHint( pData );
644 Broadcast( aReplacedHint );
648 FmEntryData* NavigatorTreeModel::FindData(const Reference< XInterface > & xElement, FmEntryDataList* pDataList, bool bRecurs)
650 // normalize
651 Reference< XInterface > xIFace( xElement, UNO_QUERY );
653 for ( size_t i = 0; i < pDataList->size(); i++ )
655 FmEntryData* pEntryData = pDataList->at( i );
656 if ( pEntryData->GetElement().get() == xIFace.get() )
657 return pEntryData;
658 else if (bRecurs)
660 pEntryData = FindData( xElement, pEntryData->GetChildList() );
661 if (pEntryData)
662 return pEntryData;
665 return NULL;
669 FmEntryData* NavigatorTreeModel::FindData( const OUString& rText, FmFormData* pParentData, bool bRecurs )
671 FmEntryDataList* pDataList;
672 if( !pParentData )
673 pDataList = GetRootList();
674 else
675 pDataList = pParentData->GetChildList();
677 OUString aEntryText;
678 FmEntryData* pEntryData;
679 FmEntryData* pChildData;
681 for( size_t i = 0; i < pDataList->size(); i++ )
683 pEntryData = pDataList->at( i );
684 aEntryText = pEntryData->GetText();
686 if (rText == aEntryText)
687 return pEntryData;
689 if( bRecurs && pEntryData->ISA(FmFormData) )
691 pChildData = FindData( rText, (FmFormData*)pEntryData );
692 if( pChildData )
693 return pChildData;
697 return NULL;
701 void NavigatorTreeModel::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
703 if( rHint.ISA(SdrHint) )
705 SdrHint* pSdrHint = (SdrHint*)&rHint;
706 switch( pSdrHint->GetKind() )
708 case HINT_OBJINSERTED:
709 InsertSdrObj(pSdrHint->GetObject());
710 break;
711 case HINT_OBJREMOVED:
712 RemoveSdrObj(pSdrHint->GetObject());
713 break;
714 default:
715 break;
718 // hat sich die shell verabschiedet?
719 else if ( rHint.ISA(SfxSimpleHint) && ((SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING)
720 UpdateContent((FmFormShell*)NULL);
722 // hat sich die Markierung der Controls veraendert ?
723 else if (rHint.ISA(FmNavViewMarksChanged))
725 FmNavViewMarksChanged* pvmcHint = (FmNavViewMarksChanged*)&rHint;
726 BroadcastMarkedObjects( pvmcHint->GetAffectedView()->GetMarkedObjectList() );
731 void NavigatorTreeModel::InsertSdrObj( const SdrObject* pObj )
733 const FmFormObj* pFormObject = FmFormObj::GetFormObject( pObj );
734 if ( pFormObject )
738 Reference< XFormComponent > xFormComponent( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW );
739 Reference< XIndexAccess > xContainer( xFormComponent->getParent(), UNO_QUERY_THROW );
741 sal_Int32 nPos = getElementPos( xContainer, xFormComponent );
742 InsertFormComponent( xFormComponent, nPos );
744 catch( const Exception& )
746 DBG_UNHANDLED_EXCEPTION();
749 else if ( pObj->IsGroupObject() )
751 SdrObjListIter aIter( *pObj->GetSubList() );
752 while ( aIter.IsMore() )
753 InsertSdrObj( aIter.Next() );
758 void NavigatorTreeModel::RemoveSdrObj( const SdrObject* pObj )
760 const FmFormObj* pFormObject = FmFormObj::GetFormObject( pObj );
761 if ( pFormObject )
765 Reference< XFormComponent > xFormComponent( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW );
766 FmEntryData* pEntryData = FindData( xFormComponent, GetRootList(), true );
767 if ( pEntryData )
768 Remove( pEntryData );
770 catch( const Exception& )
772 DBG_UNHANDLED_EXCEPTION();
775 else if ( pObj->IsGroupObject() )
777 SdrObjListIter aIter( *pObj->GetSubList() );
778 while ( aIter.IsMore() )
779 RemoveSdrObj( aIter.Next() );
783 bool NavigatorTreeModel::InsertFormComponent(FmNavRequestSelectHint& rHint, SdrObject* pObject)
785 if ( pObject->ISA(SdrObjGroup) )
786 { // rekursiv absteigen
787 const SdrObjList *pChildren = ((SdrObjGroup*)pObject)->GetSubList();
788 for ( sal_uInt16 i=0; i<pChildren->GetObjCount(); ++i )
790 SdrObject* pCurrent = pChildren->GetObj(i);
791 if (!InsertFormComponent(rHint, pCurrent))
792 return false;
795 else
797 FmFormObj* pFormObject = FmFormObj::GetFormObject( pObject );
798 if ( !pFormObject )
799 return false;
803 Reference< XFormComponent > xFormViewControl( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW );
804 FmEntryData* pControlData = FindData( xFormViewControl, GetRootList() );
805 if ( !pControlData )
806 return false;
808 rHint.AddItem( pControlData );
809 return true;
811 catch( const Exception& )
813 DBG_UNHANDLED_EXCEPTION();
814 return false;
818 return true;
821 void NavigatorTreeModel::BroadcastMarkedObjects(const SdrMarkList& mlMarked)
823 // gehen wir durch alle markierten Objekte und suchen wir die raus, mit denen ich was anfangen kann
824 FmNavRequestSelectHint rshRequestSelection;
825 bool bIsMixedSelection = false;
827 for (sal_uLong i=0; (i<mlMarked.GetMarkCount()) && !bIsMixedSelection; i++)
829 SdrObject* pobjCurrent = mlMarked.GetMark(i)->GetMarkedSdrObj();
830 bIsMixedSelection |= !InsertFormComponent(rshRequestSelection, pobjCurrent);
831 // bei einem Nicht-Form-Control liefert InsertFormComponent sal_False !
834 rshRequestSelection.SetMixedSelection(bIsMixedSelection);
835 if (bIsMixedSelection)
836 rshRequestSelection.ClearItems();
838 Broadcast(rshRequestSelection);
839 // eine leere Liste interpretiert der NavigatorTree so, dass er seine Selektion komplett rausnimmt
843 void NavigatorTreeModel::UpdateContent( const Reference< css::form::XForms > & xForms )
846 // Model von der Root aufwaerts neu fuellen
847 Clear();
848 if (xForms.is())
850 xForms->addContainerListener((XContainerListener*)m_pPropChangeList);
852 FillBranch(NULL);
854 // jetzt in meinem Tree genau die das in meiner View markierte Control selektieren
855 // (bzw alle solchen), falls es eines gibt ...
856 if(!m_pFormShell) return; // keine Shell -> wech
858 FmFormView* pFormView = m_pFormShell->GetFormView();
859 DBG_ASSERT(pFormView != NULL, "NavigatorTreeModel::UpdateContent : keine FormView");
860 BroadcastMarkedObjects(pFormView->GetMarkedObjectList());
865 void NavigatorTreeModel::UpdateContent( FmFormShell* pShell )
868 // Wenn Shell sich nicht veraendert hat, nichts machen
869 FmFormPage* pNewPage = pShell ? pShell->GetCurPage() : NULL;
870 if ((pShell == m_pFormShell) && (m_pFormPage == pNewPage))
871 return;
874 // Als Listener abmelden
875 if( m_pFormShell )
877 if (m_pFormModel)
878 EndListening( *m_pFormModel );
879 m_pFormModel = NULL;
880 EndListening( *m_pFormShell );
881 Clear();
885 // Vollupdate
886 m_pFormShell = pShell;
887 if (m_pFormShell)
889 m_pFormPage = pNewPage;
890 UpdateContent(m_pFormPage->GetForms());
891 } else
892 m_pFormPage = NULL;
895 // Als Listener neu anmelden
896 if( m_pFormShell )
898 StartListening( *m_pFormShell );
899 m_pFormModel = m_pFormShell->GetFormModel();
900 if( m_pFormModel )
901 StartListening( *m_pFormModel );
906 Reference< XIndexContainer > NavigatorTreeModel::GetFormComponents( FmFormData* pFormData )
909 // Von der Form Components holen
910 if (pFormData)
911 return Reference< XIndexContainer > (pFormData->GetFormIface(), UNO_QUERY);
913 return Reference< XIndexContainer > ();
917 bool NavigatorTreeModel::Rename( FmEntryData* pEntryData, const OUString& rNewText )
920 // Wenn Name schon vorhanden, Fehlermeldung
921 pEntryData->SetText( rNewText );
924 // PropertySet besorgen
925 Reference< XFormComponent > xFormComponent;
927 if( pEntryData->ISA(FmFormData) )
929 FmFormData* pFormData = (FmFormData*)pEntryData;
930 Reference< XForm > xForm( pFormData->GetFormIface());
931 xFormComponent = xForm;
934 if( pEntryData->ISA(FmControlData) )
936 FmControlData* pControlData = (FmControlData*)pEntryData;
937 xFormComponent = pControlData->GetFormComponent();
940 if( !xFormComponent.is() ) return false;
941 Reference< XPropertySet > xSet(xFormComponent, UNO_QUERY);
942 if( !xSet.is() ) return false;
945 // Namen setzen
946 xSet->setPropertyValue( FM_PROP_NAME, makeAny(rNewText) );
948 return true;
952 SdrObject* NavigatorTreeModel::Search(SdrObjListIter& rIter, const Reference< XFormComponent > & xComp)
954 while (rIter.IsMore())
956 SdrObject* pObj = rIter.Next();
957 FmFormObj* pFormObject = FmFormObj::GetFormObject( pObj );
958 if ( pFormObject )
960 Reference< XFormComponent > xFormViewControl( pFormObject->GetUnoControlModel(), UNO_QUERY );
961 if ( xFormViewControl == xComp )
962 return pObj;
964 else if ( pObj->IsGroupObject() )
966 SdrObjListIter aIter( *pObj->GetSubList() );
967 pObj = Search( aIter, xComp );
968 if ( pObj )
969 return pObj;
972 return NULL;
976 } // namespace svxform
980 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */