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