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