fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / svx / source / form / navigatortreemodel.cxx
blob01dc44a1422eff99ed390b07e967eb975c89fb66
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.hrc"
34 #include "fmexpl.hxx"
35 #include "svx/fmresids.hrc"
36 #include "fmshimp.hxx"
37 #include "fmobj.hxx"
38 #include <sfx2/objsh.hxx>
39 #include <tools/diagnose_ex.h>
40 #include <rtl/logfile.hxx>
41 #include <com/sun/star/container/XContainer.hpp>
43 //............................................................................
44 namespace svxform
46 //............................................................................
48 using namespace ::com::sun::star::uno;
49 using namespace ::com::sun::star::lang;
50 using namespace ::com::sun::star::beans;
51 using namespace ::com::sun::star::form;
52 using namespace ::com::sun::star::awt;
53 using namespace ::com::sun::star::container;
54 using namespace ::com::sun::star::script;
55 using namespace ::com::sun::star::sdb;
57 //========================================================================
58 // class OFormComponentObserver
59 //========================================================================
60 //------------------------------------------------------------------------
61 OFormComponentObserver::OFormComponentObserver(NavigatorTreeModel* _pModel)
62 :m_pNavModel(_pModel)
63 ,m_nLocks(0)
64 ,m_bCanUndo(sal_True)
66 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::OFormComponentObserver" );
69 // XPropertyChangeListener
70 //------------------------------------------------------------------------
71 void SAL_CALL OFormComponentObserver::disposing(const EventObject& Source) throw( RuntimeException )
73 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::disposing" );
74 Remove( Source.Source );
77 //------------------------------------------------------------------------
78 void SAL_CALL OFormComponentObserver::propertyChange(const PropertyChangeEvent& evt) throw(RuntimeException)
80 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::propertyChange" );
81 if( !m_pNavModel ) return;
82 if( evt.PropertyName != FM_PROP_NAME ) return;
84 Reference< XFormComponent > xFormComponent(evt.Source, UNO_QUERY);
85 Reference< XForm > xForm(evt.Source, UNO_QUERY);
87 FmEntryData* pEntryData( NULL );
88 if( xForm.is() )
89 pEntryData = m_pNavModel->FindData( xForm, m_pNavModel->GetRootList() );
90 else if( xFormComponent.is() )
91 pEntryData = m_pNavModel->FindData( xFormComponent, m_pNavModel->GetRootList() );
93 if( pEntryData )
95 OUString aNewName = ::comphelper::getString(evt.NewValue);
96 pEntryData->SetText( aNewName );
97 FmNavNameChangedHint aNameChangedHint( pEntryData, aNewName );
98 m_pNavModel->Broadcast( aNameChangedHint );
102 // XContainerListener
103 //------------------------------------------------------------------------------
104 void SAL_CALL OFormComponentObserver::elementInserted(const ContainerEvent& evt) throw(RuntimeException)
106 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::elementInserted" );
107 if (IsLocked() || !m_pNavModel)
108 return;
110 // keine Undoaction einfuegen
111 m_bCanUndo = sal_False;
113 Reference< XInterface > xTemp;
114 evt.Element >>= xTemp;
115 Insert(xTemp, ::comphelper::getINT32(evt.Accessor));
117 m_bCanUndo = sal_True;
120 //------------------------------------------------------------------------------
121 void OFormComponentObserver::Insert(const Reference< XInterface > & xIface, sal_Int32 nIndex)
123 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::Insert" );
124 Reference< XForm > xForm(xIface, UNO_QUERY);
125 if (xForm.is())
127 m_pNavModel->InsertForm(xForm, sal_uInt32(nIndex));
128 Reference< XIndexContainer > xContainer(xForm, UNO_QUERY);
129 Reference< XInterface > xTemp;
130 for (sal_Int32 i = 0; i < xContainer->getCount(); i++)
132 xContainer->getByIndex(i) >>= xTemp;
133 Insert(xTemp, i);
136 else
138 Reference< XFormComponent > xFormComp(xIface, UNO_QUERY);
139 if (xFormComp.is())
140 m_pNavModel->InsertFormComponent(xFormComp, sal_uInt32(nIndex));
144 //------------------------------------------------------------------------------
145 void SAL_CALL OFormComponentObserver::elementReplaced(const ContainerEvent& evt) throw(RuntimeException)
147 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::elementReplaced" );
148 if (IsLocked() || !m_pNavModel)
149 return;
151 m_bCanUndo = sal_False;
153 // EntryData loeschen
154 Reference< XFormComponent > xReplaced;
155 evt.ReplacedElement >>= xReplaced;
156 FmEntryData* pEntryData = m_pNavModel->FindData(xReplaced, m_pNavModel->GetRootList(), sal_True);
157 if (pEntryData)
159 if (pEntryData->ISA(FmControlData))
161 Reference< XFormComponent > xComp;
162 evt.Element >>= xComp;
163 DBG_ASSERT(xComp.is(), "OFormComponentObserver::elementReplaced : invalid argument !");
164 // an einer FmControlData sollte eine XFormComponent haengen
165 m_pNavModel->ReplaceFormComponent(xReplaced, xComp);
167 else if (pEntryData->ISA(FmFormData))
169 OSL_FAIL("replacing forms not implemented yet !");
173 m_bCanUndo = sal_True;
176 //------------------------------------------------------------------------------
177 void OFormComponentObserver::Remove( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxElement )
179 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::Remove" );
180 if (IsLocked() || !m_pNavModel)
181 return;
183 m_bCanUndo = sal_False;
185 //////////////////////////////////////////////////////////
186 // EntryData loeschen
187 FmEntryData* pEntryData = m_pNavModel->FindData( _rxElement, m_pNavModel->GetRootList(), sal_True );
188 if (pEntryData)
189 m_pNavModel->Remove(pEntryData);
191 m_bCanUndo = sal_True;
194 //------------------------------------------------------------------------------
195 void SAL_CALL OFormComponentObserver::elementRemoved(const ContainerEvent& evt) throw(RuntimeException)
197 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::elementRemoved" );
198 Reference< XInterface > xElement;
199 evt.Element >>= xElement;
200 Remove( xElement );
203 //========================================================================
204 // class NavigatorTreeModel
205 //========================================================================
207 //------------------------------------------------------------------------
208 NavigatorTreeModel::NavigatorTreeModel( const ImageList& _rNormalImages )
209 :m_pFormShell(NULL)
210 ,m_pFormPage(NULL)
211 ,m_pFormModel(NULL)
212 ,m_aNormalImages( _rNormalImages )
214 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::NavigatorTreeModel" );
215 m_pPropChangeList = new OFormComponentObserver(this);
216 m_pPropChangeList->acquire();
217 m_pRootList = new FmEntryDataList();
220 //------------------------------------------------------------------------
221 NavigatorTreeModel::~NavigatorTreeModel()
223 //////////////////////////////////////////////////////////////////////
224 // Als Listener abmelden
225 if( m_pFormShell)
227 FmFormModel* pFormModel = m_pFormShell->GetFormModel();
228 if( pFormModel && IsListening(*pFormModel))
229 EndListening( *pFormModel );
231 if (IsListening(*m_pFormShell))
232 EndListening(*m_pFormShell);
235 Clear();
236 delete m_pRootList;
237 m_pPropChangeList->ReleaseModel();
238 m_pPropChangeList->release();
242 //------------------------------------------------------------------------
243 void NavigatorTreeModel::SetModified( sal_Bool bMod )
245 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::SetModified" );
246 if( !m_pFormShell ) return;
247 SfxObjectShell* pObjShell = m_pFormShell->GetFormModel()->GetObjectShell();
248 if( !pObjShell ) return;
249 pObjShell->SetModified( bMod );
252 //------------------------------------------------------------------------
253 void NavigatorTreeModel::Clear()
255 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Clear" );
256 Reference< css::form::XForms > xForms( GetForms());
257 if(xForms.is())
258 xForms->removeContainerListener((XContainerListener*)m_pPropChangeList);
260 //////////////////////////////////////////////////////////////////////
261 // RootList loeschen
262 GetRootList()->clear();
264 //////////////////////////////////////////////////////////////////////
265 // UI benachrichtigen
266 FmNavClearedHint aClearedHint;
267 Broadcast( aClearedHint );
270 //------------------------------------------------------------------------
271 Reference< css::form::XForms > NavigatorTreeModel::GetForms() const
273 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::GetForms" );
274 if( !m_pFormShell || !m_pFormShell->GetCurPage())
275 return NULL;
276 else
277 return m_pFormShell->GetCurPage()->GetForms();
280 //------------------------------------------------------------------------
281 void NavigatorTreeModel::Insert(FmEntryData* pEntry, sal_uLong nRelPos, sal_Bool bAlterModel)
283 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Insert" );
284 if (IsListening(*m_pFormModel))
285 EndListening(*m_pFormModel);
287 m_pPropChangeList->Lock();
288 FmFormData* pFolder = (FmFormData*) pEntry->GetParent();
289 Reference< XChild > xElement( pEntry->GetChildIFace() );
290 if (bAlterModel)
292 XubString aStr;
293 if (pEntry->ISA(FmFormData))
294 aStr = SVX_RESSTR(RID_STR_FORM);
295 else
296 aStr = SVX_RESSTR(RID_STR_CONTROL);
298 Reference< XIndexContainer > xContainer;
299 if (pFolder)
300 xContainer = Reference< XIndexContainer > (pFolder->GetFormIface(), UNO_QUERY);
301 else
302 xContainer = Reference< XIndexContainer > (GetForms(), UNO_QUERY);
304 bool bUndo = m_pFormModel->IsUndoEnabled();
306 if( bUndo )
308 XubString aUndoStr(SVX_RES(RID_STR_UNDO_CONTAINER_INSERT));
309 aUndoStr.SearchAndReplace(OUString('#'), aStr);
310 m_pFormModel->BegUndo(aUndoStr);
313 if (nRelPos >= (sal_uInt32)xContainer->getCount())
314 nRelPos = (sal_uInt32)xContainer->getCount();
316 // UndoAction
317 if ( bUndo && m_pPropChangeList->CanUndo())
319 m_pFormModel->AddUndo(new FmUndoContainerAction(*m_pFormModel,
320 FmUndoContainerAction::Inserted,
321 xContainer,
322 xElement,
323 nRelPos));
326 // das Element muss den Typ haben, den der Container erwartet
327 if (xContainer->getElementType() ==
328 ::getCppuType((const Reference< XForm>*)0))
331 Reference< XForm > xElementAsForm(xElement, UNO_QUERY);
332 xContainer->insertByIndex(nRelPos, makeAny(xElementAsForm));
334 else if (xContainer->getElementType() ==
335 ::getCppuType((const Reference< XFormComponent>*)0))
338 Reference< XFormComponent > xElementAsComponent(xElement, UNO_QUERY);
339 xContainer->insertByIndex(nRelPos, makeAny(xElementAsComponent));
341 else
343 OSL_FAIL("NavigatorTreeModel::Insert : the parent container needs an elementtype I don't know !");
346 if( bUndo )
347 m_pFormModel->EndUndo();
350 //////////////////////////////////////////////////////////////////////
351 // Als PropertyChangeListener anmelden
352 Reference< XPropertySet > xSet(xElement, UNO_QUERY);
353 if( xSet.is() )
354 xSet->addPropertyChangeListener( FM_PROP_NAME, m_pPropChangeList );
356 //////////////////////////////////////////////////////////////////////
357 // Daten aus Model entfernen
358 if (pEntry->ISA(FmFormData))
360 Reference< XContainer > xContainer(xElement, UNO_QUERY);
361 if (xContainer.is())
362 xContainer->addContainerListener((XContainerListener*)m_pPropChangeList);
365 if (pFolder)
366 pFolder->GetChildList()->insert( pEntry, nRelPos );
367 else
368 GetRootList()->insert( pEntry, nRelPos );
370 //////////////////////////////////////////////////////////////////////
371 // UI benachrichtigen
372 FmNavInsertedHint aInsertedHint( pEntry, nRelPos );
373 Broadcast( aInsertedHint );
375 m_pPropChangeList->UnLock();
376 if (IsListening(*m_pFormModel))
377 StartListening(*m_pFormModel);
380 //------------------------------------------------------------------------
381 void NavigatorTreeModel::Remove(FmEntryData* pEntry, sal_Bool bAlterModel)
383 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Remove" );
384 //////////////////////////////////////////////////////////////////////
385 // Form und Parent holen
386 if (!pEntry || !m_pFormModel)
387 return;
389 if (IsListening(*m_pFormModel))
390 EndListening(*m_pFormModel);
392 const bool bUndo = m_pFormModel->IsUndoEnabled();
394 m_pPropChangeList->Lock();
395 FmFormData* pFolder = (FmFormData*) pEntry->GetParent();
396 Reference< XChild > xElement ( pEntry->GetChildIFace() );
397 if (bAlterModel)
399 XubString aStr;
400 if (pEntry->ISA(FmFormData))
401 aStr = SVX_RESSTR(RID_STR_FORM);
402 else
403 aStr = SVX_RESSTR(RID_STR_CONTROL);
405 if( bUndo )
407 XubString aUndoStr(SVX_RESSTR(RID_STR_UNDO_CONTAINER_REMOVE));
408 aUndoStr.SearchAndReplace(OUString('#'), aStr);
409 m_pFormModel->BegUndo(aUndoStr);
413 // jetzt die eigentliche Entfernung der Daten aus dem Model
414 if (pEntry->ISA(FmFormData))
415 RemoveForm((FmFormData*)pEntry);
416 else
417 RemoveFormComponent((FmControlData*)pEntry);
420 if (bAlterModel)
422 Reference< XIndexContainer > xContainer(xElement->getParent(), UNO_QUERY);
423 // aus dem Container entfernen
424 sal_Int32 nContainerIndex = getElementPos(xContainer.get(), xElement);
425 // UndoAction
426 if (nContainerIndex >= 0)
428 if ( bUndo && m_pPropChangeList->CanUndo())
430 m_pFormModel->AddUndo(new FmUndoContainerAction(*m_pFormModel,
431 FmUndoContainerAction::Removed,
432 xContainer,
433 xElement, nContainerIndex ));
435 else if( !m_pPropChangeList->CanUndo() )
437 FmUndoContainerAction::DisposeElement( xElement );
440 xContainer->removeByIndex(nContainerIndex );
443 if( bUndo )
444 m_pFormModel->EndUndo();
447 // beim Vater austragen
448 if (pFolder)
449 pFolder->GetChildList()->remove( pEntry );
450 else
452 GetRootList()->remove( pEntry );
453 //////////////////////////////////////////////////////////////////////
454 // Wenn keine Form mehr in der Root, an der Shell CurForm zuruecksetzen
455 if ( !GetRootList()->size() )
456 m_pFormShell->GetImpl()->forgetCurrentForm();
459 //////////////////////////////////////////////////////////////////////
460 // UI benachrichtigen
461 FmNavRemovedHint aRemovedHint( pEntry );
462 Broadcast( aRemovedHint );
464 // Eintrag loeschen
465 delete pEntry;
467 m_pPropChangeList->UnLock();
468 StartListening(*m_pFormModel);
471 //------------------------------------------------------------------------
472 void NavigatorTreeModel::RemoveForm(FmFormData* pFormData)
474 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::RemoveForm" );
475 //////////////////////////////////////////////////////////////////////
476 // Form und Parent holen
477 if (!pFormData || !m_pFormModel)
478 return;
480 FmEntryDataList* pChildList = pFormData->GetChildList();
481 for ( size_t i = pChildList->size(); i > 0; )
483 FmEntryData* pEntryData = pChildList->at( --i );
485 //////////////////////////////////////////////////////////////////////
486 // Child ist Form -> rekursiver Aufruf
487 if( pEntryData->ISA(FmFormData) )
488 RemoveForm( (FmFormData*)pEntryData);
489 else if( pEntryData->ISA(FmControlData) )
490 RemoveFormComponent((FmControlData*) pEntryData);
493 //////////////////////////////////////////////////////////////////////
494 // Als PropertyChangeListener abmelden
495 Reference< XPropertySet > xSet( pFormData->GetPropertySet() );
496 if ( xSet.is() )
497 xSet->removePropertyChangeListener( FM_PROP_NAME, m_pPropChangeList );
499 Reference< XContainer > xContainer( pFormData->GetContainer() );
500 if (xContainer.is())
501 xContainer->removeContainerListener((XContainerListener*)m_pPropChangeList);
504 //------------------------------------------------------------------------
505 void NavigatorTreeModel::RemoveFormComponent(FmControlData* pControlData)
507 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::RemoveFormComponent" );
508 //////////////////////////////////////////////////////////////////////
509 // Control und Parent holen
510 if (!pControlData)
511 return;
513 //////////////////////////////////////////////////////////////////////
514 // Als PropertyChangeListener abmelden
515 Reference< XPropertySet > xSet( pControlData->GetPropertySet() );
516 if (xSet.is())
517 xSet->removePropertyChangeListener( FM_PROP_NAME, m_pPropChangeList);
520 //------------------------------------------------------------------------
521 void NavigatorTreeModel::ClearBranch( FmFormData* pParentData )
523 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::ClearBranch" );
524 //////////////////////////////////////////////////////////////////////
525 // Alle Eintraege dieses Zweiges loeschen
526 FmEntryDataList* pChildList = pParentData->GetChildList();
528 for( size_t i = pChildList->size(); i > 0; )
530 FmEntryData* pChildData = pChildList->at( --i );
531 if( pChildData->ISA(FmFormData) )
532 ClearBranch( (FmFormData*)pChildData );
534 pChildList->remove( pChildData );
538 //------------------------------------------------------------------------
539 void NavigatorTreeModel::FillBranch( FmFormData* pFormData )
541 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::FillBranch" );
542 //////////////////////////////////////////////////////////////
543 // Forms aus der Root einfuegen
544 if( pFormData == NULL )
546 Reference< XIndexContainer > xForms(GetForms(), UNO_QUERY);
547 if (!xForms.is())
548 return;
550 Reference< XForm > xSubForm;
551 FmFormData* pSubFormData;
552 for (sal_Int32 i=0; i<xForms->getCount(); ++i)
554 DBG_ASSERT( xForms->getByIndex(i).getValueType() == ::getCppuType((const Reference< XForm>*)NULL),
555 "NavigatorTreeModel::FillBranch : the root container should supply only elements of type XForm");
557 xForms->getByIndex(i) >>= xSubForm;
558 pSubFormData = new FmFormData( xSubForm, m_aNormalImages, pFormData );
559 Insert( pSubFormData, LIST_APPEND );
561 //////////////////////////////////////////////////////////////
562 // Neuer Branch, wenn SubForm wiederum Subforms enthaelt
563 FillBranch( pSubFormData );
567 //////////////////////////////////////////////////////////////
568 // Componenten einfuegen
569 else
571 Reference< XIndexContainer > xComponents( GetFormComponents(pFormData));
572 if( !xComponents.is() ) return;
574 Reference< XInterface > xInterface;
575 Reference< XPropertySet > xSet;
576 FmControlData* pNewControlData;
577 FmFormData* pSubFormData;
579 Reference< XFormComponent > xCurrentComponent;
580 for (sal_Int32 j=0; j<xComponents->getCount(); ++j)
582 xComponents->getByIndex(j) >>= xCurrentComponent;
583 Reference< XForm > xSubForm(xCurrentComponent, UNO_QUERY);
585 if (xSubForm.is())
586 { // die aktuelle Component ist eine Form
587 pSubFormData = new FmFormData(xSubForm, m_aNormalImages, pFormData);
588 Insert(pSubFormData, LIST_APPEND);
590 //////////////////////////////////////////////////////////////
591 // Neuer Branch, wenn SubForm wiederum Subforms enthaelt
592 FillBranch(pSubFormData);
594 else
596 pNewControlData = new FmControlData(xCurrentComponent, m_aNormalImages, pFormData);
597 Insert(pNewControlData, LIST_APPEND);
603 //------------------------------------------------------------------------
604 void NavigatorTreeModel::InsertForm(const Reference< XForm > & xForm, sal_uInt32 nRelPos)
606 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::InsertForm" );
607 FmFormData* pFormData = (FmFormData*)FindData( xForm, GetRootList() );
608 if (pFormData)
609 return;
611 //////////////////////////////////////////////////////////
612 // ParentData setzen
613 Reference< XInterface > xIFace( xForm->getParent());
614 Reference< XForm > xParentForm(xIFace, UNO_QUERY);
615 FmFormData* pParentData = NULL;
616 if (xParentForm.is())
617 pParentData = (FmFormData*)FindData( xParentForm, GetRootList() );
619 pFormData = new FmFormData( xForm, m_aNormalImages, pParentData );
620 Insert( pFormData, nRelPos );
623 //------------------------------------------------------------------------
624 void NavigatorTreeModel::InsertFormComponent(const Reference< XFormComponent > & xComp, sal_uInt32 nRelPos)
626 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::InsertFormComponent" );
627 //////////////////////////////////////////////////////////
628 // ParentData setzen
629 Reference< XInterface > xIFace( xComp->getParent());
630 Reference< XForm > xForm(xIFace, UNO_QUERY);
631 if (!xForm.is())
632 return;
634 FmFormData* pParentData = (FmFormData*)FindData( xForm, GetRootList() );
635 if( !pParentData )
637 pParentData = new FmFormData( xForm, m_aNormalImages, NULL );
638 Insert( pParentData, LIST_APPEND );
641 if (!FindData(xComp, pParentData->GetChildList(),sal_False))
643 //////////////////////////////////////////////////////////
644 // Neue EntryData setzen
645 FmEntryData* pNewEntryData = new FmControlData( xComp, m_aNormalImages, pParentData );
647 //////////////////////////////////////////////////////////
648 // Neue EntryData einfuegen
649 Insert( pNewEntryData, nRelPos );
653 //------------------------------------------------------------------------
654 void NavigatorTreeModel::ReplaceFormComponent(
655 const Reference< XFormComponent > & xOld,
656 const Reference< XFormComponent > & xNew
659 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::ReplaceFormComponent" );
660 FmEntryData* pData = FindData(xOld, GetRootList(), sal_True);
661 DBG_ASSERT(pData && pData->ISA(FmControlData), "NavigatorTreeModel::ReplaceFormComponent : invalid argument !");
662 ((FmControlData*)pData)->ModelReplaced( xNew, m_aNormalImages );
664 FmNavModelReplacedHint aReplacedHint( pData );
665 Broadcast( aReplacedHint );
668 //------------------------------------------------------------------------
669 FmEntryData* NavigatorTreeModel::FindData(const Reference< XInterface > & xElement, FmEntryDataList* pDataList, sal_Bool bRecurs)
671 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::FindData" );
672 // normalize
673 Reference< XInterface > xIFace( xElement, UNO_QUERY );
675 for ( size_t i = 0; i < pDataList->size(); i++ )
677 FmEntryData* pEntryData = pDataList->at( i );
678 if ( pEntryData->GetElement().get() == xIFace.get() )
679 return pEntryData;
680 else if (bRecurs)
682 pEntryData = FindData( xElement, pEntryData->GetChildList() );
683 if (pEntryData)
684 return pEntryData;
687 return NULL;
690 //------------------------------------------------------------------------
691 FmEntryData* NavigatorTreeModel::FindData( const OUString& rText, FmFormData* pParentData, sal_Bool bRecurs )
693 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::FindData" );
694 FmEntryDataList* pDataList;
695 if( !pParentData )
696 pDataList = GetRootList();
697 else
698 pDataList = pParentData->GetChildList();
700 OUString aEntryText;
701 FmEntryData* pEntryData;
702 FmEntryData* pChildData;
704 for( size_t i = 0; i < pDataList->size(); i++ )
706 pEntryData = pDataList->at( i );
707 aEntryText = pEntryData->GetText();
709 if (rText == aEntryText)
710 return pEntryData;
712 if( bRecurs && pEntryData->ISA(FmFormData) )
714 pChildData = FindData( rText, (FmFormData*)pEntryData );
715 if( pChildData )
716 return pChildData;
720 return NULL;
723 //------------------------------------------------------------------------
724 void NavigatorTreeModel::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
726 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Notify" );
727 if( rHint.ISA(SdrHint) )
729 SdrHint* pSdrHint = (SdrHint*)&rHint;
730 switch( pSdrHint->GetKind() )
732 case HINT_OBJINSERTED:
733 InsertSdrObj(pSdrHint->GetObject());
734 break;
735 case HINT_OBJREMOVED:
736 RemoveSdrObj(pSdrHint->GetObject());
737 break;
738 default:
739 break;
742 // hat sich die shell verabschiedet?
743 else if ( rHint.ISA(SfxSimpleHint) && ((SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING)
744 UpdateContent((FmFormShell*)NULL);
746 // hat sich die Markierung der Controls veraendert ?
747 else if (rHint.ISA(FmNavViewMarksChanged))
749 FmNavViewMarksChanged* pvmcHint = (FmNavViewMarksChanged*)&rHint;
750 BroadcastMarkedObjects( pvmcHint->GetAffectedView()->GetMarkedObjectList() );
754 //------------------------------------------------------------------------
755 void NavigatorTreeModel::InsertSdrObj( const SdrObject* pObj )
757 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::InsertSdrObj" );
758 const FmFormObj* pFormObject = FmFormObj::GetFormObject( pObj );
759 if ( pFormObject )
763 Reference< XFormComponent > xFormComponent( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW );
764 Reference< XIndexAccess > xContainer( xFormComponent->getParent(), UNO_QUERY_THROW );
766 sal_Int32 nPos = getElementPos( xContainer, xFormComponent );
767 InsertFormComponent( xFormComponent, nPos );
769 catch( const Exception& )
771 DBG_UNHANDLED_EXCEPTION();
774 else if ( pObj->IsGroupObject() )
776 SdrObjListIter aIter( *pObj->GetSubList() );
777 while ( aIter.IsMore() )
778 InsertSdrObj( aIter.Next() );
782 //------------------------------------------------------------------------
783 void NavigatorTreeModel::RemoveSdrObj( const SdrObject* pObj )
785 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::RemoveSdrObj" );
786 const FmFormObj* pFormObject = FmFormObj::GetFormObject( pObj );
787 if ( pFormObject )
791 Reference< XFormComponent > xFormComponent( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW );
792 FmEntryData* pEntryData = FindData( xFormComponent, GetRootList(), sal_True );
793 if ( pEntryData )
794 Remove( pEntryData );
796 catch( const Exception& )
798 DBG_UNHANDLED_EXCEPTION();
801 else if ( pObj->IsGroupObject() )
803 SdrObjListIter aIter( *pObj->GetSubList() );
804 while ( aIter.IsMore() )
805 RemoveSdrObj( aIter.Next() );
809 sal_Bool NavigatorTreeModel::InsertFormComponent(FmNavRequestSelectHint& rHint, SdrObject* pObject)
811 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::InsertFormComponent" );
812 if ( pObject->ISA(SdrObjGroup) )
813 { // rekursiv absteigen
814 const SdrObjList *pChildren = ((SdrObjGroup*)pObject)->GetSubList();
815 for ( sal_uInt16 i=0; i<pChildren->GetObjCount(); ++i )
817 SdrObject* pCurrent = pChildren->GetObj(i);
818 if (!InsertFormComponent(rHint, pCurrent))
819 return sal_False;
822 else
824 FmFormObj* pFormObject = FmFormObj::GetFormObject( pObject );
825 if ( !pFormObject )
826 return sal_False;
830 Reference< XFormComponent > xFormViewControl( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW );
831 FmEntryData* pControlData = FindData( xFormViewControl, GetRootList() );
832 if ( !pControlData )
833 return sal_False;
835 rHint.AddItem( pControlData );
836 return sal_True;
838 catch( const Exception& )
840 DBG_UNHANDLED_EXCEPTION();
841 return sal_False;
845 return sal_True;
848 void NavigatorTreeModel::BroadcastMarkedObjects(const SdrMarkList& mlMarked)
850 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::BroadcastMarkedObjects" );
851 // gehen wir durch alle markierten Objekte und suchen wir die raus, mit denen ich was anfangen kann
852 FmNavRequestSelectHint rshRequestSelection;
853 sal_Bool bIsMixedSelection = sal_False;
855 for (sal_uLong i=0; (i<mlMarked.GetMarkCount()) && !bIsMixedSelection; i++)
857 SdrObject* pobjCurrent = mlMarked.GetMark(i)->GetMarkedSdrObj();
858 bIsMixedSelection |= !InsertFormComponent(rshRequestSelection, pobjCurrent);
859 // bei einem Nicht-Form-Control liefert InsertFormComponent sal_False !
862 rshRequestSelection.SetMixedSelection(bIsMixedSelection);
863 if (bIsMixedSelection)
864 rshRequestSelection.ClearItems();
866 Broadcast(rshRequestSelection);
867 // eine leere Liste interpretiert der NavigatorTree so, dass er seine Selektion komplett rausnimmt
870 //------------------------------------------------------------------------
871 void NavigatorTreeModel::UpdateContent( const Reference< css::form::XForms > & xForms )
873 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::UpdateContent" );
874 //////////////////////////////////////////////////////////////////////
875 // Model von der Root aufwaerts neu fuellen
876 Clear();
877 if (xForms.is())
879 xForms->addContainerListener((XContainerListener*)m_pPropChangeList);
881 FillBranch(NULL);
883 // jetzt in meinem Tree genau die das in meiner View markierte Control selektieren
884 // (bzw alle solchen), falls es eines gibt ...
885 if(!m_pFormShell) return; // keine Shell -> wech
887 FmFormView* pFormView = m_pFormShell->GetFormView();
888 DBG_ASSERT(pFormView != NULL, "NavigatorTreeModel::UpdateContent : keine FormView");
889 BroadcastMarkedObjects(pFormView->GetMarkedObjectList());
893 //------------------------------------------------------------------------
894 void NavigatorTreeModel::UpdateContent( FmFormShell* pShell )
896 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::UpdateContent" );
897 //////////////////////////////////////////////////////////////////////
898 // Wenn Shell sich nicht veraendert hat, nichts machen
899 FmFormPage* pNewPage = pShell ? pShell->GetCurPage() : NULL;
900 if ((pShell == m_pFormShell) && (m_pFormPage == pNewPage))
901 return;
903 //////////////////////////////////////////////////////////////////////
904 // Als Listener abmelden
905 if( m_pFormShell )
907 if (m_pFormModel)
908 EndListening( *m_pFormModel );
909 m_pFormModel = NULL;
910 EndListening( *m_pFormShell );
911 Clear();
914 //////////////////////////////////////////////////////////////////////
915 // Vollupdate
916 m_pFormShell = pShell;
917 if (m_pFormShell)
919 m_pFormPage = pNewPage;
920 UpdateContent(m_pFormPage->GetForms());
921 } else
922 m_pFormPage = NULL;
924 //////////////////////////////////////////////////////////////////////
925 // Als Listener neu anmelden
926 if( m_pFormShell )
928 StartListening( *m_pFormShell );
929 m_pFormModel = m_pFormShell->GetFormModel();
930 if( m_pFormModel )
931 StartListening( *m_pFormModel );
935 //------------------------------------------------------------------------
936 Reference< XIndexContainer > NavigatorTreeModel::GetFormComponents( FmFormData* pFormData )
938 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::GetFormComponents" );
939 //////////////////////////////////////////////////////////////////////
940 // Von der Form Components holen
941 if (pFormData)
942 return Reference< XIndexContainer > (pFormData->GetFormIface(), UNO_QUERY);
944 return Reference< XIndexContainer > ();
947 //------------------------------------------------------------------------
948 sal_Bool NavigatorTreeModel::Rename( FmEntryData* pEntryData, const OUString& rNewText )
950 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Rename" );
951 //////////////////////////////////////////////////////////////////////
952 // Wenn Name schon vorhanden, Fehlermeldung
953 pEntryData->SetText( rNewText );
955 //////////////////////////////////////////////////////////////////////
956 // PropertySet besorgen
957 Reference< XFormComponent > xFormComponent;
959 if( pEntryData->ISA(FmFormData) )
961 FmFormData* pFormData = (FmFormData*)pEntryData;
962 Reference< XForm > xForm( pFormData->GetFormIface());
963 xFormComponent = Reference< XFormComponent > (xForm, UNO_QUERY);
966 if( pEntryData->ISA(FmControlData) )
968 FmControlData* pControlData = (FmControlData*)pEntryData;
969 xFormComponent = pControlData->GetFormComponent();
972 if( !xFormComponent.is() ) return sal_False;
973 Reference< XPropertySet > xSet(xFormComponent, UNO_QUERY);
974 if( !xSet.is() ) return sal_False;
976 //////////////////////////////////////////////////////////////////////
977 // Namen setzen
978 xSet->setPropertyValue( FM_PROP_NAME, makeAny(rNewText) );
980 return sal_True;
983 //------------------------------------------------------------------
984 SdrObject* NavigatorTreeModel::Search(SdrObjListIter& rIter, const Reference< XFormComponent > & xComp)
986 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Search" );
987 while (rIter.IsMore())
989 SdrObject* pObj = rIter.Next();
990 FmFormObj* pFormObject = FmFormObj::GetFormObject( pObj );
991 if ( pFormObject )
993 Reference< XFormComponent > xFormViewControl( pFormObject->GetUnoControlModel(), UNO_QUERY );
994 if ( xFormViewControl == xComp )
995 return pObj;
997 else if ( pObj->IsGroupObject() )
999 SdrObjListIter aIter( *pObj->GetSubList() );
1000 pObj = Search( aIter, xComp );
1001 if ( pObj )
1002 return pObj;
1005 return NULL;
1008 //............................................................................
1009 } // namespace svxform
1010 //............................................................................
1013 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */