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