LibreOffice Module svx (master)  1
navigatortreemodel.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
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>
28 
29 #include <fmprop.hxx>
30 
31 #include <fmundo.hxx>
32 #include <fmexpl.hxx>
33 #include <svx/strings.hrc>
34 #include <fmshimp.hxx>
35 #include <fmobj.hxx>
36 #include <sfx2/objsh.hxx>
37 #include <tools/diagnose_ex.h>
38 #include <com/sun/star/container/XContainer.hpp>
39 #include <comphelper/types.hxx>
40 
41 
42 namespace svxform
43 {
44 
45 
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;
54 
56  :m_pNavModel(_pModel)
57  ,m_nLocks(0)
58  ,m_bCanUndo(true)
59  {
60  }
61 
62  // XPropertyChangeListener
63 
64  void SAL_CALL OFormComponentObserver::disposing(const EventObject& Source)
65  {
66  Remove( Source.Source );
67  }
68 
69 
70  void SAL_CALL OFormComponentObserver::propertyChange(const PropertyChangeEvent& evt)
71  {
72  if( !m_pNavModel ) return;
73  if( evt.PropertyName != FM_PROP_NAME ) return;
74 
75  Reference< XFormComponent > xFormComponent(evt.Source, UNO_QUERY);
76  Reference< XForm > xForm(evt.Source, UNO_QUERY);
77 
78  FmEntryData* pEntryData( nullptr );
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() );
83 
84  if( pEntryData )
85  {
86  OUString aNewName = ::comphelper::getString(evt.NewValue);
87  pEntryData->SetText( aNewName );
88  FmNavNameChangedHint aNameChangedHint( pEntryData, aNewName );
89  m_pNavModel->Broadcast( aNameChangedHint );
90  }
91  }
92 
93  // XContainerListener
94 
95  void SAL_CALL OFormComponentObserver::elementInserted(const ContainerEvent& evt)
96  {
97  if (IsLocked() || !m_pNavModel)
98  return;
99 
100  // insert no Undoaction
101  m_bCanUndo = false;
102 
104  evt.Element >>= xTemp;
105  Insert(xTemp, ::comphelper::getINT32(evt.Accessor));
106 
107  m_bCanUndo = true;
108  }
109 
110 
111  void OFormComponentObserver::Insert(const Reference< XInterface > & xIface, sal_Int32 nIndex)
112  {
113  Reference< XForm > xForm(xIface, UNO_QUERY);
114  if (xForm.is())
115  {
116  m_pNavModel->InsertForm(xForm, sal_uInt32(nIndex));
117  Reference< XIndexContainer > xContainer(xForm, UNO_QUERY);
119  for (sal_Int32 i = 0; i < xContainer->getCount(); i++)
120  {
121  xContainer->getByIndex(i) >>= xTemp;
122  Insert(xTemp, i);
123  }
124  }
125  else
126  {
127  Reference< XFormComponent > xFormComp(xIface, UNO_QUERY);
128  if (xFormComp.is())
129  m_pNavModel->InsertFormComponent(xFormComp, sal_uInt32(nIndex));
130  }
131  }
132 
133 
134  void SAL_CALL OFormComponentObserver::elementReplaced(const ContainerEvent& evt)
135  {
136  if (IsLocked() || !m_pNavModel)
137  return;
138 
139  m_bCanUndo = false;
140 
141  // delete EntryData
142  Reference< XFormComponent > xReplaced;
143  evt.ReplacedElement >>= xReplaced;
144  FmEntryData* pEntryData = m_pNavModel->FindData(xReplaced, m_pNavModel->GetRootList());
145  if (pEntryData)
146  {
147  if (dynamic_cast<const FmControlData*>( pEntryData) != nullptr)
148  {
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);
154  }
155  else if (dynamic_cast<const FmFormData*>( pEntryData) != nullptr)
156  {
157  OSL_FAIL("replacing forms not implemented yet !");
158  }
159  }
160 
161  m_bCanUndo = true;
162  }
163 
164 
165  void OFormComponentObserver::Remove( const css::uno::Reference< css::uno::XInterface >& _rxElement )
166  {
167  if (IsLocked() || !m_pNavModel)
168  return;
169 
170  m_bCanUndo = false;
171 
172 
173  // delete EntryData
174  FmEntryData* pEntryData = m_pNavModel->FindData( _rxElement, m_pNavModel->GetRootList() );
175  if (pEntryData)
176  m_pNavModel->Remove(pEntryData);
177 
178  m_bCanUndo = true;
179  }
180 
181 
182  void SAL_CALL OFormComponentObserver::elementRemoved(const ContainerEvent& evt)
183  {
184  Reference< XInterface > xElement;
185  evt.Element >>= xElement;
186  Remove( xElement );
187  }
188 
190  :m_pFormShell(nullptr)
191  ,m_pFormPage(nullptr)
192  ,m_pFormModel(nullptr)
193  {
195  m_pRootList.reset( new FmEntryDataList() );
196  }
197 
199  {
200 
201  // unregister Listener
202  if( m_pFormShell)
203  {
204  FmFormModel* pFormModel = m_pFormShell->GetFormModel();
205  if( pFormModel && IsListening(*pFormModel))
206  EndListening( *pFormModel );
207 
210  }
211 
212  Clear();
213  m_pRootList.reset();
214  m_pPropChangeList->ReleaseModel();
215  }
216 
217 
219  {
220  if( !m_pFormShell ) return;
222  if( !pObjShell ) return;
223  pObjShell->SetModified();
224  }
225 
226 
228  {
229  Reference< css::form::XForms > xForms( GetForms());
230  if(xForms.is())
231  xForms->removeContainerListener(m_pPropChangeList.get());
232 
233 
234  // delete RootList
235  GetRootList()->clear();
236 
237 
238  // notify UI
239  FmNavClearedHint aClearedHint;
240  Broadcast( aClearedHint );
241  }
242 
243 
244  Reference< css::form::XForms > NavigatorTreeModel::GetForms() const
245  {
247  return nullptr;
248  else
249  return m_pFormShell->GetCurPage()->GetForms();
250  }
251 
252 
253  void NavigatorTreeModel::Insert(FmEntryData* pEntry, sal_uInt32 nRelPos, bool bAlterModel)
254  {
257 
258  m_pPropChangeList->Lock();
259  FmFormData* pFolder = static_cast<FmFormData*>( pEntry->GetParent() );
260  Reference< XChild > xElement( pEntry->GetChildIFace() );
261  if (bAlterModel)
262  {
263  OUString aStr;
264  if (dynamic_cast<const FmFormData*>( pEntry) != nullptr)
265  aStr = SvxResId(RID_STR_FORM);
266  else
267  aStr = SvxResId(RID_STR_CONTROL);
268 
269  Reference< XIndexContainer > xContainer;
270  if (pFolder)
271  xContainer.set(pFolder->GetFormIface(), UNO_QUERY);
272  else
273  xContainer = GetForms();
274 
275  bool bUndo = m_pFormModel->IsUndoEnabled();
276 
277  if( bUndo )
278  {
279  OUString aUndoStr(SvxResId(RID_STR_UNDO_CONTAINER_INSERT));
280  aUndoStr = aUndoStr.replaceFirst("#", aStr);
281  m_pFormModel->BegUndo(aUndoStr);
282  }
283 
284  if (nRelPos >= static_cast<sal_uInt32>(xContainer->getCount()))
285  nRelPos = static_cast<sal_uInt32>(xContainer->getCount());
286 
287  // UndoAction
288  if ( bUndo && m_pPropChangeList->CanUndo())
289  {
290  m_pFormModel->AddUndo(std::make_unique<FmUndoContainerAction>(*m_pFormModel,
292  xContainer,
293  xElement,
294  nRelPos));
295  }
296 
297  // Element has to be of the expected type by the container
298  if (xContainer->getElementType() ==
300 
301  {
302  Reference< XForm > xElementAsForm(xElement, UNO_QUERY);
303  xContainer->insertByIndex(nRelPos, makeAny(xElementAsForm));
304  }
305  else if (xContainer->getElementType() ==
307 
308  {
309  Reference< XFormComponent > xElementAsComponent(xElement, UNO_QUERY);
310  xContainer->insertByIndex(nRelPos, makeAny(xElementAsComponent));
311  }
312  else
313  {
314  OSL_FAIL("NavigatorTreeModel::Insert : the parent container needs an elementtype I don't know !");
315  }
316 
317  if( bUndo )
319  }
320 
321  // register as PropertyChangeListener
322  Reference< XPropertySet > xSet(xElement, UNO_QUERY);
323  if( xSet.is() )
324  xSet->addPropertyChangeListener( FM_PROP_NAME, m_pPropChangeList.get() );
325 
326 
327  // Remove data from model
328  if (dynamic_cast<const FmFormData*>( pEntry) != nullptr)
329  {
330  Reference< XContainer > xContainer(xElement, UNO_QUERY);
331  if (xContainer.is())
332  xContainer->addContainerListener(m_pPropChangeList.get());
333  }
334 
335  if (pFolder)
336  pFolder->GetChildList()->insert( std::unique_ptr<FmEntryData>(pEntry), nRelPos );
337  else
338  GetRootList()->insert( std::unique_ptr<FmEntryData>(pEntry), nRelPos );
339 
340 
341  // notify UI
342  FmNavInsertedHint aInsertedHint( pEntry, nRelPos );
343  Broadcast( aInsertedHint );
344 
345  m_pPropChangeList->UnLock();
348  }
349 
350 
351  void NavigatorTreeModel::Remove(FmEntryData* pEntry, bool bAlterModel)
352  {
353 
354  // get form and parent
355  if (!pEntry || !m_pFormModel)
356  return;
357 
360 
361  const bool bUndo = m_pFormModel->IsUndoEnabled();
362 
363  m_pPropChangeList->Lock();
364  FmFormData* pFolder = static_cast<FmFormData*>( pEntry->GetParent() );
365  Reference< XChild > xElement ( pEntry->GetChildIFace() );
366  if (bAlterModel)
367  {
368  OUString aStr;
369  if (dynamic_cast<const FmFormData*>( pEntry) != nullptr)
370  aStr = SvxResId(RID_STR_FORM);
371  else
372  aStr = SvxResId(RID_STR_CONTROL);
373 
374  if( bUndo )
375  {
376  OUString aUndoStr(SvxResId(RID_STR_UNDO_CONTAINER_REMOVE));
377  aUndoStr = aUndoStr.replaceFirst("#", aStr);
378  m_pFormModel->BegUndo(aUndoStr);
379  }
380  }
381 
382  // now real deletion of data form model
383  if (dynamic_cast<const FmFormData*>( pEntry) != nullptr)
384  RemoveForm(static_cast<FmFormData*>(pEntry));
385  else
386  RemoveFormComponent(static_cast<FmControlData*>(pEntry));
387 
388 
389  if (bAlterModel)
390  {
391  Reference< XIndexContainer > xContainer(xElement->getParent(), UNO_QUERY);
392  // remove from Container
393  sal_Int32 nContainerIndex = getElementPos(xContainer.get(), xElement);
394  // UndoAction
395  if (nContainerIndex >= 0)
396  {
397  if ( bUndo && m_pPropChangeList->CanUndo())
398  {
399  m_pFormModel->AddUndo(std::make_unique<FmUndoContainerAction>(*m_pFormModel,
401  xContainer,
402  xElement, nContainerIndex ));
403  }
404  else if( !m_pPropChangeList->CanUndo() )
405  {
407  }
408 
409  xContainer->removeByIndex(nContainerIndex );
410  }
411 
412  if( bUndo )
414  }
415 
416  // remove from parent
417  if (pFolder)
418  pFolder->GetChildList()->removeNoDelete( pEntry );
419  else
420  {
421  GetRootList()->removeNoDelete( pEntry );
422 
423  // If root has no more form, reset CurForm at shell
424  if ( !GetRootList()->size() )
426  }
427 
428 
429  // notify UI
430  FmNavRemovedHint aRemovedHint( pEntry );
431  Broadcast( aRemovedHint );
432 
433  // delete entry
434  delete pEntry;
435 
436  m_pPropChangeList->UnLock();
438  }
439 
440 
442  {
443 
444  // get form and parent
445  if (!pFormData || !m_pFormModel)
446  return;
447 
448  FmEntryDataList* pChildList = pFormData->GetChildList();
449  for ( size_t i = pChildList->size(); i > 0; )
450  {
451  FmEntryData* pEntryData = pChildList->at( --i );
452 
453 
454  // Child is form -> recursive call
455  if( dynamic_cast<const FmFormData*>( pEntryData) != nullptr )
456  RemoveForm( static_cast<FmFormData*>(pEntryData));
457  else if( dynamic_cast<const FmControlData*>( pEntryData) != nullptr )
458  RemoveFormComponent(static_cast<FmControlData*>(pEntryData));
459  }
460 
461 
462  // unregister as PropertyChangeListener
463  Reference< XPropertySet > xSet( pFormData->GetPropertySet() );
464  if ( xSet.is() )
465  xSet->removePropertyChangeListener( FM_PROP_NAME, m_pPropChangeList.get() );
466  }
467 
468 
470  {
471 
472  // get control and parent
473  if (!pControlData)
474  return;
475 
476 
477  // unregister as PropertyChangeListener
478  Reference< XPropertySet > xSet( pControlData->GetPropertySet() );
479  if (xSet.is())
480  xSet->removePropertyChangeListener( FM_PROP_NAME, m_pPropChangeList.get());
481  }
482 
483 
485  {
486 
487  // insert forms from root
488  if( pFormData == nullptr )
489  {
490  Reference< XIndexContainer > xForms = GetForms();
491  if (!xForms.is())
492  return;
493 
494  Reference< XForm > xSubForm;
495  for (sal_Int32 i=0; i<xForms->getCount(); ++i)
496  {
497  DBG_ASSERT( xForms->getByIndex(i).getValueType() == cppu::UnoType<XForm>::get(),
498  "NavigatorTreeModel::FillBranch : the root container should supply only elements of type XForm");
499 
500  xForms->getByIndex(i) >>= xSubForm;
501  FmFormData* pSubFormData = new FmFormData(xSubForm, pFormData);
502  Insert( pSubFormData );
503 
504  // new branch, if SubForm contains Subforms itself
505  FillBranch( pSubFormData );
506  }
507  }
508 
509 
510  // insert components
511  else
512  {
513  Reference< XIndexContainer > xComponents( GetFormComponents(pFormData));
514  if( !xComponents.is() ) return;
515 
516  FmControlData* pNewControlData;
517  FmFormData* pSubFormData;
518 
519  Reference< XFormComponent > xCurrentComponent;
520  for (sal_Int32 j=0; j<xComponents->getCount(); ++j)
521  {
522  xComponents->getByIndex(j) >>= xCurrentComponent;
523  Reference< XForm > xSubForm(xCurrentComponent, UNO_QUERY);
524 
525  if (xSubForm.is())
526  { // actual component is a form
527  pSubFormData = new FmFormData(xSubForm, pFormData);
528  Insert(pSubFormData);
529 
530 
531  // new branch, if SubForm contains Subforms itself
532  FillBranch(pSubFormData);
533  }
534  else
535  {
536  pNewControlData = new FmControlData(xCurrentComponent, pFormData);
537  Insert(pNewControlData);
538  }
539  }
540  }
541  }
542 
543 
544  void NavigatorTreeModel::InsertForm(const Reference< XForm > & xForm, sal_uInt32 nRelPos)
545  {
546  FmFormData* pFormData = static_cast<FmFormData*>(FindData( xForm, GetRootList() ));
547  if (pFormData)
548  return;
549 
550 
551  // set ParentData
552  Reference< XInterface > xIFace( xForm->getParent());
553  Reference< XForm > xParentForm(xIFace, UNO_QUERY);
554  FmFormData* pParentData = nullptr;
555  if (xParentForm.is())
556  pParentData = static_cast<FmFormData*>(FindData( xParentForm, GetRootList() ));
557 
558  pFormData = new FmFormData(xForm, pParentData);
559  Insert( pFormData, nRelPos );
560  }
561 
562 
563  void NavigatorTreeModel::InsertFormComponent(const Reference< XFormComponent > & xComp, sal_uInt32 nRelPos)
564  {
565 
566  // set ParentData
567  Reference< XInterface > xIFace( xComp->getParent());
568  Reference< XForm > xForm(xIFace, UNO_QUERY);
569  if (!xForm.is())
570  return;
571 
572  FmFormData* pParentData = static_cast<FmFormData*>(FindData( xForm, GetRootList() ));
573  if( !pParentData )
574  {
575  pParentData = new FmFormData(xForm, nullptr);
576  Insert( pParentData );
577  }
578 
579  if (!FindData(xComp, pParentData->GetChildList(),false))
580  {
581 
582  // set new EntryData
583  FmEntryData* pNewEntryData = new FmControlData(xComp, pParentData);
584 
585 
586  // insert new EntryData
587  Insert( pNewEntryData, nRelPos );
588  }
589  }
590 
592  const Reference< XFormComponent > & xOld,
593  const Reference< XFormComponent > & xNew
594  )
595  {
597  assert(dynamic_cast<const FmControlData*>( pData)); //NavigatorTreeModel::ReplaceFormComponent : invalid argument
598  if (!dynamic_cast<const FmControlData*>( pData))
599  return;
600  static_cast<FmControlData*>(pData)->ModelReplaced(xNew);
601 
602  FmNavModelReplacedHint aReplacedHint( pData );
603  Broadcast( aReplacedHint );
604  }
605 
606  FmEntryData* NavigatorTreeModel::FindData(const Reference< XInterface > & xElement, FmEntryDataList* pDataList, bool bRecurs)
607  {
608  // normalize
609  Reference< XInterface > xIFace( xElement, UNO_QUERY );
610 
611  for ( size_t i = 0; i < pDataList->size(); i++ )
612  {
613  FmEntryData* pEntryData = pDataList->at( i );
614  if ( pEntryData->GetElement().get() == xIFace.get() )
615  return pEntryData;
616  else if (bRecurs)
617  {
618  pEntryData = FindData( xElement, pEntryData->GetChildList() );
619  if (pEntryData)
620  return pEntryData;
621  }
622  }
623  return nullptr;
624  }
625 
626 
627  FmEntryData* NavigatorTreeModel::FindData( const OUString& rText, FmFormData const * pParentData, bool bRecurs )
628  {
629  FmEntryDataList* pDataList;
630  if( !pParentData )
631  pDataList = GetRootList();
632  else
633  pDataList = pParentData->GetChildList();
634 
635  OUString aEntryText;
636  FmEntryData* pEntryData;
637  FmEntryData* pChildData;
638 
639  for( size_t i = 0; i < pDataList->size(); i++ )
640  {
641  pEntryData = pDataList->at( i );
642  aEntryText = pEntryData->GetText();
643 
644  if (rText == aEntryText)
645  return pEntryData;
646 
647  if (FmFormData* pFormData = bRecurs ? dynamic_cast<FmFormData*>(pEntryData) : nullptr)
648  {
649  pChildData = FindData(rText, pFormData, true);
650  if( pChildData )
651  return pChildData;
652  }
653  }
654 
655  return nullptr;
656  }
657 
658  void NavigatorTreeModel::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
659  {
660  if (rHint.GetId() == SfxHintId::ThisIsAnSdrHint)
661  {
662  const SdrHint* pSdrHint = static_cast<const SdrHint*>(&rHint);
663  switch( pSdrHint->GetKind() )
664  {
666  InsertSdrObj(pSdrHint->GetObject());
667  break;
669  RemoveSdrObj(pSdrHint->GetObject());
670  break;
671  default:
672  break;
673  }
674  }
675  // is shell gone?
676  else if (rHint.GetId() == SfxHintId::Dying)
677  {
678  UpdateContent(nullptr);
679  }
680  // changed mark of controls?
681  else if (const FmNavViewMarksChanged* pvmcHint = dynamic_cast<const FmNavViewMarksChanged*>(&rHint))
682  {
683  BroadcastMarkedObjects(pvmcHint->GetAffectedView()->GetMarkedObjectList());
684  }
685  }
686 
688  {
689  const FmFormObj* pFormObject = FmFormObj::GetFormObject( pObj );
690  if ( pFormObject )
691  {
692  try
693  {
694  Reference< XFormComponent > xFormComponent( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW );
695  Reference< XIndexAccess > xContainer( xFormComponent->getParent(), UNO_QUERY_THROW );
696 
697  sal_Int32 nPos = getElementPos( xContainer, xFormComponent );
698  InsertFormComponent( xFormComponent, nPos );
699  }
700  catch( const Exception& )
701  {
703  }
704  }
705  else if ( pObj->IsGroupObject() )
706  {
707  SdrObjListIter aIter( pObj->GetSubList() );
708  while ( aIter.IsMore() )
709  InsertSdrObj( aIter.Next() );
710  }
711  }
712 
713 
715  {
716  const FmFormObj* pFormObject = FmFormObj::GetFormObject( pObj );
717  if ( pFormObject )
718  {
719  try
720  {
721  Reference< XFormComponent > xFormComponent( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW );
722  FmEntryData* pEntryData = FindData( xFormComponent, GetRootList() );
723  if ( pEntryData )
724  Remove( pEntryData );
725  }
726  catch( const Exception& )
727  {
729  }
730  }
731  else if ( pObj->IsGroupObject() )
732  {
733  SdrObjListIter aIter( pObj->GetSubList() );
734  while ( aIter.IsMore() )
735  RemoveSdrObj( aIter.Next() );
736  }
737  }
738 
740  {
741  if ( dynamic_cast<const SdrObjGroup*>( pObject) != nullptr )
742  { // descend recursively
743  const SdrObjList *pChildren = static_cast<SdrObjGroup*>(pObject)->GetSubList();
744  for ( size_t i=0; i<pChildren->GetObjCount(); ++i )
745  {
746  SdrObject* pCurrent = pChildren->GetObj(i);
747  if (!InsertFormComponent(rHint, pCurrent))
748  return false;
749  }
750  }
751  else
752  {
753  FmFormObj* pFormObject = FmFormObj::GetFormObject( pObject );
754  if ( !pFormObject )
755  return false;
756 
757  try
758  {
759  Reference< XFormComponent > xFormViewControl( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW );
760  FmEntryData* pControlData = FindData( xFormViewControl, GetRootList() );
761  if ( !pControlData )
762  return false;
763 
764  rHint.AddItem( pControlData );
765  return true;
766  }
767  catch( const Exception& )
768  {
770  return false;
771  }
772  }
773 
774  return true;
775  }
776 
778  {
779  // search all objects, which can be handled, out of marked objects
780  FmNavRequestSelectHint rshRequestSelection;
781  bool bIsMixedSelection = false;
782 
783  for (size_t i=0; (i<mlMarked.GetMarkCount()) && !bIsMixedSelection; ++i)
784  {
785  SdrObject* pobjCurrent = mlMarked.GetMark(i)->GetMarkedSdrObj();
786  bIsMixedSelection |= !InsertFormComponent(rshRequestSelection, pobjCurrent);
787  // if Not-Form-Control, InsertFormComponent returns sal_False !
788  }
789 
790  rshRequestSelection.SetMixedSelection(bIsMixedSelection);
791  if (bIsMixedSelection)
792  rshRequestSelection.ClearItems();
793 
794  Broadcast(rshRequestSelection);
795  // an empty list causes NavigatorTree to remove his selection
796  }
797 
798 
799  void NavigatorTreeModel::UpdateContent( const Reference< css::form::XForms > & xForms )
800  {
801 
802  // refill model form root upward
803  Clear();
804  if (xForms.is())
805  {
806  xForms->addContainerListener(m_pPropChangeList.get());
807 
808  FillBranch(nullptr);
809 
810  // select same control in tree as in view
811  // (or all of them), if there is one ...
812  if(!m_pFormShell) return; // no shell
813 
814  FmFormView* pFormView = m_pFormShell->GetFormView();
815  DBG_ASSERT(pFormView != nullptr, "NavigatorTreeModel::UpdateContent : no FormView");
817  }
818  }
819 
820 
822  {
823 
824  // If shell is unchanged, do nothing
825  FmFormPage* pNewPage = pShell ? pShell->GetCurPage() : nullptr;
826  if ((pShell == m_pFormShell) && (m_pFormPage == pNewPage))
827  return;
828 
829 
830  // unregister as Listener
831  if( m_pFormShell )
832  {
833  if (m_pFormModel)
835  m_pFormModel = nullptr;
837  Clear();
838  }
839 
840 
841  // entire update
842  m_pFormShell = pShell;
843  if (m_pFormShell)
844  {
845  m_pFormPage = pNewPage;
847  } else
848  m_pFormPage = nullptr;
849 
850 
851  // register as Listener again
852  if( m_pFormShell )
853  {
856  if( m_pFormModel )
858  }
859  }
860 
861 
862  Reference< XIndexContainer > NavigatorTreeModel::GetFormComponents( FmFormData const * pFormData )
863  {
864 
865  // get components from form
866  if (pFormData)
867  return Reference< XIndexContainer > (pFormData->GetFormIface(), UNO_QUERY);
868 
869  return Reference< XIndexContainer > ();
870  }
871 
872 
873  bool NavigatorTreeModel::Rename( FmEntryData* pEntryData, const OUString& rNewText )
874  {
875 
876  // If name already exist, error message
877  pEntryData->SetText( rNewText );
878 
879 
880  // get PropertySet
881  Reference< XFormComponent > xFormComponent;
882 
883  if( dynamic_cast<const FmFormData*>( pEntryData) != nullptr )
884  {
885  FmFormData* pFormData = static_cast<FmFormData*>(pEntryData);
886  xFormComponent = pFormData->GetFormIface();
887  }
888 
889  if( dynamic_cast<const FmControlData*>( pEntryData) != nullptr )
890  {
891  FmControlData* pControlData = static_cast<FmControlData*>(pEntryData);
892  xFormComponent = pControlData->GetFormComponent();
893  }
894 
895  if( !xFormComponent.is() ) return false;
896  Reference< XPropertySet > xSet(xFormComponent, UNO_QUERY);
897  if( !xSet.is() ) return false;
898 
899 
900  // set name
901  xSet->setPropertyValue( FM_PROP_NAME, makeAny(rNewText) );
902 
903  return true;
904  }
905 
906 }
907 
908 
909 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual void SAL_CALL elementRemoved(const css::container::ContainerEvent &rEvent) override
virtual void SAL_CALL disposing(const css::lang::EventObject &Source) override
void SetMixedSelection(bool bMixedSelection)
Definition: fmexpl.hxx:218
void Remove(const css::uno::Reference< css::uno::XInterface > &_rxElement)
SdrHintKind GetKind() const
Definition: svdmodel.hxx:124
size_t GetMarkCount() const
Definition: svdmark.hxx:179
void removeNoDelete(FmEntryData *pItem)
Definition: fmexpl.cxx:133
FmFormView * GetFormView() const
Definition: fmshell.hxx:115
FmFormPage * m_pFormPage
Definition: fmexpl.hxx:314
FmXFormShell * GetImpl() const
Definition: fmshell.hxx:118
void InsertSdrObj(const SdrObject *pSdrObj)
virtual void SetModified(bool bModified=true)
FmEntryData * GetParent() const
Definition: fmexpl.hxx:160
std::shared_ptr< ContentProperties > const pData
void UpdateContent(const css::uno::Reference< css::form::XForms > &xForms)
SdrObject * GetObj(size_t nNum) const
Definition: svdpage.cxx:773
virtual void SAL_CALL elementReplaced(const css::container::ContainerEvent &rEvent) override
size_t GetObjCount() const
Definition: svdpage.cxx:767
FmFormPage * GetCurPage() const
Definition: fmshell.cxx:1150
void AddItem(FmEntryData *pEntry)
Definition: fmexpl.hxx:220
void InsertFormComponent(const css::uno::Reference< css::form::XFormComponent > &xComp, sal_uInt32 nRelPos)
sal_Int32 getElementPos(const Reference< css::container::XIndexAccess > &xCont, const Reference< XInterface > &xElement)
Definition: fmtools.cxx:161
SdrMark * GetMark(size_t nNum) const
Definition: svdmark.cxx:234
FmEntryDataList * GetRootList() const
Definition: fmexpl.hxx:357
virtual SdrObjList * GetSubList() const
Definition: svdobj.cxx:674
void BegUndo()
Definition: svdmodel.cxx:425
SfxHintId GetId() const
FmFormModel * m_pFormModel
Definition: fmexpl.hxx:315
void FillBranch(FmFormData *pParentData)
FmFormModel * GetFormModel() const
Definition: fmshell.hxx:116
bool IsListening(SfxBroadcaster &rBroadcaster) const
#define FM_PROP_NAME
Definition: fmprop.hxx:29
void insert(std::unique_ptr< FmEntryData > pItem, size_t Index)
Definition: fmexpl.cxx:147
const css::uno::Reference< css::uno::XInterface > & GetElement() const
Definition: fmexpl.hxx:168
OUString SvxResId(const char *pId)
Definition: dialmgr.cxx:28
void AddUndo(std::unique_ptr< SdrUndoAction > pUndo)
Definition: svdmodel.cxx:559
void InsertForm(const css::uno::Reference< css::form::XForm > &xForm, sal_uInt32 nRelPos)
FmEntryData * at(size_t Index)
Definition: fmexpl.hxx:194
std::unique_ptr< FmEntryDataList > m_pRootList
Definition: fmexpl.hxx:312
void SetText(const OUString &rText)
Definition: fmexpl.hxx:154
static css::uno::Reference< css::container::XIndexContainer > GetFormComponents(FmFormData const *pParentFormData)
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
static void DisposeElement(const css::uno::Reference< css::uno::XInterface > &xElem)
Definition: fmundo.cxx:1072
SdrObject * GetMarkedSdrObj() const
Definition: svdmark.hxx:67
#define DBG_UNHANDLED_EXCEPTION(...)
const OUString & GetText() const
Definition: fmexpl.hxx:159
::svxform::NavigatorTreeModel * m_pNavModel
Definition: fmexpl.hxx:276
#define DBG_ASSERT(sCon, aError)
const css::uno::Reference< css::form::XForm > & GetFormIface() const
Definition: fmexpl.hxx:235
bool IsUndoEnabled() const
returns true if undo is currently enabled This returns false if undo was disabled using EnableUndo( f...
Definition: svdmodel.cxx:590
void Insert(FmEntryData *pEntryData, sal_uInt32 nRelPos=SAL_MAX_UINT32, bool bAlterModel=false)
virtual void SAL_CALL elementInserted(const css::container::ContainerEvent &rEvent) override
int i
const SdrMarkList & GetMarkedObjectList() const
Definition: svdmrkv.hxx:243
const css::uno::Reference< css::form::XFormComponent > & GetFormComponent() const
Definition: fmexpl.hxx:257
bool IsGroupObject() const
Definition: svdobj.cxx:669
size
css::uno::Type const & get()
css::uno::Reference< css::form::XForms > GetForms() const
void StartListening(SfxBroadcaster &rBroadcaster, DuplicateHandling eDuplicateHanding=DuplicateHandling::Unexpected)
void clear()
Definition: fmexpl.cxx:158
static bool Rename(FmEntryData *pEntryData, const OUString &rNewText)
Abstract DrawObject.
Definition: svdobj.hxx:312
virtual ~NavigatorTreeModel() override
static SAL_DLLPRIVATE FmFormObj * GetFormObject(SdrObject *_pSdrObject)
returns the FmFormObj behind the given SdrObject
Definition: fmobj.cxx:582
void EndUndo()
Definition: svdmodel.cxx:496
size_t size() const
Definition: fmexpl.hxx:197
virtual void SAL_CALL propertyChange(const css::beans::PropertyChangeEvent &evt) override
void Insert(const css::uno::Reference< css::uno::XInterface > &xIface, sal_Int32 nIndex)
void Broadcast(const SfxHint &rHint)
FmFormShell * m_pFormShell
Definition: fmexpl.hxx:313
void RemoveForm(FmFormData const *pFormData)
const css::uno::Reference< css::container::XChild > & GetChildIFace() const
Definition: fmexpl.hxx:178
SAL_DLLPRIVATE void forgetCurrentForm_Lock()
Definition: fmshimp.cxx:2020
OFormComponentObserver(::svxform::NavigatorTreeModel *pModel)
sal_Int32 getINT32(const Any &_rAny)
void EndListening(SfxBroadcaster &rBroadcaster, bool bRemoveAllDuplicates=false)
void ReplaceFormComponent(const css::uno::Reference< css::form::XFormComponent > &xOld, const css::uno::Reference< css::form::XFormComponent > &xNew)
const css::uno::Reference< css::beans::XPropertySet > & GetPropertySet() const
Definition: fmexpl.hxx:173
FmEntryData * FindData(const css::uno::Reference< css::uno::XInterface > &xElement, FmEntryDataList *pDataList, bool bRecurs=true)
void RemoveSdrObj(const SdrObject *pSdrObj)
const css::uno::Reference< css::awt::XControlModel > & GetUnoControlModel() const
Definition: svdouno.hxx:91
class FmSearchEngine - Impl class for FmSearchDialog
friend class OFormComponentObserver
Definition: fmexpl.hxx:309
const css::uno::Reference< css::form::XForms > & GetForms(bool _bForceCreate=true) const
Definition: fmpage.cxx:90
void BroadcastMarkedObjects(const SdrMarkList &mlMarked)
rtl::Reference< OFormComponentObserver > m_pPropChangeList
Definition: fmexpl.hxx:316
aStr
FmEntryDataList * GetChildList() const
Definition: fmexpl.hxx:161
sal_uInt16 nPos
SfxObjectShell * GetObjectShell() const
Definition: fmmodel.hxx:58
void Remove(FmEntryData *pEntryData, bool bAlterModel=false)
void RemoveFormComponent(FmControlData const *pControlData)
const SdrObject * GetObject() const
Definition: svdmodel.hxx:123
css::uno::Any SAL_CALL makeAny(const SharedUNOComponent< INTERFACE, COMPONENT > &value)