LibreOffice Module svx (master)  1
fmundo.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 <sal/config.h>
21 
22 #include <map>
23 
24 #include <sal/macros.h>
25 #include <fmundo.hxx>
26 #include <fmpgeimp.hxx>
27 #include <svx/svditer.hxx>
28 #include <fmobj.hxx>
29 #include <fmprop.hxx>
30 #include <svx/strings.hrc>
31 #include <svx/dialmgr.hxx>
32 #include <svx/fmmodel.hxx>
33 #include <svx/fmpage.hxx>
34 
35 #include <com/sun/star/util/XModifyBroadcaster.hpp>
36 #include <com/sun/star/beans/PropertyAttribute.hpp>
37 #include <com/sun/star/container/XContainer.hpp>
38 #include <com/sun/star/container/XContainerListener.hpp>
39 #include <com/sun/star/script/XEventAttacherManager.hpp>
40 #include <com/sun/star/form/binding/XBindableValue.hpp>
41 #include <com/sun/star/form/binding/XListEntrySink.hpp>
42 #include <com/sun/star/sdbc/XConnection.hpp>
43 #include <com/sun/star/uno/XComponentContext.hpp>
44 
45 #include <svx/fmtools.hxx>
46 #include <tools/debug.hxx>
47 #include <tools/diagnose_ex.h>
48 #include <sfx2/objsh.hxx>
49 #include <sfx2/event.hxx>
50 #include <osl/mutex.hxx>
51 #include <comphelper/property.hxx>
52 #include <comphelper/types.hxx>
53 #include <connectivity/dbtools.hxx>
54 #include <vcl/svapp.hxx>
55 
56 using namespace ::com::sun::star::uno;
57 using namespace ::com::sun::star::awt;
58 using namespace ::com::sun::star::beans;
59 using namespace ::com::sun::star::container;
60 using namespace ::com::sun::star::script;
61 using namespace ::com::sun::star::lang;
62 using namespace ::com::sun::star::form;
63 using namespace ::com::sun::star::util;
64 using namespace ::com::sun::star::form::binding;
65 using namespace ::com::sun::star::sdbc;
66 using namespace ::svxform;
67 using namespace ::dbtools;
68 
69 
70 #include <com/sun/star/script/XScriptListener.hpp>
72 #include <cppuhelper/implbase.hxx>
73 
74 namespace {
75 
76 class ScriptEventListenerWrapper : public cppu::WeakImplHelper< XScriptListener >
77 {
78 public:
80  explicit ScriptEventListenerWrapper( FmFormModel& _rModel)
81  :m_rModel( _rModel )
82  ,m_attemptedListenerCreation( false )
83  {
84 
85  }
86  // XEventListener
87  virtual void SAL_CALL disposing(const EventObject& ) override {}
88 
89  // XScriptListener
90  virtual void SAL_CALL firing(const ScriptEvent& evt) override
91  {
92  attemptListenerCreation();
93  if ( m_vbaListener.is() )
94  {
95  m_vbaListener->firing( evt );
96  }
97  }
98 
99  virtual Any SAL_CALL approveFiring(const ScriptEvent& evt) override
100  {
101  attemptListenerCreation();
102  if ( m_vbaListener.is() )
103  {
104  return m_vbaListener->approveFiring( evt );
105  }
106  return Any();
107  }
108 
109 private:
110  void attemptListenerCreation()
111  {
112  if ( m_attemptedListenerCreation )
113  return;
114  m_attemptedListenerCreation = true;
115 
116  try
117  {
118  css::uno::Reference<css::uno::XComponentContext> context(
120  Reference< XScriptListener > const xScriptListener(
121  context->getServiceManager()->createInstanceWithContext(
122  "ooo.vba.EventListener", context),
123  UNO_QUERY_THROW);
124  Reference< XPropertySet > const xListenerProps( xScriptListener, UNO_QUERY_THROW );
125  // SfxObjectShellRef is good here since the model controls the lifetime of the shell
126  SfxObjectShellRef const xObjectShell = m_rModel.GetObjectShell();
127  ENSURE_OR_THROW( xObjectShell.is(), "no object shell!" );
128  xListenerProps->setPropertyValue("Model", Any( xObjectShell->GetModel() ) );
129 
130  m_vbaListener = xScriptListener;
131  }
132  catch( Exception const & )
133  {
135  }
136  }
138  Reference< XScriptListener > m_vbaListener;
139  bool m_attemptedListenerCreation;
140 
141 
142 };
143 
144 
145 // some helper structs for caching property infos
146 
147 struct PropertyInfo
148 {
149  bool bIsTransientOrReadOnly : 1; // the property is transient or read-only, thus we need no undo action for it
150  bool bIsValueProperty : 1; // the property is the special value property, thus it may be handled
151  // as if it's transient or persistent
152 };
153 
154 struct PropertySetInfo
155 {
156  typedef std::map<OUString, PropertyInfo> AllProperties;
157 
158  AllProperties aProps; // all properties of this set which we know so far
159  bool bHasEmptyControlSource; // sal_True -> the set has a DataField property, and the current value is an empty string
160  // sal_False -> the set has _no_ such property or its value isn't empty
161 };
162 
163 }
164 
165 typedef std::map<Reference< XPropertySet >, PropertySetInfo> PropertySetInfoCache;
166 
167 
168 static OUString static_STR_UNDO_PROPERTY;
169 
170 
172  :rModel( _rModel )
173  ,m_pPropertySetCache( nullptr )
174  ,m_pScriptingEnv( new svxform::FormScriptingEnvironment( _rModel ) )
175  ,m_Locks( 0 )
176  ,bReadOnly( false )
177  ,m_bDisposed( false )
178 {
179  try
180  {
181  m_vbaListener = new ScriptEventListenerWrapper( _rModel );
182  }
183  catch( Exception& )
184  {
185  }
186 }
187 
189 {
190  if ( !m_bDisposed ) // i120746, call FormScriptingEnvironment::dispose to avoid memory leak
191  m_pScriptingEnv->dispose();
192 
194  delete static_cast<PropertySetInfoCache*>(m_pPropertySetCache);
195 }
196 
198 {
199  OSL_ENSURE( !m_bDisposed, "FmXUndoEnvironment::dispose: disposed twice?" );
200  if ( !m_bDisposed )
201  return;
202 
203  Lock();
204 
205  sal_uInt16 nCount = rModel.GetPageCount();
206  sal_uInt16 i;
207  for (i = 0; i < nCount; i++)
208  {
209  FmFormPage* pPage = dynamic_cast<FmFormPage*>( rModel.GetPage(i) );
210  if ( pPage )
211  {
212  Reference< css::form::XForms > xForms = pPage->GetForms( false );
213  if ( xForms.is() )
214  RemoveElement( xForms );
215  }
216  }
217 
218  nCount = rModel.GetMasterPageCount();
219  for (i = 0; i < nCount; i++)
220  {
221  FmFormPage* pPage = dynamic_cast<FmFormPage*>( rModel.GetMasterPage(i) );
222  if ( pPage )
223  {
224  Reference< css::form::XForms > xForms = pPage->GetForms( false );
225  if ( xForms.is() )
226  RemoveElement( xForms );
227  }
228  }
229 
230  UnLock();
231 
232  OSL_PRECOND( rModel.GetObjectShell(), "FmXUndoEnvironment::dispose: no object shell anymore!" );
233  if ( rModel.GetObjectShell() )
235 
236  if ( IsListening( rModel ) )
237  EndListening( rModel );
238 
239  m_pScriptingEnv->dispose();
240 
241  m_bDisposed = true;
242 }
243 
244 
246 {
247  OSL_PRECOND( rModel.GetObjectShell(), "FmXUndoEnvironment::ModeChanged: no object shell anymore!" );
248  if ( !rModel.GetObjectShell() )
249  return;
250 
252  return;
253 
254  bReadOnly = !bReadOnly;
255 
256  sal_uInt16 nCount = rModel.GetPageCount();
257  sal_uInt16 i;
258  for (i = 0; i < nCount; i++)
259  {
260  FmFormPage* pPage = dynamic_cast<FmFormPage*>( rModel.GetPage(i) );
261  if ( pPage )
262  {
263  Reference< css::form::XForms > xForms = pPage->GetForms( false );
264  if ( xForms.is() )
265  TogglePropertyListening( xForms );
266  }
267  }
268 
269  nCount = rModel.GetMasterPageCount();
270  for (i = 0; i < nCount; i++)
271  {
272  FmFormPage* pPage = dynamic_cast<FmFormPage*>( rModel.GetMasterPage(i) );
273  if ( pPage )
274  {
275  Reference< css::form::XForms > xForms = pPage->GetForms( false );
276  if ( xForms.is() )
277  TogglePropertyListening( xForms );
278  }
279  }
280 
281  if (!bReadOnly)
283  else
285 }
286 
287 
288 void FmXUndoEnvironment::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
289 {
290  if (rHint.GetId() == SfxHintId::ThisIsAnSdrHint)
291  {
292  const SdrHint* pSdrHint = static_cast<const SdrHint*>(&rHint);
293  switch (pSdrHint->GetKind())
294  {
296  {
297  SdrObject* pSdrObj = const_cast<SdrObject*>(pSdrHint->GetObject());
298  Inserted( pSdrObj );
299  } break;
301  {
302  SdrObject* pSdrObj = const_cast<SdrObject*>(pSdrHint->GetObject());
303  Removed( pSdrObj );
304  }
305  break;
306  default:
307  break;
308  }
309  }
310  else if (rHint.GetId() != SfxHintId::NONE)
311  {
312  switch (rHint.GetId())
313  {
314  case SfxHintId::Dying:
315  dispose();
316  rModel.SetObjectShell( nullptr );
317  break;
318  case SfxHintId::ModeChanged:
319  ModeChanged();
320  break;
321  default: break;
322  }
323  }
324  else if (const SfxEventHint* pEventHint = dynamic_cast<const SfxEventHint*>(&rHint))
325  {
326  switch (pEventHint->GetEventId())
327  {
328  case SfxEventHintId::CreateDoc:
329  case SfxEventHintId::OpenDoc:
330  ModeChanged();
331  break;
332  default: break;
333  }
334  }
335 }
336 
338 {
339  if (pObj->GetObjInventor() == SdrInventor::FmForm)
340  {
341  FmFormObj* pFormObj = dynamic_cast<FmFormObj*>( pObj );
342  Inserted( pFormObj );
343  }
344  else if (pObj->IsGroupObject())
345  {
346  SdrObjListIter aIter(pObj->GetSubList());
347  while ( aIter.IsMore() )
348  Inserted( aIter.Next() );
349  }
350 }
351 
352 
353 namespace
354 {
355  bool lcl_searchElement(const Reference< XIndexAccess>& xCont, const Reference< XInterface >& xElement)
356  {
357  if (!xCont.is() || !xElement.is())
358  return false;
359 
360  sal_Int32 nCount = xCont->getCount();
361  Reference< XInterface > xComp;
362  for (sal_Int32 i = 0; i < nCount; i++)
363  {
364  try
365  {
366  xCont->getByIndex(i) >>= xComp;
367  if (xComp.is())
368  {
369  if ( xElement == xComp )
370  return true;
371  else
372  {
373  Reference< XIndexAccess> xCont2(xComp, UNO_QUERY);
374  if (xCont2.is() && lcl_searchElement(xCont2, xElement))
375  return true;
376  }
377  }
378  }
379  catch(const Exception&)
380  {
382  }
383  }
384  return false;
385  }
386 }
387 
388 
389 void FmXUndoEnvironment::Inserted(FmFormObj* pObj)
390 {
391  DBG_ASSERT( pObj, "FmXUndoEnvironment::Inserted: invalid object!" );
392  if ( !pObj )
393  return;
394 
395  // is the control still assigned to a form
396  Reference< XInterface > xModel(pObj->GetUnoControlModel(), UNO_QUERY);
397  Reference< XFormComponent > xContent(xModel, UNO_QUERY);
398  if (!(xContent.is() && pObj->getSdrPageFromSdrObject()))
399  return;
400 
401  // if the component doesn't belong to a form, yet, find one to insert into
402  if (!xContent->getParent().is())
403  {
404  try
405  {
406  const Reference< XIndexContainer >& xObjectParent = pObj->GetOriginalParent();
407 
408  FmFormPage& rPage(dynamic_cast< FmFormPage& >( *pObj->getSdrPageFromSdrObject()));
409  Reference< XIndexAccess > xForms( rPage.GetForms(), UNO_QUERY_THROW );
410 
411  Reference< XIndexContainer > xNewParent;
412  Reference< XForm > xForm;
413  sal_Int32 nPos = -1;
414  if ( lcl_searchElement( xForms, xObjectParent ) )
415  {
416  // the form which was the parent of the object when it was removed is still
417  // part of the form component hierarchy of the current page
418  xNewParent = xObjectParent;
419  xForm.set( xNewParent, UNO_QUERY_THROW );
420  nPos = ::std::min( pObj->GetOriginalIndex(), xNewParent->getCount() );
421  }
422  else
423  {
424  xForm.set( rPage.GetImpl().findPlaceInFormComponentHierarchy( xContent ), UNO_SET_THROW );
425  xNewParent.set( xForm, UNO_QUERY_THROW );
426  nPos = xNewParent->getCount();
427  }
428 
429  FmFormPageImpl::setUniqueName( xContent, xForm );
430  xNewParent->insertByIndex( nPos, Any( xContent ) );
431 
432  Reference< XEventAttacherManager > xManager( xNewParent, UNO_QUERY_THROW );
433  xManager->registerScriptEvents( nPos, pObj->GetOriginalEvents() );
434  }
435  catch( const Exception& )
436  {
438  }
439  }
440 
441  // reset FormObject
442  pObj->ClearObjEnv();
443 }
444 
445 
447 {
448  if ( pObj->IsVirtualObj() )
449  // for virtual objects, we've already been notified of the removal of the master
450  // object, which is sufficient here
451  return;
452 
453  if (pObj->GetObjInventor() == SdrInventor::FmForm)
454  {
455  FmFormObj* pFormObj = dynamic_cast<FmFormObj*>( pObj );
456  Removed(pFormObj);
457  }
458  else if (pObj->IsGroupObject())
459  {
460  SdrObjListIter aIter(pObj->GetSubList());
461  while ( aIter.IsMore() )
462  Removed( aIter.Next() );
463  }
464 }
465 
466 
467 void FmXUndoEnvironment::Removed(FmFormObj* pObj)
468 {
469  DBG_ASSERT( pObj, "FmXUndoEnvironment::Removed: invalid object!" );
470  if ( !pObj )
471  return;
472 
473  // is the control still assigned to a form
474  Reference< XFormComponent > xContent(pObj->GetUnoControlModel(), UNO_QUERY);
475  if (!xContent.is())
476  return;
477 
478  // The object is taken out of a list.
479  // If a father exists, the object is removed at the father and
480  // noted at the FormObject!
481 
482  // If the object is reinserted and a parent exists, this parent is set though.
483  Reference< XIndexContainer > xForm(xContent->getParent(), UNO_QUERY);
484  if (!xForm.is())
485  return;
486 
487  // determine which position the child was at
488  const sal_Int32 nPos = getElementPos(xForm, xContent);
489  if (nPos < 0)
490  return;
491 
492  Sequence< ScriptEventDescriptor > aEvts;
493  Reference< XEventAttacherManager > xManager(xForm, UNO_QUERY);
494  if (xManager.is())
495  aEvts = xManager->getScriptEvents(nPos);
496 
497  try
498  {
499  pObj->SetObjEnv(xForm, nPos, aEvts);
500  xForm->removeByIndex(nPos);
501  }
502  catch(Exception&)
503  {
505  }
506 }
507 
508 // XEventListener
509 
510 void SAL_CALL FmXUndoEnvironment::disposing(const EventObject& e)
511 {
512  // check if it's an object we have cached information about
514  {
515  Reference< XPropertySet > xSourceSet(e.Source, UNO_QUERY);
516  if (xSourceSet.is())
517  {
518  PropertySetInfoCache* pCache = static_cast<PropertySetInfoCache*>(m_pPropertySetCache);
519  PropertySetInfoCache::iterator aSetPos = pCache->find(xSourceSet);
520  if (aSetPos != pCache->end())
521  pCache->erase(aSetPos);
522  }
523  }
524 }
525 
526 // XPropertyChangeListener
527 
528 void SAL_CALL FmXUndoEnvironment::propertyChange(const PropertyChangeEvent& evt)
529 {
530  ::osl::ClearableMutexGuard aGuard( m_aMutex );
531 
532  if (!IsLocked())
533  {
534  Reference< XPropertySet > xSet(evt.Source, UNO_QUERY);
535  if (!xSet.is())
536  return;
537 
538  // if it's a "default value" property of a control model, set the according "value" property
539  static constexpr rtl::OUStringConstExpr pDefaultValueProperties[] = {
542  };
543  static constexpr rtl::OUStringConstExpr aValueProperties[] = {
546  };
547  sal_Int32 nDefaultValueProps = SAL_N_ELEMENTS(pDefaultValueProperties);
548  OSL_ENSURE(SAL_N_ELEMENTS(aValueProperties) == nDefaultValueProps,
549  "FmXUndoEnvironment::propertyChange: inconsistence!");
550  for (sal_Int32 i=0; i<nDefaultValueProps; ++i)
551  {
552  if (evt.PropertyName == pDefaultValueProperties[i])
553  {
554  try
555  {
556  xSet->setPropertyValue(aValueProperties[i], evt.NewValue);
557  }
558  catch(const Exception&)
559  {
560  OSL_FAIL("FmXUndoEnvironment::propertyChange: could not adjust the value property!");
561  }
562  }
563  }
564 
565  // no Undo for transient and readonly props. But unfortunately "transient" is not only that the
566  // "transient" flag is set for the property in question, instead it is somewhat more complex
567  // Transience criterions are:
568  // - the "transient" flag is set for the property
569  // - OR the control has a non-empty COntrolSource property, i.e. is intended to be bound
570  // to a database column. Note that it doesn't matter here whether the control actually
571  // *is* bound to a column
572  // - OR the control is bound to an external value via XBindableValue/XValueBinding
573  // which does not have a "ExternalData" property being <TRUE/>
574 
575  if (!m_pPropertySetCache)
577  PropertySetInfoCache* pCache = static_cast<PropertySetInfoCache*>(m_pPropertySetCache);
578 
579  // let's see if we know something about the set
580  PropertySetInfoCache::iterator aSetPos = pCache->find(xSet);
581  if (aSetPos == pCache->end())
582  {
583  PropertySetInfo aNewEntry;
585  {
586  aNewEntry.bHasEmptyControlSource = false;
587  }
588  else
589  {
590  try
591  {
592  Any aCurrentControlSource = xSet->getPropertyValue(FM_PROP_CONTROLSOURCE);
593  aNewEntry.bHasEmptyControlSource = !aCurrentControlSource.hasValue() || ::comphelper::getString(aCurrentControlSource).isEmpty();
594  }
595  catch(const Exception&)
596  {
598  }
599  }
600  aSetPos = pCache->emplace(xSet,aNewEntry).first;
601  DBG_ASSERT(aSetPos != pCache->end(), "FmXUndoEnvironment::propertyChange : just inserted it ... why it's not there ?");
602  }
603  else
604  { // is it the DataField property ?
605  if (evt.PropertyName == FM_PROP_CONTROLSOURCE)
606  {
607  aSetPos->second.bHasEmptyControlSource = !evt.NewValue.hasValue() || ::comphelper::getString(evt.NewValue).isEmpty();
608  }
609  }
610 
611  // now we have access to the cached info about the set
612  // let's see what we know about the property
613  PropertySetInfo::AllProperties& rPropInfos = aSetPos->second.aProps;
614  PropertySetInfo::AllProperties::iterator aPropertyPos = rPropInfos.find(evt.PropertyName);
615  if (aPropertyPos == rPropInfos.end())
616  { // nothing 'til now ... have to change this...
617  PropertyInfo aNewEntry;
618 
619  // the attributes
620  sal_Int32 nAttributes = xSet->getPropertySetInfo()->getPropertyByName(evt.PropertyName).Attributes;
621  aNewEntry.bIsTransientOrReadOnly = ((nAttributes & PropertyAttribute::READONLY) != 0) || ((nAttributes & PropertyAttribute::TRANSIENT) != 0);
622 
623  // check if it is the special "DataFieldProperty"
624  aNewEntry.bIsValueProperty = false;
625  try
626  {
628  {
629  Any aControlSourceProperty = xSet->getPropertyValue(FM_PROP_CONTROLSOURCEPROPERTY);
630  OUString sControlSourceProperty;
631  aControlSourceProperty >>= sControlSourceProperty;
632 
633  aNewEntry.bIsValueProperty = (sControlSourceProperty == evt.PropertyName);
634  }
635  }
636  catch(const Exception&)
637  {
639  }
640 
641  // insert the new entry
642  aPropertyPos = rPropInfos.emplace(evt.PropertyName,aNewEntry).first;
643  DBG_ASSERT(aPropertyPos != rPropInfos.end(), "FmXUndoEnvironment::propertyChange : just inserted it ... why it's not there ?");
644  }
645 
646  // now we have access to the cached info about the property affected
647  // and are able to decide whether or not we need an undo action
648 
649  bool bAddUndoAction = rModel.IsUndoEnabled();
650  // no UNDO for transient/readonly properties
651  if ( bAddUndoAction && aPropertyPos->second.bIsTransientOrReadOnly )
652  bAddUndoAction = false;
653 
654  if ( bAddUndoAction && aPropertyPos->second.bIsValueProperty )
655  {
656  // no UNDO when the "value" property changes, but the ControlSource is non-empty
657  // (in this case the control is intended to be bound to a database column)
658  if ( !aSetPos->second.bHasEmptyControlSource )
659  bAddUndoAction = false;
660 
661  // no UNDO if the control is currently bound to an external value
662  if ( bAddUndoAction )
663  {
664  Reference< XBindableValue > xBindable( evt.Source, UNO_QUERY );
665  Reference< XValueBinding > xBinding;
666  if ( xBindable.is() )
667  xBinding = xBindable->getValueBinding();
668 
669  Reference< XPropertySet > xBindingProps;
670  Reference< XPropertySetInfo > xBindingPropsPSI;
671  if ( xBindable.is() )
672  xBindingProps.set( xBinding, UNO_QUERY );
673  if ( xBindingProps.is() )
674  xBindingPropsPSI = xBindingProps->getPropertySetInfo();
675  // TODO: we should cache all those things, else this might be too expensive.
676  // However, this requires we're notified of changes in the value binding
677 
678  static constexpr OUStringLiteral s_sExternalData = u"ExternalData";
679  if ( xBindingPropsPSI.is() && xBindingPropsPSI->hasPropertyByName( s_sExternalData ) )
680  {
681  bool bExternalData = true;
682  OSL_VERIFY( xBindingProps->getPropertyValue( s_sExternalData ) >>= bExternalData );
683  bAddUndoAction = !bExternalData;
684  }
685  else
686  bAddUndoAction = !xBinding.is();
687  }
688  }
689 
690  if ( bAddUndoAction && ( evt.PropertyName == FM_PROP_STRINGITEMLIST ) )
691  {
692  Reference< XListEntrySink > xSink( evt.Source, UNO_QUERY );
693  if ( xSink.is() && xSink->getListEntrySource().is() )
694  // #i41029# / 2005-01-31 / frank.schoenheit@sun.com
695  bAddUndoAction = false;
696  }
697 
698  if ( bAddUndoAction )
699  {
700  aGuard.clear();
701  // TODO: this is a potential race condition: two threads here could in theory
702  // add their undo actions out-of-order
703 
704  SolarMutexGuard aSolarGuard;
705  rModel.AddUndo(std::make_unique<FmUndoPropertyAction>(rModel, evt));
706  }
707  }
708  else
709  {
710  // if it's the DataField property we may have to adjust our cache
711  if (m_pPropertySetCache && evt.PropertyName == FM_PROP_CONTROLSOURCE)
712  {
713  Reference< XPropertySet > xSet(evt.Source, UNO_QUERY);
714  PropertySetInfoCache* pCache = static_cast<PropertySetInfoCache*>(m_pPropertySetCache);
715  PropertySetInfo& rSetInfo = (*pCache)[xSet];
716  rSetInfo.bHasEmptyControlSource = !evt.NewValue.hasValue() || ::comphelper::getString(evt.NewValue).isEmpty();
717  }
718  }
719 }
720 
721 // XContainerListener
722 
723 void SAL_CALL FmXUndoEnvironment::elementInserted(const ContainerEvent& evt)
724 {
725  SolarMutexGuard aSolarGuard;
726  ::osl::MutexGuard aGuard( m_aMutex );
727 
728  // new object for listening
729  Reference< XInterface > xIface;
730  evt.Element >>= xIface;
731  OSL_ENSURE(xIface.is(), "FmXUndoEnvironment::elementInserted: invalid container notification!");
732  AddElement(xIface);
733 
734  implSetModified();
735 }
736 
737 
739 {
740  if ( !IsLocked() && rModel.GetObjectShell() )
741  {
743  }
744 }
745 
746 
747 void SAL_CALL FmXUndoEnvironment::elementReplaced(const ContainerEvent& evt)
748 {
749  SolarMutexGuard aSolarGuard;
750  ::osl::MutexGuard aGuard( m_aMutex );
751 
752  Reference< XInterface > xIface;
753  evt.ReplacedElement >>= xIface;
754  OSL_ENSURE(xIface.is(), "FmXUndoEnvironment::elementReplaced: invalid container notification!");
755  RemoveElement(xIface);
756 
757  evt.Element >>= xIface;
758  AddElement(xIface);
759 
760  implSetModified();
761 }
762 
763 
764 void SAL_CALL FmXUndoEnvironment::elementRemoved(const ContainerEvent& evt)
765 {
766  SolarMutexGuard aSolarGuard;
767  ::osl::MutexGuard aGuard( m_aMutex );
768 
769  Reference< XInterface > xIface( evt.Element, UNO_QUERY );
770  OSL_ENSURE(xIface.is(), "FmXUndoEnvironment::elementRemoved: invalid container notification!");
771  RemoveElement(xIface);
772 
773  implSetModified();
774 }
775 
776 
777 void SAL_CALL FmXUndoEnvironment::modified( const EventObject& /*aEvent*/ )
778 {
779  implSetModified();
780 }
781 
782 
783 void FmXUndoEnvironment::AddForms(const Reference< XNameContainer > & rForms)
784 {
785  Lock();
786  AddElement(Reference<XInterface>( rForms, UNO_QUERY ));
787  UnLock();
788 }
789 
790 
791 void FmXUndoEnvironment::RemoveForms(const Reference< XNameContainer > & rForms)
792 {
793  Lock();
794  RemoveElement(Reference<XInterface>( rForms, UNO_QUERY ));
795  UnLock();
796 }
797 
798 
799 void FmXUndoEnvironment::TogglePropertyListening(const Reference< XInterface > & Element)
800 {
801  // listen at the container
802  Reference< XIndexContainer > xContainer(Element, UNO_QUERY);
803  if (xContainer.is())
804  {
805  sal_uInt32 nCount = xContainer->getCount();
806  Reference< XInterface > xIface;
807  for (sal_uInt32 i = 0; i < nCount; i++)
808  {
809  xContainer->getByIndex(i) >>= xIface;
810  TogglePropertyListening(xIface);
811  }
812  }
813 
814  Reference< XPropertySet > xSet(Element, UNO_QUERY);
815  if (xSet.is())
816  {
817  if (!bReadOnly)
818  xSet->addPropertyChangeListener( OUString(), this );
819  else
820  xSet->removePropertyChangeListener( OUString(), this );
821  }
822 }
823 
824 
825 void FmXUndoEnvironment::switchListening( const Reference< XIndexContainer >& _rxContainer, bool _bStartListening )
826 {
827  OSL_PRECOND( _rxContainer.is(), "FmXUndoEnvironment::switchListening: invalid container!" );
828  if ( !_rxContainer.is() )
829  return;
830 
831  try
832  {
833  // if it's an EventAttacherManager, then we need to listen for
834  // script events
835  Reference< XEventAttacherManager > xManager( _rxContainer, UNO_QUERY );
836  if ( xManager.is() )
837  {
838  if ( _bStartListening )
839  {
840  m_pScriptingEnv->registerEventAttacherManager( xManager );
841  if ( m_vbaListener.is() )
842  xManager->addScriptListener( m_vbaListener );
843  }
844  else
845  {
846  m_pScriptingEnv->revokeEventAttacherManager( xManager );
847  if ( m_vbaListener.is() )
848  xManager->removeScriptListener( m_vbaListener );
849  }
850  }
851 
852  // also handle all children of this element
853  sal_uInt32 nCount = _rxContainer->getCount();
854  Reference< XInterface > xInterface;
855  for ( sal_uInt32 i = 0; i < nCount; ++i )
856  {
857  _rxContainer->getByIndex( i ) >>= xInterface;
858  if ( _bStartListening )
859  AddElement( xInterface );
860  else
861  RemoveElement( xInterface );
862  }
863 
864  // be notified of any changes in the container elements
865  Reference< XContainer > xSimpleContainer( _rxContainer, UNO_QUERY );
866  OSL_ENSURE( xSimpleContainer.is(), "FmXUndoEnvironment::switchListening: how are we expected to be notified of changes in the container?" );
867  if ( xSimpleContainer.is() )
868  {
869  if ( _bStartListening )
870  xSimpleContainer->addContainerListener( this );
871  else
872  xSimpleContainer->removeContainerListener( this );
873  }
874  }
875  catch( const Exception& )
876  {
877  TOOLS_WARN_EXCEPTION( "svx", "FmXUndoEnvironment::switchListening" );
878  }
879 }
880 
881 
882 void FmXUndoEnvironment::switchListening( const Reference< XInterface >& _rxObject, bool _bStartListening )
883 {
884  OSL_PRECOND( _rxObject.is(), "FmXUndoEnvironment::switchListening: how should I listen at a NULL object?" );
885 
886  try
887  {
888  if ( !bReadOnly )
889  {
890  Reference< XPropertySet > xProps( _rxObject, UNO_QUERY );
891  if ( xProps.is() )
892  {
893  if ( _bStartListening )
894  xProps->addPropertyChangeListener( OUString(), this );
895  else
896  xProps->removePropertyChangeListener( OUString(), this );
897  }
898  }
899 
900  Reference< XModifyBroadcaster > xBroadcaster( _rxObject, UNO_QUERY );
901  if ( xBroadcaster.is() )
902  {
903  if ( _bStartListening )
904  xBroadcaster->addModifyListener( this );
905  else
906  xBroadcaster->removeModifyListener( this );
907  }
908  }
909  catch( const Exception& )
910  {
911  TOOLS_WARN_EXCEPTION( "svx", "FmXUndoEnvironment::switchListening" );
912  }
913 }
914 
915 
916 void FmXUndoEnvironment::AddElement(const Reference< XInterface >& _rxElement )
917 {
918  OSL_ENSURE( !m_bDisposed, "FmXUndoEnvironment::AddElement: not when I'm already disposed!" );
919 
920  // listen at the container
921  Reference< XIndexContainer > xContainer( _rxElement, UNO_QUERY );
922  if ( xContainer.is() )
923  switchListening( xContainer, true );
924 
925  switchListening( _rxElement, true );
926 }
927 
928 
929 void FmXUndoEnvironment::RemoveElement(const Reference< XInterface >& _rxElement)
930 {
931  if ( m_bDisposed )
932  return;
933 
934  switchListening( _rxElement, false );
935 
936  if (!bReadOnly)
937  {
938  // reset the ActiveConnection if the form is to be removed. This will (should) free the resources
939  // associated with this connection
940  // 86299 - 05/02/2001 - frank.schoenheit@germany.sun.com
941  Reference< XForm > xForm( _rxElement, UNO_QUERY );
942  Reference< XPropertySet > xFormProperties( xForm, UNO_QUERY );
943  if ( xFormProperties.is() )
944  {
946  if ( !isEmbeddedInDatabase( _rxElement, xDummy ) )
947  // (if there is a connection in the context of the component, setting
948  // a new connection would be vetoed, anyway)
949  // #i34196#
950  xFormProperties->setPropertyValue( FM_PROP_ACTIVE_CONNECTION, Any() );
951  }
952  }
953 
954  Reference< XIndexContainer > xContainer( _rxElement, UNO_QUERY );
955  if ( xContainer.is() )
956  switchListening( xContainer, false );
957 }
958 
959 
960 FmUndoPropertyAction::FmUndoPropertyAction(FmFormModel& rNewMod, const PropertyChangeEvent& evt)
961  :SdrUndoAction(rNewMod)
962  ,xObj(evt.Source, UNO_QUERY)
963  ,aPropertyName(evt.PropertyName)
964  ,aNewValue(evt.NewValue)
965  ,aOldValue(evt.OldValue)
966 {
967  if (rNewMod.GetObjectShell())
968  rNewMod.GetObjectShell()->SetModified();
969  if(static_STR_UNDO_PROPERTY.isEmpty())
970  static_STR_UNDO_PROPERTY = SvxResId(RID_STR_UNDO_PROPERTY);
971 }
972 
973 
975 {
976  FmXUndoEnvironment& rEnv = static_cast<FmFormModel&>(rMod).GetUndoEnv();
977 
978  if (!xObj.is() || rEnv.IsLocked())
979  return;
980 
981  rEnv.Lock();
982  try
983  {
984  xObj->setPropertyValue( aPropertyName, aOldValue );
985  }
986  catch( const Exception& )
987  {
988  TOOLS_WARN_EXCEPTION( "svx", "FmUndoPropertyAction::Undo" );
989  }
990  rEnv.UnLock();
991 }
992 
993 
995 {
996  FmXUndoEnvironment& rEnv = static_cast<FmFormModel&>(rMod).GetUndoEnv();
997 
998  if (!xObj.is() || rEnv.IsLocked())
999  return;
1000 
1001  rEnv.Lock();
1002  try
1003  {
1004  xObj->setPropertyValue( aPropertyName, aNewValue );
1005  }
1006  catch( const Exception& )
1007  {
1008  TOOLS_WARN_EXCEPTION( "svx", "FmUndoPropertyAction::Redo" );
1009  }
1010  rEnv.UnLock();
1011 }
1012 
1013 
1015 {
1016  OUString aStr = static_STR_UNDO_PROPERTY.replaceFirst( "#", aPropertyName );
1017  return aStr;
1018 }
1019 
1020 
1022  Action _eAction,
1023  const Reference< XIndexContainer > & xCont,
1024  const Reference< XInterface > & xElem,
1025  sal_Int32 nIdx)
1026  :SdrUndoAction( _rMod )
1027  ,m_xContainer( xCont )
1028  ,m_nIndex( nIdx )
1029  ,m_eAction( _eAction )
1030 {
1031  OSL_ENSURE( nIdx >= 0, "FmUndoContainerAction::FmUndoContainerAction: invalid index!" );
1032  // some old code suggested this could be a valid argument. However, this code was
1033  // buggy, and it *seemed* that nobody used it - so it was removed.
1034 
1035  if ( !(xCont.is() && xElem.is()) )
1036  return;
1037 
1038  // normalize
1039  m_xElement = xElem;
1040  if ( m_eAction != Removed )
1041  return;
1042 
1043  if (m_nIndex >= 0)
1044  {
1045  Reference< XEventAttacherManager > xManager( xCont, UNO_QUERY );
1046  if ( xManager.is() )
1047  m_aEvents = xManager->getScriptEvents(m_nIndex);
1048  }
1049  else
1050  m_xElement = nullptr;
1051 
1052  // we now own the element
1054 }
1055 
1056 
1058 {
1059  // if we own the object...
1061 }
1062 
1063 
1064 void FmUndoContainerAction::DisposeElement( const Reference< XInterface > & xElem )
1065 {
1066  Reference< XComponent > xComp( xElem, UNO_QUERY );
1067  if ( xComp.is() )
1068  {
1069  // and the object does not have a parent
1070  Reference< XChild > xChild( xElem, UNO_QUERY );
1071  if ( xChild.is() && !xChild->getParent().is() )
1072  // -> dispose it
1073  xComp->dispose();
1074  }
1075 }
1076 
1077 
1079 {
1080  if ( m_xContainer->getCount() < m_nIndex )
1081  return;
1082 
1083  // insert the element
1084  Any aVal;
1085  if ( m_xContainer->getElementType() == cppu::UnoType<XFormComponent>::get() )
1086  {
1087  aVal <<= Reference< XFormComponent >( m_xElement, UNO_QUERY );
1088  }
1089  else
1090  {
1091  aVal <<= Reference< XForm >( m_xElement, UNO_QUERY );
1092  }
1093  m_xContainer->insertByIndex( m_nIndex, aVal );
1094 
1095  OSL_ENSURE( getElementPos( m_xContainer, m_xElement ) == m_nIndex, "FmUndoContainerAction::implReInsert: insertion did not work!" );
1096 
1097  // register the events
1098  Reference< XEventAttacherManager > xManager( m_xContainer, UNO_QUERY );
1099  if ( xManager.is() )
1100  xManager->registerScriptEvents( m_nIndex, m_aEvents );
1101 
1102  // we don't own the object anymore
1103  m_xOwnElement = nullptr;
1104 }
1105 
1106 
1108 {
1109  Reference< XInterface > xElement;
1110  if ( ( m_nIndex >= 0 ) && ( m_nIndex < m_xContainer->getCount() ) )
1111  m_xContainer->getByIndex( m_nIndex ) >>= xElement;
1112 
1113  if ( xElement != m_xElement )
1114  {
1115  // the indexes in the container changed. Okay, so go the long way and
1116  // manually determine the index
1118  if ( m_nIndex != -1 )
1119  xElement = m_xElement;
1120  }
1121 
1122  OSL_ENSURE( xElement == m_xElement, "FmUndoContainerAction::implReRemove: cannot find the element which I'm responsible for!" );
1123  if ( xElement == m_xElement )
1124  {
1125  Reference< XEventAttacherManager > xManager( m_xContainer, UNO_QUERY );
1126  if ( xManager.is() )
1127  m_aEvents = xManager->getScriptEvents( m_nIndex );
1128  m_xContainer->removeByIndex( m_nIndex );
1129  // from now on, we own this object
1131  }
1132 }
1133 
1134 
1136 {
1137  FmXUndoEnvironment& rEnv = static_cast< FmFormModel& >( rMod ).GetUndoEnv();
1138 
1139  if ( !(m_xContainer.is() && !rEnv.IsLocked() && m_xElement.is()) )
1140  return;
1141 
1142  rEnv.Lock();
1143  try
1144  {
1145  switch ( m_eAction )
1146  {
1147  case Inserted:
1148  implReRemove();
1149  break;
1150 
1151  case Removed:
1152  implReInsert();
1153  break;
1154  }
1155  }
1156  catch( const Exception& )
1157  {
1158  TOOLS_WARN_EXCEPTION( "svx", "FmUndoContainerAction::Undo" );
1159  }
1160  rEnv.UnLock();
1161 }
1162 
1163 
1165 {
1166  FmXUndoEnvironment& rEnv = static_cast< FmFormModel& >( rMod ).GetUndoEnv();
1167  if ( !(m_xContainer.is() && !rEnv.IsLocked() && m_xElement.is()) )
1168  return;
1169 
1170  rEnv.Lock();
1171  try
1172  {
1173  switch ( m_eAction )
1174  {
1175  case Inserted:
1176  implReInsert();
1177  break;
1178 
1179  case Removed:
1180  implReRemove();
1181  break;
1182  }
1183  }
1184  catch( const Exception& )
1185  {
1186  TOOLS_WARN_EXCEPTION( "svx", "FmUndoContainerAction::Redo" );
1187  }
1188  rEnv.UnLock();
1189 }
1190 
1191 
1192 FmUndoModelReplaceAction::FmUndoModelReplaceAction(FmFormModel& _rMod, SdrUnoObj* _pObject, const Reference< XControlModel > & _xReplaced)
1193  :SdrUndoAction(_rMod)
1194  ,m_xReplaced(_xReplaced)
1195  ,m_pObject(_pObject)
1196 {
1197 }
1198 
1199 
1201 {
1202  // dispose our element if nobody else is responsible for
1204 }
1205 
1206 
1207 void FmUndoModelReplaceAction::DisposeElement( const css::uno::Reference< css::awt::XControlModel>& xReplaced )
1208 {
1209  Reference< XComponent > xComp(xReplaced, UNO_QUERY);
1210  if (xComp.is())
1211  {
1212  Reference< XChild > xChild(xReplaced, UNO_QUERY);
1213  if (!xChild.is() || !xChild->getParent().is())
1214  xComp->dispose();
1215  }
1216 }
1217 
1218 
1220 {
1221  try
1222  {
1223  Reference< XControlModel > xCurrentModel( m_pObject->GetUnoControlModel() );
1224 
1225  // replace the model within the parent
1226  Reference< XChild > xCurrentAsChild( xCurrentModel, UNO_QUERY );
1227  Reference< XNameContainer > xCurrentsParent;
1228  if ( xCurrentAsChild.is() )
1229  xCurrentsParent.set(xCurrentAsChild->getParent(), css::uno::UNO_QUERY);
1230  DBG_ASSERT( xCurrentsParent.is(), "FmUndoModelReplaceAction::Undo: invalid current model!" );
1231 
1232  if ( xCurrentsParent.is() )
1233  {
1234  // the form container works with FormComponents
1235  Reference< XFormComponent > xComponent( m_xReplaced, UNO_QUERY );
1236  DBG_ASSERT( xComponent.is(), "FmUndoModelReplaceAction::Undo: the new model is no form component !" );
1237 
1238  Reference< XPropertySet > xCurrentAsSet( xCurrentModel, UNO_QUERY );
1239  DBG_ASSERT( ::comphelper::hasProperty(FM_PROP_NAME, xCurrentAsSet ), "FmUndoModelReplaceAction::Undo : one of the models is invalid !");
1240 
1241  OUString sName;
1242  xCurrentAsSet->getPropertyValue( FM_PROP_NAME ) >>= sName;
1243  xCurrentsParent->replaceByName( sName, Any( xComponent ) );
1244 
1246  m_pObject->SetChanged();
1247 
1248  m_xReplaced = xCurrentModel;
1249  }
1250  }
1251  catch(Exception&)
1252  {
1253  OSL_FAIL("FmUndoModelReplaceAction::Undo : could not replace the model !");
1254  }
1255 }
1256 
1257 
1259 {
1260  return SvxResId(RID_STR_UNDO_MODEL_REPLACE);
1261 }
1262 
1263 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
css::uno::Reference< css::uno::XInterface > m_xOwnElement
Definition: fmundo.hxx:93
tools::SvRef< SvBaseLink > xSink
bool is() const
void * m_pPropertySetCache
Definition: fmundo.hxx:187
constexpr OUStringLiteral FM_PROP_TIME
Definition: fmprop.hxx:58
void TogglePropertyListening(const css::uno::Reference< css::uno::XInterface > &Element)
Definition: fmundo.cxx:799
constexpr OUStringLiteral FM_PROP_DEFAULT_SELECT_SEQ
Definition: fmprop.hxx:73
SdrHintKind GetKind() const
Definition: svdmodel.hxx:132
virtual ~FmUndoContainerAction() override
Definition: fmundo.cxx:1057
css::uno::Reference< css::awt::XControlModel > m_xReplaced
Definition: fmundo.hxx:102
bool m_bDisposed
virtual void Undo() override
Definition: fmundo.cxx:974
css::uno::Reference< css::form::XForm > findPlaceInFormComponentHierarchy(const css::uno::Reference< css::form::XFormComponent > &rContent, const css::uno::Reference< css::sdbc::XDataSource > &rDatabase=css::uno::Reference< css::sdbc::XDataSource >(), const OUString &rDBTitle=OUString(), const OUString &rCursorSource=OUString(), sal_Int32 nCommandType=0)
finds a place in the form component hierarchy where to insert the given component ...
Definition: fmpgeimp.cxx:443
constexpr OUStringLiteral FM_PROP_DEFAULTCHECKED
Definition: fmprop.hxx:63
void Inserted(SdrObject *pObj)
Definition: fmundo.cxx:337
static OUString setUniqueName(const css::uno::Reference< css::form::XFormComponent > &xFormComponent, const css::uno::Reference< css::form::XForm > &xControls)
Definition: fmpgeimp.cxx:618
void Removed(SdrObject *pObj)
Definition: fmundo.cxx:446
std::map< OUString, bool > AllProperties
void switchListening(const css::uno::Reference< css::container::XIndexContainer > &_rxContainer, bool _bStartListening)
virtual void SetModified(bool bModified=true)
OUString aPropertyName
Definition: fmundo.hxx:49
virtual void Redo() override
Definition: fmundo.cxx:994
SdrUnoObj * m_pObject
Definition: fmundo.hxx:103
Abstract base class (ABC) for all UndoActions of DrawingEngine.
Definition: svdundo.hxx:60
css::uno::Reference< css::frame::XModel3 > GetModel() const
virtual OUString GetComment() const override
Definition: fmundo.cxx:1258
sal_Int32 getElementPos(const Reference< css::container::XIndexAccess > &xCont, const Reference< XInterface > &xElement)
Definition: fmtools.cxx:115
const SdrPage * GetMasterPage(sal_uInt16 nPgNum) const
Definition: svdmodel.cxx:1825
bool bReadOnly
bool IsReadOnlyUI() const
virtual SdrObjList * GetSubList() const
Definition: svdobj.cxx:738
SfxHintId GetId() const
constexpr OUStringLiteral FM_PROP_VALUE
Definition: fmprop.hxx:37
constexpr OUStringLiteral FM_PROP_DEFAULT_VALUE
Definition: fmprop.hxx:66
FmXUndoEnvironment(FmFormModel &_rModel)
Definition: fmundo.cxx:171
virtual ~FmXUndoEnvironment() override
Definition: fmundo.cxx:188
bool IsListening(SfxBroadcaster &rBroadcaster) const
constexpr OUStringLiteral FM_PROP_CONTROLSOURCEPROPERTY
Definition: fmprop.hxx:131
SdrModel & rMod
Definition: svdundo.hxx:63
FmUndoPropertyAction(FmFormModel &rMod, const css::beans::PropertyChangeEvent &evt)
Definition: fmundo.cxx:960
Reference< XNameAccess > m_xContainer
virtual OUString GetComment() const override
Definition: fmundo.cxx:1014
void RemoveElement(const css::uno::Reference< css::uno::XInterface > &Element)
Definition: fmundo.cxx:929
void AddUndo(std::unique_ptr< SdrUndoAction > pUndo)
Definition: svdmodel.cxx:502
void AddElement(const css::uno::Reference< css::uno::XInterface > &Element)
Definition: fmundo.cxx:916
int nCount
OUString SvxResId(TranslateId aId)
Definition: dialmgr.cxx:24
sal_Int32 m_nIndex
Definition: fmundo.hxx:94
static void DisposeElement(const css::uno::Reference< css::awt::XControlModel > &xReplaced)
Definition: fmundo.cxx:1207
constexpr OUStringLiteral FM_PROP_EFFECTIVE_DEFAULT
Definition: fmprop.hxx:105
FmFormPageImpl & GetImpl() const
Definition: fmpage.hxx:62
virtual void SAL_CALL elementReplaced(const css::container::ContainerEvent &rEvent) override
Definition: fmundo.cxx:747
static void DisposeElement(const css::uno::Reference< css::uno::XInterface > &xElem)
Definition: fmundo.cxx:1064
#define SAL_N_ELEMENTS(arr)
css::uno::Reference< css::uno::XInterface > m_xElement
Definition: fmundo.hxx:91
#define DBG_UNHANDLED_EXCEPTION(...)
#define TOOLS_WARN_EXCEPTION(area, stream)
sal_uInt16 GetMasterPageCount() const
Definition: svdmodel.cxx:1837
#define DBG_ASSERT(sCon, aError)
void implSetModified()
Definition: fmundo.cxx:738
int i
constexpr OUStringLiteral FM_PROP_TEXT
Definition: fmprop.hxx:41
bool IsUndoEnabled() const
returns true if undo is currently enabled This returns false if undo was disabled using EnableUndo( f...
Definition: svdmodel.cxx:533
virtual void SAL_CALL modified(const css::lang::EventObject &aEvent) override
Definition: fmundo.cxx:777
OUString sName
css::uno::Any aNewValue
Definition: fmundo.hxx:50
OBoundControlModel & m_rModel
const SdrPage * GetPage(sal_uInt16 nPgNum) const
Definition: svdmodel.cxx:1801
constexpr OUStringLiteral FM_PROP_DEFAULT_TEXT
Definition: fmprop.hxx:62
virtual void SetUnoControlModel(const css::uno::Reference< css::awt::XControlModel > &xModel)
Definition: svdouno.cxx:411
sal_Int16 nAttributes
float u
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: fmundo.cxx:288
bool IsGroupObject() const
Definition: svdobj.cxx:733
css::uno::Type const & get()
void StartListening(SfxBroadcaster &rBroadcaster, DuplicateHandling eDuplicateHanding=DuplicateHandling::Unexpected)
bool IsLocked() const
Definition: fmundo.hxx:136
FmUndoModelReplaceAction(FmFormModel &rMod, SdrUnoObj *pObject, const css::uno::Reference< css::awt::XControlModel > &xReplaced)
Definition: fmundo.cxx:1192
Abstract DrawObject.
Definition: svdobj.hxx:259
virtual void SAL_CALL propertyChange(const css::beans::PropertyChangeEvent &evt) override
Definition: fmundo.cxx:528
FmFormModel & rModel
Definition: fmundo.hxx:186
FmUndoContainerAction(FmFormModel &rMod, Action _eAction, const css::uno::Reference< css::container::XIndexContainer > &xCont, const css::uno::Reference< css::uno::XInterface > &xElem, sal_Int32 nIdx)
Definition: fmundo.cxx:1021
bool IsReadOnly() const
virtual SdrInventor GetObjInventor() const
Definition: svdobj.cxx:644
constexpr OUStringLiteral FM_PROP_DEFAULT_TIME
Definition: fmprop.hxx:65
#define ENSURE_OR_THROW(c, m)
constexpr OUStringLiteral FM_PROP_SELECT_SEQ
Definition: fmprop.hxx:71
virtual void SAL_CALL elementRemoved(const css::container::ContainerEvent &rEvent) override
Definition: fmundo.cxx:764
virtual void Undo() override
Definition: fmundo.cxx:1135
void ModeChanged()
Definition: fmundo.cxx:245
void AddForms(const css::uno::Reference< css::container::XNameContainer > &rForms)
Definition: fmundo.cxx:783
constexpr OUStringLiteral FM_PROP_EFFECTIVE_VALUE
Definition: fmprop.hxx:104
constexpr OUStringLiteral FM_PROP_STATE
Definition: fmprop.hxx:59
::rtl::Reference< svxform::FormScriptingEnvironment > m_pScriptingEnv
Definition: fmundo.hxx:188
constexpr OUStringLiteral FM_PROP_DEFAULT_DATE
Definition: fmprop.hxx:64
css::uno::Reference< css::beans::XPropertySet > xObj
Definition: fmundo.hxx:48
virtual void Undo() override
Definition: fmundo.cxx:1219
void SetObjectShell(SfxObjectShell *pShell)
Definition: fmmodel.cxx:179
OOO_DLLPUBLIC_DBTOOLS bool isEmbeddedInDatabase(const css::uno::Reference< css::uno::XInterface > &_rxComponent, css::uno::Reference< css::sdbc::XConnection > &_rxActualConnection)
constexpr OUStringLiteral FM_PROP_DATE
Definition: fmprop.hxx:57
void EndListening(SfxBroadcaster &rBroadcaster, bool bRemoveAllDuplicates=false)
css::uno::Reference< css::script::XScriptListener > m_vbaListener
Definition: fmundo.hxx:193
bool IsVirtualObj() const
Definition: svdobj.hxx:729
constexpr OUStringLiteral FM_PROP_NAME
Definition: fmprop.hxx:31
Reference< XComponentContext > getProcessComponentContext()
virtual void SAL_CALL disposing(const css::lang::EventObject &Source) override
Definition: fmundo.cxx:510
void RemoveForms(const css::uno::Reference< css::container::XNameContainer > &rForms)
Definition: fmundo.cxx:791
const css::uno::Reference< css::awt::XControlModel > & GetUnoControlModel() const
Definition: svdouno.hxx:91
bool hasProperty(const OUString &_rName, const Reference< XPropertySet > &_rxSet)
::rtl::Reference< OContentHelper > xContent
css::uno::Reference< css::container::XIndexContainer > m_xContainer
Definition: fmundo.hxx:89
Reference< XModel > xModel
class FmSearchEngine - Impl class for FmSearchDialog
constexpr OUStringLiteral FM_PROP_CONTROLSOURCE
Definition: fmprop.hxx:45
const css::uno::Reference< css::form::XForms > & GetForms(bool _bForceCreate=true) const
Definition: fmpage.cxx:86
css::uno::Any aOldValue
Definition: fmundo.hxx:51
virtual void SetChanged()
Definition: svdobj.cxx:1025
constexpr OUStringLiteral FM_PROP_STRINGITEMLIST
Definition: fmprop.hxx:61
virtual void Redo() override
Definition: fmundo.cxx:1164
SectionViewAction m_eAction
::osl::Mutex m_aMutex
Definition: fmundo.hxx:190
static OUString static_STR_UNDO_PROPERTY
Definition: fmundo.cxx:168
virtual ~FmUndoModelReplaceAction() override
Definition: fmundo.cxx:1200
aStr
std::map< Reference< XPropertySet >, PropertySetInfo > PropertySetInfoCache
Definition: fmundo.cxx:165
css::uno::Sequence< css::script::ScriptEventDescriptor > m_aEvents
Definition: fmundo.hxx:96
sal_uInt16 GetPageCount() const
Definition: svdmodel.cxx:1811
sal_uInt16 nPos
SfxObjectShell * GetObjectShell() const
Definition: fmmodel.hxx:58
bool m_bDetectedRangeSegmentation false
constexpr OUStringLiteral FM_PROP_ACTIVE_CONNECTION
Definition: fmprop.hxx:130
const SdrObject * GetObject() const
Definition: svdmodel.hxx:131
virtual void SAL_CALL elementInserted(const css::container::ContainerEvent &rEvent) override
Definition: fmundo.cxx:723