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