lok: Don't attempt to select the exact text after a failed search.
[LibreOffice.git] / svx / source / form / navigatortreemodel.cxx
blobf00b331e84ce1cb9108a05b71b7bdf81d3d44a87
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;
55 OFormComponentObserver::OFormComponentObserver(NavigatorTreeModel* _pModel)
56 :m_pNavModel(_pModel)
57 ,m_nLocks(0)
58 ,m_bCanUndo(true)
62 // XPropertyChangeListener
64 void SAL_CALL OFormComponentObserver::disposing(const EventObject& Source) throw( RuntimeException, std::exception )
66 Remove( Source.Source );
70 void SAL_CALL OFormComponentObserver::propertyChange(const PropertyChangeEvent& evt) throw(RuntimeException, std::exception)
72 if( !m_pNavModel ) return;
73 if( evt.PropertyName != FM_PROP_NAME ) return;
75 Reference< XFormComponent > xFormComponent(evt.Source, UNO_QUERY);
76 Reference< XForm > xForm(evt.Source, UNO_QUERY);
78 FmEntryData* pEntryData( NULL );
79 if( xForm.is() )
80 pEntryData = m_pNavModel->FindData( xForm, m_pNavModel->GetRootList() );
81 else if( xFormComponent.is() )
82 pEntryData = m_pNavModel->FindData( xFormComponent, m_pNavModel->GetRootList() );
84 if( pEntryData )
86 OUString aNewName = ::comphelper::getString(evt.NewValue);
87 pEntryData->SetText( aNewName );
88 FmNavNameChangedHint aNameChangedHint( pEntryData, aNewName );
89 m_pNavModel->Broadcast( aNameChangedHint );
93 // XContainerListener
95 void SAL_CALL OFormComponentObserver::elementInserted(const ContainerEvent& evt) throw(RuntimeException, std::exception)
97 if (IsLocked() || !m_pNavModel)
98 return;
100 // insert no Undoaction
101 m_bCanUndo = false;
103 Reference< XInterface > xTemp;
104 evt.Element >>= xTemp;
105 Insert(xTemp, ::comphelper::getINT32(evt.Accessor));
107 m_bCanUndo = true;
111 void OFormComponentObserver::Insert(const Reference< XInterface > & xIface, sal_Int32 nIndex)
113 Reference< XForm > xForm(xIface, UNO_QUERY);
114 if (xForm.is())
116 m_pNavModel->InsertForm(xForm, sal_uInt32(nIndex));
117 Reference< XIndexContainer > xContainer(xForm, UNO_QUERY);
118 Reference< XInterface > xTemp;
119 for (sal_Int32 i = 0; i < xContainer->getCount(); i++)
121 xContainer->getByIndex(i) >>= xTemp;
122 Insert(xTemp, i);
125 else
127 Reference< XFormComponent > xFormComp(xIface, UNO_QUERY);
128 if (xFormComp.is())
129 m_pNavModel->InsertFormComponent(xFormComp, sal_uInt32(nIndex));
134 void SAL_CALL OFormComponentObserver::elementReplaced(const ContainerEvent& evt) throw(RuntimeException, std::exception)
136 if (IsLocked() || !m_pNavModel)
137 return;
139 m_bCanUndo = false;
141 // delete EntryData
142 Reference< XFormComponent > xReplaced;
143 evt.ReplacedElement >>= xReplaced;
144 FmEntryData* pEntryData = m_pNavModel->FindData(xReplaced, m_pNavModel->GetRootList(), true);
145 if (pEntryData)
147 if (pEntryData->ISA(FmControlData))
149 Reference< XFormComponent > xComp;
150 evt.Element >>= xComp;
151 DBG_ASSERT(xComp.is(), "OFormComponentObserver::elementReplaced : invalid argument !");
152 // FmControlData should be coupled with XFormComponent
153 m_pNavModel->ReplaceFormComponent(xReplaced, xComp);
155 else if (pEntryData->ISA(FmFormData))
157 OSL_FAIL("replacing forms not implemented yet !");
161 m_bCanUndo = true;
165 void OFormComponentObserver::Remove( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxElement )
167 if (IsLocked() || !m_pNavModel)
168 return;
170 m_bCanUndo = false;
173 // delete EntryData
174 FmEntryData* pEntryData = m_pNavModel->FindData( _rxElement, m_pNavModel->GetRootList(), true );
175 if (pEntryData)
176 m_pNavModel->Remove(pEntryData);
178 m_bCanUndo = true;
182 void SAL_CALL OFormComponentObserver::elementRemoved(const ContainerEvent& evt) throw(RuntimeException, std::exception)
184 Reference< XInterface > xElement;
185 evt.Element >>= xElement;
186 Remove( xElement );
189 NavigatorTreeModel::NavigatorTreeModel( const ImageList& _rNormalImages )
190 :m_pFormShell(NULL)
191 ,m_pFormPage(NULL)
192 ,m_pFormModel(NULL)
193 ,m_aNormalImages( _rNormalImages )
195 m_pPropChangeList = new OFormComponentObserver(this);
196 m_pPropChangeList->acquire();
197 m_pRootList = new FmEntryDataList();
201 NavigatorTreeModel::~NavigatorTreeModel()
204 // unregister Listener
205 if( m_pFormShell)
207 FmFormModel* pFormModel = m_pFormShell->GetFormModel();
208 if( pFormModel && IsListening(*pFormModel))
209 EndListening( *pFormModel );
211 if (IsListening(*m_pFormShell))
212 EndListening(*m_pFormShell);
215 Clear();
216 delete m_pRootList;
217 m_pPropChangeList->ReleaseModel();
218 m_pPropChangeList->release();
223 void NavigatorTreeModel::SetModified( bool bMod )
225 if( !m_pFormShell ) return;
226 SfxObjectShell* pObjShell = m_pFormShell->GetFormModel()->GetObjectShell();
227 if( !pObjShell ) return;
228 pObjShell->SetModified( bMod );
232 void NavigatorTreeModel::Clear()
234 Reference< css::form::XForms > xForms( GetForms());
235 if(xForms.is())
236 xForms->removeContainerListener((XContainerListener*)m_pPropChangeList);
239 // delete RootList
240 GetRootList()->clear();
243 // notify UI
244 FmNavClearedHint aClearedHint;
245 Broadcast( aClearedHint );
249 Reference< css::form::XForms > NavigatorTreeModel::GetForms() const
251 if( !m_pFormShell || !m_pFormShell->GetCurPage())
252 return NULL;
253 else
254 return m_pFormShell->GetCurPage()->GetForms();
258 void NavigatorTreeModel::Insert(FmEntryData* pEntry, sal_uLong nRelPos, bool bAlterModel)
260 if (IsListening(*m_pFormModel))
261 EndListening(*m_pFormModel);
263 m_pPropChangeList->Lock();
264 FmFormData* pFolder = static_cast<FmFormData*>( pEntry->GetParent() );
265 Reference< XChild > xElement( pEntry->GetChildIFace() );
266 if (bAlterModel)
268 OUString aStr;
269 if (pEntry->ISA(FmFormData))
270 aStr = SVX_RESSTR(RID_STR_FORM);
271 else
272 aStr = SVX_RESSTR(RID_STR_CONTROL);
274 Reference< XIndexContainer > xContainer;
275 if (pFolder)
276 xContainer = Reference< XIndexContainer > (pFolder->GetFormIface(), UNO_QUERY);
277 else
278 xContainer = Reference< XIndexContainer > (GetForms(), UNO_QUERY);
280 bool bUndo = m_pFormModel->IsUndoEnabled();
282 if( bUndo )
284 OUString aUndoStr(SVX_RESSTR(RID_STR_UNDO_CONTAINER_INSERT));
285 aUndoStr = aUndoStr.replaceFirst("#", aStr);
286 m_pFormModel->BegUndo(aUndoStr);
289 if (nRelPos >= (sal_uInt32)xContainer->getCount())
290 nRelPos = (sal_uInt32)xContainer->getCount();
292 // UndoAction
293 if ( bUndo && m_pPropChangeList->CanUndo())
295 m_pFormModel->AddUndo(new FmUndoContainerAction(*m_pFormModel,
296 FmUndoContainerAction::Inserted,
297 xContainer,
298 xElement,
299 nRelPos));
302 // Element has to be of the expected type by the container
303 if (xContainer->getElementType() ==
304 cppu::UnoType<XForm>::get())
307 Reference< XForm > xElementAsForm(xElement, UNO_QUERY);
308 xContainer->insertByIndex(nRelPos, makeAny(xElementAsForm));
310 else if (xContainer->getElementType() ==
311 cppu::UnoType<XFormComponent>::get())
314 Reference< XFormComponent > xElementAsComponent(xElement, UNO_QUERY);
315 xContainer->insertByIndex(nRelPos, makeAny(xElementAsComponent));
317 else
319 OSL_FAIL("NavigatorTreeModel::Insert : the parent container needs an elementtype I don't know !");
322 if( bUndo )
323 m_pFormModel->EndUndo();
326 // register as PropertyChangeListener
327 Reference< XPropertySet > xSet(xElement, UNO_QUERY);
328 if( xSet.is() )
329 xSet->addPropertyChangeListener( FM_PROP_NAME, m_pPropChangeList );
332 // Remove data from model
333 if (pEntry->ISA(FmFormData))
335 Reference< XContainer > xContainer(xElement, UNO_QUERY);
336 if (xContainer.is())
337 xContainer->addContainerListener((XContainerListener*)m_pPropChangeList);
340 if (pFolder)
341 pFolder->GetChildList()->insert( pEntry, nRelPos );
342 else
343 GetRootList()->insert( pEntry, nRelPos );
346 // notify UI
347 FmNavInsertedHint aInsertedHint( pEntry, nRelPos );
348 Broadcast( aInsertedHint );
350 m_pPropChangeList->UnLock();
351 if (IsListening(*m_pFormModel))
352 StartListening(*m_pFormModel);
356 void NavigatorTreeModel::Remove(FmEntryData* pEntry, bool bAlterModel)
359 // get form and parent
360 if (!pEntry || !m_pFormModel)
361 return;
363 if (IsListening(*m_pFormModel))
364 EndListening(*m_pFormModel);
366 const bool bUndo = m_pFormModel->IsUndoEnabled();
368 m_pPropChangeList->Lock();
369 FmFormData* pFolder = static_cast<FmFormData*>( pEntry->GetParent() );
370 Reference< XChild > xElement ( pEntry->GetChildIFace() );
371 if (bAlterModel)
373 OUString aStr;
374 if (pEntry->ISA(FmFormData))
375 aStr = SVX_RESSTR(RID_STR_FORM);
376 else
377 aStr = SVX_RESSTR(RID_STR_CONTROL);
379 if( bUndo )
381 OUString aUndoStr(SVX_RESSTR(RID_STR_UNDO_CONTAINER_REMOVE));
382 aUndoStr = aUndoStr.replaceFirst("#", aStr);
383 m_pFormModel->BegUndo(aUndoStr);
387 // now real deletion of data form model
388 if (pEntry->ISA(FmFormData))
389 RemoveForm(static_cast<FmFormData*>(pEntry));
390 else
391 RemoveFormComponent(static_cast<FmControlData*>(pEntry));
394 if (bAlterModel)
396 Reference< XIndexContainer > xContainer(xElement->getParent(), UNO_QUERY);
397 // remove from Container
398 sal_Int32 nContainerIndex = getElementPos(xContainer.get(), xElement);
399 // UndoAction
400 if (nContainerIndex >= 0)
402 if ( bUndo && m_pPropChangeList->CanUndo())
404 m_pFormModel->AddUndo(new FmUndoContainerAction(*m_pFormModel,
405 FmUndoContainerAction::Removed,
406 xContainer,
407 xElement, nContainerIndex ));
409 else if( !m_pPropChangeList->CanUndo() )
411 FmUndoContainerAction::DisposeElement( xElement );
414 xContainer->removeByIndex(nContainerIndex );
417 if( bUndo )
418 m_pFormModel->EndUndo();
421 // remove from parent
422 if (pFolder)
423 pFolder->GetChildList()->remove( pEntry );
424 else
426 GetRootList()->remove( pEntry );
428 // If root has no more form, reset CurForm at shell
429 if ( !GetRootList()->size() )
430 m_pFormShell->GetImpl()->forgetCurrentForm();
434 // notify UI
435 FmNavRemovedHint aRemovedHint( pEntry );
436 Broadcast( aRemovedHint );
438 // delete entry
439 delete pEntry;
441 m_pPropChangeList->UnLock();
442 StartListening(*m_pFormModel);
446 void NavigatorTreeModel::RemoveForm(FmFormData* pFormData)
449 // get form and parent
450 if (!pFormData || !m_pFormModel)
451 return;
453 FmEntryDataList* pChildList = pFormData->GetChildList();
454 for ( size_t i = pChildList->size(); i > 0; )
456 FmEntryData* pEntryData = pChildList->at( --i );
459 // Child is form -> recursive call
460 if( pEntryData->ISA(FmFormData) )
461 RemoveForm( static_cast<FmFormData*>(pEntryData));
462 else if( pEntryData->ISA(FmControlData) )
463 RemoveFormComponent(static_cast<FmControlData*>(pEntryData));
467 // unregister as PropertyChangeListener
468 Reference< XPropertySet > xSet( pFormData->GetPropertySet() );
469 if ( xSet.is() )
470 xSet->removePropertyChangeListener( FM_PROP_NAME, m_pPropChangeList );
472 Reference< XContainer > xContainer( pFormData->GetContainer() );
473 if (xContainer.is())
474 xContainer->removeContainerListener((XContainerListener*)m_pPropChangeList);
478 void NavigatorTreeModel::RemoveFormComponent(FmControlData* pControlData)
481 // get control and parent
482 if (!pControlData)
483 return;
486 // unregister as PropertyChangeListener
487 Reference< XPropertySet > xSet( pControlData->GetPropertySet() );
488 if (xSet.is())
489 xSet->removePropertyChangeListener( FM_PROP_NAME, m_pPropChangeList);
493 void NavigatorTreeModel::ClearBranch( FmFormData* pParentData )
496 // delete all entries of this branch
497 FmEntryDataList* pChildList = pParentData->GetChildList();
499 for( size_t i = pChildList->size(); i > 0; )
501 FmEntryData* pChildData = pChildList->at( --i );
502 if( pChildData->ISA(FmFormData) )
503 ClearBranch( static_cast<FmFormData*>(pChildData) );
505 pChildList->remove( pChildData );
510 void NavigatorTreeModel::FillBranch( FmFormData* pFormData )
513 // insert froms from root
514 if( pFormData == NULL )
516 Reference< XIndexContainer > xForms(GetForms(), UNO_QUERY);
517 if (!xForms.is())
518 return;
520 Reference< XForm > xSubForm;
521 for (sal_Int32 i=0; i<xForms->getCount(); ++i)
523 DBG_ASSERT( xForms->getByIndex(i).getValueType() == cppu::UnoType<XForm>::get(),
524 "NavigatorTreeModel::FillBranch : the root container should supply only elements of type XForm");
526 xForms->getByIndex(i) >>= xSubForm;
527 FmFormData* pSubFormData = new FmFormData( xSubForm, m_aNormalImages, pFormData );
528 Insert( pSubFormData, CONTAINER_APPEND );
531 // new branch, if SubForm contains Subforms itself
532 FillBranch( pSubFormData );
537 // insert components
538 else
540 Reference< XIndexContainer > xComponents( GetFormComponents(pFormData));
541 if( !xComponents.is() ) return;
543 Reference< XInterface > xInterface;
544 Reference< XPropertySet > xSet;
545 FmControlData* pNewControlData;
546 FmFormData* pSubFormData;
548 Reference< XFormComponent > xCurrentComponent;
549 for (sal_Int32 j=0; j<xComponents->getCount(); ++j)
551 xComponents->getByIndex(j) >>= xCurrentComponent;
552 Reference< XForm > xSubForm(xCurrentComponent, UNO_QUERY);
554 if (xSubForm.is())
555 { // actuell component is a form
556 pSubFormData = new FmFormData(xSubForm, m_aNormalImages, pFormData);
557 Insert(pSubFormData, CONTAINER_APPEND);
560 // new branch, if SubForm contains Subfroms itself
561 FillBranch(pSubFormData);
563 else
565 pNewControlData = new FmControlData(xCurrentComponent, m_aNormalImages, pFormData);
566 Insert(pNewControlData, CONTAINER_APPEND);
573 void NavigatorTreeModel::InsertForm(const Reference< XForm > & xForm, sal_uInt32 nRelPos)
575 FmFormData* pFormData = static_cast<FmFormData*>(FindData( xForm, GetRootList() ));
576 if (pFormData)
577 return;
580 // set ParentData
581 Reference< XInterface > xIFace( xForm->getParent());
582 Reference< XForm > xParentForm(xIFace, UNO_QUERY);
583 FmFormData* pParentData = NULL;
584 if (xParentForm.is())
585 pParentData = static_cast<FmFormData*>(FindData( xParentForm, GetRootList() ));
587 pFormData = new FmFormData( xForm, m_aNormalImages, pParentData );
588 Insert( pFormData, nRelPos );
592 void NavigatorTreeModel::InsertFormComponent(const Reference< XFormComponent > & xComp, sal_uInt32 nRelPos)
595 // set ParentData
596 Reference< XInterface > xIFace( xComp->getParent());
597 Reference< XForm > xForm(xIFace, UNO_QUERY);
598 if (!xForm.is())
599 return;
601 FmFormData* pParentData = static_cast<FmFormData*>(FindData( xForm, GetRootList() ));
602 if( !pParentData )
604 pParentData = new FmFormData( xForm, m_aNormalImages, NULL );
605 Insert( pParentData, CONTAINER_APPEND );
608 if (!FindData(xComp, pParentData->GetChildList(),false))
611 // set new EntryData
612 FmEntryData* pNewEntryData = new FmControlData( xComp, m_aNormalImages, pParentData );
615 // insert new EntryData
616 Insert( pNewEntryData, nRelPos );
621 void NavigatorTreeModel::ReplaceFormComponent(
622 const Reference< XFormComponent > & xOld,
623 const Reference< XFormComponent > & xNew
626 FmEntryData* pData = FindData(xOld, GetRootList(), true);
627 assert(pData && pData->ISA(FmControlData)); //NavigatorTreeModel::ReplaceFormComponent : invalid argument
628 if (!pData || !pData->ISA(FmControlData))
629 return;
630 static_cast<FmControlData*>(pData)->ModelReplaced( xNew, m_aNormalImages );
632 FmNavModelReplacedHint aReplacedHint( pData );
633 Broadcast( aReplacedHint );
637 FmEntryData* NavigatorTreeModel::FindData(const Reference< XInterface > & xElement, FmEntryDataList* pDataList, bool bRecurs)
639 // normalize
640 Reference< XInterface > xIFace( xElement, UNO_QUERY );
642 for ( size_t i = 0; i < pDataList->size(); i++ )
644 FmEntryData* pEntryData = pDataList->at( i );
645 if ( pEntryData->GetElement().get() == xIFace.get() )
646 return pEntryData;
647 else if (bRecurs)
649 pEntryData = FindData( xElement, pEntryData->GetChildList() );
650 if (pEntryData)
651 return pEntryData;
654 return NULL;
658 FmEntryData* NavigatorTreeModel::FindData( const OUString& rText, FmFormData* pParentData, bool bRecurs )
660 FmEntryDataList* pDataList;
661 if( !pParentData )
662 pDataList = GetRootList();
663 else
664 pDataList = pParentData->GetChildList();
666 OUString aEntryText;
667 FmEntryData* pEntryData;
668 FmEntryData* pChildData;
670 for( size_t i = 0; i < pDataList->size(); i++ )
672 pEntryData = pDataList->at( i );
673 aEntryText = pEntryData->GetText();
675 if (rText == aEntryText)
676 return pEntryData;
678 if( bRecurs && pEntryData->ISA(FmFormData) )
680 pChildData = FindData( rText, static_cast<FmFormData*>(pEntryData) );
681 if( pChildData )
682 return pChildData;
686 return NULL;
690 void NavigatorTreeModel::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
692 const SdrHint* pSdrHint = dynamic_cast<const SdrHint*>(&rHint);
693 if( pSdrHint )
695 switch( pSdrHint->GetKind() )
697 case HINT_OBJINSERTED:
698 InsertSdrObj(pSdrHint->GetObject());
699 break;
700 case HINT_OBJREMOVED:
701 RemoveSdrObj(pSdrHint->GetObject());
702 break;
703 default:
704 break;
707 // is shell gone?
708 else if ( dynamic_cast<const SfxSimpleHint*>(&rHint) && static_cast<const SfxSimpleHint*>(&rHint)->GetId() == SFX_HINT_DYING)
709 UpdateContent((FmFormShell*)NULL);
711 // changed mark of controls?
712 else if (dynamic_cast<const FmNavViewMarksChanged*>(&rHint))
714 const FmNavViewMarksChanged* pvmcHint = static_cast<const FmNavViewMarksChanged*>(&rHint);
715 BroadcastMarkedObjects( pvmcHint->GetAffectedView()->GetMarkedObjectList() );
720 void NavigatorTreeModel::InsertSdrObj( const SdrObject* pObj )
722 const FmFormObj* pFormObject = FmFormObj::GetFormObject( pObj );
723 if ( pFormObject )
727 Reference< XFormComponent > xFormComponent( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW );
728 Reference< XIndexAccess > xContainer( xFormComponent->getParent(), UNO_QUERY_THROW );
730 sal_Int32 nPos = getElementPos( xContainer, xFormComponent );
731 InsertFormComponent( xFormComponent, nPos );
733 catch( const Exception& )
735 DBG_UNHANDLED_EXCEPTION();
738 else if ( pObj->IsGroupObject() )
740 SdrObjListIter aIter( *pObj->GetSubList() );
741 while ( aIter.IsMore() )
742 InsertSdrObj( aIter.Next() );
747 void NavigatorTreeModel::RemoveSdrObj( const SdrObject* pObj )
749 const FmFormObj* pFormObject = FmFormObj::GetFormObject( pObj );
750 if ( pFormObject )
754 Reference< XFormComponent > xFormComponent( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW );
755 FmEntryData* pEntryData = FindData( xFormComponent, GetRootList(), true );
756 if ( pEntryData )
757 Remove( pEntryData );
759 catch( const Exception& )
761 DBG_UNHANDLED_EXCEPTION();
764 else if ( pObj->IsGroupObject() )
766 SdrObjListIter aIter( *pObj->GetSubList() );
767 while ( aIter.IsMore() )
768 RemoveSdrObj( aIter.Next() );
772 bool NavigatorTreeModel::InsertFormComponent(FmNavRequestSelectHint& rHint, SdrObject* pObject)
774 if ( pObject->ISA(SdrObjGroup) )
775 { // descend recursively
776 const SdrObjList *pChildren = static_cast<SdrObjGroup*>(pObject)->GetSubList();
777 for ( size_t i=0; i<pChildren->GetObjCount(); ++i )
779 SdrObject* pCurrent = pChildren->GetObj(i);
780 if (!InsertFormComponent(rHint, pCurrent))
781 return false;
784 else
786 FmFormObj* pFormObject = FmFormObj::GetFormObject( pObject );
787 if ( !pFormObject )
788 return false;
792 Reference< XFormComponent > xFormViewControl( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW );
793 FmEntryData* pControlData = FindData( xFormViewControl, GetRootList() );
794 if ( !pControlData )
795 return false;
797 rHint.AddItem( pControlData );
798 return true;
800 catch( const Exception& )
802 DBG_UNHANDLED_EXCEPTION();
803 return false;
807 return true;
810 void NavigatorTreeModel::BroadcastMarkedObjects(const SdrMarkList& mlMarked)
812 // search all objects, which can be handled, out of marked objects
813 FmNavRequestSelectHint rshRequestSelection;
814 bool bIsMixedSelection = false;
816 for (size_t i=0; (i<mlMarked.GetMarkCount()) && !bIsMixedSelection; ++i)
818 SdrObject* pobjCurrent = mlMarked.GetMark(i)->GetMarkedSdrObj();
819 bIsMixedSelection |= !InsertFormComponent(rshRequestSelection, pobjCurrent);
820 // if Not-Form-Control, InsertFormComponent returns sal_False !
823 rshRequestSelection.SetMixedSelection(bIsMixedSelection);
824 if (bIsMixedSelection)
825 rshRequestSelection.ClearItems();
827 Broadcast(rshRequestSelection);
828 // an empty list causes NavigatorTree to remove his selection
832 void NavigatorTreeModel::UpdateContent( const Reference< css::form::XForms > & xForms )
835 // refill model form root upward
836 Clear();
837 if (xForms.is())
839 xForms->addContainerListener((XContainerListener*)m_pPropChangeList);
841 FillBranch(NULL);
843 // select same control in tree as in view
844 // (or all of them), if there is one ...
845 if(!m_pFormShell) return; // no shell
847 FmFormView* pFormView = m_pFormShell->GetFormView();
848 DBG_ASSERT(pFormView != NULL, "NavigatorTreeModel::UpdateContent : keine FormView");
849 BroadcastMarkedObjects(pFormView->GetMarkedObjectList());
854 void NavigatorTreeModel::UpdateContent( FmFormShell* pShell )
857 // If shell is unchanged, do nothing
858 FmFormPage* pNewPage = pShell ? pShell->GetCurPage() : NULL;
859 if ((pShell == m_pFormShell) && (m_pFormPage == pNewPage))
860 return;
863 // unregister as Listener
864 if( m_pFormShell )
866 if (m_pFormModel)
867 EndListening( *m_pFormModel );
868 m_pFormModel = NULL;
869 EndListening( *m_pFormShell );
870 Clear();
874 // entire update
875 m_pFormShell = pShell;
876 if (m_pFormShell)
878 m_pFormPage = pNewPage;
879 UpdateContent(m_pFormPage->GetForms());
880 } else
881 m_pFormPage = NULL;
884 // register as Listener again
885 if( m_pFormShell )
887 StartListening( *m_pFormShell );
888 m_pFormModel = m_pFormShell->GetFormModel();
889 if( m_pFormModel )
890 StartListening( *m_pFormModel );
895 Reference< XIndexContainer > NavigatorTreeModel::GetFormComponents( FmFormData* pFormData )
898 // get components from form
899 if (pFormData)
900 return Reference< XIndexContainer > (pFormData->GetFormIface(), UNO_QUERY);
902 return Reference< XIndexContainer > ();
906 bool NavigatorTreeModel::Rename( FmEntryData* pEntryData, const OUString& rNewText )
909 // If name already exist, error message
910 pEntryData->SetText( rNewText );
913 // get PropertySet
914 Reference< XFormComponent > xFormComponent;
916 if( pEntryData->ISA(FmFormData) )
918 FmFormData* pFormData = static_cast<FmFormData*>(pEntryData);
919 Reference< XForm > xForm( pFormData->GetFormIface());
920 xFormComponent = xForm;
923 if( pEntryData->ISA(FmControlData) )
925 FmControlData* pControlData = static_cast<FmControlData*>(pEntryData);
926 xFormComponent = pControlData->GetFormComponent();
929 if( !xFormComponent.is() ) return false;
930 Reference< XPropertySet > xSet(xFormComponent, UNO_QUERY);
931 if( !xSet.is() ) return false;
934 // set name
935 xSet->setPropertyValue( FM_PROP_NAME, makeAny(rNewText) );
937 return true;
941 SdrObject* NavigatorTreeModel::Search(SdrObjListIter& rIter, const Reference< XFormComponent > & xComp)
943 while (rIter.IsMore())
945 SdrObject* pObj = rIter.Next();
946 FmFormObj* pFormObject = FmFormObj::GetFormObject( pObj );
947 if ( pFormObject )
949 Reference< XFormComponent > xFormViewControl( pFormObject->GetUnoControlModel(), UNO_QUERY );
950 if ( xFormViewControl == xComp )
951 return pObj;
953 else if ( pObj->IsGroupObject() )
955 SdrObjListIter aIter( *pObj->GetSubList() );
956 pObj = Search( aIter, xComp );
957 if ( pObj )
958 return pObj;
961 return NULL;
969 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */