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