LibreOffice Module reportdesign (master)  1
RptUndo.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <RptUndo.hxx>
21 #include <strings.hxx>
22 #include <rptui_slotid.hrc>
23 #include <UITools.hxx>
24 #include <UndoEnv.hxx>
25 
26 #include <dbaccess/IController.hxx>
27 #include <com/sun/star/report/XSection.hpp>
28 #include <com/sun/star/beans/PropertyAttribute.hpp>
29 
30 #include <com/sun/star/awt/Point.hpp>
31 #include <com/sun/star/awt/Size.hpp>
32 #include <comphelper/types.hxx>
33 #include <svx/unoshape.hxx>
34 #include <utility>
35 #include <tools/diagnose_ex.h>
36 
37 #include <functional>
38 
39 namespace rptui
40 {
41  using namespace ::com::sun::star;
42  using namespace uno;
43  using namespace lang;
44  using namespace beans;
45  using namespace awt;
46  using namespace util;
47  using namespace container;
48  using namespace report;
49 
50 
51 namespace
52 {
53  void lcl_collectElements(const uno::Reference< report::XSection >& _xSection,::std::vector< uno::Reference< drawing::XShape> >& _rControls)
54  {
55  if ( _xSection.is() )
56  {
57  sal_Int32 nCount = _xSection->getCount();
58  _rControls.reserve(nCount);
59  while ( nCount )
60  {
61  uno::Reference< drawing::XShape> xShape(_xSection->getByIndex(nCount-1),uno::UNO_QUERY);
62  _rControls.push_back(xShape);
63  _xSection->remove(xShape);
64  --nCount;
65  }
66  }
67  }
68 
69  void lcl_insertElements(const uno::Reference< report::XSection >& _xSection,const ::std::vector< uno::Reference< drawing::XShape> >& _aControls)
70  {
71  if ( !_xSection.is() )
72  return;
73 
74  ::std::vector< uno::Reference< drawing::XShape> >::const_reverse_iterator aIter = _aControls.rbegin();
75  ::std::vector< uno::Reference< drawing::XShape> >::const_reverse_iterator aEnd = _aControls.rend();
76  for (; aIter != aEnd; ++aIter)
77  {
78  try
79  {
80  const awt::Point aPos = (*aIter)->getPosition();
81  const awt::Size aSize = (*aIter)->getSize();
82  _xSection->add(*aIter);
83  (*aIter)->setPosition( aPos );
84  (*aIter)->setSize( aSize );
85  }
86  catch(const uno::Exception&)
87  {
88  TOOLS_WARN_EXCEPTION( "reportdesign", "lcl_insertElements");
89  }
90  }
91  }
92 
93  void lcl_setValues(const uno::Reference< report::XSection >& _xSection,const ::std::vector< ::std::pair< OUString ,uno::Any> >& _aValues)
94  {
95  if ( !_xSection.is() )
96  return;
97 
98  for (const auto& [rPropName, rValue] : _aValues)
99  {
100  try
101  {
102  _xSection->setPropertyValue(rPropName, rValue);
103  }
104  catch(const uno::Exception&)
105  {
106  TOOLS_WARN_EXCEPTION( "reportdesign", "lcl_setValues");
107  }
108  }
109  }
110 }
111 
112 
114  ,sal_uInt16 _nSlot
115  ,Action _eAction
116  ,TranslateId pCommentID)
117 : OCommentUndoAction(_rMod,pCommentID)
118 ,m_eAction(_eAction)
119 ,m_nSlot(_nSlot)
120 ,m_bInserted(false)
121 {
122 }
123 
125 {
126  if ( m_bInserted )
127  return;
128 
129  OXUndoEnvironment& rEnv = static_cast< OReportModel& >( rMod ).GetUndoEnv();
130  for (uno::Reference<drawing::XShape>& xShape : m_aControls)
131  {
132  rEnv.RemoveElement(xShape);
133 
134 #if OSL_DEBUG_LEVEL > 0
135  SvxShape* pShape = comphelper::getFromUnoTunnel<SvxShape>( xShape );
136  SdrObject* pObject = pShape ? pShape->GetSdrObject() : nullptr;
137  OSL_ENSURE( pShape && pShape->HasSdrObjectOwnership() && pObject && !pObject->IsInserted(),
138  "OSectionUndo::~OSectionUndo: inconsistency in the shape/object ownership!" );
139 #endif
140  try
141  {
143  }
144  catch(const uno::Exception &)
145  {
146  TOOLS_WARN_EXCEPTION( "reportdesign", "");
147  }
148  }
149 }
150 
151 void OSectionUndo::collectControls(const uno::Reference< report::XSection >& _xSection)
152 {
153  m_aControls.clear();
154  try
155  {
156  // copy all properties for restoring
157  uno::Reference< beans::XPropertySetInfo> xInfo = _xSection->getPropertySetInfo();
158  const uno::Sequence< beans::Property> aSeq = xInfo->getProperties();
159  for(const beans::Property& rProp : aSeq)
160  {
161  if ( 0 == (rProp.Attributes & beans::PropertyAttribute::READONLY) )
162  m_aValues.emplace_back(rProp.Name,_xSection->getPropertyValue(rProp.Name));
163  }
164  lcl_collectElements(_xSection,m_aControls);
165  }
166  catch(uno::Exception&)
167  {
168  }
169 }
170 
172 {
173  try
174  {
175  switch ( m_eAction )
176  {
177  case Inserted:
178  implReRemove();
179  break;
180 
181  case Removed:
182  implReInsert();
183  break;
184  }
185  }
186  catch( const Exception& )
187  {
188  TOOLS_WARN_EXCEPTION( "reportdesign", "OSectionUndo::Undo" );
189  }
190 }
191 
193 {
194  try
195  {
196  switch ( m_eAction )
197  {
198  case Inserted:
199  implReInsert();
200  break;
201 
202  case Removed:
203  implReRemove();
204  break;
205  }
206  }
207  catch( const Exception& )
208  {
209  TOOLS_WARN_EXCEPTION( "reportdesign", "OSectionUndo::Redo" );
210  }
211 }
212 
214  OReportModel& _rMod, sal_uInt16 _nSlot,
215  ::std::function<uno::Reference<report::XSection>(OReportHelper*)> _pMemberFunction,
216  const uno::Reference<report::XReportDefinition>& _xReport, Action _eAction)
217  : OSectionUndo(_rMod, _nSlot, _eAction, {})
218  , m_aReportHelper(_xReport)
219  , m_pMemberFunction(std::move(_pMemberFunction))
220 {
221  if( m_eAction == Removed )
222  collectControls(m_pMemberFunction(&m_aReportHelper));
223 }
224 
226 {
227 }
228 
230 {
231  const uno::Sequence< beans::PropertyValue > aArgs;
233  uno::Reference< report::XSection > xSection = m_pMemberFunction(&m_aReportHelper);
234  lcl_insertElements(xSection,m_aControls);
235  lcl_setValues(xSection,m_aValues);
236  m_bInserted = true;
237 }
238 
240 {
241  if( m_eAction == Removed )
243  const uno::Sequence< beans::PropertyValue > aArgs;
245  m_bInserted = false;
246 }
247 
249  OReportModel& _rMod, sal_uInt16 _nSlot,
250  ::std::function<uno::Reference<report::XSection>(OGroupHelper*)> _pMemberFunction,
251  const uno::Reference<report::XGroup>& _xGroup, Action _eAction, TranslateId pCommentID)
252  : OSectionUndo(_rMod, _nSlot, _eAction, pCommentID)
253  , m_aGroupHelper(_xGroup)
254  , m_pMemberFunction(std::move(_pMemberFunction))
255 {
256  if( m_eAction == Removed )
257  {
258  uno::Reference< report::XSection > xSection = m_pMemberFunction(&m_aGroupHelper);
259  if ( xSection.is() )
260  m_sName = xSection->getName();
261  collectControls(xSection);
262  }
263 }
264 
266 {
267  if ( m_sName.isEmpty() )
268  {
269  try
270  {
271  uno::Reference< report::XSection > xSection = const_cast<OGroupSectionUndo*>(this)->m_pMemberFunction(&const_cast<OGroupSectionUndo*>(this)->m_aGroupHelper);
272 
273  if ( xSection.is() )
274  m_sName = xSection->getName();
275  }
276  catch (const uno::Exception&)
277  {
278  }
279  }
280  return m_strComment + m_sName;
281 }
282 
284 {
285  uno::Sequence< beans::PropertyValue > aArgs(2);
286 
287  aArgs[0].Name = SID_GROUPHEADER_WITHOUT_UNDO == m_nSlot? OUStringLiteral(u"" PROPERTY_HEADERON) : OUStringLiteral(u"" PROPERTY_FOOTERON);
288  aArgs[0].Value <<= true;
289  aArgs[1].Name = PROPERTY_GROUP;
290  aArgs[1].Value <<= m_aGroupHelper.getGroup();
292 
293  uno::Reference< report::XSection > xSection = m_pMemberFunction(&m_aGroupHelper);
294  lcl_insertElements(xSection,m_aControls);
295  lcl_setValues(xSection,m_aValues);
296  m_bInserted = true;
297 }
298 
300 {
301  if( m_eAction == Removed )
303 
304  uno::Sequence< beans::PropertyValue > aArgs(2);
305 
306  aArgs[0].Name = SID_GROUPHEADER_WITHOUT_UNDO == m_nSlot? OUStringLiteral(u"" PROPERTY_HEADERON) : OUStringLiteral(u"" PROPERTY_FOOTERON);
307  aArgs[0].Value <<= false;
308  aArgs[1].Name = PROPERTY_GROUP;
309  aArgs[1].Value <<= m_aGroupHelper.getGroup();
310 
312  m_bInserted = false;
313 }
314 
315 
317  ,TranslateId pCommentID
318  ,Action _eAction
319  ,const uno::Reference< report::XGroup>& _xGroup
320  ,const uno::Reference< report::XReportDefinition >& _xReportDefinition)
321 : OCommentUndoAction(_rMod,pCommentID)
322 ,m_xGroup(_xGroup)
323 ,m_xReportDefinition(_xReportDefinition)
324 ,m_eAction(_eAction)
325 {
327 }
328 
330 {
331  try
332  {
333  m_xReportDefinition->getGroups()->insertByIndex(m_nLastPosition,uno::makeAny(m_xGroup));
334  }
335  catch(uno::Exception&)
336  {
337  TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while undoing remove group");
338  }
339 }
340 
342 {
343  try
344  {
345  m_xReportDefinition->getGroups()->removeByIndex(m_nLastPosition);
346  }
347  catch(uno::Exception&)
348  {
349  TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while redoing remove group");
350  }
351 }
352 
354 {
355  switch ( m_eAction )
356  {
357  case Inserted:
358  implReRemove();
359  break;
360 
361  case Removed:
362  implReInsert();
363  break;
364  }
365 
366 }
367 
369 {
370  switch ( m_eAction )
371  {
372  case Inserted:
373  implReInsert();
374  break;
375 
376  case Removed:
377  implReRemove();
378  break;
379  }
380 }
381 
382 
383 } // rptui
384 
385 
386 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void implReInsert()
Definition: RptUndo.cxx:329
::dbaui::IController * m_pController
virtual void Redo() override
Definition: RptUndo.cxx:192
virtual void implReRemove()=0
void implReRemove() override
Definition: RptUndo.cxx:299
void RemoveElement(const css::uno::Reference< css::uno::XInterface > &Element)
Definition: UndoEnv.cxx:594
#define PROPERTY_HEADERON
Definition: strings.hxx:71
#define PROPERTY_GROUP
Definition: strings.hxx:48
::std::function< css::uno::Reference< css::report::XSection >OReportHelper *)> m_pMemberFunction
Definition: RptUndo.hxx:70
virtual ~OReportSectionUndo() override
Definition: RptUndo.cxx:225
::std::vector< css::uno::Reference< css::drawing::XShape > > m_aControls
Definition: RptUndo.hxx:43
virtual void implReInsert()=0
EmbeddedObjectRef * pObject
Undo action for the group header, footer.
Definition: RptUndo.hxx:88
#define PROPERTY_FOOTERON
Definition: strings.hxx:72
Helper class to allow std::mem_fun for SAL_CALL.
Definition: UndoActions.hxx:70
SdrModel & rMod
::std::vector< ::std::pair< OUString,css::uno::Any > > m_aValues
Definition: RptUndo.hxx:45
virtual ~OSectionUndo() override
Definition: RptUndo.cxx:124
int nCount
OSectionUndo(const OSectionUndo &)=delete
virtual void Redo() override
Definition: RptUndo.cxx:368
virtual OUString GetComment() const override
Definition: RptUndo.cxx:265
void collectControls(const css::uno::Reference< css::report::XSection > &_xSection)
Definition: RptUndo.cxx:151
#define TOOLS_WARN_EXCEPTION(area, stream)
::std::function< css::uno::Reference< css::report::XSection >OGroupHelper *)> m_pMemberFunction
Definition: RptUndo.hxx:91
OGroupSectionUndo(const OGroupSectionUndo &)=delete
float u
OGroupHelper m_aGroupHelper
Definition: RptUndo.hxx:90
const css::uno::Reference< css::report::XGroup > & getGroup() const
Definition: UndoActions.hxx:59
OGroupUndo(OReportModel &rMod, TranslateId pCommentID, Action _eAction, const css::uno::Reference< css::report::XGroup > &_xGroup, const css::uno::Reference< css::report::XReportDefinition > &_xReportDefinition)
Definition: RptUndo.cxx:316
sal_uInt16 m_nSlot
Definition: RptUndo.hxx:47
Undo class for section add and remove.
Definition: RptUndo.hxx:37
sal_Int32 getPositionInIndexAccess(const css::uno::Reference< css::container::XIndexAccess > &_xCollection, const css::uno::Reference< T > &_xSearch)
returns the position of the object inside the index container
Definition: UITools.hxx:52
Action m_eAction
! the current action
Definition: RptUndo.hxx:118
sal_Int32 m_nLastPosition
! the last position of the group
Definition: RptUndo.hxx:119
void implReInsert() override
Definition: RptUndo.cxx:229
void implReInsert() override
Definition: RptUndo.cxx:283
SdrObject * GetSdrObject() const
css::uno::Reference< css::report::XGroup > m_xGroup
! the group for the undo redo action
Definition: RptUndo.hxx:116
void implReRemove() override
Definition: RptUndo.cxx:239
virtual void Undo() override
Definition: RptUndo.cxx:171
virtual void executeChecked(const css::util::URL &_rCommand, const css::uno::Sequence< css::beans::PropertyValue > &aArgs)=0
Sequence< sal_Int8 > aSeq
void disposeComponent(css::uno::Reference< TYPE > &_rxComp)
virtual void Undo() override
Definition: RptUndo.cxx:353
SectionViewAction m_eAction
bool HasSdrObjectOwnership() const
css::uno::Reference< css::report::XReportDefinition > m_xReportDefinition
! the parent report definition
Definition: RptUndo.hxx:117
void implReRemove()
Definition: RptUndo.cxx:341
OReportHelper m_aReportHelper
Definition: RptUndo.hxx:69
OReportSectionUndo(const OReportSectionUndo &)=delete
Helper class to allow std::mem_fun for SAL_CALL.
Definition: UndoActions.hxx:47