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 { 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 //---------------------------------------------------------------------------- 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 //---------------------------------------------------------------------------- 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 ); 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 // ----------------------------------------------------------------------------- 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 // ----------------------------------------------------------------------------- 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 //---------------------------------------------------------------------------- 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 //---------------------------------------------------------------------------- 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 //---------------------------------------------------------------------------- 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 // ----------------------------------------------------------------------------- 242 OReportSectionUndo::~OReportSectionUndo() 243 { 244 } 245 //---------------------------------------------------------------------------- 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 //---------------------------------------------------------------------------- 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 //---------------------------------------------------------------------------- 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 //---------------------------------------------------------------------------- 286 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 //---------------------------------------------------------------------------- 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 //---------------------------------------------------------------------------- 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 //---------------------------------------------------------------------------- 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 //---------------------------------------------------------------------------- 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 //---------------------------------------------------------------------------- 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 //---------------------------------------------------------------------------- 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 //---------------------------------------------------------------------------- 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