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 408