1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <sal/macros.h>
23 #include "fmpgeimp.hxx"
24 #include "svx/dbtoolsclient.hxx"
25 #include "svx/svditer.hxx"
28 #include "svx/fmresids.hrc"
29 #include "svx/fmglob.hxx"
30 #include "svx/dialmgr.hxx"
31 #include "svx/fmmodel.hxx"
32 #include "svx/fmpage.hxx"
34 #include <com/sun/star/util/XModifyBroadcaster.hpp>
35 #include <com/sun/star/beans/PropertyAttribute.hpp>
36 #include <com/sun/star/container/XContainer.hpp>
37 #include <com/sun/star/container/XContainerListener.hpp>
38 #include <com/sun/star/script/XEventAttacherManager.hpp>
39 #include <com/sun/star/form/binding/XBindableValue.hpp>
40 #include <com/sun/star/form/binding/XListEntrySink.hpp>
41 #include <com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp>
43 #include "svx/fmtools.hxx"
44 #include <rtl/logfile.hxx>
45 #include <svl/macitem.hxx>
46 #include <tools/shl.hxx>
47 #include <tools/diagnose_ex.h>
48 #include <sfx2/objsh.hxx>
49 #include <sfx2/docfile.hxx>
50 #include <sfx2/app.hxx>
51 #include <sfx2/sfx.hrc>
52 #include <sfx2/event.hxx>
53 #include <osl/mutex.hxx>
54 #include <comphelper/property.hxx>
55 #include <comphelper/uno3.hxx>
56 #include <comphelper/stl_types.hxx>
57 #include <comphelper/componentcontext.hxx>
59 using namespace ::com::sun::star::uno
;
60 using namespace ::com::sun::star::awt
;
61 using namespace ::com::sun::star::beans
;
62 using namespace ::com::sun::star::container
;
63 using namespace ::com::sun::star::script
;
64 using namespace ::com::sun::star::lang
;
65 using namespace ::com::sun::star::form
;
66 using namespace ::com::sun::star::util
;
67 using namespace ::com::sun::star::reflection
;
68 using namespace ::com::sun::star::form::binding
;
69 using namespace ::svxform
;
72 #include <com/sun/star/script/XScriptListener.hpp>
73 #include <comphelper/processfactory.hxx>
74 #include <cppuhelper/implbase1.hxx>
76 typedef cppu::WeakImplHelper1
< XScriptListener
> ScriptEventListener_BASE
;
77 class ScriptEventListenerWrapper
: public ScriptEventListener_BASE
80 ScriptEventListenerWrapper( FmFormModel
& _rModel
) throw ( RuntimeException
)
82 ,m_attemptedListenerCreation( false )
87 virtual void SAL_CALL
disposing(const EventObject
& ) throw( RuntimeException
){}
90 virtual void SAL_CALL
firing(const ScriptEvent
& evt
) throw(RuntimeException
)
92 attemptListenerCreation();
93 if ( m_vbaListener
.is() )
95 m_vbaListener
->firing( evt
);
99 virtual Any SAL_CALL
approveFiring(const ScriptEvent
& evt
) throw( com::sun::star::reflection::InvocationTargetException
, RuntimeException
)
101 attemptListenerCreation();
102 if ( m_vbaListener
.is() )
104 return m_vbaListener
->approveFiring( evt
);
110 void attemptListenerCreation()
112 if ( m_attemptedListenerCreation
)
114 m_attemptedListenerCreation
= true;
118 ::comphelper::ComponentContext
const aContext( ::comphelper::getProcessComponentContext() );
119 Reference
< XScriptListener
> const xScriptListener( aContext
.createComponent( "ooo.vba.EventListener" ), UNO_QUERY_THROW
);
120 Reference
< XPropertySet
> const xListenerProps( xScriptListener
, UNO_QUERY_THROW
);
121 // SfxObjectShellRef is good here since the model controls the lifetime of the shell
122 SfxObjectShellRef
const xObjectShell
= m_rModel
.GetObjectShell();
123 ENSURE_OR_THROW( xObjectShell
.Is(), "no object shell!" );
124 xListenerProps
->setPropertyValue( OUString( "Model" ), makeAny( xObjectShell
->GetModel() ) );
126 m_vbaListener
= xScriptListener
;
128 catch( Exception
const & )
130 DBG_UNHANDLED_EXCEPTION();
133 FmFormModel
& m_rModel
;
134 Reference
< XScriptListener
> m_vbaListener
;
135 bool m_attemptedListenerCreation
;
140 //------------------------------------------------------------------------------
141 // some helper structs for caching property infos
142 //------------------------------------------------------------------------------
145 sal_Bool bIsTransientOrReadOnly
: 1; // the property is transient or read-only, thus we need no undo action for it
146 sal_Bool bIsValueProperty
: 1; // the property is the special value property, thus it may be handled
147 // as if it's transient or persistent
150 struct PropertySetInfo
152 DECLARE_STL_USTRINGACCESS_MAP(PropertyInfo
, AllProperties
);
154 AllProperties aProps
; // all properties of this set which we know so far
155 sal_Bool bHasEmptyControlSource
; // sal_True -> the set has a DataField property, and the current value is an empty string
156 // sal_False -> the set has _no_ such property or it's value isn't empty
159 sal_Bool
operator < (const Reference
< XPropertySet
>& lhs
,
160 const Reference
< XPropertySet
>& rhs
)
162 return lhs
.get() < rhs
.get();
165 DECLARE_STL_STDKEY_MAP(Reference
< XPropertySet
>, PropertySetInfo
, PropertySetInfoCache
);
167 //------------------------------------------------------------------------------
169 String static_STR_UNDO_PROPERTY
;
170 //------------------------------------------------------------------------------
171 DBG_NAME(FmXUndoEnvironment
)
172 //------------------------------------------------------------------------------
173 FmXUndoEnvironment::FmXUndoEnvironment(FmFormModel
& _rModel
)
175 ,m_pPropertySetCache( NULL
)
176 ,m_pScriptingEnv( ::svxform::createDefaultFormScriptingEnvironment( _rModel
) )
178 ,bReadOnly( sal_False
)
179 ,m_bDisposed( false )
181 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXUndoEnvironment::FmXUndoEnvironment" );
182 DBG_CTOR(FmXUndoEnvironment
,NULL
);
185 m_vbaListener
= new ScriptEventListenerWrapper( _rModel
);
192 //------------------------------------------------------------------------------
193 FmXUndoEnvironment::~FmXUndoEnvironment()
195 DBG_DTOR(FmXUndoEnvironment
,NULL
);
196 if (m_pPropertySetCache
)
197 delete static_cast<PropertySetInfoCache
*>(m_pPropertySetCache
);
200 //------------------------------------------------------------------------------
201 void FmXUndoEnvironment::dispose()
203 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXUndoEnvironment::dispose" );
204 OSL_ENSURE( !m_bDisposed
, "FmXUndoEnvironment::dispose: disposed twice?" );
210 sal_uInt16 nCount
= rModel
.GetPageCount();
212 for (i
= 0; i
< nCount
; i
++)
214 FmFormPage
* pPage
= PTR_CAST( FmFormPage
, rModel
.GetPage(i
) );
217 Reference
< css::form::XForms
> xForms
= pPage
->GetForms( false ).get();
219 RemoveElement( xForms
);
223 nCount
= rModel
.GetMasterPageCount();
224 for (i
= 0; i
< nCount
; i
++)
226 FmFormPage
* pPage
= PTR_CAST( FmFormPage
, rModel
.GetMasterPage(i
) );
229 Reference
< css::form::XForms
> xForms
= pPage
->GetForms( false ).get();
231 RemoveElement( xForms
);
237 OSL_PRECOND( rModel
.GetObjectShell(), "FmXUndoEnvironment::dispose: no object shell anymore!" );
238 if ( rModel
.GetObjectShell() )
239 EndListening( *rModel
.GetObjectShell() );
241 if ( IsListening( rModel
) )
242 EndListening( rModel
);
244 m_pScriptingEnv
->dispose();
249 //------------------------------------------------------------------------------
250 void FmXUndoEnvironment::ModeChanged()
252 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXUndoEnvironment::ModeChanged" );
253 OSL_PRECOND( rModel
.GetObjectShell(), "FmXUndoEnvironment::ModeChanged: no object shell anymore!" );
254 if ( !rModel
.GetObjectShell() )
257 if (bReadOnly
!= (rModel
.GetObjectShell()->IsReadOnly() || rModel
.GetObjectShell()->IsReadOnlyUI()))
259 bReadOnly
= !bReadOnly
;
261 sal_uInt16 nCount
= rModel
.GetPageCount();
263 for (i
= 0; i
< nCount
; i
++)
265 FmFormPage
* pPage
= PTR_CAST( FmFormPage
, rModel
.GetPage(i
) );
268 Reference
< css::form::XForms
> xForms
= pPage
->GetForms( false ).get();
270 TogglePropertyListening( xForms
);
274 nCount
= rModel
.GetMasterPageCount();
275 for (i
= 0; i
< nCount
; i
++)
277 FmFormPage
* pPage
= PTR_CAST( FmFormPage
, rModel
.GetMasterPage(i
) );
280 Reference
< css::form::XForms
> xForms
= pPage
->GetForms( false ).get();
282 TogglePropertyListening( xForms
);
287 StartListening(rModel
);
289 EndListening(rModel
);
293 //------------------------------------------------------------------------------
294 void FmXUndoEnvironment::Notify( SfxBroadcaster
& /*rBC*/, const SfxHint
& rHint
)
296 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXUndoEnvironment::Notify" );
297 if (rHint
.ISA(SdrHint
))
299 SdrHint
* pSdrHint
= (SdrHint
*)&rHint
;
300 switch( pSdrHint
->GetKind() )
302 case HINT_OBJINSERTED
:
304 SdrObject
* pSdrObj
= (SdrObject
*)pSdrHint
->GetObject();
307 case HINT_OBJREMOVED
:
309 SdrObject
* pSdrObj
= (SdrObject
*)pSdrHint
->GetObject();
317 else if (rHint
.ISA(SfxSimpleHint
))
319 switch ( ((SfxSimpleHint
&)rHint
).GetId() )
323 rModel
.SetObjectShell( NULL
);
325 case SFX_HINT_MODECHANGED
:
330 else if (rHint
.ISA(SfxEventHint
))
332 switch (((SfxEventHint
&)rHint
).GetEventId())
334 case SFX_EVENT_CREATEDOC
:
335 case SFX_EVENT_OPENDOC
:
343 //------------------------------------------------------------------
344 void FmXUndoEnvironment::Inserted(SdrObject
* pObj
)
346 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXUndoEnvironment::Inserted" );
347 if (pObj
->GetObjInventor() == FmFormInventor
)
349 FmFormObj
* pFormObj
= PTR_CAST(FmFormObj
, pObj
);
350 Inserted( pFormObj
);
352 else if (pObj
->IsGroupObject())
354 SdrObjListIter
aIter(*pObj
->GetSubList());
355 while ( aIter
.IsMore() )
356 Inserted( aIter
.Next() );
360 //------------------------------------------------------------------------------
363 sal_Bool
lcl_searchElement(const Reference
< XIndexAccess
>& xCont
, const Reference
< XInterface
>& xElement
)
365 if (!xCont
.is() || !xElement
.is())
368 sal_Int32 nCount
= xCont
->getCount();
369 Reference
< XInterface
> xComp
;
370 for (sal_Int32 i
= 0; i
< nCount
; i
++)
374 xCont
->getByIndex(i
) >>= xComp
;
377 if ( xElement
== xComp
)
381 Reference
< XIndexAccess
> xCont2(xComp
, UNO_QUERY
);
382 if (xCont2
.is() && lcl_searchElement(xCont2
, xElement
))
387 catch(const Exception
&)
389 DBG_UNHANDLED_EXCEPTION();
396 //------------------------------------------------------------------------------
397 void FmXUndoEnvironment::Inserted(FmFormObj
* pObj
)
399 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXUndoEnvironment::Inserted" );
400 DBG_ASSERT( pObj
, "FmXUndoEnvironment::Inserted: invalid object!" );
404 // ist das Control noch einer Form zugeordnet
405 Reference
< XInterface
> xModel(pObj
->GetUnoControlModel(), UNO_QUERY
);
406 Reference
< XFormComponent
> xContent(xModel
, UNO_QUERY
);
407 if (xContent
.is() && pObj
->GetPage())
409 // if the component doesn't belong to a form, yet, find one to insert into
410 if (!xContent
->getParent().is())
414 Reference
< XIndexContainer
> xObjectParent
= pObj
->GetOriginalParent();
416 FmFormPage
& rPage
= dynamic_cast< FmFormPage
& >( *pObj
->GetPage() );
417 Reference
< XIndexAccess
> xForms( rPage
.GetForms(), UNO_QUERY_THROW
);
419 Reference
< XIndexContainer
> xNewParent
;
420 Reference
< XForm
> xForm
;
422 if ( lcl_searchElement( xForms
, xObjectParent
) )
424 // the form which was the parent of the object when it was removed is still
425 // part of the form component hierachy of the current page
426 xNewParent
= xObjectParent
;
427 xForm
.set( xNewParent
, UNO_QUERY_THROW
);
428 nPos
= ::std::min( pObj
->GetOriginalIndex(), xNewParent
->getCount() );
432 xForm
.set( rPage
.GetImpl().findPlaceInFormComponentHierarchy( xContent
), UNO_SET_THROW
);
433 xNewParent
.set( xForm
, UNO_QUERY_THROW
);
434 nPos
= xNewParent
->getCount();
437 rPage
.GetImpl().setUniqueName( xContent
, xForm
);
438 xNewParent
->insertByIndex( nPos
, makeAny( xContent
) );
440 Reference
< XEventAttacherManager
> xManager( xNewParent
, UNO_QUERY_THROW
);
441 xManager
->registerScriptEvents( nPos
, pObj
->GetOriginalEvents() );
443 catch( const Exception
& )
445 DBG_UNHANDLED_EXCEPTION();
449 // FormObject zuruecksetzen
454 //------------------------------------------------------------------
455 void FmXUndoEnvironment::Removed(SdrObject
* pObj
)
457 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXUndoEnvironment::Removed" );
458 if ( pObj
->IsVirtualObj() )
459 // for virtual objects, we've already been notified of the removal of the master
460 // object, which is sufficient here
463 if (pObj
->GetObjInventor() == FmFormInventor
)
465 FmFormObj
* pFormObj
= PTR_CAST(FmFormObj
, pObj
);
468 else if (pObj
->IsGroupObject())
470 SdrObjListIter
aIter(*pObj
->GetSubList());
471 while ( aIter
.IsMore() )
472 Removed( aIter
.Next() );
476 //------------------------------------------------------------------------------
477 void FmXUndoEnvironment::Removed(FmFormObj
* pObj
)
479 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXUndoEnvironment::Removed" );
480 DBG_ASSERT( pObj
, "FmXUndoEnvironment::Removed: invalid object!" );
484 // ist das Control noch einer Form zugeordnet
485 Reference
< XFormComponent
> xContent(pObj
->GetUnoControlModel(), UNO_QUERY
);
488 // das Object wird aus einer Liste herausgenommen
489 // existiert ein Vater wird das Object beim beim Vater entfernt und
490 // am FormObject gemerkt!
492 // wird das Object wieder eingefuegt und ein Parent existiert, so wird dieser
493 // Parent wiederum gesetzt
494 Reference
< XIndexContainer
> xForm(xContent
->getParent(), UNO_QUERY
);
497 Reference
< XIndexAccess
> xIndexAccess((XIndexContainer
*)xForm
.get());
498 // Feststellen an welcher Position sich das Kind befunden hat
499 const sal_Int32 nPos
= getElementPos(xIndexAccess
, xContent
);
502 Sequence
< ScriptEventDescriptor
> aEvts
;
503 Reference
< XEventAttacherManager
> xManager(xForm
, UNO_QUERY
);
505 aEvts
= xManager
->getScriptEvents(nPos
);
509 pObj
->SetObjEnv(xForm
, nPos
, aEvts
);
510 xForm
->removeByIndex(nPos
);
514 DBG_UNHANDLED_EXCEPTION();
523 //------------------------------------------------------------------------------
524 void SAL_CALL
FmXUndoEnvironment::disposing(const EventObject
& e
) throw( RuntimeException
)
526 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXUndoEnvironment::disposing" );
527 // check if it's an object we have cached information about
528 if (m_pPropertySetCache
)
530 Reference
< XPropertySet
> xSourceSet(e
.Source
, UNO_QUERY
);
533 PropertySetInfoCache
* pCache
= static_cast<PropertySetInfoCache
*>(m_pPropertySetCache
);
534 PropertySetInfoCacheIterator aSetPos
= pCache
->find(xSourceSet
);
535 if (aSetPos
!= pCache
->end())
536 pCache
->erase(aSetPos
);
541 // XPropertyChangeListener
542 //------------------------------------------------------------------------------
543 void SAL_CALL
FmXUndoEnvironment::propertyChange(const PropertyChangeEvent
& evt
) throw(::com::sun::star::uno::RuntimeException
)
545 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXUndoEnvironment::propertyChange" );
546 ::osl::ClearableMutexGuard
aGuard( m_aMutex
);
550 Reference
< XPropertySet
> xSet(evt
.Source
, UNO_QUERY
);
554 // if it's a "default value" property of a control model, set the according "value" property
555 static OUString pDefaultValueProperties
[] = {
556 OUString(FM_PROP_DEFAULT_TEXT
), OUString(FM_PROP_DEFAULTCHECKED
), OUString(FM_PROP_DEFAULT_DATE
), OUString(FM_PROP_DEFAULT_TIME
),
557 OUString(FM_PROP_DEFAULT_VALUE
), OUString(FM_PROP_DEFAULT_SELECT_SEQ
), OUString(FM_PROP_EFFECTIVE_DEFAULT
)
559 const OUString aValueProperties
[] = {
560 OUString(FM_PROP_TEXT
), OUString(FM_PROP_STATE
), OUString(FM_PROP_DATE
), OUString(FM_PROP_TIME
),
561 OUString(FM_PROP_VALUE
), OUString(FM_PROP_SELECT_SEQ
), OUString(FM_PROP_EFFECTIVE_VALUE
)
563 sal_Int32 nDefaultValueProps
= sizeof(pDefaultValueProperties
)/sizeof(pDefaultValueProperties
[0]);
564 OSL_ENSURE(sizeof(aValueProperties
)/sizeof(aValueProperties
[0]) == nDefaultValueProps
,
565 "FmXUndoEnvironment::propertyChange: inconsistence!");
566 for (sal_Int32 i
=0; i
<nDefaultValueProps
; ++i
)
568 if (evt
.PropertyName
== pDefaultValueProperties
[i
])
572 xSet
->setPropertyValue(aValueProperties
[i
], evt
.NewValue
);
574 catch(const Exception
&)
576 OSL_FAIL("FmXUndoEnvironment::propertyChange: could not adjust the value property!");
581 // no Undo for transient and readonly props. But unfortunately "transient" is not only that the
582 // "transient" flag is set for the property in question, instead is is somewhat more complex
583 // Transience criterions are:
584 // - the "transient" flag is set for the property
585 // - OR the control has a non-empty COntrolSource property, i.e. is intended to be bound
586 // to a database column. Note that it doesn't matter here whether the control actually
587 // *is* bound to a column
588 // - OR the control is bound to an external value via XBindableValue/XValueBinding
589 // which does not have a "ExternalData" property being <TRUE/>
591 if (!m_pPropertySetCache
)
592 m_pPropertySetCache
= new PropertySetInfoCache
;
593 PropertySetInfoCache
* pCache
= static_cast<PropertySetInfoCache
*>(m_pPropertySetCache
);
595 // let's see if we know something about the set
596 PropertySetInfoCacheIterator aSetPos
= pCache
->find(xSet
);
597 if (aSetPos
== pCache
->end())
599 PropertySetInfo aNewEntry
;
600 if (!::comphelper::hasProperty(FM_PROP_CONTROLSOURCE
, xSet
))
602 aNewEntry
.bHasEmptyControlSource
= sal_False
;
608 Any aCurrentControlSource
= xSet
->getPropertyValue(FM_PROP_CONTROLSOURCE
);
609 aNewEntry
.bHasEmptyControlSource
= !aCurrentControlSource
.hasValue() || ::comphelper::getString(aCurrentControlSource
).isEmpty();
611 catch(const Exception
&)
613 DBG_UNHANDLED_EXCEPTION();
616 aSetPos
= pCache
->insert(PropertySetInfoCache::value_type(xSet
,aNewEntry
)).first
;
617 DBG_ASSERT(aSetPos
!= pCache
->end(), "FmXUndoEnvironment::propertyChange : just inserted it ... why it's not there ?");
620 { // is it the DataField property ?
621 if (evt
.PropertyName
.equals(FM_PROP_CONTROLSOURCE
))
623 aSetPos
->second
.bHasEmptyControlSource
= !evt
.NewValue
.hasValue() || ::comphelper::getString(evt
.NewValue
).isEmpty();
627 // now we have access to the cached info about the set
628 // let's see what we know about the property
629 PropertySetInfo::AllProperties
& rPropInfos
= aSetPos
->second
.aProps
;
630 PropertySetInfo::AllPropertiesIterator aPropertyPos
= rPropInfos
.find(evt
.PropertyName
);
631 if (aPropertyPos
== rPropInfos
.end())
632 { // nothing 'til now ... have to change this ....
633 PropertyInfo aNewEntry
;
636 sal_Int32 nAttributes
= xSet
->getPropertySetInfo()->getPropertyByName(evt
.PropertyName
).Attributes
;
637 aNewEntry
.bIsTransientOrReadOnly
= ((nAttributes
& PropertyAttribute::READONLY
) != 0) || ((nAttributes
& PropertyAttribute::TRANSIENT
) != 0);
639 // check if it is the special "DataFieldProperty"
640 aNewEntry
.bIsValueProperty
= sal_False
;
643 if (::comphelper::hasProperty(FM_PROP_CONTROLSOURCEPROPERTY
, xSet
))
645 Any aControlSourceProperty
= xSet
->getPropertyValue(FM_PROP_CONTROLSOURCEPROPERTY
);
646 OUString sControlSourceProperty
;
647 aControlSourceProperty
>>= sControlSourceProperty
;
649 aNewEntry
.bIsValueProperty
= (sControlSourceProperty
.equals(evt
.PropertyName
));
652 catch(const Exception
&)
654 DBG_UNHANDLED_EXCEPTION();
657 // insert the new entry
658 aPropertyPos
= rPropInfos
.insert(PropertySetInfo::AllProperties::value_type(evt
.PropertyName
,aNewEntry
)).first
;
659 DBG_ASSERT(aPropertyPos
!= rPropInfos
.end(), "FmXUndoEnvironment::propertyChange : just inserted it ... why it's not there ?");
662 // now we have access to the cached info about the property affected
663 // and are able to decide whether or not we need an undo action
665 bool bAddUndoAction
= rModel
.IsUndoEnabled();
666 // no UNDO for transient/readonly properties
667 if ( bAddUndoAction
&& aPropertyPos
->second
.bIsTransientOrReadOnly
)
668 bAddUndoAction
= false;
670 if ( bAddUndoAction
&& aPropertyPos
->second
.bIsValueProperty
)
672 // no UNDO when the "value" property changes, but the ControlSource is non-empty
673 // (in this case the control is intended to be bound to a database column)
674 if ( !aSetPos
->second
.bHasEmptyControlSource
)
675 bAddUndoAction
= false;
677 // no UNDO if the control is currently bound to an external value
678 if ( bAddUndoAction
)
680 Reference
< XBindableValue
> xBindable( evt
.Source
, UNO_QUERY
);
681 Reference
< XValueBinding
> xBinding
;
682 if ( xBindable
.is() )
683 xBinding
= xBindable
->getValueBinding();
685 Reference
< XPropertySet
> xBindingProps
;
686 Reference
< XPropertySetInfo
> xBindingPropsPSI
;
687 if ( xBindable
.is() )
688 xBindingProps
.set( xBinding
, UNO_QUERY
);
689 if ( xBindingProps
.is() )
690 xBindingPropsPSI
= xBindingProps
->getPropertySetInfo();
691 // TODO: we should cache all those things, else this might be too expensive.
692 // However, this requires we're notified of changes in the value binding
694 static const OUString
s_sExternalData( "ExternalData" );
695 if ( xBindingPropsPSI
.is() && xBindingPropsPSI
->hasPropertyByName( s_sExternalData
) )
697 sal_Bool bExternalData
= sal_True
;
698 OSL_VERIFY( xBindingProps
->getPropertyValue( s_sExternalData
) >>= bExternalData
);
699 bAddUndoAction
= !bExternalData
;
702 bAddUndoAction
= !xBinding
.is();
706 if ( bAddUndoAction
&& ( evt
.PropertyName
== FM_PROP_STRINGITEMLIST
) )
708 Reference
< XListEntrySink
> xSink( evt
.Source
, UNO_QUERY
);
709 if ( xSink
.is() && xSink
->getListEntrySource().is() )
710 // #i41029# / 2005-01-31 / frank.schoenheit@sun.com
711 bAddUndoAction
= false;
714 if ( bAddUndoAction
)
717 // TODO: this is a potential race condition: two threads here could in theory
718 // add their undo actions out-of-order
720 SolarMutexGuard aSolarGuard
;
721 rModel
.AddUndo(new FmUndoPropertyAction(rModel
, evt
));
726 // if it's the DataField property we may have to adjust our cache
727 if (m_pPropertySetCache
&& evt
.PropertyName
.equals(FM_PROP_CONTROLSOURCE
))
729 Reference
< XPropertySet
> xSet(evt
.Source
, UNO_QUERY
);
730 PropertySetInfoCache
* pCache
= static_cast<PropertySetInfoCache
*>(m_pPropertySetCache
);
731 PropertySetInfo
& rSetInfo
= (*pCache
)[xSet
];
732 rSetInfo
.bHasEmptyControlSource
= !evt
.NewValue
.hasValue() || ::comphelper::getString(evt
.NewValue
).isEmpty();
737 // XContainerListener
738 //------------------------------------------------------------------------------
739 void SAL_CALL
FmXUndoEnvironment::elementInserted(const ContainerEvent
& evt
) throw(::com::sun::star::uno::RuntimeException
)
741 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXUndoEnvironment::elementInserted" );
742 SolarMutexGuard aSolarGuard
;
743 ::osl::MutexGuard
aGuard( m_aMutex
);
745 // neues Object zum lauschen
746 Reference
< XInterface
> xIface
;
747 evt
.Element
>>= xIface
;
748 OSL_ENSURE(xIface
.is(), "FmXUndoEnvironment::elementInserted: invalid container notification!");
754 //------------------------------------------------------------------------------
755 void FmXUndoEnvironment::implSetModified()
757 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXUndoEnvironment::implSetModified" );
758 if ( !IsLocked() && rModel
.GetObjectShell() )
760 rModel
.GetObjectShell()->SetModified( sal_True
);
764 //------------------------------------------------------------------------------
765 void SAL_CALL
FmXUndoEnvironment::elementReplaced(const ContainerEvent
& evt
) throw(::com::sun::star::uno::RuntimeException
)
767 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXUndoEnvironment::elementReplaced" );
768 SolarMutexGuard aSolarGuard
;
769 ::osl::MutexGuard
aGuard( m_aMutex
);
771 Reference
< XInterface
> xIface
;
772 evt
.ReplacedElement
>>= xIface
;
773 OSL_ENSURE(xIface
.is(), "FmXUndoEnvironment::elementReplaced: invalid container notification!");
774 RemoveElement(xIface
);
776 evt
.Element
>>= xIface
;
782 //------------------------------------------------------------------------------
783 void SAL_CALL
FmXUndoEnvironment::elementRemoved(const ContainerEvent
& evt
) throw(::com::sun::star::uno::RuntimeException
)
785 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXUndoEnvironment::elementRemoved" );
786 SolarMutexGuard aSolarGuard
;
787 ::osl::MutexGuard
aGuard( m_aMutex
);
789 Reference
< XInterface
> xIface( evt
.Element
, UNO_QUERY
);
790 OSL_ENSURE(xIface
.is(), "FmXUndoEnvironment::elementRemoved: invalid container notification!");
791 RemoveElement(xIface
);
796 //------------------------------------------------------------------------------
797 void SAL_CALL
FmXUndoEnvironment::modified( const EventObject
& /*aEvent*/ ) throw (RuntimeException
)
799 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXUndoEnvironment::modified" );
803 //------------------------------------------------------------------------------
804 void FmXUndoEnvironment::AddForms(const Reference
< XNameContainer
> & rForms
)
806 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXUndoEnvironment::AddForms" );
808 Reference
< XInterface
> xInt(rForms
, UNO_QUERY
);
813 //------------------------------------------------------------------------------
814 void FmXUndoEnvironment::RemoveForms(const Reference
< XNameContainer
> & rForms
)
816 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXUndoEnvironment::RemoveForms" );
818 Reference
< XInterface
> xInt(rForms
, UNO_QUERY
);
823 //------------------------------------------------------------------------------
824 void FmXUndoEnvironment::TogglePropertyListening(const Reference
< XInterface
> & Element
)
826 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXUndoEnvironment::TogglePropertyListening" );
827 // am Container horchen
828 Reference
< XIndexContainer
> xContainer(Element
, UNO_QUERY
);
831 sal_uInt32 nCount
= xContainer
->getCount();
832 Reference
< XInterface
> xIface
;
833 for (sal_uInt32 i
= 0; i
< nCount
; i
++)
835 xContainer
->getByIndex(i
) >>= xIface
;
836 TogglePropertyListening(xIface
);
840 Reference
< XPropertySet
> xSet(Element
, UNO_QUERY
);
844 xSet
->addPropertyChangeListener( OUString(), this );
846 xSet
->removePropertyChangeListener( OUString(), this );
851 //------------------------------------------------------------------------------
852 void FmXUndoEnvironment::switchListening( const Reference
< XIndexContainer
>& _rxContainer
, bool _bStartListening
) SAL_THROW(())
854 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXUndoEnvironment::switchListening" );
855 OSL_PRECOND( _rxContainer
.is(), "FmXUndoEnvironment::switchListening: invalid container!" );
856 if ( !_rxContainer
.is() )
861 // if it's an EventAttacherManager, then we need to listen for
863 Reference
< XEventAttacherManager
> xManager( _rxContainer
, UNO_QUERY
);
866 if ( _bStartListening
)
868 m_pScriptingEnv
->registerEventAttacherManager( xManager
);
869 if ( m_vbaListener
.is() )
870 xManager
->addScriptListener( m_vbaListener
);
874 m_pScriptingEnv
->revokeEventAttacherManager( xManager
);
875 if ( m_vbaListener
.is() )
876 xManager
->removeScriptListener( m_vbaListener
);
880 // also handle all children of this element
881 sal_uInt32 nCount
= _rxContainer
->getCount();
882 Reference
< XInterface
> xInterface
;
883 for ( sal_uInt32 i
= 0; i
< nCount
; ++i
)
885 _rxContainer
->getByIndex( i
) >>= xInterface
;
886 if ( _bStartListening
)
887 AddElement( xInterface
);
889 RemoveElement( xInterface
);
892 // be notified of any changes in the container elements
893 Reference
< XContainer
> xSimpleContainer( _rxContainer
, UNO_QUERY
);
894 OSL_ENSURE( xSimpleContainer
.is(), "FmXUndoEnvironment::switchListening: how are we expected to be notified of changes in the container?" );
895 if ( xSimpleContainer
.is() )
897 if ( _bStartListening
)
898 xSimpleContainer
->addContainerListener( this );
900 xSimpleContainer
->removeContainerListener( this );
903 catch( const Exception
& )
905 OSL_FAIL( "FmXUndoEnvironment::switchListening: caught an exception!" );
909 //------------------------------------------------------------------------------
910 void FmXUndoEnvironment::switchListening( const Reference
< XInterface
>& _rxObject
, bool _bStartListening
) SAL_THROW(())
912 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXUndoEnvironment::switchListening" );
913 OSL_PRECOND( _rxObject
.is(), "FmXUndoEnvironment::switchListening: how should I listen at a NULL object?" );
919 Reference
< XPropertySet
> xProps( _rxObject
, UNO_QUERY
);
922 if ( _bStartListening
)
923 xProps
->addPropertyChangeListener( OUString(), this );
925 xProps
->removePropertyChangeListener( OUString(), this );
929 Reference
< XModifyBroadcaster
> xBroadcaster( _rxObject
, UNO_QUERY
);
930 if ( xBroadcaster
.is() )
932 if ( _bStartListening
)
933 xBroadcaster
->addModifyListener( this );
935 xBroadcaster
->removeModifyListener( this );
938 catch( const Exception
& )
940 OSL_FAIL( "FmXUndoEnvironment::switchListening: caught an exception!" );
944 //------------------------------------------------------------------------------
945 void FmXUndoEnvironment::AddElement(const Reference
< XInterface
>& _rxElement
)
947 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXUndoEnvironment::AddElement" );
948 OSL_ENSURE( !m_bDisposed
, "FmXUndoEnvironment::AddElement: not when I'm already disposed!" );
950 // am Container horchen
951 Reference
< XIndexContainer
> xContainer( _rxElement
, UNO_QUERY
);
952 if ( xContainer
.is() )
953 switchListening( xContainer
, true );
955 switchListening( _rxElement
, true );
958 //------------------------------------------------------------------------------
959 void FmXUndoEnvironment::RemoveElement(const Reference
< XInterface
>& _rxElement
)
961 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXUndoEnvironment::RemoveElement" );
965 switchListening( _rxElement
, false );
969 // reset the ActiveConnection if the form is to be removed. This will (should) free the resources
970 // associated with this connection
971 // 86299 - 05/02/2001 - frank.schoenheit@germany.sun.com
972 Reference
< XForm
> xForm( _rxElement
, UNO_QUERY
);
973 Reference
< XPropertySet
> xFormProperties( xForm
, UNO_QUERY
);
974 if ( xFormProperties
.is() )
975 if ( !::svxform::OStaticDataAccessTools().isEmbeddedInDatabase( _rxElement
) )
976 // (if there is a connection in the context of the component, setting
977 // a new connection would be vetoed, anyway)
979 xFormProperties
->setPropertyValue( FM_PROP_ACTIVE_CONNECTION
, Any() );
982 Reference
< XIndexContainer
> xContainer( _rxElement
, UNO_QUERY
);
983 if ( xContainer
.is() )
984 switchListening( xContainer
, false );
988 //------------------------------------------------------------------------------
989 FmUndoPropertyAction::FmUndoPropertyAction(FmFormModel
& rNewMod
, const PropertyChangeEvent
& evt
)
990 :SdrUndoAction(rNewMod
)
991 ,xObj(evt
.Source
, UNO_QUERY
)
992 ,aPropertyName(evt
.PropertyName
)
993 ,aNewValue(evt
.NewValue
)
994 ,aOldValue(evt
.OldValue
)
996 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmUndoPropertyAction::FmUndoPropertyAction" );
997 if (rNewMod
.GetObjectShell())
998 rNewMod
.GetObjectShell()->SetModified(sal_True
);
999 if(static_STR_UNDO_PROPERTY
.Len() == 0)
1000 static_STR_UNDO_PROPERTY
= SVX_RESSTR(RID_STR_UNDO_PROPERTY
);
1004 //------------------------------------------------------------------------------
1005 void FmUndoPropertyAction::Undo()
1007 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmUndoPropertyAction::Undo" );
1008 FmXUndoEnvironment
& rEnv
= ((FmFormModel
&)rMod
).GetUndoEnv();
1010 if (xObj
.is() && !rEnv
.IsLocked())
1015 xObj
->setPropertyValue( aPropertyName
, aOldValue
);
1017 catch( const Exception
& )
1019 OSL_FAIL( "FmUndoPropertyAction::Undo: caught an exception!" );
1025 //------------------------------------------------------------------------------
1026 void FmUndoPropertyAction::Redo()
1028 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmUndoPropertyAction::Redo" );
1029 FmXUndoEnvironment
& rEnv
= ((FmFormModel
&)rMod
).GetUndoEnv();
1031 if (xObj
.is() && !rEnv
.IsLocked())
1036 xObj
->setPropertyValue( aPropertyName
, aNewValue
);
1038 catch( const Exception
& )
1040 OSL_FAIL( "FmUndoPropertyAction::Redo: caught an exception!" );
1046 //------------------------------------------------------------------------------
1047 OUString
FmUndoPropertyAction::GetComment() const
1049 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmUndoPropertyAction::GetComment" );
1050 String
aStr(static_STR_UNDO_PROPERTY
);
1052 aStr
.SearchAndReplace( OUString('#'), aPropertyName
);
1057 DBG_NAME(FmUndoContainerAction
);
1058 //------------------------------------------------------------------------------
1059 FmUndoContainerAction::FmUndoContainerAction(FmFormModel
& _rMod
,
1061 const Reference
< XIndexContainer
> & xCont
,
1062 const Reference
< XInterface
> & xElem
,
1064 :SdrUndoAction( _rMod
)
1065 ,m_xContainer( xCont
)
1067 ,m_eAction( _eAction
)
1069 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmUndoContainerAction::FmUndoContainerAction" );
1070 OSL_ENSURE( nIdx
>= 0, "FmUndoContainerAction::FmUndoContainerAction: invalid index!" );
1071 // some old code suggested this could be a valid argument. However, this code was
1072 // buggy, and it *seemed* that nobody used it - so it was removed.
1074 DBG_CTOR(FmUndoContainerAction
,NULL
);
1075 if ( xCont
.is() && xElem
.is() )
1078 m_xElement
= m_xElement
.query( xElem
);
1079 if ( m_eAction
== Removed
)
1083 Reference
< XEventAttacherManager
> xManager( xCont
, UNO_QUERY
);
1084 if ( xManager
.is() )
1085 m_aEvents
= xManager
->getScriptEvents(m_nIndex
);
1090 // we now own the element
1091 m_xOwnElement
= m_xElement
;
1096 //------------------------------------------------------------------------------
1097 FmUndoContainerAction::~FmUndoContainerAction()
1099 // if we own the object ....
1100 DisposeElement( m_xOwnElement
);
1101 DBG_DTOR(FmUndoContainerAction
,NULL
);
1104 //------------------------------------------------------------------------------
1106 void FmUndoContainerAction::DisposeElement( const Reference
< XInterface
> & xElem
)
1108 Reference
< XComponent
> xComp( xElem
, UNO_QUERY
);
1111 // and the object does not have a parent
1112 Reference
< XChild
> xChild( xElem
, UNO_QUERY
);
1113 if ( xChild
.is() && !xChild
->getParent().is() )
1119 //------------------------------------------------------------------------------
1120 void FmUndoContainerAction::implReInsert( ) SAL_THROW( ( Exception
) )
1122 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmUndoContainerAction::implReInsert" );
1123 if ( m_xContainer
->getCount() >= m_nIndex
)
1125 // insert the element
1127 if ( m_xContainer
->getElementType() == ::getCppuType( static_cast< const Reference
< XFormComponent
>* >( NULL
) ) )
1129 aVal
<<= Reference
< XFormComponent
>( m_xElement
, UNO_QUERY
);
1133 aVal
<<= Reference
< XForm
>( m_xElement
, UNO_QUERY
);
1135 m_xContainer
->insertByIndex( m_nIndex
, aVal
);
1137 OSL_ENSURE( getElementPos( m_xContainer
.get(), m_xElement
) == m_nIndex
, "FmUndoContainerAction::implReInsert: insertion did not work!" );
1139 // register the events
1140 Reference
< XEventAttacherManager
> xManager( m_xContainer
, UNO_QUERY
);
1141 if ( xManager
.is() )
1142 xManager
->registerScriptEvents( m_nIndex
, m_aEvents
);
1144 // we don't own the object anymore
1145 m_xOwnElement
= NULL
;
1149 //------------------------------------------------------------------------------
1150 void FmUndoContainerAction::implReRemove( ) SAL_THROW( ( Exception
) )
1152 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmUndoContainerAction::implReRemove" );
1153 Reference
< XInterface
> xElement
;
1154 if ( ( m_nIndex
>= 0 ) && ( m_nIndex
< m_xContainer
->getCount() ) )
1155 m_xContainer
->getByIndex( m_nIndex
) >>= xElement
;
1157 if ( xElement
!= m_xElement
)
1159 // the indexes in the container changed. Okay, so go the long way and
1160 // manually determine the index
1161 m_nIndex
= getElementPos( m_xContainer
.get(), m_xElement
);
1162 if ( m_nIndex
!= -1 )
1163 xElement
= m_xElement
;
1166 OSL_ENSURE( xElement
== m_xElement
, "FmUndoContainerAction::implReRemove: cannot find the element which I'm responsible for!" );
1167 if ( xElement
== m_xElement
)
1169 Reference
< XEventAttacherManager
> xManager( m_xContainer
, UNO_QUERY
);
1170 if ( xManager
.is() )
1171 m_aEvents
= xManager
->getScriptEvents( m_nIndex
);
1172 m_xContainer
->removeByIndex( m_nIndex
);
1173 // from now on, we own this object
1174 m_xOwnElement
= m_xElement
;
1178 //------------------------------------------------------------------------------
1179 void FmUndoContainerAction::Undo()
1181 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmUndoContainerAction::Undo" );
1182 FmXUndoEnvironment
& rEnv
= static_cast< FmFormModel
& >( rMod
).GetUndoEnv();
1184 if ( m_xContainer
.is() && !rEnv
.IsLocked() && m_xElement
.is() )
1189 switch ( m_eAction
)
1200 catch( const Exception
& )
1202 OSL_FAIL( "FmUndoContainerAction::Undo: caught an exception!" );
1208 //------------------------------------------------------------------------------
1209 void FmUndoContainerAction::Redo()
1211 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmUndoContainerAction::Redo" );
1212 FmXUndoEnvironment
& rEnv
= static_cast< FmFormModel
& >( rMod
).GetUndoEnv();
1213 if ( m_xContainer
.is() && !rEnv
.IsLocked() && m_xElement
.is() )
1218 switch ( m_eAction
)
1229 catch( const Exception
& )
1231 OSL_FAIL( "FmUndoContainerAction::Redo: caught an exception!" );
1237 //------------------------------------------------------------------------------
1238 FmUndoModelReplaceAction::FmUndoModelReplaceAction(FmFormModel
& _rMod
, SdrUnoObj
* _pObject
, const Reference
< XControlModel
> & _xReplaced
)
1239 :SdrUndoAction(_rMod
)
1240 ,m_xReplaced(_xReplaced
)
1241 ,m_pObject(_pObject
)
1243 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmUndoModelReplaceAction::FmUndoModelReplaceAction" );
1246 //------------------------------------------------------------------------------
1247 FmUndoModelReplaceAction::~FmUndoModelReplaceAction()
1249 // dispose our element if nobody else is responsible for
1250 DisposeElement(m_xReplaced
);
1253 //------------------------------------------------------------------------------
1255 void FmUndoModelReplaceAction::DisposeElement( const ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
>& xReplaced
)
1257 Reference
< XComponent
> xComp(xReplaced
, UNO_QUERY
);
1260 Reference
< XChild
> xChild(xReplaced
, UNO_QUERY
);
1261 if (!xChild
.is() || !xChild
->getParent().is())
1266 //------------------------------------------------------------------------------
1267 void FmUndoModelReplaceAction::Undo()
1269 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmUndoModelReplaceAction::Undo" );
1272 Reference
< XControlModel
> xCurrentModel( m_pObject
->GetUnoControlModel() );
1274 // replace the model within the parent
1275 Reference
< XChild
> xCurrentAsChild( xCurrentModel
, UNO_QUERY
);
1276 Reference
< XNameContainer
> xCurrentsParent
;
1277 if ( xCurrentAsChild
.is() )
1278 xCurrentsParent
= xCurrentsParent
.query( xCurrentAsChild
->getParent() );
1279 DBG_ASSERT( xCurrentsParent
.is(), "FmUndoModelReplaceAction::Undo: invalid current model!" );
1281 if ( xCurrentsParent
.is() )
1283 // the form container works with FormComponents
1284 Reference
< XFormComponent
> xComponent( m_xReplaced
, UNO_QUERY
);
1285 DBG_ASSERT( xComponent
.is(), "FmUndoModelReplaceAction::Undo: the new model is no form component !" );
1287 Reference
< XPropertySet
> xCurrentAsSet( xCurrentModel
, UNO_QUERY
);
1288 DBG_ASSERT( ::comphelper::hasProperty(FM_PROP_NAME
, xCurrentAsSet
), "FmUndoModelReplaceAction::Undo : one of the models is invalid !");
1291 xCurrentAsSet
->getPropertyValue( FM_PROP_NAME
) >>= sName
;
1292 xCurrentsParent
->replaceByName( sName
, makeAny( xComponent
) );
1294 m_pObject
->SetUnoControlModel(m_xReplaced
);
1295 m_pObject
->SetChanged();
1297 m_xReplaced
= xCurrentModel
;
1302 OSL_FAIL("FmUndoModelReplaceAction::Undo : could not replace the model !");
1306 //------------------------------------------------------------------------------
1307 OUString
FmUndoModelReplaceAction::GetComment() const
1309 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmUndoModelReplaceAction::GetComment" );
1310 return SVX_RESSTR(RID_STR_UNDO_MODEL_REPLACE
);
1313 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */