xref: /AOO41X/main/reportdesign/source/core/sdr/UndoActions.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 #include "precompiled_reportdesign.hxx"
28 
29 #include "UndoActions.hxx"
30 #include "UndoEnv.hxx"
31 #include "formatnormalizer.hxx"
32 #include "conditionupdater.hxx"
33 #include "corestrings.hrc"
34 #include "rptui_slotid.hrc"
35 #include "RptDef.hxx"
36 #include "ModuleHelper.hxx"
37 #include "RptObject.hxx"
38 #include "RptPage.hxx"
39 #include "RptResId.hrc"
40 #include "RptModel.hxx"
41 
42 /** === begin UNO includes === **/
43 #include <com/sun/star/script/XEventAttacherManager.hpp>
44 #include <com/sun/star/container/XChild.hpp>
45 #include <com/sun/star/container/XNameContainer.hpp>
46 #include <com/sun/star/beans/PropertyAttribute.hpp>
47 #include <com/sun/star/util/XModifyBroadcaster.hpp>
48 /** === end UNO includes === **/
49 
50 #include <connectivity/dbtools.hxx>
51 #include <svl/smplhint.hxx>
52 #include <tools/diagnose_ex.h>
53 #include <comphelper/stl_types.hxx>
54 #include <vcl/svapp.hxx>
55 #include <dbaccess/dbsubcomponentcontroller.hxx>
56 #include <svx/unoshape.hxx>
57 #include <vos/mutex.hxx>
58 
59 namespace rptui
60 {
61 	using namespace ::com::sun::star;
62 	using namespace uno;
63 	using namespace lang;
64 	using namespace script;
65 	using namespace beans;
66 	using namespace awt;
67 	using namespace util;
68 	using namespace container;
69 	using namespace report;
70 //----------------------------------------------------------------------------
71 ::std::mem_fun_t<uno::Reference<report::XSection> , OGroupHelper> OGroupHelper::getMemberFunction(const Reference< XSection >& _xSection)
72 {
73     ::std::mem_fun_t<uno::Reference<report::XSection> , OGroupHelper> pMemFunSection = ::std::mem_fun(&OGroupHelper::getFooter);
74     uno::Reference< report::XGroup> xGroup = _xSection->getGroup();
75     if ( xGroup->getHeaderOn() && xGroup->getHeader() == _xSection )
76         pMemFunSection = ::std::mem_fun(&OGroupHelper::getHeader);
77     return pMemFunSection;
78 }
79 // -----------------------------------------------------------------------------
80 ::std::mem_fun_t<uno::Reference<report::XSection> , OReportHelper> OReportHelper::getMemberFunction(const Reference< XSection >& _xSection)
81 {
82     uno::Reference< report::XReportDefinition> xReportDefinition(_xSection->getReportDefinition());
83     ::std::mem_fun_t<uno::Reference<report::XSection> , OReportHelper> pMemFunSection = ::std::mem_fun(&OReportHelper::getReportFooter);
84     if ( xReportDefinition->getReportHeaderOn() && xReportDefinition->getReportHeader() == _xSection )
85         pMemFunSection = ::std::mem_fun(&OReportHelper::getReportHeader);
86     else if ( xReportDefinition->getPageHeaderOn() && xReportDefinition->getPageHeader() == _xSection )
87         pMemFunSection = ::std::mem_fun(&OReportHelper::getPageHeader);
88     else if ( xReportDefinition->getPageFooterOn() && xReportDefinition->getPageFooter() == _xSection )
89         pMemFunSection = ::std::mem_fun(&OReportHelper::getPageFooter);
90     else if ( xReportDefinition->getDetail() == _xSection )
91         pMemFunSection = ::std::mem_fun(&OReportHelper::getDetail);
92     return pMemFunSection;
93 }
94 
95 //------------------------------------------------------------------------------
96 TYPEINIT1( OCommentUndoAction,          SdrUndoAction );
97 DBG_NAME(rpt_OCommentUndoAction)
98 //----------------------------------------------------------------------------
99 OCommentUndoAction::OCommentUndoAction(SdrModel& _rMod,sal_uInt16 nCommentID)
100 	:SdrUndoAction(_rMod)
101 {
102     DBG_CTOR(rpt_OCommentUndoAction,NULL);
103     m_pController = static_cast< OReportModel& >( _rMod ).getController();
104 	if ( nCommentID )
105         m_strComment = String(ModuleRes(nCommentID));
106 }
107 OCommentUndoAction::~OCommentUndoAction()
108 {
109     DBG_DTOR(rpt_OCommentUndoAction,NULL);
110 }
111 //----------------------------------------------------------------------------
112 void OCommentUndoAction::Undo()
113 {
114 }
115 //----------------------------------------------------------------------------
116 void OCommentUndoAction::Redo()
117 {
118 }
119 DBG_NAME( rpt_OUndoContainerAction );
120 //------------------------------------------------------------------------------
121 OUndoContainerAction::OUndoContainerAction(SdrModel& _rMod
122 											 ,Action _eAction
123 											 ,const uno::Reference< container::XIndexContainer > _xContainer
124 											 ,const Reference< XInterface > & xElem
125                                              ,sal_uInt16 _nCommentId)
126 					  :OCommentUndoAction(_rMod,_nCommentId)
127                       ,m_xElement(xElem)
128                       ,m_xContainer(_xContainer)
129    					  ,m_eAction( _eAction )
130 {
131 	DBG_CTOR( rpt_OUndoContainerAction,NULL);
132 	// normalize
133     if ( m_eAction == Removed )
134         // we now own the element
135 		m_xOwnElement = m_xElement;
136 }
137 //------------------------------------------------------------------------------
138 OUndoContainerAction::~OUndoContainerAction()
139 {
140     // if we own the object ....
141 	Reference< XComponent > xComp( m_xOwnElement, UNO_QUERY );
142 	if ( xComp.is() )
143 	{
144         // and the object does not have a parent
145 		Reference< XChild >  xChild( m_xOwnElement, UNO_QUERY );
146 		if ( xChild.is() && !xChild->getParent().is() )
147         {
148             OXUndoEnvironment& rEnv = static_cast< OReportModel& >( rMod ).GetUndoEnv();
149             rEnv.RemoveElement( m_xOwnElement );
150 
151 #if OSL_DEBUG_LEVEL > 0
152             SvxShape* pShape = SvxShape::getImplementation( xChild );
153             SdrObject* pObject = pShape ? pShape->GetSdrObject() : NULL;
154             OSL_ENSURE( pObject ? pShape->HasSdrObjectOwnership() && !pObject->IsInserted() : true ,
155                 "OUndoContainerAction::~OUndoContainerAction: inconsistency in the shape/object ownership!" );
156 #endif
157             // -> dispose it
158             try
159             {
160                 comphelper::disposeComponent( xComp );
161             }
162             catch ( const uno::Exception& )
163             {
164                 DBG_UNHANDLED_EXCEPTION();
165             }
166         }
167 	}
168 	DBG_DTOR( rpt_OUndoContainerAction,NULL);
169 }
170 //------------------------------------------------------------------------------
171 void OUndoContainerAction::implReInsert( ) SAL_THROW( ( Exception ) )
172 {
173 	if ( m_xContainer.is() )
174 	{
175         // insert the element
176         m_xContainer->insertByIndex( m_xContainer->getCount(),uno::makeAny(m_xElement) );
177 	}
178     // we don't own the object anymore
179     m_xOwnElement = NULL;
180 }
181 
182 //------------------------------------------------------------------------------
183 void OUndoContainerAction::implReRemove( ) SAL_THROW( ( Exception ) )
184 {
185     OXUndoEnvironment& rEnv = static_cast< OReportModel& >( rMod ).GetUndoEnv();
186     try
187     {
188         OXUndoEnvironment::OUndoEnvLock aLock(rEnv);
189         if ( m_xContainer.is() )
190         {
191             const sal_Int32 nCount = m_xContainer->getCount();
192             for (sal_Int32 i = 0; i < nCount; ++i)
193             {
194                 uno::Reference< uno::XInterface> xObj(m_xContainer->getByIndex(i),uno::UNO_QUERY);
195                 if ( xObj == m_xElement )
196                 {
197                     m_xContainer->removeByIndex( i );
198                     break;
199                 }
200             }
201         }
202     }
203     catch(uno::Exception&){}
204     // from now on, we own this object
205 	m_xOwnElement = m_xElement;
206 }
207 
208 //------------------------------------------------------------------------------
209 void OUndoContainerAction::Undo()
210 {
211 	if ( m_xElement.is() )
212 	{
213         // prevents that an undo action will be created for elementInserted
214         try
215         {
216 		    switch ( m_eAction )
217 		    {
218 			case Inserted:
219                 implReRemove();
220                 break;
221 
222 			case Removed:
223                 implReInsert();
224                 break;
225             default:
226                 OSL_ENSURE(0,"Illegal case value");
227                 break;
228     	    }
229         }
230         catch( const Exception& )
231         {
232         	OSL_ENSURE( sal_False, "OUndoContainerAction::Undo: caught an exception!" );
233         }
234 	}
235 }
236 
237 //------------------------------------------------------------------------------
238 void OUndoContainerAction::Redo()
239 {
240 	if ( m_xElement.is() )
241 	{
242         try
243         {
244 	    	switch ( m_eAction )
245 		    {
246 			case Inserted:
247                 implReInsert();
248                 break;
249 
250 			case Removed:
251                 implReRemove();
252 			    break;
253             default:
254                 OSL_ENSURE(0,"Illegal case value");
255                 break;
256     		}
257         }
258         catch( const Exception& )
259         {
260         	OSL_ENSURE( sal_False, "OUndoContainerAction::Redo: caught an exception!" );
261         }
262 	}
263 }
264 // -----------------------------------------------------------------------------
265 OUndoGroupSectionAction::OUndoGroupSectionAction(SdrModel& _rMod
266 											 ,Action _eAction
267 											 ,::std::mem_fun_t< uno::Reference< report::XSection >
268 											        ,OGroupHelper> _pMemberFunction
269 									         ,const uno::Reference< report::XGroup >& _xGroup
270 											 ,const Reference< XInterface > & xElem
271                                              ,sal_uInt16 _nCommentId)
272 :OUndoContainerAction(_rMod,_eAction,NULL,xElem,_nCommentId)
273 ,m_aGroupHelper(_xGroup)
274 ,m_pMemberFunction(_pMemberFunction)
275 {
276 }
277 //------------------------------------------------------------------------------
278 void OUndoGroupSectionAction::implReInsert( ) SAL_THROW( ( Exception ) )
279 {
280     OXUndoEnvironment& rEnv = static_cast< OReportModel& >( rMod ).GetUndoEnv();
281     try
282     {
283         OXUndoEnvironment::OUndoEnvLock aLock(rEnv);
284         uno::Reference< report::XSection> xSection = m_pMemberFunction(&m_aGroupHelper);
285         if ( xSection.is() )
286             xSection->add(uno::Reference< drawing::XShape>(m_xElement,uno::UNO_QUERY));
287     }
288     catch(uno::Exception&){}
289 
290     // we don't own the object anymore
291     m_xOwnElement = NULL;
292 }
293 
294 //------------------------------------------------------------------------------
295 void OUndoGroupSectionAction::implReRemove( ) SAL_THROW( ( Exception ) )
296 {
297         OXUndoEnvironment& rEnv = static_cast< OReportModel& >( rMod ).GetUndoEnv();
298     try
299     {
300         OXUndoEnvironment::OUndoEnvLock aLock(rEnv);
301         uno::Reference< report::XSection> xSection = m_pMemberFunction(&m_aGroupHelper);
302         if ( xSection.is() )
303             xSection->remove(uno::Reference< drawing::XShape>(m_xElement,uno::UNO_QUERY));
304     }
305     catch(uno::Exception&){}
306 
307     // from now on, we own this object
308 	m_xOwnElement = m_xElement;
309 }
310 //----------------------------------------------------------------------------
311 OUndoReportSectionAction::OUndoReportSectionAction(SdrModel& _rMod
312 											 ,Action _eAction
313 											 ,::std::mem_fun_t< uno::Reference< report::XSection >
314 											    ,OReportHelper> _pMemberFunction
315 									         ,const uno::Reference< report::XReportDefinition >& _xReport
316 											 ,const Reference< XInterface > & xElem
317                                              ,sal_uInt16 _nCommentId)
318 :OUndoContainerAction(_rMod,_eAction,NULL,xElem,_nCommentId)
319 ,m_aReportHelper(_xReport)
320 ,m_pMemberFunction(_pMemberFunction)
321 {
322 }
323 //------------------------------------------------------------------------------
324 void OUndoReportSectionAction::implReInsert( ) SAL_THROW( ( Exception ) )
325 {
326     OXUndoEnvironment& rEnv = static_cast< OReportModel& >( rMod ).GetUndoEnv();
327     try
328     {
329         OXUndoEnvironment::OUndoEnvLock aLock(rEnv);
330         uno::Reference< report::XSection> xSection = m_pMemberFunction(&m_aReportHelper);
331         if ( xSection.is() )
332         {
333             uno::Reference< drawing::XShape> xShape(m_xElement,uno::UNO_QUERY_THROW);
334             awt::Point aPos = xShape->getPosition();
335             awt::Size aSize = xShape->getSize();
336             xSection->add(xShape);
337             xShape->setPosition( aPos );
338             xShape->setSize( aSize );
339         }
340     }
341     catch(uno::Exception&){}
342     // we don't own the object anymore
343     m_xOwnElement = NULL;
344 }
345 
346 //------------------------------------------------------------------------------
347 void OUndoReportSectionAction::implReRemove( ) SAL_THROW( ( Exception ) )
348 {
349     OXUndoEnvironment& rEnv = static_cast< OReportModel& >( rMod ).GetUndoEnv();
350     try
351     {
352         OXUndoEnvironment::OUndoEnvLock aLock(rEnv);
353         uno::Reference< report::XSection> xSection = m_pMemberFunction(&m_aReportHelper);
354         if ( xSection.is() )
355             xSection->remove(uno::Reference< drawing::XShape>(m_xElement,uno::UNO_QUERY));
356     }
357     catch(uno::Exception&){}
358     // from now on, we own this object
359 	m_xOwnElement = m_xElement;
360 }
361 //------------------------------------------------------------------------------
362 ORptUndoPropertyAction::ORptUndoPropertyAction(SdrModel& rNewMod, const PropertyChangeEvent& evt)
363 					 :OCommentUndoAction(rNewMod,0)
364 					 ,m_xObj(evt.Source, UNO_QUERY)
365 					 ,m_aPropertyName(evt.PropertyName)
366 					 ,m_aNewValue(evt.NewValue)
367 					 ,m_aOldValue(evt.OldValue)
368 {
369 }
370 //------------------------------------------------------------------------------
371 void ORptUndoPropertyAction::Undo()
372 {
373     setProperty(sal_True);
374 }
375 
376 //------------------------------------------------------------------------------
377 void ORptUndoPropertyAction::Redo()
378 {
379 	setProperty(sal_False);
380 }
381 // -----------------------------------------------------------------------------
382 Reference< XPropertySet> ORptUndoPropertyAction::getObject()
383 {
384     return m_xObj;
385 }
386 // -----------------------------------------------------------------------------
387 void ORptUndoPropertyAction::setProperty(sal_Bool _bOld)
388 {
389     Reference< XPropertySet> xObj = getObject();
390 
391 	if (xObj.is() )
392 	{
393         try
394         {
395             xObj->setPropertyValue( m_aPropertyName, _bOld ? m_aOldValue : m_aNewValue );
396         }
397         catch( const Exception& )
398         {
399         	OSL_ENSURE( sal_False, "ORptUndoPropertyAction::Redo: caught an exception!" );
400         }
401 	}
402 }
403 
404 //------------------------------------------------------------------------------
405 String ORptUndoPropertyAction::GetComment() const
406 {
407 	String aStr(ModuleRes(RID_STR_UNDO_PROPERTY));
408 
409 	aStr.SearchAndReplace( '#', m_aPropertyName );
410 	return aStr;
411 }
412 // -----------------------------------------------------------------------------
413 OUndoPropertyGroupSectionAction::OUndoPropertyGroupSectionAction(SdrModel& _rMod
414 											 ,const PropertyChangeEvent& evt
415 											 ,::std::mem_fun_t< uno::Reference< report::XSection >
416 											        ,OGroupHelper> _pMemberFunction
417 									         ,const uno::Reference< report::XGroup >& _xGroup
418                                              )
419 :ORptUndoPropertyAction(_rMod,evt)
420 ,m_aGroupHelper(_xGroup)
421 ,m_pMemberFunction(_pMemberFunction)
422 {
423 }
424 // -----------------------------------------------------------------------------
425 Reference< XPropertySet> OUndoPropertyGroupSectionAction::getObject()
426 {
427     return m_pMemberFunction(&m_aGroupHelper).get();
428 }
429 // -----------------------------------------------------------------------------
430 OUndoPropertyReportSectionAction::OUndoPropertyReportSectionAction(SdrModel& _rMod
431 											 ,const PropertyChangeEvent& evt
432 											 ,::std::mem_fun_t< uno::Reference< report::XSection >
433 											    ,OReportHelper> _pMemberFunction
434 									         ,const uno::Reference< report::XReportDefinition >& _xReport
435                                              )
436 :ORptUndoPropertyAction(_rMod,evt)
437 ,m_aReportHelper(_xReport)
438 ,m_pMemberFunction(_pMemberFunction)
439 {
440 }
441 // -----------------------------------------------------------------------------
442 Reference< XPropertySet> OUndoPropertyReportSectionAction::getObject()
443 {
444     return m_pMemberFunction(&m_aReportHelper).get();
445 }
446 //============================================================================
447 } // rptui
448 //============================================================================
449 
450