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 "RptUndo.hxx"
26 #include "uistrings.hrc"
27 #include "rptui_slotid.hrc"
28 #include "UITools.hxx"
29 #include "UndoEnv.hxx"
30
31 #include <dbaccess/IController.hxx>
32 #include <com/sun/star/report/XSection.hpp>
33 #include <com/sun/star/beans/PropertyAttribute.hpp>
34
35 #include <com/sun/star/awt/Point.hpp>
36 #include <com/sun/star/awt/Size.hpp>
37 #include <svx/unoshape.hxx>
38 #include <boost/bind.hpp>
39 #include <functional>
40
41 namespace rptui
42 {
43 using namespace ::com::sun::star;
44 using namespace uno;
45 using namespace lang;
46 using namespace script;
47 using namespace beans;
48 using namespace awt;
49 using namespace util;
50 using namespace container;
51 using namespace report;
52
53 //----------------------------------------------------------------------------
54 namespace
55 {
lcl_collectElements(const uno::Reference<report::XSection> & _xSection,::std::vector<uno::Reference<drawing::XShape>> & _rControls)56 void lcl_collectElements(const uno::Reference< report::XSection >& _xSection,::std::vector< uno::Reference< drawing::XShape> >& _rControls)
57 {
58 if ( _xSection.is() )
59 {
60 sal_Int32 nCount = _xSection->getCount();
61 _rControls.reserve(nCount);
62 while ( nCount )
63 {
64 uno::Reference< drawing::XShape> xShape(_xSection->getByIndex(nCount-1),uno::UNO_QUERY);
65 _rControls.push_back(xShape);
66 _xSection->remove(xShape);
67 --nCount;
68 }
69 } // if ( _xSection.is() )
70 }
71 //----------------------------------------------------------------------------
lcl_insertElements(const uno::Reference<report::XSection> & _xSection,const::std::vector<uno::Reference<drawing::XShape>> & _aControls)72 void lcl_insertElements(const uno::Reference< report::XSection >& _xSection,const ::std::vector< uno::Reference< drawing::XShape> >& _aControls)
73 {
74 if ( _xSection.is() )
75 {
76 ::std::vector< uno::Reference< drawing::XShape> >::const_reverse_iterator aIter = _aControls.rbegin();
77 ::std::vector< uno::Reference< drawing::XShape> >::const_reverse_iterator aEnd = _aControls.rend();
78 for (; aIter != aEnd; ++aIter)
79 {
80 try
81 {
82 const awt::Point aPos = (*aIter)->getPosition();
83 const awt::Size aSize = (*aIter)->getSize();
84 _xSection->add(*aIter);
85 (*aIter)->setPosition( aPos );
86 (*aIter)->setSize( aSize );
87 }
88 catch(const uno::Exception&)
89 {
90 OSL_ENSURE(0,"lcl_insertElements:Exception caught!");
91 }
92 }
93 }
94 }
95 //----------------------------------------------------------------------------
lcl_setValues(const uno::Reference<report::XSection> & _xSection,const::std::vector<::std::pair<::rtl::OUString,uno::Any>> & _aValues)96 void lcl_setValues(const uno::Reference< report::XSection >& _xSection,const ::std::vector< ::std::pair< ::rtl::OUString ,uno::Any> >& _aValues)
97 {
98 if ( _xSection.is() )
99 {
100 ::std::vector< ::std::pair< ::rtl::OUString ,uno::Any> >::const_iterator aIter = _aValues.begin();
101 ::std::vector< ::std::pair< ::rtl::OUString ,uno::Any> >::const_iterator aEnd = _aValues.end();
102 for (; aIter != aEnd; ++aIter)
103 {
104 try
105 {
106 _xSection->setPropertyValue(aIter->first,aIter->second);
107 }
108 catch(const uno::Exception&)
109 {
110 OSL_ENSURE(0,"lcl_setValues:Exception caught!");
111 }
112 }
113 }
114 }
115 }
116 //----------------------------------------------------------------------------
117 TYPEINIT1( OSectionUndo, OCommentUndoAction );
DBG_NAME(rpt_OSectionUndo)118 DBG_NAME(rpt_OSectionUndo)
119 //----------------------------------------------------------------------------
120 OSectionUndo::OSectionUndo(OReportModel& _rMod
121 ,sal_uInt16 _nSlot
122 ,Action _eAction
123 ,sal_uInt16 nCommentID)
124 : OCommentUndoAction(_rMod,nCommentID)
125 ,m_eAction(_eAction)
126 ,m_nSlot(_nSlot)
127 ,m_bInserted(false)
128 {
129 DBG_CTOR(rpt_OSectionUndo,NULL);
130 }
131 // -----------------------------------------------------------------------------
~OSectionUndo()132 OSectionUndo::~OSectionUndo()
133 {
134 if ( !m_bInserted )
135 {
136 OXUndoEnvironment& rEnv = static_cast< OReportModel& >( rMod ).GetUndoEnv();
137 ::std::vector< uno::Reference< drawing::XShape> >::iterator aEnd = m_aControls.end();
138 for (::std::vector< uno::Reference< drawing::XShape> >::iterator aIter = m_aControls.begin(); aIter != aEnd; ++aIter)
139 {
140 uno::Reference< drawing::XShape> xShape = *aIter;
141 rEnv.RemoveElement(xShape);
142
143 #if OSL_DEBUG_LEVEL > 0
144 SvxShape* pShape = SvxShape::getImplementation( xShape );
145 SdrObject* pObject = pShape ? pShape->GetSdrObject() : NULL;
146 OSL_ENSURE( pShape && pShape->HasSdrObjectOwnership() && pObject && !pObject->IsInserted(),
147 "OSectionUndo::~OSectionUndo: inconsistency in the shape/object ownership!" );
148 #endif
149 try
150 {
151 comphelper::disposeComponent(xShape);
152 }
153 catch(uno::Exception)
154 {
155 OSL_ENSURE(0,"Exception caught!");
156 }
157 }
158 }
159 DBG_DTOR(rpt_OSectionUndo,NULL);
160 }
161 // -----------------------------------------------------------------------------
collectControls(const uno::Reference<report::XSection> & _xSection)162 void OSectionUndo::collectControls(const uno::Reference< report::XSection >& _xSection)
163 {
164 m_aControls.clear();
165 try
166 {
167 // copy all properties for restoring
168 uno::Reference< beans::XPropertySetInfo> xInfo = _xSection->getPropertySetInfo();
169 uno::Sequence< beans::Property> aSeq = xInfo->getProperties();
170 const beans::Property* pIter = aSeq.getConstArray();
171 const beans::Property* pEnd = pIter + aSeq.getLength();
172 for(;pIter != pEnd;++pIter)
173 {
174 if ( 0 == (pIter->Attributes & beans::PropertyAttribute::READONLY) )
175 m_aValues.push_back(::std::pair< ::rtl::OUString ,uno::Any>(pIter->Name,_xSection->getPropertyValue(pIter->Name)));
176 }
177 lcl_collectElements(_xSection,m_aControls);
178 }
179 catch(uno::Exception&)
180 {
181 }
182 }
183 //----------------------------------------------------------------------------
Undo()184 void OSectionUndo::Undo()
185 {
186 try
187 {
188 switch ( m_eAction )
189 {
190 case Inserted:
191 implReRemove();
192 break;
193
194 case Removed:
195 implReInsert();
196 break;
197 }
198 }
199 catch( const Exception& )
200 {
201 OSL_ENSURE( sal_False, "OSectionUndo::Undo: caught an exception!" );
202 }
203 }
204 //----------------------------------------------------------------------------
Redo()205 void OSectionUndo::Redo()
206 {
207 try
208 {
209 switch ( m_eAction )
210 {
211 case Inserted:
212 implReInsert();
213 break;
214
215 case Removed:
216 implReRemove();
217 break;
218 }
219 }
220 catch( const Exception& )
221 {
222 OSL_ENSURE( sal_False, "OSectionUndo::Redo: caught an exception!" );
223 }
224 }
225 //----------------------------------------------------------------------------
226 TYPEINIT1( OReportSectionUndo, OSectionUndo );
227 //----------------------------------------------------------------------------
OReportSectionUndo(OReportModel & _rMod,sal_uInt16 _nSlot,::std::mem_fun_t<uno::Reference<report::XSection>,OReportHelper> _pMemberFunction,const uno::Reference<report::XReportDefinition> & _xReport,Action _eAction,sal_uInt16 nCommentID)228 OReportSectionUndo::OReportSectionUndo(OReportModel& _rMod,sal_uInt16 _nSlot
229 ,::std::mem_fun_t< uno::Reference< report::XSection >
230 ,OReportHelper> _pMemberFunction
231 ,const uno::Reference< report::XReportDefinition >& _xReport
232 ,Action _eAction
233 ,sal_uInt16 nCommentID)
234 : OSectionUndo(_rMod,_nSlot,_eAction,nCommentID)
235 ,m_aReportHelper(_xReport)
236 ,m_pMemberFunction(_pMemberFunction)
237 {
238 if( m_eAction == Removed )
239 collectControls(m_pMemberFunction(&m_aReportHelper));
240 }
241 // -----------------------------------------------------------------------------
~OReportSectionUndo()242 OReportSectionUndo::~OReportSectionUndo()
243 {
244 }
245 //----------------------------------------------------------------------------
implReInsert()246 void OReportSectionUndo::implReInsert( )
247 {
248 const uno::Sequence< beans::PropertyValue > aArgs;
249 m_pController->executeChecked(m_nSlot,aArgs);
250 uno::Reference< report::XSection > xSection = m_pMemberFunction(&m_aReportHelper);
251 lcl_insertElements(xSection,m_aControls);
252 lcl_setValues(xSection,m_aValues);
253 m_bInserted = true;
254 }
255 //----------------------------------------------------------------------------
implReRemove()256 void OReportSectionUndo::implReRemove( )
257 {
258 if( m_eAction == Removed )
259 collectControls(m_pMemberFunction(&m_aReportHelper));
260 const uno::Sequence< beans::PropertyValue > aArgs;
261 m_pController->executeChecked(m_nSlot,aArgs);
262 m_bInserted = false;
263 }
264 //----------------------------------------------------------------------------
265 TYPEINIT1( OGroupSectionUndo, OSectionUndo );
266 //----------------------------------------------------------------------------
OGroupSectionUndo(OReportModel & _rMod,sal_uInt16 _nSlot,::std::mem_fun_t<uno::Reference<report::XSection>,OGroupHelper> _pMemberFunction,const uno::Reference<report::XGroup> & _xGroup,Action _eAction,sal_uInt16 nCommentID)267 OGroupSectionUndo::OGroupSectionUndo(OReportModel& _rMod,sal_uInt16 _nSlot
268 ,::std::mem_fun_t< uno::Reference< report::XSection >
269 ,OGroupHelper> _pMemberFunction
270 ,const uno::Reference< report::XGroup >& _xGroup
271 ,Action _eAction
272 ,sal_uInt16 nCommentID)
273 : OSectionUndo(_rMod,_nSlot,_eAction,nCommentID)
274 ,m_aGroupHelper(_xGroup)
275 ,m_pMemberFunction(_pMemberFunction)
276 {
277 if( m_eAction == Removed )
278 {
279 uno::Reference< report::XSection > xSection = m_pMemberFunction(&m_aGroupHelper);
280 if ( xSection.is() )
281 m_sName = xSection->getName();
282 collectControls(xSection);
283 }
284 }
285 //----------------------------------------------------------------------------
GetComment() const286 String OGroupSectionUndo::GetComment() const
287 {
288 if ( !m_sName.getLength() )
289 {
290 try
291 {
292 uno::Reference< report::XSection > xSection = const_cast<OGroupSectionUndo*>(this)->m_pMemberFunction(&const_cast<OGroupSectionUndo*>(this)->m_aGroupHelper);
293
294 if ( xSection.is() )
295 m_sName = xSection->getName();
296 }
297 catch(uno::Exception&)
298 {}
299 }
300 return m_strComment + m_sName;
301 }
302 //----------------------------------------------------------------------------
implReInsert()303 void OGroupSectionUndo::implReInsert( )
304 {
305 uno::Sequence< beans::PropertyValue > aArgs(2);
306
307 aArgs[0].Name = SID_GROUPHEADER_WITHOUT_UNDO == m_nSlot? PROPERTY_HEADERON : PROPERTY_FOOTERON;
308 aArgs[0].Value <<= sal_True;
309 aArgs[1].Name = PROPERTY_GROUP;
310 aArgs[1].Value <<= m_aGroupHelper.getGroup();
311 m_pController->executeChecked(m_nSlot,aArgs);
312
313 uno::Reference< report::XSection > xSection = m_pMemberFunction(&m_aGroupHelper);
314 lcl_insertElements(xSection,m_aControls);
315 lcl_setValues(xSection,m_aValues);
316 m_bInserted = true;
317 }
318 //----------------------------------------------------------------------------
implReRemove()319 void OGroupSectionUndo::implReRemove( )
320 {
321 if( m_eAction == Removed )
322 collectControls(m_pMemberFunction(&m_aGroupHelper));
323
324 uno::Sequence< beans::PropertyValue > aArgs(2);
325
326 aArgs[0].Name = SID_GROUPHEADER_WITHOUT_UNDO == m_nSlot? PROPERTY_HEADERON : PROPERTY_FOOTERON;
327 aArgs[0].Value <<= sal_False;
328 aArgs[1].Name = PROPERTY_GROUP;
329 aArgs[1].Value <<= m_aGroupHelper.getGroup();
330
331 m_pController->executeChecked(m_nSlot,aArgs);
332 m_bInserted = false;
333 }
334 //----------------------------------------------------------------------------
335 TYPEINIT1( OGroupUndo, OCommentUndoAction );
336 //----------------------------------------------------------------------------
OGroupUndo(OReportModel & _rMod,sal_uInt16 nCommentID,Action _eAction,const uno::Reference<report::XGroup> & _xGroup,const uno::Reference<report::XReportDefinition> & _xReportDefinition)337 OGroupUndo::OGroupUndo(OReportModel& _rMod
338 ,sal_uInt16 nCommentID
339 ,Action _eAction
340 ,const uno::Reference< report::XGroup>& _xGroup
341 ,const uno::Reference< report::XReportDefinition >& _xReportDefinition)
342 : OCommentUndoAction(_rMod,nCommentID)
343 ,m_xGroup(_xGroup)
344 ,m_xReportDefinition(_xReportDefinition)
345 ,m_eAction(_eAction)
346 {
347 m_nLastPosition = getPositionInIndexAccess(m_xReportDefinition->getGroups().get(),m_xGroup);
348 }
349 //----------------------------------------------------------------------------
implReInsert()350 void OGroupUndo::implReInsert( )
351 {
352 try
353 {
354 m_xReportDefinition->getGroups()->insertByIndex(m_nLastPosition,uno::makeAny(m_xGroup));
355 }
356 catch(uno::Exception&)
357 {
358 OSL_ENSURE(0,"Exception catched while undoing remove group");
359 }
360 }
361 //----------------------------------------------------------------------------
implReRemove()362 void OGroupUndo::implReRemove( )
363 {
364 try
365 {
366 m_xReportDefinition->getGroups()->removeByIndex(m_nLastPosition);
367 }
368 catch(uno::Exception&)
369 {
370 OSL_ENSURE(0,"Exception catched while redoing remove group");
371 }
372 }
373 //----------------------------------------------------------------------------
Undo()374 void OGroupUndo::Undo()
375 {
376 switch ( m_eAction )
377 {
378 case Inserted:
379 implReRemove();
380 break;
381
382 case Removed:
383 implReInsert();
384 break;
385 }
386
387 }
388 //----------------------------------------------------------------------------
Redo()389 void OGroupUndo::Redo()
390 {
391 switch ( m_eAction )
392 {
393 case Inserted:
394 implReInsert();
395 break;
396
397 case Removed:
398 implReRemove();
399 break;
400 }
401 }
402 //----------------------------------------------------------------------------
403 //============================================================================
404 } // rptui
405 //============================================================================
406
407
408