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 mxObjRef->ActionChanged(); 141 } 142 143 void CellUndo::getDataFromCell( Data& rData ) 144 { 145 if( mxObjRef.is() && mxCell.is() ) 146 { 147 if( mxCell->mpProperties ) 148 rData.mpProperties = mxCell->CloneProperties( *mxObjRef.get(), *mxCell.get()); 149 150 if( mxCell->GetOutlinerParaObject() ) 151 rData.mpOutlinerParaObject = new OutlinerParaObject(*mxCell->GetOutlinerParaObject()); 152 else 153 rData.mpOutlinerParaObject = 0; 154 155 rData.mnCellContentType = mxCell->mnCellContentType; 156 157 rData.msFormula = mxCell->msFormula; 158 rData.mfValue = mxCell->mfValue; 159 rData.mnError = mxCell->mnError; 160 rData.mbMerged = mxCell->mbMerged; 161 rData.mnRowSpan = mxCell->mnRowSpan; 162 rData.mnColSpan = mxCell->mnColSpan; 163 } 164 } 165 166 // ----------------------------------------------------------------------------- 167 // class InsertRowUndo : public SdrUndoAction 168 // ----------------------------------------------------------------------------- 169 170 static void Dispose( RowVector& rRows ) 171 { 172 RowVector::iterator aIter( rRows.begin() ); 173 while( aIter != rRows.end() ) 174 (*aIter++)->dispose(); 175 } 176 177 // ----------------------------------------------------------------------------- 178 179 InsertRowUndo::InsertRowUndo( const TableModelRef& xTable, sal_Int32 nIndex, RowVector& aNewRows ) 180 : SdrUndoAction( *xTable->getSdrTableObj()->GetModel() ) 181 , mxTable( xTable ) 182 , mnIndex( nIndex ) 183 , mbUndo( true ) 184 { 185 maRows.swap( aNewRows ); 186 } 187 188 // ----------------------------------------------------------------------------- 189 190 InsertRowUndo::~InsertRowUndo() 191 { 192 if( !mbUndo ) 193 Dispose( maRows ); 194 } 195 196 // ----------------------------------------------------------------------------- 197 198 void InsertRowUndo::Undo() 199 { 200 if( mxTable.is() ) 201 { 202 mxTable->UndoInsertRows( mnIndex, sal::static_int_cast< sal_Int32 >( maRows.size() ) ); 203 mbUndo = false; 204 } 205 } 206 207 // ----------------------------------------------------------------------------- 208 209 void InsertRowUndo::Redo() 210 { 211 if( mxTable.is() ) 212 { 213 mxTable->UndoRemoveRows( mnIndex, maRows ); 214 mbUndo = true; 215 } 216 } 217 218 // ----------------------------------------------------------------------------- 219 // class RemoveRowUndo : public SdrUndoAction 220 // ----------------------------------------------------------------------------- 221 222 RemoveRowUndo::RemoveRowUndo( const TableModelRef& xTable, sal_Int32 nIndex, RowVector& aRemovedRows ) 223 : SdrUndoAction( *xTable->getSdrTableObj()->GetModel() ) 224 , mxTable( xTable ) 225 , mnIndex( nIndex ) 226 , mbUndo( true ) 227 { 228 maRows.swap( aRemovedRows ); 229 } 230 231 // ----------------------------------------------------------------------------- 232 233 RemoveRowUndo::~RemoveRowUndo() 234 { 235 if( mbUndo ) 236 Dispose( maRows ); 237 } 238 239 // ----------------------------------------------------------------------------- 240 241 void RemoveRowUndo::Undo() 242 { 243 if( mxTable.is() ) 244 { 245 mxTable->UndoRemoveRows( mnIndex, maRows ); 246 mbUndo = false; 247 } 248 } 249 250 // ----------------------------------------------------------------------------- 251 252 void RemoveRowUndo::Redo() 253 { 254 if( mxTable.is() ) 255 { 256 mxTable->UndoInsertRows( mnIndex, sal::static_int_cast< sal_Int32 >( maRows.size() ) ); 257 mbUndo = true; 258 } 259 } 260 261 // ----------------------------------------------------------------------------- 262 // class InsertColUndo : public SdrUndoAction 263 // ----------------------------------------------------------------------------- 264 265 static void Dispose( ColumnVector& rCols ) 266 { 267 ColumnVector::iterator aIter( rCols.begin() ); 268 while( aIter != rCols.end() ) 269 (*aIter++)->dispose(); 270 } 271 272 // ----------------------------------------------------------------------------- 273 274 static void Dispose( CellVector& rCells ) 275 { 276 CellVector::iterator aIter( rCells.begin() ); 277 while( aIter != rCells.end() ) 278 (*aIter++)->dispose(); 279 } 280 281 // ----------------------------------------------------------------------------- 282 283 InsertColUndo::InsertColUndo( const TableModelRef& xTable, sal_Int32 nIndex, ColumnVector& aNewCols, CellVector& aCells ) 284 : SdrUndoAction( *xTable->getSdrTableObj()->GetModel() ) 285 , mxTable( xTable ) 286 , mnIndex( nIndex ) 287 , mbUndo( true ) 288 { 289 maColumns.swap( aNewCols ); 290 maCells.swap( aCells ); 291 } 292 293 // ----------------------------------------------------------------------------- 294 295 InsertColUndo::~InsertColUndo() 296 { 297 if( !mbUndo ) 298 { 299 Dispose( maColumns ); 300 Dispose( maCells ); 301 } 302 } 303 304 // ----------------------------------------------------------------------------- 305 306 void InsertColUndo::Undo() 307 { 308 if( mxTable.is() ) 309 { 310 mxTable->UndoInsertColumns( mnIndex, sal::static_int_cast< sal_Int32 >( maColumns.size() ) ); 311 mbUndo = false; 312 } 313 } 314 315 // ----------------------------------------------------------------------------- 316 317 void InsertColUndo::Redo() 318 { 319 if( mxTable.is() ) 320 { 321 mxTable->UndoRemoveColumns( mnIndex, maColumns, maCells ); 322 mbUndo = true; 323 } 324 } 325 326 // ----------------------------------------------------------------------------- 327 // class RemoveColUndo : public SdrUndoAction 328 // ----------------------------------------------------------------------------- 329 330 RemoveColUndo::RemoveColUndo( const TableModelRef& xTable, sal_Int32 nIndex, ColumnVector& aNewCols, CellVector& aCells ) 331 : SdrUndoAction( *xTable->getSdrTableObj()->GetModel() ) 332 , mxTable( xTable ) 333 , mnIndex( nIndex ) 334 , mbUndo( true ) 335 { 336 maColumns.swap( aNewCols ); 337 maCells.swap( aCells ); 338 } 339 340 // ----------------------------------------------------------------------------- 341 342 RemoveColUndo::~RemoveColUndo() 343 { 344 if( mbUndo ) 345 { 346 Dispose( maColumns ); 347 Dispose( maCells ); 348 } 349 } 350 351 // ----------------------------------------------------------------------------- 352 353 void RemoveColUndo::Undo() 354 { 355 if( mxTable.is() ) 356 { 357 mxTable->UndoRemoveColumns( mnIndex, maColumns, maCells ); 358 mbUndo = false; 359 } 360 } 361 362 // ----------------------------------------------------------------------------- 363 364 void RemoveColUndo::Redo() 365 { 366 if( mxTable.is() ) 367 { 368 mxTable->UndoInsertColumns( mnIndex, sal::static_int_cast< sal_Int32 >( maColumns.size() ) ); 369 mbUndo = true; 370 } 371 } 372 373 // ----------------------------------------------------------------------------- 374 // class TableColumnUndo : public SdrUndoAction 375 // ----------------------------------------------------------------------------- 376 377 TableColumnUndo::TableColumnUndo( const TableColumnRef& xCol ) 378 : SdrUndoAction( *xCol->mxTableModel->getSdrTableObj()->GetModel() ) 379 , mxCol( xCol ) 380 , mbHasRedoData( false ) 381 { 382 getData( maUndoData ); 383 } 384 385 // ----------------------------------------------------------------------------- 386 387 TableColumnUndo::~TableColumnUndo() 388 { 389 } 390 391 // ----------------------------------------------------------------------------- 392 393 void TableColumnUndo::Undo() 394 { 395 if( !mbHasRedoData ) 396 { 397 getData( maRedoData ); 398 mbHasRedoData = true; 399 } 400 setData( maUndoData ); 401 } 402 403 // ----------------------------------------------------------------------------- 404 405 void TableColumnUndo::Redo() 406 { 407 setData( maRedoData ); 408 } 409 410 // ----------------------------------------------------------------------------- 411 412 sal_Bool TableColumnUndo::Merge( SfxUndoAction *pNextAction ) 413 { 414 TableColumnUndo* pNext = dynamic_cast< TableColumnUndo* >( pNextAction ); 415 return pNext && pNext->mxCol == mxCol; 416 } 417 418 // ----------------------------------------------------------------------------- 419 420 void TableColumnUndo::setData( const Data& rData ) 421 { 422 mxCol->mnColumn = rData.mnColumn; 423 mxCol->mnWidth = rData.mnWidth; 424 mxCol->mbOptimalWidth = rData.mbOptimalWidth; 425 mxCol->mbIsVisible = rData.mbIsVisible; 426 mxCol->mbIsStartOfNewPage = rData.mbIsStartOfNewPage; 427 mxCol->maName = rData.maName; 428 } 429 430 // ----------------------------------------------------------------------------- 431 432 void TableColumnUndo::getData( Data& rData ) 433 { 434 rData.mnColumn = mxCol->mnColumn; 435 rData.mnWidth = mxCol->mnWidth; 436 rData.mbOptimalWidth = mxCol->mbOptimalWidth; 437 rData.mbIsVisible = mxCol->mbIsVisible; 438 rData.mbIsStartOfNewPage = mxCol->mbIsStartOfNewPage; 439 rData.maName = mxCol->maName; 440 } 441 442 // ----------------------------------------------------------------------------- 443 // class TableRowUndo : public SdrUndoAction 444 // ----------------------------------------------------------------------------- 445 446 TableRowUndo::TableRowUndo( const TableRowRef& xRow ) 447 : SdrUndoAction( *xRow->mxTableModel->getSdrTableObj()->GetModel() ) 448 , mxRow( xRow ) 449 , mbHasRedoData( false ) 450 { 451 getData( maUndoData ); 452 } 453 454 // ----------------------------------------------------------------------------- 455 456 TableRowUndo::~TableRowUndo() 457 { 458 } 459 460 // ----------------------------------------------------------------------------- 461 462 void TableRowUndo::Undo() 463 { 464 if( !mbHasRedoData ) 465 { 466 getData( maRedoData ); 467 mbHasRedoData = true; 468 } 469 setData( maUndoData ); 470 } 471 472 // ----------------------------------------------------------------------------- 473 474 void TableRowUndo::Redo() 475 { 476 setData( maRedoData ); 477 } 478 479 // ----------------------------------------------------------------------------- 480 481 sal_Bool TableRowUndo::Merge( SfxUndoAction *pNextAction ) 482 { 483 TableRowUndo* pNext = dynamic_cast< TableRowUndo* >( pNextAction ); 484 return pNext && pNext->mxRow == mxRow; 485 } 486 487 // ----------------------------------------------------------------------------- 488 489 void TableRowUndo::setData( const Data& rData ) 490 { 491 mxRow->mnRow = rData.mnRow; 492 mxRow->mnHeight = rData.mnHeight; 493 mxRow->mbOptimalHeight = rData.mbOptimalHeight; 494 mxRow->mbIsVisible = rData.mbIsVisible; 495 mxRow->mbIsStartOfNewPage = rData.mbIsStartOfNewPage; 496 mxRow->maName = rData.maName; 497 } 498 499 // ----------------------------------------------------------------------------- 500 501 void TableRowUndo::getData( Data& rData ) 502 { 503 rData.mnRow = mxRow->mnRow; 504 rData.mnHeight = mxRow->mnHeight; 505 rData.mbOptimalHeight = mxRow->mbOptimalHeight; 506 rData.mbIsVisible = mxRow->mbIsVisible; 507 rData.mbIsStartOfNewPage = mxRow->mbIsStartOfNewPage; 508 rData.maName = mxRow->maName; 509 } 510 511 // ----------------------------------------------------------------------------- 512 513 TableStyleUndo::TableStyleUndo( const SdrTableObj& rTableObj ) 514 : SdrUndoAction( *rTableObj.GetModel() ) 515 , mxObjRef( const_cast< sdr::table::SdrTableObj*>( &rTableObj ) ) 516 { 517 getData( maUndoData ); 518 } 519 520 void TableStyleUndo::Undo() 521 { 522 if( !mbHasRedoData ) 523 { 524 getData( maRedoData ); 525 mbHasRedoData = true; 526 } 527 setData( maUndoData ); 528 } 529 530 void TableStyleUndo::Redo() 531 { 532 setData( maRedoData ); 533 } 534 535 void TableStyleUndo::setData( const Data& rData ) 536 { 537 SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxObjRef.get() ); 538 if( pTableObj ) 539 { 540 pTableObj->setTableStyle( rData.mxTableStyle ); 541 pTableObj->setTableStyleSettings( rData.maSettings ); 542 } 543 } 544 545 void TableStyleUndo::getData( Data& rData ) 546 { 547 SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxObjRef.get() ); 548 if( pTableObj ) 549 { 550 rData.maSettings = pTableObj->getTableStyleSettings(); 551 rData.mxTableStyle = pTableObj->getTableStyle(); 552 } 553 } 554 555 } } 556