xref: /trunk/main/reportdesign/source/ui/misc/RptUndo.cxx (revision ffd38472365e95f6a578737bc9a5eb0fac624a86)
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 {
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     //----------------------------------------------------------------------------
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     //----------------------------------------------------------------------------
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 );
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 // -----------------------------------------------------------------------------
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 // -----------------------------------------------------------------------------
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 //----------------------------------------------------------------------------
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 //----------------------------------------------------------------------------
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 //----------------------------------------------------------------------------
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 // -----------------------------------------------------------------------------
243 OReportSectionUndo::~OReportSectionUndo()
244 {
245 }
246 //----------------------------------------------------------------------------
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 //----------------------------------------------------------------------------
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 //----------------------------------------------------------------------------
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 //----------------------------------------------------------------------------
287 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 //----------------------------------------------------------------------------
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 //----------------------------------------------------------------------------
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 //----------------------------------------------------------------------------
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 //----------------------------------------------------------------------------
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 //----------------------------------------------------------------------------
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 //----------------------------------------------------------------------------
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 //----------------------------------------------------------------------------
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