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 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_svx.hxx" 30 31 #include "svx/sdr/properties/textproperties.hxx" 32 #include "editeng/outlobj.hxx" 33 34 #include "cell.hxx" 35 #include "tableundo.hxx" 36 #include "svx/svdotable.hxx" 37 #include "tablerow.hxx" 38 #include "tablecolumn.hxx" 39 40 41 // ----------------------------------------------------------------------------- 42 43 using ::rtl::OUString; 44 using namespace ::com::sun::star::uno; 45 using namespace ::com::sun::star::table; 46 47 // ----------------------------------------------------------------------------- 48 49 namespace sdr { namespace table { 50 51 CellUndo::CellUndo( const SdrObjectWeakRef& xObjRef, const CellRef& xCell ) 52 : SdrUndoAction( *xCell->GetModel() ) 53 , mxObjRef( xObjRef ) 54 , mxCell( xCell ) 55 , mbUndo( true ) 56 { 57 if( mxCell.is() && mxObjRef.is() ) 58 { 59 getDataFromCell( maUndoData ); 60 mxObjRef->AddObjectUser( *this ); 61 } 62 } 63 64 CellUndo::~CellUndo() 65 { 66 if( mxObjRef.is() ) 67 mxObjRef->RemoveObjectUser( *this ); 68 dispose(); 69 } 70 71 void CellUndo::dispose() 72 { 73 mxCell.clear(); 74 delete maUndoData.mpProperties; 75 maUndoData.mpProperties = 0; 76 delete maRedoData.mpProperties; 77 maRedoData.mpProperties = 0; 78 delete maUndoData.mpOutlinerParaObject; 79 maUndoData.mpOutlinerParaObject = 0; 80 delete maRedoData.mpOutlinerParaObject; 81 maRedoData.mpOutlinerParaObject = 0; 82 } 83 84 void CellUndo::ObjectInDestruction(const SdrObject& ) 85 { 86 dispose(); 87 } 88 89 void CellUndo::Undo() 90 { 91 if( mxCell.is() && mbUndo ) 92 { 93 if( maRedoData.mpProperties == 0 ) 94 getDataFromCell( maRedoData ); 95 96 setDataToCell( maUndoData ); 97 mbUndo = false; 98 } 99 } 100 101 void CellUndo::Redo() 102 { 103 if( mxCell.is() && !mbUndo ) 104 { 105 setDataToCell( maRedoData ); 106 mbUndo = true; 107 } 108 } 109 110 sal_Bool CellUndo::Merge( SfxUndoAction *pNextAction ) 111 { 112 CellUndo* pNext = dynamic_cast< CellUndo* >( pNextAction ); 113 if( pNext && pNext->mxCell.get() == mxCell.get() ) 114 { 115 return sal_True; 116 } 117 else 118 { 119 return sal_False; 120 } 121 } 122 123 void CellUndo::setDataToCell( const Data& rData ) 124 { 125 delete mxCell->mpProperties; 126 if( rData.mpProperties ) 127 mxCell->mpProperties = Cell::CloneProperties( rData.mpProperties, *mxObjRef.get(), *mxCell.get() ); 128 else 129 mxCell->mpProperties = 0; 130 131 if( rData.mpOutlinerParaObject ) 132 mxCell->SetOutlinerParaObject( new OutlinerParaObject(*rData.mpOutlinerParaObject) ); 133 else 134 mxCell->RemoveOutlinerParaObject(); 135 136 mxCell->msFormula = rData.msFormula; 137 mxCell->mfValue = rData.mfValue; 138 mxCell->mnError = rData.mnError; 139 mxCell->mbMerged = rData.mbMerged; 140 mxCell->mnRowSpan = rData.mnRowSpan; 141 mxCell->mnColSpan = rData.mnColSpan; 142 143 if( mxObjRef.is() ) 144 mxObjRef->ActionChanged(); 145 } 146 147 void CellUndo::getDataFromCell( Data& rData ) 148 { 149 if( mxObjRef.is() && mxCell.is() ) 150 { 151 if( mxCell->mpProperties ) 152 rData.mpProperties = mxCell->CloneProperties( *mxObjRef.get(), *mxCell.get()); 153 154 if( mxCell->GetOutlinerParaObject() ) 155 rData.mpOutlinerParaObject = new OutlinerParaObject(*mxCell->GetOutlinerParaObject()); 156 else 157 rData.mpOutlinerParaObject = 0; 158 159 rData.mnCellContentType = mxCell->mnCellContentType; 160 161 rData.msFormula = mxCell->msFormula; 162 rData.mfValue = mxCell->mfValue; 163 rData.mnError = mxCell->mnError; 164 rData.mbMerged = mxCell->mbMerged; 165 rData.mnRowSpan = mxCell->mnRowSpan; 166 rData.mnColSpan = mxCell->mnColSpan; 167 } 168 } 169 170 // ----------------------------------------------------------------------------- 171 // class InsertRowUndo : public SdrUndoAction 172 // ----------------------------------------------------------------------------- 173 174 static void Dispose( RowVector& rRows ) 175 { 176 RowVector::iterator aIter( rRows.begin() ); 177 while( aIter != rRows.end() ) 178 (*aIter++)->dispose(); 179 } 180 181 // ----------------------------------------------------------------------------- 182 183 InsertRowUndo::InsertRowUndo( const TableModelRef& xTable, sal_Int32 nIndex, RowVector& aNewRows ) 184 : SdrUndoAction( *xTable->getSdrTableObj()->GetModel() ) 185 , mxTable( xTable ) 186 , mnIndex( nIndex ) 187 , mbUndo( true ) 188 { 189 maRows.swap( aNewRows ); 190 } 191 192 // ----------------------------------------------------------------------------- 193 194 InsertRowUndo::~InsertRowUndo() 195 { 196 if( !mbUndo ) 197 Dispose( maRows ); 198 } 199 200 // ----------------------------------------------------------------------------- 201 202 void InsertRowUndo::Undo() 203 { 204 if( mxTable.is() ) 205 { 206 mxTable->UndoInsertRows( mnIndex, sal::static_int_cast< sal_Int32 >( maRows.size() ) ); 207 mbUndo = false; 208 } 209 } 210 211 // ----------------------------------------------------------------------------- 212 213 void InsertRowUndo::Redo() 214 { 215 if( mxTable.is() ) 216 { 217 mxTable->UndoRemoveRows( mnIndex, maRows ); 218 mbUndo = true; 219 } 220 } 221 222 // ----------------------------------------------------------------------------- 223 // class RemoveRowUndo : public SdrUndoAction 224 // ----------------------------------------------------------------------------- 225 226 RemoveRowUndo::RemoveRowUndo( const TableModelRef& xTable, sal_Int32 nIndex, RowVector& aRemovedRows ) 227 : SdrUndoAction( *xTable->getSdrTableObj()->GetModel() ) 228 , mxTable( xTable ) 229 , mnIndex( nIndex ) 230 , mbUndo( true ) 231 { 232 maRows.swap( aRemovedRows ); 233 } 234 235 // ----------------------------------------------------------------------------- 236 237 RemoveRowUndo::~RemoveRowUndo() 238 { 239 if( mbUndo ) 240 Dispose( maRows ); 241 } 242 243 // ----------------------------------------------------------------------------- 244 245 void RemoveRowUndo::Undo() 246 { 247 if( mxTable.is() ) 248 { 249 mxTable->UndoRemoveRows( mnIndex, maRows ); 250 mbUndo = false; 251 } 252 } 253 254 // ----------------------------------------------------------------------------- 255 256 void RemoveRowUndo::Redo() 257 { 258 if( mxTable.is() ) 259 { 260 mxTable->UndoInsertRows( mnIndex, sal::static_int_cast< sal_Int32 >( maRows.size() ) ); 261 mbUndo = true; 262 } 263 } 264 265 // ----------------------------------------------------------------------------- 266 // class InsertColUndo : public SdrUndoAction 267 // ----------------------------------------------------------------------------- 268 269 static void Dispose( ColumnVector& rCols ) 270 { 271 ColumnVector::iterator aIter( rCols.begin() ); 272 while( aIter != rCols.end() ) 273 (*aIter++)->dispose(); 274 } 275 276 // ----------------------------------------------------------------------------- 277 278 static void Dispose( CellVector& rCells ) 279 { 280 CellVector::iterator aIter( rCells.begin() ); 281 while( aIter != rCells.end() ) 282 (*aIter++)->dispose(); 283 } 284 285 // ----------------------------------------------------------------------------- 286 287 InsertColUndo::InsertColUndo( const TableModelRef& xTable, sal_Int32 nIndex, ColumnVector& aNewCols, CellVector& aCells ) 288 : SdrUndoAction( *xTable->getSdrTableObj()->GetModel() ) 289 , mxTable( xTable ) 290 , mnIndex( nIndex ) 291 , mbUndo( true ) 292 { 293 maColumns.swap( aNewCols ); 294 maCells.swap( aCells ); 295 } 296 297 // ----------------------------------------------------------------------------- 298 299 InsertColUndo::~InsertColUndo() 300 { 301 if( !mbUndo ) 302 { 303 Dispose( maColumns ); 304 Dispose( maCells ); 305 } 306 } 307 308 // ----------------------------------------------------------------------------- 309 310 void InsertColUndo::Undo() 311 { 312 if( mxTable.is() ) 313 { 314 mxTable->UndoInsertColumns( mnIndex, sal::static_int_cast< sal_Int32 >( maColumns.size() ) ); 315 mbUndo = false; 316 } 317 } 318 319 // ----------------------------------------------------------------------------- 320 321 void InsertColUndo::Redo() 322 { 323 if( mxTable.is() ) 324 { 325 mxTable->UndoRemoveColumns( mnIndex, maColumns, maCells ); 326 mbUndo = true; 327 } 328 } 329 330 // ----------------------------------------------------------------------------- 331 // class RemoveColUndo : public SdrUndoAction 332 // ----------------------------------------------------------------------------- 333 334 RemoveColUndo::RemoveColUndo( const TableModelRef& xTable, sal_Int32 nIndex, ColumnVector& aNewCols, CellVector& aCells ) 335 : SdrUndoAction( *xTable->getSdrTableObj()->GetModel() ) 336 , mxTable( xTable ) 337 , mnIndex( nIndex ) 338 , mbUndo( true ) 339 { 340 maColumns.swap( aNewCols ); 341 maCells.swap( aCells ); 342 } 343 344 // ----------------------------------------------------------------------------- 345 346 RemoveColUndo::~RemoveColUndo() 347 { 348 if( mbUndo ) 349 { 350 Dispose( maColumns ); 351 Dispose( maCells ); 352 } 353 } 354 355 // ----------------------------------------------------------------------------- 356 357 void RemoveColUndo::Undo() 358 { 359 if( mxTable.is() ) 360 { 361 mxTable->UndoRemoveColumns( mnIndex, maColumns, maCells ); 362 mbUndo = false; 363 } 364 } 365 366 // ----------------------------------------------------------------------------- 367 368 void RemoveColUndo::Redo() 369 { 370 if( mxTable.is() ) 371 { 372 mxTable->UndoInsertColumns( mnIndex, sal::static_int_cast< sal_Int32 >( maColumns.size() ) ); 373 mbUndo = true; 374 } 375 } 376 377 // ----------------------------------------------------------------------------- 378 // class TableColumnUndo : public SdrUndoAction 379 // ----------------------------------------------------------------------------- 380 381 TableColumnUndo::TableColumnUndo( const TableColumnRef& xCol ) 382 : SdrUndoAction( *xCol->mxTableModel->getSdrTableObj()->GetModel() ) 383 , mxCol( xCol ) 384 , mbHasRedoData( false ) 385 { 386 getData( maUndoData ); 387 } 388 389 // ----------------------------------------------------------------------------- 390 391 TableColumnUndo::~TableColumnUndo() 392 { 393 } 394 395 // ----------------------------------------------------------------------------- 396 397 void TableColumnUndo::Undo() 398 { 399 if( !mbHasRedoData ) 400 { 401 getData( maRedoData ); 402 mbHasRedoData = true; 403 } 404 setData( maUndoData ); 405 } 406 407 // ----------------------------------------------------------------------------- 408 409 void TableColumnUndo::Redo() 410 { 411 setData( maRedoData ); 412 } 413 414 // ----------------------------------------------------------------------------- 415 416 sal_Bool TableColumnUndo::Merge( SfxUndoAction *pNextAction ) 417 { 418 TableColumnUndo* pNext = dynamic_cast< TableColumnUndo* >( pNextAction ); 419 return pNext && pNext->mxCol == mxCol; 420 } 421 422 // ----------------------------------------------------------------------------- 423 424 void TableColumnUndo::setData( const Data& rData ) 425 { 426 mxCol->mnColumn = rData.mnColumn; 427 mxCol->mnWidth = rData.mnWidth; 428 mxCol->mbOptimalWidth = rData.mbOptimalWidth; 429 mxCol->mbIsVisible = rData.mbIsVisible; 430 mxCol->mbIsStartOfNewPage = rData.mbIsStartOfNewPage; 431 mxCol->maName = rData.maName; 432 } 433 434 // ----------------------------------------------------------------------------- 435 436 void TableColumnUndo::getData( Data& rData ) 437 { 438 rData.mnColumn = mxCol->mnColumn; 439 rData.mnWidth = mxCol->mnWidth; 440 rData.mbOptimalWidth = mxCol->mbOptimalWidth; 441 rData.mbIsVisible = mxCol->mbIsVisible; 442 rData.mbIsStartOfNewPage = mxCol->mbIsStartOfNewPage; 443 rData.maName = mxCol->maName; 444 } 445 446 // ----------------------------------------------------------------------------- 447 // class TableRowUndo : public SdrUndoAction 448 // ----------------------------------------------------------------------------- 449 450 TableRowUndo::TableRowUndo( const TableRowRef& xRow ) 451 : SdrUndoAction( *xRow->mxTableModel->getSdrTableObj()->GetModel() ) 452 , mxRow( xRow ) 453 , mbHasRedoData( false ) 454 { 455 getData( maUndoData ); 456 } 457 458 // ----------------------------------------------------------------------------- 459 460 TableRowUndo::~TableRowUndo() 461 { 462 } 463 464 // ----------------------------------------------------------------------------- 465 466 void TableRowUndo::Undo() 467 { 468 if( !mbHasRedoData ) 469 { 470 getData( maRedoData ); 471 mbHasRedoData = true; 472 } 473 setData( maUndoData ); 474 } 475 476 // ----------------------------------------------------------------------------- 477 478 void TableRowUndo::Redo() 479 { 480 setData( maRedoData ); 481 } 482 483 // ----------------------------------------------------------------------------- 484 485 sal_Bool TableRowUndo::Merge( SfxUndoAction *pNextAction ) 486 { 487 TableRowUndo* pNext = dynamic_cast< TableRowUndo* >( pNextAction ); 488 return pNext && pNext->mxRow == mxRow; 489 } 490 491 // ----------------------------------------------------------------------------- 492 493 void TableRowUndo::setData( const Data& rData ) 494 { 495 mxRow->mnRow = rData.mnRow; 496 mxRow->mnHeight = rData.mnHeight; 497 mxRow->mbOptimalHeight = rData.mbOptimalHeight; 498 mxRow->mbIsVisible = rData.mbIsVisible; 499 mxRow->mbIsStartOfNewPage = rData.mbIsStartOfNewPage; 500 mxRow->maName = rData.maName; 501 } 502 503 // ----------------------------------------------------------------------------- 504 505 void TableRowUndo::getData( Data& rData ) 506 { 507 rData.mnRow = mxRow->mnRow; 508 rData.mnHeight = mxRow->mnHeight; 509 rData.mbOptimalHeight = mxRow->mbOptimalHeight; 510 rData.mbIsVisible = mxRow->mbIsVisible; 511 rData.mbIsStartOfNewPage = mxRow->mbIsStartOfNewPage; 512 rData.maName = mxRow->maName; 513 } 514 515 // ----------------------------------------------------------------------------- 516 517 TableStyleUndo::TableStyleUndo( const SdrTableObj& rTableObj ) 518 : SdrUndoAction( *rTableObj.GetModel() ) 519 , mxObjRef( const_cast< sdr::table::SdrTableObj*>( &rTableObj ) ) 520 { 521 getData( maUndoData ); 522 } 523 524 void TableStyleUndo::Undo() 525 { 526 if( !mbHasRedoData ) 527 { 528 getData( maRedoData ); 529 mbHasRedoData = true; 530 } 531 setData( maUndoData ); 532 } 533 534 void TableStyleUndo::Redo() 535 { 536 setData( maRedoData ); 537 } 538 539 void TableStyleUndo::setData( const Data& rData ) 540 { 541 SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxObjRef.get() ); 542 if( pTableObj ) 543 { 544 pTableObj->setTableStyle( rData.mxTableStyle ); 545 pTableObj->setTableStyleSettings( rData.maSettings ); 546 } 547 } 548 549 void TableStyleUndo::getData( Data& rData ) 550 { 551 SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxObjRef.get() ); 552 if( pTableObj ) 553 { 554 rData.maSettings = pTableObj->getTableStyleSettings(); 555 rData.mxTableStyle = pTableObj->getTableStyle(); 556 } 557 } 558 559 } } 560