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