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