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_sc.hxx" 30 31 32 33 //------------------------------------------------------------------ 34 35 // INCLUDE --------------------------------------------------------------- 36 37 #include "scitems.hxx" 38 #include <vcl/virdev.hxx> 39 #include <vcl/waitobj.hxx> 40 #include <editeng/boxitem.hxx> 41 #include <sfx2/app.hxx> 42 43 #include "undoblk.hxx" 44 #include "undoutil.hxx" 45 #include "document.hxx" 46 #include "patattr.hxx" 47 #include "docsh.hxx" 48 #include "tabvwsh.hxx" 49 #include "rangenam.hxx" 50 #include "rangeutl.hxx" 51 #include "dbcolect.hxx" 52 #include "stlpool.hxx" 53 #include "stlsheet.hxx" 54 #include "globstr.hrc" 55 #include "global.hxx" 56 #include "target.hxx" 57 #include "docpool.hxx" 58 #include "docfunc.hxx" 59 #include "attrib.hxx" 60 #include "chgtrack.hxx" 61 #include "transobj.hxx" 62 #include "refundo.hxx" 63 #include "undoolk.hxx" 64 #include "clipparam.hxx" 65 #include "sc.hrc" 66 67 68 // STATIC DATA ----------------------------------------------------------- 69 70 TYPEINIT1(ScUndoInsertCells, SfxUndoAction); 71 TYPEINIT1(ScUndoDeleteCells, SfxUndoAction); 72 TYPEINIT1(ScUndoDeleteMulti, SfxUndoAction); 73 TYPEINIT1(ScUndoCut, ScBlockUndo); 74 TYPEINIT1(ScUndoPaste, SfxUndoAction); 75 TYPEINIT1(ScUndoDragDrop, SfxUndoAction); 76 TYPEINIT1(ScUndoListNames, SfxUndoAction); 77 TYPEINIT1(ScUndoUseScenario, SfxUndoAction); 78 TYPEINIT1(ScUndoSelectionStyle, SfxUndoAction); 79 TYPEINIT1(ScUndoEnterMatrix, ScBlockUndo); 80 TYPEINIT1(ScUndoIndent, ScBlockUndo); 81 TYPEINIT1(ScUndoTransliterate, ScBlockUndo); 82 TYPEINIT1(ScUndoClearItems, ScBlockUndo); 83 TYPEINIT1(ScUndoRemoveBreaks, SfxUndoAction); 84 TYPEINIT1(ScUndoRemoveMerge, ScBlockUndo); 85 TYPEINIT1(ScUndoBorder, ScBlockUndo); 86 87 88 89 // To Do: 90 /*A*/ // SetOptimalHeight auf Dokument, wenn keine View 91 /*B*/ // gelinkte Tabellen 92 /*C*/ // ScArea 93 //? // spaeter mal pruefen 94 95 96 // ----------------------------------------------------------------------- 97 // 98 // Zellen einfuegen 99 // Zeilen einfuegen 100 // einzeln oder Block 101 // 102 103 ScUndoInsertCells::ScUndoInsertCells( ScDocShell* pNewDocShell, 104 const ScRange& rRange, SCTAB nNewCount, SCTAB* pNewTabs, SCTAB* pNewScenarios, 105 InsCellCmd eNewCmd, ScDocument* pUndoDocument, ScRefUndoData* pRefData, 106 sal_Bool bNewPartOfPaste ) : 107 ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFLAST ), 108 aEffRange( rRange ), 109 nCount( nNewCount ), 110 pTabs( pNewTabs ), 111 pScenarios( pNewScenarios ), 112 eCmd( eNewCmd ), 113 bPartOfPaste( bNewPartOfPaste ), 114 pPasteUndo( NULL ) 115 { 116 if (eCmd == INS_INSROWS) // ganze Zeilen? 117 { 118 aEffRange.aStart.SetCol(0); 119 aEffRange.aEnd.SetCol(MAXCOL); 120 } 121 122 if (eCmd == INS_INSCOLS) // ganze Spalten? 123 { 124 aEffRange.aStart.SetRow(0); 125 aEffRange.aEnd.SetRow(MAXROW); 126 } 127 128 SetChangeTrack(); 129 } 130 131 __EXPORT ScUndoInsertCells::~ScUndoInsertCells() 132 { 133 delete pPasteUndo; 134 delete []pTabs; 135 delete []pScenarios; 136 } 137 138 String __EXPORT ScUndoInsertCells::GetComment() const 139 { 140 return ScGlobal::GetRscString( pPasteUndo ? STR_UNDO_PASTE : STR_UNDO_INSERTCELLS ); 141 } 142 143 sal_Bool ScUndoInsertCells::Merge( SfxUndoAction* pNextAction ) 144 { 145 // If a paste undo action has already been added, append (detective) action there. 146 if ( pPasteUndo ) 147 return pPasteUndo->Merge( pNextAction ); 148 149 if ( bPartOfPaste && pNextAction->ISA( ScUndoWrapper ) ) 150 { 151 ScUndoWrapper* pWrapper = (ScUndoWrapper*)pNextAction; 152 SfxUndoAction* pWrappedAction = pWrapper->GetWrappedUndo(); 153 if ( pWrappedAction && pWrappedAction->ISA( ScUndoPaste ) ) 154 { 155 // Store paste action if this is part of paste with inserting cells. 156 // A list action isn't used because Repeat wouldn't work (insert wrong cells). 157 158 pPasteUndo = pWrappedAction; 159 pWrapper->ForgetWrappedUndo(); // pWrapper is deleted by UndoManager 160 return sal_True; 161 } 162 } 163 164 // Call base class for detective handling 165 return ScMoveUndo::Merge( pNextAction ); 166 } 167 168 void ScUndoInsertCells::SetChangeTrack() 169 { 170 ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack(); 171 if ( pChangeTrack ) 172 { 173 pChangeTrack->AppendInsert( aEffRange ); 174 nEndChangeAction = pChangeTrack->GetActionMax(); 175 } 176 else 177 nEndChangeAction = 0; 178 } 179 180 void ScUndoInsertCells::DoChange( const sal_Bool bUndo ) 181 { 182 ScDocument* pDoc = pDocShell->GetDocument(); 183 SCTAB i; 184 185 if ( bUndo ) 186 { 187 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack(); 188 if ( pChangeTrack ) 189 pChangeTrack->Undo( nEndChangeAction, nEndChangeAction ); 190 } 191 else 192 SetChangeTrack(); 193 194 // refresh of merged cells has to be after inserting/deleting 195 196 switch (eCmd) 197 { 198 case INS_INSROWS: 199 case INS_CELLSDOWN: 200 for( i=0; i<nCount; i++ ) 201 { 202 if (bUndo) 203 pDoc->DeleteRow( aEffRange.aStart.Col(), pTabs[i], aEffRange.aEnd.Col(), pTabs[i]+pScenarios[i], 204 aEffRange.aStart.Row(), static_cast<SCSIZE>(aEffRange.aEnd.Row()-aEffRange.aStart.Row()+1)); 205 else 206 pDoc->InsertRow( aEffRange.aStart.Col(), pTabs[i], aEffRange.aEnd.Col(), pTabs[i]+pScenarios[i], 207 aEffRange.aStart.Row(), static_cast<SCSIZE>(aEffRange.aEnd.Row()-aEffRange.aStart.Row()+1)); 208 } 209 break; 210 case INS_INSCOLS: 211 case INS_CELLSRIGHT: 212 for( i=0; i<nCount; i++ ) 213 { 214 if (bUndo) 215 pDoc->DeleteCol( aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i], 216 aEffRange.aStart.Col(), static_cast<SCSIZE>(aEffRange.aEnd.Col()-aEffRange.aStart.Col()+1)); 217 else 218 pDoc->InsertCol( aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i], 219 aEffRange.aStart.Col(), static_cast<SCSIZE>(aEffRange.aEnd.Col()-aEffRange.aStart.Col()+1)); 220 } 221 break; 222 default: 223 { 224 // added to avoid warnings 225 } 226 } 227 228 ScRange aWorkRange( aEffRange ); 229 if ( eCmd == INS_CELLSRIGHT ) // only "shift right" requires refresh of the moved area 230 aWorkRange.aEnd.SetCol(MAXCOL); 231 for( i=0; i<nCount; i++ ) 232 { 233 if ( pDoc->HasAttrib( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), pTabs[i], 234 aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), pTabs[i], HASATTR_MERGED ) ) 235 { 236 SCCOL nEndCol = aWorkRange.aEnd.Col(); 237 SCROW nEndRow = aWorkRange.aEnd.Row(); 238 pDoc->ExtendMerge( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), nEndCol, nEndRow, pTabs[i], sal_True ); 239 } 240 } 241 242 //? Undo fuer herausgeschobene Attribute ? 243 244 sal_uInt16 nPaint = PAINT_GRID; 245 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell(); 246 switch (eCmd) 247 { 248 case INS_INSROWS: 249 nPaint |= PAINT_LEFT; 250 aWorkRange.aEnd.SetRow(MAXROW); 251 break; 252 case INS_CELLSDOWN: 253 for( i=0; i<nCount; i++ ) 254 { 255 aWorkRange.aEnd.SetRow(MAXROW); 256 if ( pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), pTabs[i] )) 257 { 258 aWorkRange.aStart.SetCol(0); 259 aWorkRange.aEnd.SetCol(MAXCOL); 260 nPaint |= PAINT_LEFT; 261 } 262 } 263 break; 264 case INS_INSCOLS: 265 nPaint |= PAINT_TOP; // obere Leiste 266 case INS_CELLSRIGHT: 267 for( i=0; i<nCount; i++ ) 268 { 269 aWorkRange.aEnd.SetCol(MAXCOL); // bis ganz nach rechts 270 if ( pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), pTabs[i]) ) 271 { // AdjustDraw zeichnet PAINT_TOP nicht, 272 aWorkRange.aStart.SetCol(0); // daher so geloest 273 aWorkRange.aEnd.SetRow(MAXROW); 274 nPaint |= PAINT_LEFT; 275 } 276 } 277 break; 278 default: 279 { 280 // added to avoid warnings 281 } 282 } 283 284 for( i=0; i<nCount; i++ ) 285 { 286 pDocShell->PostPaint( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), pTabs[i], 287 aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), pTabs[i]+pScenarios[i], nPaint ); 288 } 289 pDocShell->PostDataChanged(); 290 if (pViewShell) 291 pViewShell->CellContentChanged(); 292 } 293 294 void __EXPORT ScUndoInsertCells::Undo() 295 { 296 if ( pPasteUndo ) 297 pPasteUndo->Undo(); // undo paste first 298 299 WaitObject aWait( pDocShell->GetActiveDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference 300 BeginUndo(); 301 DoChange( sal_True ); 302 EndUndo(); 303 } 304 305 void __EXPORT ScUndoInsertCells::Redo() 306 { 307 WaitObject aWait( pDocShell->GetActiveDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference 308 BeginRedo(); 309 DoChange( sal_False ); 310 EndRedo(); 311 312 if ( pPasteUndo ) 313 pPasteUndo->Redo(); // redo paste last 314 } 315 316 void __EXPORT ScUndoInsertCells::Repeat(SfxRepeatTarget& rTarget) 317 { 318 if (rTarget.ISA(ScTabViewTarget)) 319 { 320 if ( pPasteUndo ) 321 { 322 // #94115# Repeat for paste with inserting cells is handled completely 323 // by the Paste undo action 324 325 pPasteUndo->Repeat( rTarget ); 326 } 327 else 328 ((ScTabViewTarget&)rTarget).GetViewShell()->InsertCells( eCmd, sal_True ); 329 } 330 } 331 332 sal_Bool __EXPORT ScUndoInsertCells::CanRepeat(SfxRepeatTarget& rTarget) const 333 { 334 return (rTarget.ISA(ScTabViewTarget)); 335 } 336 337 338 // ----------------------------------------------------------------------- 339 // 340 // Zellen loeschen 341 // Zeilen loeschen 342 // einzeln oder Block 343 // 344 345 ScUndoDeleteCells::ScUndoDeleteCells( ScDocShell* pNewDocShell, 346 const ScRange& rRange, SCTAB nNewCount, SCTAB* pNewTabs, SCTAB* pNewScenarios, 347 DelCellCmd eNewCmd, ScDocument* pUndoDocument, ScRefUndoData* pRefData ) : 348 ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFLAST ), 349 aEffRange( rRange ), 350 nCount( nNewCount ), 351 pTabs( pNewTabs ), 352 pScenarios( pNewScenarios ), 353 eCmd( eNewCmd ) 354 { 355 if (eCmd == DEL_DELROWS) // gaze Zeilen? 356 { 357 aEffRange.aStart.SetCol(0); 358 aEffRange.aEnd.SetCol(MAXCOL); 359 } 360 361 if (eCmd == DEL_DELCOLS) // ganze Spalten? 362 { 363 aEffRange.aStart.SetRow(0); 364 aEffRange.aEnd.SetRow(MAXROW); 365 } 366 367 SetChangeTrack(); 368 } 369 370 __EXPORT ScUndoDeleteCells::~ScUndoDeleteCells() 371 { 372 delete []pTabs; 373 delete []pScenarios; 374 } 375 376 String __EXPORT ScUndoDeleteCells::GetComment() const 377 { 378 return ScGlobal::GetRscString( STR_UNDO_DELETECELLS ); // "Loeschen" 379 } 380 381 void ScUndoDeleteCells::SetChangeTrack() 382 { 383 ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack(); 384 if ( pChangeTrack ) 385 pChangeTrack->AppendDeleteRange( aEffRange, pRefUndoDoc, 386 nStartChangeAction, nEndChangeAction ); 387 else 388 nStartChangeAction = nEndChangeAction = 0; 389 } 390 391 void ScUndoDeleteCells::DoChange( const sal_Bool bUndo ) 392 { 393 ScDocument* pDoc = pDocShell->GetDocument(); 394 SCTAB i; 395 396 if ( bUndo ) 397 { 398 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack(); 399 if ( pChangeTrack ) 400 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction ); 401 } 402 else 403 SetChangeTrack(); 404 405 // Ausfuehren 406 switch (eCmd) 407 { 408 case DEL_DELROWS: 409 case DEL_CELLSUP: 410 for( i=0; i<nCount; i++ ) 411 { 412 if (bUndo) 413 pDoc->InsertRow( aEffRange.aStart.Col(), pTabs[i], aEffRange.aEnd.Col(), pTabs[i]+pScenarios[i], 414 aEffRange.aStart.Row(), static_cast<SCSIZE>(aEffRange.aEnd.Row()-aEffRange.aStart.Row()+1)); 415 else 416 pDoc->DeleteRow( aEffRange.aStart.Col(), pTabs[i], aEffRange.aEnd.Col(), pTabs[i]+pScenarios[i], 417 aEffRange.aStart.Row(), static_cast<SCSIZE>(aEffRange.aEnd.Row()-aEffRange.aStart.Row()+1)); 418 } 419 break; 420 case DEL_DELCOLS: 421 case DEL_CELLSLEFT: 422 for( i=0; i<nCount; i++ ) 423 { 424 if (bUndo) 425 pDoc->InsertCol( aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i], 426 aEffRange.aStart.Col(), static_cast<SCSIZE>(aEffRange.aEnd.Col()-aEffRange.aStart.Col()+1)); 427 else 428 pDoc->DeleteCol( aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i], 429 aEffRange.aStart.Col(), static_cast<SCSIZE>(aEffRange.aEnd.Col()-aEffRange.aStart.Col()+1)); 430 } 431 break; 432 default: 433 { 434 // added to avoid warnings 435 } 436 } 437 438 // bei Undo Referenzen wiederherstellen 439 for( i=0; i<nCount && bUndo; i++ ) 440 { 441 pRefUndoDoc->CopyToDocument( aEffRange.aStart.Col(), aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Col(), aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i], 442 IDF_ALL | IDF_NOCAPTIONS, sal_False, pDoc ); 443 } 444 445 ScRange aWorkRange( aEffRange ); 446 if ( eCmd == DEL_CELLSLEFT ) // only "shift left" requires refresh of the moved area 447 aWorkRange.aEnd.SetCol(MAXCOL); 448 449 for( i=0; i<nCount; i++ ) 450 { 451 if ( pDoc->HasAttrib( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), pTabs[i], 452 aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), pTabs[i], HASATTR_MERGED | HASATTR_OVERLAPPED ) ) 453 { 454 // #i51445# old merge flag attributes must be deleted also for single cells, 455 // not only for whole columns/rows 456 457 if ( !bUndo ) 458 { 459 if ( eCmd==DEL_DELCOLS || eCmd==DEL_CELLSLEFT ) 460 aWorkRange.aEnd.SetCol(MAXCOL); 461 if ( eCmd==DEL_DELROWS || eCmd==DEL_CELLSUP ) 462 aWorkRange.aEnd.SetRow(MAXROW); 463 ScMarkData aMarkData; 464 aMarkData.SelectOneTable( aWorkRange.aStart.Tab() ); 465 ScPatternAttr aPattern( pDoc->GetPool() ); 466 aPattern.GetItemSet().Put( ScMergeFlagAttr() ); 467 pDoc->ApplyPatternArea( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), 468 aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), 469 aMarkData, aPattern ); 470 } 471 472 SCCOL nEndCol = aWorkRange.aEnd.Col(); 473 SCROW nEndRow = aWorkRange.aEnd.Row(); 474 pDoc->ExtendMerge( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), nEndCol, nEndRow, pTabs[i], sal_True ); 475 } 476 } 477 478 // Zeichnen 479 sal_uInt16 nPaint = PAINT_GRID; 480 switch (eCmd) 481 { 482 case DEL_DELROWS: 483 nPaint |= PAINT_LEFT; 484 aWorkRange.aEnd.SetRow(MAXROW); 485 break; 486 case DEL_CELLSUP: 487 for( i=0; i<nCount; i++ ) 488 { 489 aWorkRange.aEnd.SetRow(MAXROW); 490 if ( pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), pTabs[i] )) 491 { 492 aWorkRange.aStart.SetCol(0); 493 aWorkRange.aEnd.SetCol(MAXCOL); 494 nPaint |= PAINT_LEFT; 495 } 496 } 497 break; 498 case DEL_DELCOLS: 499 nPaint |= PAINT_TOP; // obere Leiste 500 case DEL_CELLSLEFT: 501 for( i=0; i<nCount; i++ ) 502 { 503 aWorkRange.aEnd.SetCol(MAXCOL); // bis ganz nach rechts 504 if ( pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), pTabs[i] ) ) 505 { 506 aWorkRange.aStart.SetCol(0); 507 aWorkRange.aEnd.SetRow(MAXROW); 508 nPaint |= PAINT_LEFT; 509 } 510 } 511 break; 512 default: 513 { 514 // added to avoid warnings 515 } 516 } 517 518 for( i=0; i<nCount; i++ ) 519 { 520 pDocShell->PostPaint( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), pTabs[i], 521 aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), pTabs[i]+pScenarios[i], nPaint, SC_PF_LINES ); 522 } 523 // Markierung erst nach EndUndo 524 525 pDocShell->PostDataChanged(); 526 // CellContentChanged kommt mit der Markierung 527 } 528 529 void __EXPORT ScUndoDeleteCells::Undo() 530 { 531 WaitObject aWait( pDocShell->GetActiveDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference 532 BeginUndo(); 533 DoChange( sal_True ); 534 EndUndo(); 535 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) ); 536 537 // Markierung erst nach EndUndo 538 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell(); 539 if (pViewShell) 540 { 541 for( SCTAB i=0; i<nCount; i++ ) 542 { 543 pViewShell->MarkRange( ScRange(aEffRange.aStart.Col(), aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Col(), aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i]) ); 544 } 545 } 546 } 547 548 void __EXPORT ScUndoDeleteCells::Redo() 549 { 550 WaitObject aWait( pDocShell->GetActiveDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference 551 BeginRedo(); 552 DoChange( sal_False); 553 EndRedo(); 554 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) ); 555 556 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell(); 557 if (pViewShell) 558 pViewShell->DoneBlockMode(); // aktuelle weg 559 } 560 561 void __EXPORT ScUndoDeleteCells::Repeat(SfxRepeatTarget& rTarget) 562 { 563 if (rTarget.ISA(ScTabViewTarget)) 564 ((ScTabViewTarget&)rTarget).GetViewShell()->DeleteCells( eCmd, sal_True ); 565 } 566 567 sal_Bool __EXPORT ScUndoDeleteCells::CanRepeat(SfxRepeatTarget& rTarget) const 568 { 569 return (rTarget.ISA(ScTabViewTarget)); 570 } 571 572 573 // ----------------------------------------------------------------------- 574 // 575 // Zellen loeschen auf Mehrfachselektion 576 // 577 578 ScUndoDeleteMulti::ScUndoDeleteMulti( ScDocShell* pNewDocShell, 579 sal_Bool bNewRows, sal_Bool bNeedsRefresh, SCTAB nNewTab, 580 const SCCOLROW* pRng, SCCOLROW nRngCnt, 581 ScDocument* pUndoDocument, ScRefUndoData* pRefData ) : 582 ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFLAST ), 583 bRows( bNewRows ), 584 bRefresh( bNeedsRefresh ), 585 nTab( nNewTab ), 586 nRangeCnt( nRngCnt ) 587 { 588 pRanges = new SCCOLROW[ 2 * nRangeCnt ]; 589 memcpy(pRanges,pRng,nRangeCnt*2*sizeof(SCCOLROW)); 590 SetChangeTrack(); 591 } 592 593 __EXPORT ScUndoDeleteMulti::~ScUndoDeleteMulti() 594 { 595 delete [] pRanges; 596 } 597 598 String __EXPORT ScUndoDeleteMulti::GetComment() const 599 { 600 return ScGlobal::GetRscString( STR_UNDO_DELETECELLS ); // wie DeleteCells 601 } 602 603 void ScUndoDeleteMulti::DoChange() const 604 { 605 SCCOL nStartCol; 606 SCROW nStartRow; 607 sal_uInt16 nPaint; 608 if (bRows) 609 { 610 nStartCol = 0; 611 nStartRow = static_cast<SCROW>(pRanges[0]); 612 nPaint = PAINT_GRID | PAINT_LEFT; 613 } 614 else 615 { 616 nStartCol = static_cast<SCCOL>(pRanges[0]); 617 nStartRow = 0; 618 nPaint = PAINT_GRID | PAINT_TOP; 619 } 620 621 if ( bRefresh ) 622 { 623 ScDocument* pDoc = pDocShell->GetDocument(); 624 SCCOL nEndCol = MAXCOL; 625 SCROW nEndRow = MAXROW; 626 pDoc->RemoveFlagsTab( nStartCol, nStartRow, nEndCol, nEndRow, nTab, SC_MF_HOR | SC_MF_VER ); 627 pDoc->ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, nTab, sal_True ); 628 } 629 630 pDocShell->PostPaint( nStartCol, nStartRow, nTab, MAXCOL, MAXROW, nTab, nPaint ); 631 pDocShell->PostDataChanged(); 632 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell(); 633 if (pViewShell) 634 pViewShell->CellContentChanged(); 635 636 ShowTable( nTab ); 637 } 638 639 void ScUndoDeleteMulti::SetChangeTrack() 640 { 641 ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack(); 642 if ( pChangeTrack ) 643 { 644 nStartChangeAction = pChangeTrack->GetActionMax() + 1; 645 ScRange aRange( 0, 0, nTab, 0, 0, nTab ); 646 if ( bRows ) 647 aRange.aEnd.SetCol( MAXCOL ); 648 else 649 aRange.aEnd.SetRow( MAXROW ); 650 // rueckwaerts loeschen 651 SCCOLROW* pOneRange = &pRanges[2*nRangeCnt]; 652 for ( SCCOLROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++ ) 653 { 654 SCCOLROW nEnd = *(--pOneRange); 655 SCCOLROW nStart = *(--pOneRange); 656 if ( bRows ) 657 { 658 aRange.aStart.SetRow( nStart ); 659 aRange.aEnd.SetRow( nEnd ); 660 } 661 else 662 { 663 aRange.aStart.SetCol( static_cast<SCCOL>(nStart) ); 664 aRange.aEnd.SetCol( static_cast<SCCOL>(nEnd) ); 665 } 666 sal_uLong nDummyStart; 667 pChangeTrack->AppendDeleteRange( aRange, pRefUndoDoc, 668 nDummyStart, nEndChangeAction ); 669 } 670 } 671 else 672 nStartChangeAction = nEndChangeAction = 0; 673 } 674 675 void __EXPORT ScUndoDeleteMulti::Undo() 676 { 677 WaitObject aWait( pDocShell->GetActiveDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference 678 BeginUndo(); 679 680 ScDocument* pDoc = pDocShell->GetDocument(); 681 SCCOLROW* pOneRange; 682 SCCOLROW nRangeNo; 683 684 // rueckwaerts geloescht -> vorwaerts einfuegen 685 pOneRange = pRanges; 686 for (nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++) 687 { 688 SCCOLROW nStart = *(pOneRange++); 689 SCCOLROW nEnd = *(pOneRange++); 690 if (bRows) 691 pDoc->InsertRow( 0,nTab, MAXCOL,nTab, nStart,static_cast<SCSIZE>(nEnd-nStart+1) ); 692 else 693 pDoc->InsertCol( 0,nTab, MAXROW,nTab, static_cast<SCCOL>(nStart), static_cast<SCSIZE>(nEnd-nStart+1) ); 694 } 695 696 pOneRange = pRanges; 697 for (nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++) 698 { 699 SCCOLROW nStart = *(pOneRange++); 700 SCCOLROW nEnd = *(pOneRange++); 701 if (bRows) 702 pRefUndoDoc->CopyToDocument( 0,nStart,nTab, MAXCOL,nEnd,nTab, IDF_ALL,sal_False,pDoc ); 703 else 704 pRefUndoDoc->CopyToDocument( static_cast<SCCOL>(nStart),0,nTab, 705 static_cast<SCCOL>(nEnd),MAXROW,nTab, IDF_ALL,sal_False,pDoc ); 706 } 707 708 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack(); 709 if ( pChangeTrack ) 710 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction ); 711 712 DoChange(); 713 714 //! Markierung wieder einzeichnen 715 //! geht im Moment nicht, da keine Daten fuer Markierung vorhanden! 716 717 EndUndo(); 718 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) ); 719 } 720 721 void __EXPORT ScUndoDeleteMulti::Redo() 722 { 723 WaitObject aWait( pDocShell->GetActiveDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference 724 BeginRedo(); 725 726 ScDocument* pDoc = pDocShell->GetDocument(); 727 728 // rueckwaerts loeschen 729 SCCOLROW* pOneRange = &pRanges[2*nRangeCnt]; 730 for (SCCOLROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++) 731 { 732 SCCOLROW nEnd = *(--pOneRange); 733 SCCOLROW nStart = *(--pOneRange); 734 if (bRows) 735 pDoc->DeleteRow( 0,nTab, MAXCOL,nTab, nStart,static_cast<SCSIZE>(nEnd-nStart+1) ); 736 else 737 pDoc->DeleteCol( 0,nTab, MAXROW,nTab, static_cast<SCCOL>(nStart), static_cast<SCSIZE>(nEnd-nStart+1) ); 738 } 739 740 SetChangeTrack(); 741 742 DoChange(); 743 744 //! Markierung loeschen, derzeit unnoetig (s.o.) 745 //! ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell(); 746 //! if (pViewShell) 747 //! DoneBlockMode(); 748 749 EndRedo(); 750 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) ); 751 } 752 753 void __EXPORT ScUndoDeleteMulti::Repeat(SfxRepeatTarget& rTarget) 754 { 755 // DeleteCells, falls einfache Selektion 756 if (rTarget.ISA(ScTabViewTarget)) 757 ((ScTabViewTarget&)rTarget).GetViewShell()->DeleteCells( DEL_DELROWS, sal_True ); 758 } 759 760 sal_Bool __EXPORT ScUndoDeleteMulti::CanRepeat(SfxRepeatTarget& rTarget) const 761 { 762 return (rTarget.ISA(ScTabViewTarget)); 763 } 764 765 766 // ----------------------------------------------------------------------- 767 // 768 // Ausschneiden (Cut) 769 // 770 771 ScUndoCut::ScUndoCut( ScDocShell* pNewDocShell, 772 ScRange aRange, ScAddress aOldEnd, const ScMarkData& rMark, 773 ScDocument* pNewUndoDoc ) : 774 ScBlockUndo( pNewDocShell, ScRange(aRange.aStart, aOldEnd), SC_UNDO_AUTOHEIGHT ), 775 aMarkData( rMark ), 776 pUndoDoc( pNewUndoDoc ), 777 aExtendedRange( aRange ) 778 { 779 SetChangeTrack(); 780 } 781 782 __EXPORT ScUndoCut::~ScUndoCut() 783 { 784 delete pUndoDoc; 785 } 786 787 String __EXPORT ScUndoCut::GetComment() const 788 { 789 return ScGlobal::GetRscString( STR_UNDO_CUT ); // "Ausschneiden" 790 } 791 792 void ScUndoCut::SetChangeTrack() 793 { 794 ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack(); 795 if ( pChangeTrack ) 796 pChangeTrack->AppendContentRange( aBlockRange, pUndoDoc, 797 nStartChangeAction, nEndChangeAction, SC_CACM_CUT ); 798 else 799 nStartChangeAction = nEndChangeAction = 0; 800 } 801 802 void ScUndoCut::DoChange( const sal_Bool bUndo ) 803 { 804 ScDocument* pDoc = pDocShell->GetDocument(); 805 sal_uInt16 nExtFlags = 0; 806 807 // do not undo/redo objects and note captions, they are handled via drawing undo 808 sal_uInt16 nUndoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS; 809 810 if (bUndo) // nur bei Undo 811 { 812 // all sheets - CopyToDocument skips those that don't exist in pUndoDoc 813 SCTAB nTabCount = pDoc->GetTableCount(); 814 ScRange aCopyRange = aExtendedRange; 815 aCopyRange.aStart.SetTab(0); 816 aCopyRange.aEnd.SetTab(nTabCount-1); 817 pUndoDoc->CopyToDocument( aCopyRange, nUndoFlags, sal_False, pDoc ); 818 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack(); 819 if ( pChangeTrack ) 820 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction ); 821 } 822 else // nur bei Redo 823 { 824 pDocShell->UpdatePaintExt( nExtFlags, aExtendedRange ); 825 pDoc->DeleteArea( aBlockRange.aStart.Col(), aBlockRange.aStart.Row(), 826 aBlockRange.aEnd.Col(), aBlockRange.aEnd.Row(), aMarkData, nUndoFlags ); 827 SetChangeTrack(); 828 } 829 830 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell(); 831 if ( !( (pViewShell) && pViewShell->AdjustBlockHeight() ) ) 832 /*A*/ pDocShell->PostPaint( aExtendedRange, PAINT_GRID, nExtFlags ); 833 834 if ( !bUndo ) // draw redo after updating row heights 835 RedoSdrUndoAction( pDrawUndo ); //! include in ScBlockUndo? 836 837 pDocShell->PostDataChanged(); 838 if (pViewShell) 839 pViewShell->CellContentChanged(); 840 } 841 842 void __EXPORT ScUndoCut::Undo() 843 { 844 BeginUndo(); 845 DoChange( sal_True ); 846 EndUndo(); 847 } 848 849 void __EXPORT ScUndoCut::Redo() 850 { 851 BeginRedo(); 852 ScDocument* pDoc = pDocShell->GetDocument(); 853 EnableDrawAdjust( pDoc, sal_False ); //! include in ScBlockUndo? 854 DoChange( sal_False ); 855 EnableDrawAdjust( pDoc, sal_True ); //! include in ScBlockUndo? 856 EndRedo(); 857 } 858 859 void __EXPORT ScUndoCut::Repeat(SfxRepeatTarget& rTarget) 860 { 861 if (rTarget.ISA(ScTabViewTarget)) 862 ((ScTabViewTarget&)rTarget).GetViewShell()->CutToClip( NULL, sal_True ); 863 } 864 865 sal_Bool __EXPORT ScUndoCut::CanRepeat(SfxRepeatTarget& rTarget) const 866 { 867 return (rTarget.ISA(ScTabViewTarget)); 868 } 869 870 871 // ----------------------------------------------------------------------- 872 // 873 // Einfuegen (Paste) 874 // 875 876 ScUndoPaste::ScUndoPaste( ScDocShell* pNewDocShell, 877 SCCOL nStartX, SCROW nStartY, SCTAB nStartZ, 878 SCCOL nEndX, SCROW nEndY, SCTAB nEndZ, 879 const ScMarkData& rMark, 880 ScDocument* pNewUndoDoc, ScDocument* pNewRedoDoc, 881 sal_uInt16 nNewFlags, 882 ScRefUndoData* pRefData, 883 void* /* pFill1 */, void* /* pFill2 */, void* /* pFill3 */, 884 sal_Bool bRedoIsFilled, const ScUndoPasteOptions* pOptions ) : 885 ScBlockUndo( pNewDocShell, ScRange( nStartX, nStartY, nStartZ, nEndX, nEndY, nEndZ ), SC_UNDO_SIMPLE ), 886 aMarkData( rMark ), 887 pUndoDoc( pNewUndoDoc ), 888 pRedoDoc( pNewRedoDoc ), 889 nFlags( nNewFlags ), 890 pRefUndoData( pRefData ), 891 pRefRedoData( NULL ), 892 bRedoFilled( bRedoIsFilled ) 893 { 894 // pFill1,pFill2,pFill3 are there so the ctor calls for simple paste (without cutting) 895 // don't have to be changed and branched for 641. 896 // They can be removed later. 897 898 if ( !aMarkData.IsMarked() ) // no cell marked: 899 aMarkData.SetMarkArea( aBlockRange ); // mark paste block 900 901 if ( pRefUndoData ) 902 pRefUndoData->DeleteUnchanged( pDocShell->GetDocument() ); 903 904 if ( pOptions ) 905 aPasteOptions = *pOptions; // used only for Repeat 906 907 SetChangeTrack(); 908 } 909 910 __EXPORT ScUndoPaste::~ScUndoPaste() 911 { 912 delete pUndoDoc; 913 delete pRedoDoc; 914 delete pRefUndoData; 915 delete pRefRedoData; 916 } 917 918 String __EXPORT ScUndoPaste::GetComment() const 919 { 920 return ScGlobal::GetRscString( STR_UNDO_PASTE ); // "Einfuegen" 921 } 922 923 void ScUndoPaste::SetChangeTrack() 924 { 925 ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack(); 926 if ( pChangeTrack && (nFlags & IDF_CONTENTS) ) 927 pChangeTrack->AppendContentRange( aBlockRange, pUndoDoc, 928 nStartChangeAction, nEndChangeAction, SC_CACM_PASTE ); 929 else 930 nStartChangeAction = nEndChangeAction = 0; 931 } 932 933 void ScUndoPaste::DoChange( const sal_Bool bUndo ) 934 { 935 ScDocument* pDoc = pDocShell->GetDocument(); 936 937 // RefUndoData for redo is created before first undo 938 // (with DeleteUnchanged after the DoUndo call) 939 sal_Bool bCreateRedoData = ( bUndo && pRefUndoData && !pRefRedoData ); 940 if ( bCreateRedoData ) 941 pRefRedoData = new ScRefUndoData( pDoc ); 942 943 ScRefUndoData* pWorkRefData = bUndo ? pRefUndoData : pRefRedoData; 944 945 // fuer Undo immer alle oder keine Inhalte sichern 946 sal_uInt16 nUndoFlags = IDF_NONE; 947 if (nFlags & IDF_CONTENTS) 948 nUndoFlags |= IDF_CONTENTS; 949 if (nFlags & IDF_ATTRIB) 950 nUndoFlags |= IDF_ATTRIB; 951 952 // do not undo/redo objects and note captions, they are handled via drawing undo 953 (nUndoFlags &= ~IDF_OBJECTS) |= IDF_NOCAPTIONS; 954 955 sal_Bool bPaintAll = sal_False; 956 957 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell(); 958 959 // marking is in ScBlockUndo... 960 ScUndoUtil::MarkSimpleBlock( pDocShell, aBlockRange ); 961 962 SCTAB nTabCount = pDoc->GetTableCount(); 963 if ( bUndo && !bRedoFilled ) 964 { 965 if (!pRedoDoc) 966 { 967 sal_Bool bColInfo = ( aBlockRange.aStart.Row()==0 && aBlockRange.aEnd.Row()==MAXROW ); 968 sal_Bool bRowInfo = ( aBlockRange.aStart.Col()==0 && aBlockRange.aEnd.Col()==MAXCOL ); 969 970 pRedoDoc = new ScDocument( SCDOCMODE_UNDO ); 971 pRedoDoc->InitUndoSelected( pDoc, aMarkData, bColInfo, bRowInfo ); 972 } 973 // read "redo" data from the document in the first undo 974 // all sheets - CopyToDocument skips those that don't exist in pRedoDoc 975 ScRange aCopyRange = aBlockRange; 976 aCopyRange.aStart.SetTab(0); 977 aCopyRange.aEnd.SetTab(nTabCount-1); 978 pDoc->CopyToDocument( aCopyRange, nUndoFlags, sal_False, pRedoDoc ); 979 bRedoFilled = sal_True; 980 } 981 982 sal_uInt16 nExtFlags = 0; 983 pDocShell->UpdatePaintExt( nExtFlags, aBlockRange ); 984 985 aMarkData.MarkToMulti(); 986 pDoc->DeleteSelection( nUndoFlags, aMarkData ); 987 aMarkData.MarkToSimple(); 988 989 SCTAB nFirstSelected = aMarkData.GetFirstSelected(); 990 ScRange aTabSelectRange = aBlockRange; 991 SCTAB nTab; 992 993 if ( !bUndo && pRedoDoc ) // Redo: UndoToDocument before handling RefData 994 { 995 aTabSelectRange.aStart.SetTab( nFirstSelected ); 996 aTabSelectRange.aEnd.SetTab( nFirstSelected ); 997 pRedoDoc->UndoToDocument( aTabSelectRange, nUndoFlags, sal_False, pDoc ); 998 for (nTab=0; nTab<nTabCount; nTab++) 999 if (nTab != nFirstSelected && aMarkData.GetTableSelect(nTab)) 1000 { 1001 aTabSelectRange.aStart.SetTab( nTab ); 1002 aTabSelectRange.aEnd.SetTab( nTab ); 1003 pRedoDoc->CopyToDocument( aTabSelectRange, nUndoFlags, sal_False, pDoc ); 1004 } 1005 } 1006 1007 if (pWorkRefData) 1008 { 1009 pWorkRefData->DoUndo( pDoc, sal_True ); // sal_True = bSetChartRangeLists for SetChartListenerCollection 1010 if ( pDoc->RefreshAutoFilter( 0,0, MAXCOL,MAXROW, aBlockRange.aStart.Tab() ) ) 1011 bPaintAll = sal_True; 1012 } 1013 1014 if ( bCreateRedoData && pRefRedoData ) 1015 pRefRedoData->DeleteUnchanged( pDoc ); 1016 1017 if (bUndo) // Undo: UndoToDocument after handling RefData 1018 { 1019 aTabSelectRange.aStart.SetTab( nFirstSelected ); 1020 aTabSelectRange.aEnd.SetTab( nFirstSelected ); 1021 pUndoDoc->UndoToDocument( aTabSelectRange, nUndoFlags, sal_False, pDoc ); 1022 for (nTab=0; nTab<nTabCount; nTab++) 1023 if (nTab != nFirstSelected && aMarkData.GetTableSelect(nTab)) 1024 { 1025 aTabSelectRange.aStart.SetTab( nTab ); 1026 aTabSelectRange.aEnd.SetTab( nTab ); 1027 pUndoDoc->UndoToDocument( aTabSelectRange, nUndoFlags, sal_False, pDoc ); 1028 } 1029 } 1030 1031 if ( bUndo ) 1032 { 1033 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack(); 1034 if ( pChangeTrack ) 1035 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction ); 1036 } 1037 else 1038 SetChangeTrack(); 1039 1040 ScRange aDrawRange( aBlockRange ); 1041 pDoc->ExtendMerge( aDrawRange, sal_True ); // only needed for single sheet (text/rtf etc.) 1042 sal_uInt16 nPaint = PAINT_GRID; 1043 if (bPaintAll) 1044 { 1045 aDrawRange.aStart.SetCol(0); 1046 aDrawRange.aStart.SetRow(0); 1047 aDrawRange.aEnd.SetCol(MAXCOL); 1048 aDrawRange.aEnd.SetRow(MAXROW); 1049 nPaint |= PAINT_TOP | PAINT_LEFT; 1050 /*A*/ if (pViewShell) 1051 pViewShell->AdjustBlockHeight(sal_False); 1052 } 1053 else 1054 { 1055 if ( aBlockRange.aStart.Row() == 0 && aBlockRange.aEnd.Row() == MAXROW ) // ganze Spalte 1056 { 1057 nPaint |= PAINT_TOP; 1058 aDrawRange.aEnd.SetCol(MAXCOL); 1059 } 1060 if ( aBlockRange.aStart.Col() == 0 && aBlockRange.aEnd.Col() == MAXCOL ) // ganze Zeile 1061 { 1062 nPaint |= PAINT_LEFT; 1063 aDrawRange.aEnd.SetRow(MAXROW); 1064 } 1065 /*A*/ if ((pViewShell) && pViewShell->AdjustBlockHeight(sal_False)) 1066 { 1067 aDrawRange.aStart.SetCol(0); 1068 aDrawRange.aStart.SetRow(0); 1069 aDrawRange.aEnd.SetCol(MAXCOL); 1070 aDrawRange.aEnd.SetRow(MAXROW); 1071 nPaint |= PAINT_LEFT; 1072 } 1073 pDocShell->UpdatePaintExt( nExtFlags, aDrawRange ); 1074 } 1075 1076 if ( !bUndo ) // draw redo after updating row heights 1077 RedoSdrUndoAction( pDrawUndo ); //! include in ScBlockUndo? 1078 1079 pDocShell->PostPaint( aDrawRange, nPaint, nExtFlags ); 1080 1081 pDocShell->PostDataChanged(); 1082 if (pViewShell) 1083 pViewShell->CellContentChanged(); 1084 } 1085 1086 void __EXPORT ScUndoPaste::Undo() 1087 { 1088 BeginUndo(); 1089 DoChange( sal_True ); 1090 ShowTable( aBlockRange ); 1091 EndUndo(); 1092 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) ); 1093 } 1094 1095 void __EXPORT ScUndoPaste::Redo() 1096 { 1097 BeginRedo(); 1098 ScDocument* pDoc = pDocShell->GetDocument(); 1099 EnableDrawAdjust( pDoc, sal_False ); //! include in ScBlockUndo? 1100 DoChange( sal_False ); 1101 EnableDrawAdjust( pDoc, sal_True ); //! include in ScBlockUndo? 1102 EndRedo(); 1103 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) ); 1104 } 1105 1106 void __EXPORT ScUndoPaste::Repeat(SfxRepeatTarget& rTarget) 1107 { 1108 if (rTarget.ISA(ScTabViewTarget)) 1109 { 1110 ScTabViewShell* pViewSh = ((ScTabViewTarget&)rTarget).GetViewShell(); 1111 ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pViewSh->GetActiveWin() ); 1112 if (pOwnClip) 1113 { 1114 // #129384# keep a reference in case the clipboard is changed during PasteFromClip 1115 com::sun::star::uno::Reference<com::sun::star::datatransfer::XTransferable> aOwnClipRef( pOwnClip ); 1116 pViewSh->PasteFromClip( nFlags, pOwnClip->GetDocument(), 1117 aPasteOptions.nFunction, aPasteOptions.bSkipEmpty, aPasteOptions.bTranspose, 1118 aPasteOptions.bAsLink, aPasteOptions.eMoveMode, IDF_NONE, 1119 sal_True ); // allow warning dialog 1120 } 1121 } 1122 } 1123 1124 sal_Bool __EXPORT ScUndoPaste::CanRepeat(SfxRepeatTarget& rTarget) const 1125 { 1126 return (rTarget.ISA(ScTabViewTarget)); 1127 } 1128 1129 1130 // ----------------------------------------------------------------------- 1131 // 1132 // Verschieben/Kopieren (Drag & Drop) 1133 // 1134 1135 ScUndoDragDrop::ScUndoDragDrop( ScDocShell* pNewDocShell, 1136 const ScRange& rRange, ScAddress aNewDestPos, sal_Bool bNewCut, 1137 ScDocument* pUndoDocument, ScRefUndoData* pRefData, sal_Bool bScenario ) : 1138 ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFFIRST ), 1139 aSrcRange( rRange ), 1140 bCut( bNewCut ), 1141 bKeepScenarioFlags( bScenario ) 1142 { 1143 ScAddress aDestEnd(aNewDestPos); 1144 aDestEnd.IncRow(aSrcRange.aEnd.Row() - aSrcRange.aStart.Row()); 1145 aDestEnd.IncCol(aSrcRange.aEnd.Col() - aSrcRange.aStart.Col()); 1146 aDestEnd.IncTab(aSrcRange.aEnd.Tab() - aSrcRange.aStart.Tab()); 1147 1148 sal_Bool bIncludeFiltered = bCut; 1149 if ( !bIncludeFiltered ) 1150 { 1151 // find number of non-filtered rows 1152 SCROW nPastedCount = pDocShell->GetDocument()->CountNonFilteredRows( 1153 aSrcRange.aStart.Row(), aSrcRange.aEnd.Row(), aSrcRange.aStart.Tab()); 1154 1155 if ( nPastedCount == 0 ) 1156 nPastedCount = 1; 1157 aDestEnd.SetRow( aNewDestPos.Row() + nPastedCount - 1 ); 1158 } 1159 1160 aDestRange.aStart = aNewDestPos; 1161 aDestRange.aEnd = aDestEnd; 1162 1163 SetChangeTrack(); 1164 } 1165 1166 __EXPORT ScUndoDragDrop::~ScUndoDragDrop() 1167 { 1168 } 1169 1170 String __EXPORT ScUndoDragDrop::GetComment() const 1171 { // "Verschieben" : "Kopieren" 1172 return bCut ? 1173 ScGlobal::GetRscString( STR_UNDO_MOVE ) : 1174 ScGlobal::GetRscString( STR_UNDO_COPY ); 1175 } 1176 1177 void ScUndoDragDrop::SetChangeTrack() 1178 { 1179 ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack(); 1180 if ( pChangeTrack ) 1181 { 1182 if ( bCut ) 1183 { 1184 nStartChangeAction = pChangeTrack->GetActionMax() + 1; 1185 pChangeTrack->AppendMove( aSrcRange, aDestRange, pRefUndoDoc ); 1186 nEndChangeAction = pChangeTrack->GetActionMax(); 1187 } 1188 else 1189 pChangeTrack->AppendContentRange( aDestRange, pRefUndoDoc, 1190 nStartChangeAction, nEndChangeAction ); 1191 } 1192 else 1193 nStartChangeAction = nEndChangeAction = 0; 1194 } 1195 1196 void ScUndoDragDrop::PaintArea( ScRange aRange, sal_uInt16 nExtFlags ) const 1197 { 1198 sal_uInt16 nPaint = PAINT_GRID; 1199 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell(); 1200 ScDocument* pDoc = pDocShell->GetDocument(); 1201 1202 if (pViewShell) 1203 { 1204 VirtualDevice aVirtDev; 1205 ScViewData* pViewData = pViewShell->GetViewData(); 1206 1207 if ( pDoc->SetOptimalHeight( aRange.aStart.Row(), aRange.aEnd.Row(), 1208 aRange.aStart.Tab(), 0, &aVirtDev, 1209 pViewData->GetPPTX(), pViewData->GetPPTY(), 1210 pViewData->GetZoomX(), pViewData->GetZoomY(), 1211 sal_False ) ) 1212 { 1213 aRange.aStart.SetCol(0); 1214 aRange.aEnd.SetCol(MAXCOL); 1215 aRange.aEnd.SetRow(MAXROW); 1216 nPaint |= PAINT_LEFT; 1217 } 1218 } 1219 1220 if ( bKeepScenarioFlags ) 1221 { 1222 // Szenarien mitkopiert -> auch Szenario-Rahmen painten 1223 aRange.aStart.SetCol(0); 1224 aRange.aStart.SetRow(0); 1225 aRange.aEnd.SetCol(MAXCOL); 1226 aRange.aEnd.SetRow(MAXROW); 1227 } 1228 1229 // column/row info (width/height) included if whole columns/rows were copied 1230 if ( aSrcRange.aStart.Col() == 0 && aSrcRange.aEnd.Col() == MAXCOL ) 1231 { 1232 nPaint |= PAINT_LEFT; 1233 aRange.aEnd.SetRow(MAXROW); 1234 } 1235 if ( aSrcRange.aStart.Row() == 0 && aSrcRange.aEnd.Row() == MAXROW ) 1236 { 1237 nPaint |= PAINT_TOP; 1238 aRange.aEnd.SetCol(MAXCOL); 1239 } 1240 1241 pDocShell->PostPaint( aRange, nPaint, nExtFlags ); 1242 } 1243 1244 1245 void ScUndoDragDrop::DoUndo( ScRange aRange ) const 1246 { 1247 ScDocument* pDoc = pDocShell->GetDocument(); 1248 1249 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack(); 1250 if ( pChangeTrack ) 1251 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction ); 1252 1253 //? DB-Areas vor Daten, damit bei ExtendMerge die Autofilter-Knoepfe stimmen 1254 1255 ScRange aPaintRange = aRange; 1256 pDoc->ExtendMerge( aPaintRange ); // before deleting 1257 1258 sal_uInt16 nExtFlags = 0; 1259 pDocShell->UpdatePaintExt( nExtFlags, aPaintRange ); 1260 1261 // do not undo objects and note captions, they are handled via drawing undo 1262 sal_uInt16 nUndoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS; 1263 1264 pDoc->DeleteAreaTab( aRange, nUndoFlags ); 1265 pRefUndoDoc->CopyToDocument( aRange, nUndoFlags, sal_False, pDoc ); 1266 if ( pDoc->HasAttrib( aRange, HASATTR_MERGED ) ) 1267 pDoc->ExtendMerge( aRange, sal_True ); 1268 1269 aPaintRange.aEnd.SetCol( Max( aPaintRange.aEnd.Col(), aRange.aEnd.Col() ) ); 1270 aPaintRange.aEnd.SetRow( Max( aPaintRange.aEnd.Row(), aRange.aEnd.Row() ) ); 1271 1272 pDocShell->UpdatePaintExt( nExtFlags, aPaintRange ); 1273 PaintArea( aPaintRange, nExtFlags ); 1274 } 1275 1276 void __EXPORT ScUndoDragDrop::Undo() 1277 { 1278 BeginUndo(); 1279 DoUndo(aDestRange); 1280 if (bCut) 1281 DoUndo(aSrcRange); 1282 EndUndo(); 1283 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) ); 1284 } 1285 1286 void __EXPORT ScUndoDragDrop::Redo() 1287 { 1288 BeginRedo(); 1289 1290 ScDocument* pDoc = pDocShell->GetDocument(); 1291 ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP ); 1292 1293 EnableDrawAdjust( pDoc, sal_False ); //! include in ScBlockUndo? 1294 1295 // do not undo/redo objects and note captions, they are handled via drawing undo 1296 sal_uInt16 nRedoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS; 1297 1298 /* TODO: Redoing note captions is quite tricky due to the fact that a 1299 helper clip document is used. While (re-)pasting the contents to the 1300 destination area, the original pointers to the captions created while 1301 dropping have to be restored. A simple CopyFromClip() would create new 1302 caption objects that are not tracked by drawing undo, and the captions 1303 restored by drawing redo would live without cell note objects pointing 1304 to them. So, first, CopyToClip() and CopyFromClip() are called without 1305 cloning the caption objects. This leads to cell notes pointing to the 1306 wrong captions from source area that will be removed by drawing redo 1307 later. Second, the pointers to the new captions have to be restored. 1308 Sadly, currently these pointers are not stored anywhere but in the list 1309 of drawing undo actions. */ 1310 1311 SCTAB nTab; 1312 ScMarkData aSourceMark; 1313 for (nTab=aSrcRange.aStart.Tab(); nTab<=aSrcRange.aEnd.Tab(); nTab++) 1314 aSourceMark.SelectTable( nTab, sal_True ); 1315 1316 // do not clone objects and note captions into clipdoc (see above) 1317 ScClipParam aClipParam(aSrcRange, bCut); 1318 pDoc->CopyToClip(aClipParam, pClipDoc, &aSourceMark, false, bKeepScenarioFlags, false, false); 1319 1320 if (bCut) 1321 { 1322 ScRange aSrcPaintRange = aSrcRange; 1323 pDoc->ExtendMerge( aSrcPaintRange ); // before deleting 1324 sal_uInt16 nExtFlags = 0; 1325 pDocShell->UpdatePaintExt( nExtFlags, aSrcPaintRange ); 1326 pDoc->DeleteAreaTab( aSrcRange, nRedoFlags ); 1327 PaintArea( aSrcPaintRange, nExtFlags ); 1328 } 1329 1330 ScMarkData aDestMark; 1331 for (nTab=aDestRange.aStart.Tab(); nTab<=aDestRange.aEnd.Tab(); nTab++) 1332 aDestMark.SelectTable( nTab, sal_True ); 1333 1334 sal_Bool bIncludeFiltered = bCut; 1335 // TODO: restore old note captions instead of cloning new captions... 1336 pDoc->CopyFromClip( aDestRange, aDestMark, IDF_ALL & ~IDF_OBJECTS, NULL, pClipDoc, sal_True, sal_False, bIncludeFiltered ); 1337 1338 if (bCut) 1339 for (nTab=aSrcRange.aStart.Tab(); nTab<=aSrcRange.aEnd.Tab(); nTab++) 1340 pDoc->RefreshAutoFilter( aSrcRange.aStart.Col(), aSrcRange.aStart.Row(), 1341 aSrcRange.aEnd.Col(), aSrcRange.aEnd.Row(), nTab ); 1342 1343 // skipped rows and merged cells don't mix 1344 if ( !bIncludeFiltered && pClipDoc->HasClipFilteredRows() ) 1345 pDocShell->GetDocFunc().UnmergeCells( aDestRange, sal_False, sal_True ); 1346 1347 for (nTab=aDestRange.aStart.Tab(); nTab<=aDestRange.aEnd.Tab(); nTab++) 1348 { 1349 SCCOL nEndCol = aDestRange.aEnd.Col(); 1350 SCROW nEndRow = aDestRange.aEnd.Row(); 1351 pDoc->ExtendMerge( aDestRange.aStart.Col(), aDestRange.aStart.Row(), 1352 nEndCol, nEndRow, nTab, sal_True ); 1353 PaintArea( ScRange( aDestRange.aStart.Col(), aDestRange.aStart.Row(), nTab, 1354 nEndCol, nEndRow, nTab ), 0 ); 1355 } 1356 1357 SetChangeTrack(); 1358 1359 delete pClipDoc; 1360 ShowTable( aDestRange.aStart.Tab() ); 1361 1362 RedoSdrUndoAction( pDrawUndo ); //! include in ScBlockUndo? 1363 EnableDrawAdjust( pDoc, sal_True ); //! include in ScBlockUndo? 1364 1365 EndRedo(); 1366 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) ); 1367 } 1368 1369 void __EXPORT ScUndoDragDrop::Repeat(SfxRepeatTarget& /* rTarget */) 1370 { 1371 } 1372 1373 sal_Bool __EXPORT ScUndoDragDrop::CanRepeat(SfxRepeatTarget& /* rTarget */) const 1374 { 1375 return sal_False; // geht nicht 1376 } 1377 1378 1379 // ----------------------------------------------------------------------- 1380 // 1381 // Liste der Bereichsnamen einfuegen 1382 // (Einfuegen|Name|Einfuegen =>[Liste]) 1383 // 1384 1385 ScUndoListNames::ScUndoListNames( ScDocShell* pNewDocShell, const ScRange& rRange, 1386 ScDocument* pNewUndoDoc, ScDocument* pNewRedoDoc ) : 1387 ScBlockUndo( pNewDocShell, rRange, SC_UNDO_AUTOHEIGHT ), 1388 pUndoDoc( pNewUndoDoc ), 1389 pRedoDoc( pNewRedoDoc ) 1390 { 1391 } 1392 1393 __EXPORT ScUndoListNames::~ScUndoListNames() 1394 { 1395 delete pUndoDoc; 1396 delete pRedoDoc; 1397 } 1398 1399 String __EXPORT ScUndoListNames::GetComment() const 1400 { 1401 return ScGlobal::GetRscString( STR_UNDO_LISTNAMES ); 1402 } 1403 1404 void ScUndoListNames::DoChange( ScDocument* pSrcDoc ) const 1405 { 1406 ScDocument* pDoc = pDocShell->GetDocument(); 1407 1408 pDoc->DeleteAreaTab( aBlockRange, IDF_ALL ); 1409 pSrcDoc->CopyToDocument( aBlockRange, IDF_ALL, sal_False, pDoc ); 1410 pDocShell->PostPaint( aBlockRange, PAINT_GRID ); 1411 pDocShell->PostDataChanged(); 1412 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell(); 1413 if (pViewShell) 1414 pViewShell->CellContentChanged(); 1415 } 1416 1417 void __EXPORT ScUndoListNames::Undo() 1418 { 1419 BeginUndo(); 1420 DoChange(pUndoDoc); 1421 EndUndo(); 1422 } 1423 1424 void __EXPORT ScUndoListNames::Redo() 1425 { 1426 BeginRedo(); 1427 DoChange(pRedoDoc); 1428 EndRedo(); 1429 } 1430 1431 void __EXPORT ScUndoListNames::Repeat(SfxRepeatTarget& rTarget) 1432 { 1433 if (rTarget.ISA(ScTabViewTarget)) 1434 ((ScTabViewTarget&)rTarget).GetViewShell()->InsertNameList(); 1435 } 1436 1437 sal_Bool __EXPORT ScUndoListNames::CanRepeat(SfxRepeatTarget& rTarget) const 1438 { 1439 return (rTarget.ISA(ScTabViewTarget)); 1440 } 1441 1442 1443 // ----------------------------------------------------------------------- 1444 // 1445 // Szenario anwenden 1446 // (Extras|Szenarien) 1447 // 1448 1449 ScUndoUseScenario::ScUndoUseScenario( ScDocShell* pNewDocShell, 1450 const ScMarkData& rMark, 1451 /*C*/ const ScArea& rDestArea, 1452 ScDocument* pNewUndoDoc, 1453 const String& rNewName ) : 1454 ScSimpleUndo( pNewDocShell ), 1455 pUndoDoc( pNewUndoDoc ), 1456 aMarkData( rMark ), 1457 aName( rNewName ) 1458 { 1459 aRange.aStart.SetCol(rDestArea.nColStart); 1460 aRange.aStart.SetRow(rDestArea.nRowStart); 1461 aRange.aStart.SetTab(rDestArea.nTab); 1462 aRange.aEnd.SetCol(rDestArea.nColEnd); 1463 aRange.aEnd.SetRow(rDestArea.nRowEnd); 1464 aRange.aEnd.SetTab(rDestArea.nTab); 1465 } 1466 1467 __EXPORT ScUndoUseScenario::~ScUndoUseScenario() 1468 { 1469 delete pUndoDoc; 1470 } 1471 1472 String __EXPORT ScUndoUseScenario::GetComment() const 1473 { 1474 return ScGlobal::GetRscString( STR_UNDO_USESCENARIO ); 1475 } 1476 1477 void __EXPORT ScUndoUseScenario::Undo() 1478 { 1479 BeginUndo(); 1480 1481 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell(); 1482 if (pViewShell) 1483 { 1484 pViewShell->DoneBlockMode(); 1485 pViewShell->InitOwnBlockMode(); 1486 } 1487 1488 ScDocument* pDoc = pDocShell->GetDocument(); 1489 pDoc->DeleteSelection( IDF_ALL, aMarkData ); 1490 pUndoDoc->CopyToDocument( aRange, IDF_ALL, sal_True, pDoc, &aMarkData ); 1491 1492 // Szenario-Tabellen 1493 sal_Bool bFrame = sal_False; 1494 SCTAB nTab = aRange.aStart.Tab(); 1495 SCTAB nEndTab = nTab; 1496 while ( pUndoDoc->HasTable(nEndTab+1) && pUndoDoc->IsScenario(nEndTab+1) ) 1497 ++nEndTab; 1498 for (SCTAB i = nTab+1; i<=nEndTab; i++) 1499 { 1500 // Flags immer 1501 String aComment; 1502 Color aColor; 1503 sal_uInt16 nScenFlags; 1504 pUndoDoc->GetScenarioData( i, aComment, aColor, nScenFlags ); 1505 pDoc->SetScenarioData( i, aComment, aColor, nScenFlags ); 1506 sal_Bool bActive = pUndoDoc->IsActiveScenario( i ); 1507 pDoc->SetActiveScenario( i, bActive ); 1508 // Bei Zurueckkopier-Szenarios auch Inhalte 1509 if ( nScenFlags & SC_SCENARIO_TWOWAY ) 1510 { 1511 pDoc->DeleteAreaTab( 0,0, MAXCOL,MAXROW, i, IDF_ALL ); 1512 pUndoDoc->CopyToDocument( 0,0,i, MAXCOL,MAXROW,i, IDF_ALL,sal_False, pDoc ); 1513 } 1514 if ( nScenFlags & SC_SCENARIO_SHOWFRAME ) 1515 bFrame = sal_True; 1516 } 1517 1518 // Wenn sichtbare Rahmen, dann alles painten 1519 if (bFrame) 1520 pDocShell->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID | PAINT_EXTRAS ); 1521 else 1522 pDocShell->PostPaint( aRange, PAINT_GRID | PAINT_EXTRAS ); 1523 pDocShell->PostDataChanged(); 1524 if (pViewShell) 1525 pViewShell->CellContentChanged(); 1526 1527 ShowTable( aRange.aStart.Tab() ); 1528 1529 EndUndo(); 1530 } 1531 1532 void __EXPORT ScUndoUseScenario::Redo() 1533 { 1534 SCTAB nTab = aRange.aStart.Tab(); 1535 BeginRedo(); 1536 1537 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell(); 1538 if (pViewShell) 1539 { 1540 pViewShell->SetTabNo( nTab ); 1541 pViewShell->DoneBlockMode(); 1542 pViewShell->InitOwnBlockMode(); 1543 } 1544 1545 pDocShell->UseScenario( nTab, aName, sal_False ); 1546 1547 EndRedo(); 1548 } 1549 1550 void __EXPORT ScUndoUseScenario::Repeat(SfxRepeatTarget& rTarget) 1551 { 1552 if (rTarget.ISA(ScTabViewTarget)) 1553 { 1554 String aTemp = aName; 1555 ((ScTabViewTarget&)rTarget).GetViewShell()->UseScenario(aTemp); 1556 } 1557 } 1558 1559 sal_Bool __EXPORT ScUndoUseScenario::CanRepeat(SfxRepeatTarget& rTarget) const 1560 { 1561 if (rTarget.ISA(ScTabViewTarget)) 1562 { 1563 ScViewData* pViewData = ((ScTabViewTarget&)rTarget).GetViewShell()->GetViewData(); 1564 return !pViewData->GetDocument()->IsScenario( pViewData->GetTabNo() ); 1565 } 1566 return sal_False; 1567 } 1568 1569 1570 // ----------------------------------------------------------------------- 1571 // 1572 // Vorlage anwenden 1573 // (Format|Vorlagenkatalog) 1574 // 1575 1576 ScUndoSelectionStyle::ScUndoSelectionStyle( ScDocShell* pNewDocShell, 1577 const ScMarkData& rMark, 1578 const ScRange& rRange, 1579 const String& rName, 1580 ScDocument* pNewUndoDoc ) : 1581 ScSimpleUndo( pNewDocShell ), 1582 aMarkData( rMark ), 1583 pUndoDoc( pNewUndoDoc ), 1584 aStyleName( rName ), 1585 aRange( rRange ) 1586 { 1587 aMarkData.MarkToMulti(); 1588 } 1589 1590 __EXPORT ScUndoSelectionStyle::~ScUndoSelectionStyle() 1591 { 1592 delete pUndoDoc; 1593 } 1594 1595 String __EXPORT ScUndoSelectionStyle::GetComment() const 1596 { 1597 return ScGlobal::GetRscString( STR_UNDO_APPLYCELLSTYLE ); 1598 } 1599 1600 void ScUndoSelectionStyle::DoChange( const sal_Bool bUndo ) 1601 { 1602 ScDocument* pDoc = pDocShell->GetDocument(); 1603 1604 SetViewMarkData( aMarkData ); 1605 1606 ScRange aWorkRange( aRange ); 1607 if ( pDoc->HasAttrib( aWorkRange, HASATTR_MERGED ) ) // zusammengefasste Zellen? 1608 pDoc->ExtendMerge( aWorkRange, sal_True ); 1609 1610 sal_uInt16 nExtFlags = 0; 1611 pDocShell->UpdatePaintExt( nExtFlags, aWorkRange ); 1612 1613 if (bUndo) // bei Undo alte Daten wieder reinschubsen 1614 { 1615 SCTAB nTabCount = pDoc->GetTableCount(); 1616 ScRange aCopyRange = aWorkRange; 1617 aCopyRange.aStart.SetTab(0); 1618 aCopyRange.aEnd.SetTab(nTabCount-1); 1619 pUndoDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, sal_True, pDoc, &aMarkData ); 1620 } 1621 else // bei Redo Style wieder zuweisen 1622 { 1623 ScStyleSheetPool* pStlPool = pDoc->GetStyleSheetPool(); 1624 ScStyleSheet* pStyleSheet = 1625 (ScStyleSheet*) pStlPool->Find( aStyleName, SFX_STYLE_FAMILY_PARA ); 1626 if (!pStyleSheet) 1627 { 1628 DBG_ERROR("StyleSheet not found"); 1629 return; 1630 } 1631 pDoc->ApplySelectionStyle( *pStyleSheet, aMarkData ); 1632 } 1633 1634 pDocShell->UpdatePaintExt( nExtFlags, aWorkRange ); 1635 1636 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell(); 1637 if ( !( (pViewShell) && pViewShell->AdjustBlockHeight() ) ) 1638 /*A*/ pDocShell->PostPaint( aWorkRange, PAINT_GRID | PAINT_EXTRAS, nExtFlags ); 1639 1640 ShowTable( aWorkRange.aStart.Tab() ); 1641 } 1642 1643 void __EXPORT ScUndoSelectionStyle::Undo() 1644 { 1645 BeginUndo(); 1646 DoChange( sal_True ); 1647 EndUndo(); 1648 } 1649 1650 void __EXPORT ScUndoSelectionStyle::Redo() 1651 { 1652 BeginRedo(); 1653 DoChange( sal_False ); 1654 EndRedo(); 1655 } 1656 1657 void __EXPORT ScUndoSelectionStyle::Repeat(SfxRepeatTarget& rTarget) 1658 { 1659 if (rTarget.ISA(ScTabViewTarget)) 1660 { 1661 ScDocument* pDoc = pDocShell->GetDocument(); 1662 ScStyleSheetPool* pStlPool = pDoc->GetStyleSheetPool(); 1663 ScStyleSheet* pStyleSheet = (ScStyleSheet*) pStlPool-> 1664 Find( aStyleName, SFX_STYLE_FAMILY_PARA ); 1665 if (!pStyleSheet) 1666 { 1667 DBG_ERROR("StyleSheet not found"); 1668 return; 1669 } 1670 1671 ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell(); 1672 rViewShell.SetStyleSheetToMarked( pStyleSheet, sal_True ); 1673 } 1674 } 1675 1676 sal_Bool __EXPORT ScUndoSelectionStyle::CanRepeat(SfxRepeatTarget& rTarget) const 1677 { 1678 return (rTarget.ISA(ScTabViewTarget)); 1679 } 1680 1681 sal_uInt16 __EXPORT ScUndoSelectionStyle::GetId() const 1682 { 1683 return STR_UNDO_APPLYCELLSTYLE; 1684 } 1685 1686 1687 // ----------------------------------------------------------------------- 1688 // 1689 // Matrix-Formel eingeben 1690 // 1691 1692 ScUndoEnterMatrix::ScUndoEnterMatrix( ScDocShell* pNewDocShell, const ScRange& rArea, 1693 ScDocument* pNewUndoDoc, const String& rForm ) : 1694 ScBlockUndo( pNewDocShell, rArea, SC_UNDO_SIMPLE ), 1695 pUndoDoc( pNewUndoDoc ), 1696 aFormula( rForm ) 1697 { 1698 SetChangeTrack(); 1699 } 1700 1701 __EXPORT ScUndoEnterMatrix::~ScUndoEnterMatrix() 1702 { 1703 delete pUndoDoc; 1704 } 1705 1706 String __EXPORT ScUndoEnterMatrix::GetComment() const 1707 { 1708 return ScGlobal::GetRscString( STR_UNDO_ENTERMATRIX ); 1709 } 1710 1711 void ScUndoEnterMatrix::SetChangeTrack() 1712 { 1713 ScDocument* pDoc = pDocShell->GetDocument(); 1714 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack(); 1715 if ( pChangeTrack ) 1716 pChangeTrack->AppendContentRange( aBlockRange, pUndoDoc, 1717 nStartChangeAction, nEndChangeAction ); 1718 else 1719 nStartChangeAction = nEndChangeAction = 0; 1720 } 1721 1722 void __EXPORT ScUndoEnterMatrix::Undo() 1723 { 1724 BeginUndo(); 1725 1726 ScDocument* pDoc = pDocShell->GetDocument(); 1727 1728 pDoc->DeleteAreaTab( aBlockRange, IDF_ALL & ~IDF_NOTE ); 1729 pUndoDoc->CopyToDocument( aBlockRange, IDF_ALL & ~IDF_NOTE, sal_False, pDoc ); 1730 pDocShell->PostPaint( aBlockRange, PAINT_GRID ); 1731 pDocShell->PostDataChanged(); 1732 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell(); 1733 if (pViewShell) 1734 pViewShell->CellContentChanged(); 1735 1736 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack(); 1737 if ( pChangeTrack ) 1738 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction ); 1739 1740 EndUndo(); 1741 } 1742 1743 void __EXPORT ScUndoEnterMatrix::Redo() 1744 { 1745 BeginRedo(); 1746 1747 ScDocument* pDoc = pDocShell->GetDocument(); 1748 1749 ScMarkData aDestMark; 1750 aDestMark.SelectOneTable( aBlockRange.aStart.Tab() ); 1751 aDestMark.SetMarkArea( aBlockRange ); 1752 1753 pDoc->InsertMatrixFormula( aBlockRange.aStart.Col(), aBlockRange.aStart.Row(), 1754 aBlockRange.aEnd.Col(), aBlockRange.aEnd.Row(), 1755 aDestMark, aFormula ); 1756 // pDocShell->PostPaint( aBlockRange, PAINT_GRID ); // nicht noetig ??? 1757 1758 SetChangeTrack(); 1759 1760 EndRedo(); 1761 } 1762 1763 void __EXPORT ScUndoEnterMatrix::Repeat(SfxRepeatTarget& rTarget) 1764 { 1765 if (rTarget.ISA(ScTabViewTarget)) 1766 { 1767 String aTemp = aFormula; 1768 ((ScTabViewTarget&)rTarget).GetViewShell()->EnterMatrix(aTemp); 1769 } 1770 } 1771 1772 sal_Bool __EXPORT ScUndoEnterMatrix::CanRepeat(SfxRepeatTarget& rTarget) const 1773 { 1774 return (rTarget.ISA(ScTabViewTarget)); 1775 } 1776 1777 // ----------------------------------------------------------------------- 1778 // 1779 // Einzug vermindern / erhoehen 1780 // 1781 1782 ScRange lcl_GetMultiMarkRange( const ScMarkData& rMark ) 1783 { 1784 DBG_ASSERT( rMark.IsMultiMarked(), "wrong mark type" ); 1785 1786 ScRange aRange; 1787 rMark.GetMultiMarkArea( aRange ); 1788 return aRange; 1789 } 1790 1791 ScUndoIndent::ScUndoIndent( ScDocShell* pNewDocShell, const ScMarkData& rMark, 1792 ScDocument* pNewUndoDoc, sal_Bool bIncrement ) : 1793 ScBlockUndo( pNewDocShell, lcl_GetMultiMarkRange(rMark), SC_UNDO_AUTOHEIGHT ), 1794 aMarkData( rMark ), 1795 pUndoDoc( pNewUndoDoc ), 1796 bIsIncrement( bIncrement ) 1797 { 1798 } 1799 1800 __EXPORT ScUndoIndent::~ScUndoIndent() 1801 { 1802 delete pUndoDoc; 1803 } 1804 1805 String __EXPORT ScUndoIndent::GetComment() const 1806 { 1807 sal_uInt16 nId = bIsIncrement ? STR_UNDO_INC_INDENT : STR_UNDO_DEC_INDENT; 1808 return ScGlobal::GetRscString( nId ); 1809 } 1810 1811 void __EXPORT ScUndoIndent::Undo() 1812 { 1813 BeginUndo(); 1814 1815 ScDocument* pDoc = pDocShell->GetDocument(); 1816 SCTAB nTabCount = pDoc->GetTableCount(); 1817 ScRange aCopyRange = aBlockRange; 1818 aCopyRange.aStart.SetTab(0); 1819 aCopyRange.aEnd.SetTab(nTabCount-1); 1820 pUndoDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, sal_True, pDoc, &aMarkData ); 1821 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE ); 1822 1823 EndUndo(); 1824 } 1825 1826 void __EXPORT ScUndoIndent::Redo() 1827 { 1828 BeginRedo(); 1829 1830 ScDocument* pDoc = pDocShell->GetDocument(); 1831 pDoc->ChangeSelectionIndent( bIsIncrement, aMarkData ); 1832 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE ); 1833 1834 EndRedo(); 1835 } 1836 1837 void __EXPORT ScUndoIndent::Repeat(SfxRepeatTarget& rTarget) 1838 { 1839 if (rTarget.ISA(ScTabViewTarget)) 1840 ((ScTabViewTarget&)rTarget).GetViewShell()->ChangeIndent( bIsIncrement ); 1841 } 1842 1843 sal_Bool __EXPORT ScUndoIndent::CanRepeat(SfxRepeatTarget& rTarget) const 1844 { 1845 return (rTarget.ISA(ScTabViewTarget)); 1846 } 1847 1848 // ----------------------------------------------------------------------- 1849 // 1850 // Transliteration for cells 1851 // 1852 1853 ScUndoTransliterate::ScUndoTransliterate( ScDocShell* pNewDocShell, const ScMarkData& rMark, 1854 ScDocument* pNewUndoDoc, sal_Int32 nType ) : 1855 ScBlockUndo( pNewDocShell, lcl_GetMultiMarkRange(rMark), SC_UNDO_AUTOHEIGHT ), 1856 aMarkData( rMark ), 1857 pUndoDoc( pNewUndoDoc ), 1858 nTransliterationType( nType ) 1859 { 1860 } 1861 1862 __EXPORT ScUndoTransliterate::~ScUndoTransliterate() 1863 { 1864 delete pUndoDoc; 1865 } 1866 1867 String __EXPORT ScUndoTransliterate::GetComment() const 1868 { 1869 return ScGlobal::GetRscString( STR_UNDO_TRANSLITERATE ); 1870 } 1871 1872 void __EXPORT ScUndoTransliterate::Undo() 1873 { 1874 BeginUndo(); 1875 1876 ScDocument* pDoc = pDocShell->GetDocument(); 1877 SCTAB nTabCount = pDoc->GetTableCount(); 1878 ScRange aCopyRange = aBlockRange; 1879 aCopyRange.aStart.SetTab(0); 1880 aCopyRange.aEnd.SetTab(nTabCount-1); 1881 pUndoDoc->CopyToDocument( aCopyRange, IDF_CONTENTS, sal_True, pDoc, &aMarkData ); 1882 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE ); 1883 1884 EndUndo(); 1885 } 1886 1887 void __EXPORT ScUndoTransliterate::Redo() 1888 { 1889 BeginRedo(); 1890 1891 ScDocument* pDoc = pDocShell->GetDocument(); 1892 pDoc->TransliterateText( aMarkData, nTransliterationType ); 1893 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE ); 1894 1895 EndRedo(); 1896 } 1897 1898 void __EXPORT ScUndoTransliterate::Repeat(SfxRepeatTarget& rTarget) 1899 { 1900 if (rTarget.ISA(ScTabViewTarget)) 1901 ((ScTabViewTarget&)rTarget).GetViewShell()->TransliterateText( nTransliterationType ); 1902 } 1903 1904 sal_Bool __EXPORT ScUndoTransliterate::CanRepeat(SfxRepeatTarget& rTarget) const 1905 { 1906 return (rTarget.ISA(ScTabViewTarget)); 1907 } 1908 1909 // ----------------------------------------------------------------------- 1910 // 1911 // einzelne Items per Which-IDs aus Bereich loeschen 1912 // 1913 1914 ScUndoClearItems::ScUndoClearItems( ScDocShell* pNewDocShell, const ScMarkData& rMark, 1915 ScDocument* pNewUndoDoc, const sal_uInt16* pW ) : 1916 ScBlockUndo( pNewDocShell, lcl_GetMultiMarkRange(rMark), SC_UNDO_AUTOHEIGHT ), 1917 aMarkData( rMark ), 1918 pUndoDoc( pNewUndoDoc ), 1919 pWhich( NULL ) 1920 { 1921 DBG_ASSERT( pW, "ScUndoClearItems: Which-Pointer ist 0" ); 1922 1923 sal_uInt16 nCount = 0; 1924 while ( pW[nCount] ) 1925 ++nCount; 1926 pWhich = new sal_uInt16[nCount+1]; 1927 for (sal_uInt16 i=0; i<=nCount; i++) 1928 pWhich[i] = pW[i]; 1929 } 1930 1931 __EXPORT ScUndoClearItems::~ScUndoClearItems() 1932 { 1933 delete pUndoDoc; 1934 delete pWhich; 1935 } 1936 1937 String __EXPORT ScUndoClearItems::GetComment() const 1938 { 1939 return ScGlobal::GetRscString( STR_UNDO_DELETECONTENTS ); 1940 } 1941 1942 void __EXPORT ScUndoClearItems::Undo() 1943 { 1944 BeginUndo(); 1945 1946 ScDocument* pDoc = pDocShell->GetDocument(); 1947 pUndoDoc->CopyToDocument( aBlockRange, IDF_ATTRIB, sal_True, pDoc, &aMarkData ); 1948 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE ); 1949 1950 EndUndo(); 1951 } 1952 1953 void __EXPORT ScUndoClearItems::Redo() 1954 { 1955 BeginRedo(); 1956 1957 ScDocument* pDoc = pDocShell->GetDocument(); 1958 pDoc->ClearSelectionItems( pWhich, aMarkData ); 1959 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE ); 1960 1961 EndRedo(); 1962 } 1963 1964 void __EXPORT ScUndoClearItems::Repeat(SfxRepeatTarget& rTarget) 1965 { 1966 if (rTarget.ISA(ScTabViewTarget)) 1967 { 1968 ScViewData* pViewData = ((ScTabViewTarget&)rTarget).GetViewShell()->GetViewData(); 1969 ScDocFunc aFunc(*pViewData->GetDocShell()); 1970 aFunc.ClearItems( pViewData->GetMarkData(), pWhich, sal_False ); 1971 } 1972 } 1973 1974 sal_Bool __EXPORT ScUndoClearItems::CanRepeat(SfxRepeatTarget& rTarget) const 1975 { 1976 return (rTarget.ISA(ScTabViewTarget)); 1977 } 1978 1979 // ----------------------------------------------------------------------- 1980 // 1981 // Alle Umbrueche einer Tabelle loeschen 1982 // 1983 1984 ScUndoRemoveBreaks::ScUndoRemoveBreaks( ScDocShell* pNewDocShell, 1985 SCTAB nNewTab, ScDocument* pNewUndoDoc ) : 1986 ScSimpleUndo( pNewDocShell ), 1987 nTab( nNewTab ), 1988 pUndoDoc( pNewUndoDoc ) 1989 { 1990 } 1991 1992 __EXPORT ScUndoRemoveBreaks::~ScUndoRemoveBreaks() 1993 { 1994 delete pUndoDoc; 1995 } 1996 1997 String __EXPORT ScUndoRemoveBreaks::GetComment() const 1998 { 1999 return ScGlobal::GetRscString( STR_UNDO_REMOVEBREAKS ); 2000 } 2001 2002 void __EXPORT ScUndoRemoveBreaks::Undo() 2003 { 2004 BeginUndo(); 2005 2006 ScDocument* pDoc = pDocShell->GetDocument(); 2007 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell(); 2008 2009 pUndoDoc->CopyToDocument( 0,0,nTab, MAXCOL,MAXROW,nTab, IDF_NONE, sal_False, pDoc ); 2010 if (pViewShell) 2011 pViewShell->UpdatePageBreakData( sal_True ); 2012 pDocShell->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID ); 2013 2014 EndUndo(); 2015 } 2016 2017 void __EXPORT ScUndoRemoveBreaks::Redo() 2018 { 2019 BeginRedo(); 2020 2021 ScDocument* pDoc = pDocShell->GetDocument(); 2022 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell(); 2023 2024 pDoc->RemoveManualBreaks(nTab); 2025 pDoc->UpdatePageBreaks(nTab); 2026 if (pViewShell) 2027 pViewShell->UpdatePageBreakData( sal_True ); 2028 pDocShell->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID ); 2029 2030 EndRedo(); 2031 } 2032 2033 void __EXPORT ScUndoRemoveBreaks::Repeat(SfxRepeatTarget& rTarget) 2034 { 2035 if (rTarget.ISA(ScTabViewTarget)) 2036 { 2037 ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell(); 2038 rViewShell.RemoveManualBreaks(); 2039 } 2040 } 2041 2042 sal_Bool __EXPORT ScUndoRemoveBreaks::CanRepeat(SfxRepeatTarget& rTarget) const 2043 { 2044 return (rTarget.ISA(ScTabViewTarget)); 2045 } 2046 2047 // ----------------------------------------------------------------------- 2048 // 2049 // Zusammenfassung aufheben (fuer einen ganzen Bereich) 2050 // 2051 2052 ScUndoRemoveMerge::ScUndoRemoveMerge( ScDocShell* pNewDocShell, 2053 const ScRange& rArea, ScDocument* pNewUndoDoc ) : 2054 ScBlockUndo( pNewDocShell, rArea, SC_UNDO_SIMPLE ), 2055 pUndoDoc( pNewUndoDoc ) 2056 { 2057 } 2058 2059 __EXPORT ScUndoRemoveMerge::~ScUndoRemoveMerge() 2060 { 2061 delete pUndoDoc; 2062 } 2063 2064 String __EXPORT ScUndoRemoveMerge::GetComment() const 2065 { 2066 return ScGlobal::GetRscString( STR_UNDO_REMERGE ); // "Zusammenfassung aufheben" 2067 } 2068 2069 void __EXPORT ScUndoRemoveMerge::Undo() 2070 { 2071 BeginUndo(); 2072 2073 ScDocument* pDoc = pDocShell->GetDocument(); 2074 2075 ScRange aExtended = aBlockRange; 2076 pUndoDoc->ExtendMerge( aExtended ); 2077 2078 pDoc->DeleteAreaTab( aExtended, IDF_ATTRIB ); 2079 pUndoDoc->CopyToDocument( aExtended, IDF_ATTRIB, sal_False, pDoc ); 2080 2081 sal_Bool bDidPaint = sal_False; 2082 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell(); 2083 if ( pViewShell ) 2084 { 2085 pViewShell->SetTabNo( aExtended.aStart.Tab() ); 2086 bDidPaint = pViewShell->AdjustRowHeight( aExtended.aStart.Row(), aExtended.aEnd.Row() ); 2087 } 2088 if (!bDidPaint) 2089 ScUndoUtil::PaintMore( pDocShell, aExtended ); 2090 2091 EndUndo(); 2092 } 2093 2094 void __EXPORT ScUndoRemoveMerge::Redo() 2095 { 2096 BeginRedo(); 2097 2098 SCTAB nTab = aBlockRange.aStart.Tab(); 2099 ScDocument* pDoc = pDocShell->GetDocument(); 2100 ScRange aExtended = aBlockRange; 2101 pDoc->ExtendMerge( aExtended ); 2102 ScRange aRefresh = aExtended; 2103 pDoc->ExtendOverlapped( aRefresh ); 2104 2105 // ausfuehren 2106 2107 const SfxPoolItem& rDefAttr = pDoc->GetPool()->GetDefaultItem( ATTR_MERGE ); 2108 ScPatternAttr aPattern( pDoc->GetPool() ); 2109 aPattern.GetItemSet().Put( rDefAttr ); 2110 pDoc->ApplyPatternAreaTab( aBlockRange.aStart.Col(), aBlockRange.aStart.Row(), 2111 aBlockRange.aEnd.Col(), aBlockRange.aEnd.Row(), nTab, 2112 aPattern ); 2113 2114 pDoc->RemoveFlagsTab( aExtended.aStart.Col(), aExtended.aStart.Row(), 2115 aExtended.aEnd.Col(), aExtended.aEnd.Row(), nTab, 2116 SC_MF_HOR | SC_MF_VER ); 2117 2118 pDoc->ExtendMerge( aRefresh, sal_True, sal_False ); 2119 2120 // Paint 2121 2122 sal_Bool bDidPaint = sal_False; 2123 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell(); 2124 if ( pViewShell ) 2125 { 2126 pViewShell->SetTabNo( aExtended.aStart.Tab() ); 2127 bDidPaint = pViewShell->AdjustRowHeight( aExtended.aStart.Row(), aExtended.aEnd.Row() ); 2128 } 2129 if (!bDidPaint) 2130 ScUndoUtil::PaintMore( pDocShell, aExtended ); 2131 2132 EndRedo(); 2133 } 2134 2135 void __EXPORT ScUndoRemoveMerge::Repeat(SfxRepeatTarget& rTarget) 2136 { 2137 if (rTarget.ISA(ScTabViewTarget)) 2138 ((ScTabViewTarget&)rTarget).GetViewShell()->RemoveMerge(); 2139 } 2140 2141 sal_Bool __EXPORT ScUndoRemoveMerge::CanRepeat(SfxRepeatTarget& rTarget) const 2142 { 2143 return (rTarget.ISA(ScTabViewTarget)); 2144 } 2145 2146 // ----------------------------------------------------------------------- 2147 // 2148 // nur Umrandung setzen, per ScRangeList (StarOne) 2149 // 2150 2151 ScRange lcl_TotalRange( const ScRangeList& rRanges ) 2152 { 2153 ScRange aTotal; 2154 sal_uLong nCount = rRanges.Count(); 2155 for (sal_uLong i=0; i<nCount; i++) 2156 { 2157 ScRange aRange = *rRanges.GetObject(i); 2158 if (i==0) 2159 aTotal = aRange; 2160 else 2161 { 2162 if (aRange.aStart.Col() < aTotal.aStart.Col()) 2163 aTotal.aStart.SetCol(aRange.aStart.Col()); 2164 if (aRange.aStart.Row() < aTotal.aStart.Row()) 2165 aTotal.aStart.SetRow(aRange.aStart.Row()); 2166 if (aRange.aStart.Tab() < aTotal.aStart.Tab()) 2167 aTotal.aStart.SetTab(aRange.aStart.Tab()); 2168 if (aRange.aEnd.Col() > aTotal.aEnd.Col()) 2169 aTotal.aEnd.SetCol(aRange.aEnd.Col()); 2170 if (aRange.aEnd.Row() > aTotal.aEnd.Row()) 2171 aTotal.aEnd.SetRow(aRange.aEnd.Row()); 2172 if (aRange.aEnd.Tab() > aTotal.aEnd.Tab()) 2173 aTotal.aEnd.SetTab(aRange.aEnd.Tab()); 2174 } 2175 } 2176 return aTotal; 2177 } 2178 2179 ScUndoBorder::ScUndoBorder( ScDocShell* pNewDocShell, 2180 const ScRangeList& rRangeList, ScDocument* pNewUndoDoc, 2181 const SvxBoxItem& rNewOuter, const SvxBoxInfoItem& rNewInner ) : 2182 ScBlockUndo( pNewDocShell, lcl_TotalRange(rRangeList), SC_UNDO_SIMPLE ), 2183 pUndoDoc( pNewUndoDoc ) 2184 { 2185 pRanges = new ScRangeList(rRangeList); 2186 pOuter = new SvxBoxItem(rNewOuter); 2187 pInner = new SvxBoxInfoItem(rNewInner); 2188 } 2189 2190 __EXPORT ScUndoBorder::~ScUndoBorder() 2191 { 2192 delete pUndoDoc; 2193 delete pRanges; 2194 delete pOuter; 2195 delete pInner; 2196 } 2197 2198 String __EXPORT ScUndoBorder::GetComment() const 2199 { 2200 return ScGlobal::GetRscString( STR_UNDO_SELATTRLINES ); //! eigener String? 2201 } 2202 2203 void __EXPORT ScUndoBorder::Undo() 2204 { 2205 BeginUndo(); 2206 2207 ScDocument* pDoc = pDocShell->GetDocument(); 2208 ScMarkData aMarkData; 2209 aMarkData.MarkFromRangeList( *pRanges, sal_False ); 2210 pUndoDoc->CopyToDocument( aBlockRange, IDF_ATTRIB, sal_True, pDoc, &aMarkData ); 2211 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE ); 2212 2213 EndUndo(); 2214 } 2215 2216 void __EXPORT ScUndoBorder::Redo() 2217 { 2218 BeginRedo(); 2219 2220 ScDocument* pDoc = pDocShell->GetDocument(); //! Funktion an docfunc aufrufen 2221 sal_uLong nCount = pRanges->Count(); 2222 sal_uLong i; 2223 for (i=0; i<nCount; i++) 2224 { 2225 ScRange aRange = *pRanges->GetObject(i); 2226 SCTAB nTab = aRange.aStart.Tab(); 2227 2228 ScMarkData aMark; 2229 aMark.SetMarkArea( aRange ); 2230 aMark.SelectTable( nTab, sal_True ); 2231 2232 pDoc->ApplySelectionFrame( aMark, pOuter, pInner ); 2233 } 2234 for (i=0; i<nCount; i++) 2235 pDocShell->PostPaint( *pRanges->GetObject(i), PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE ); 2236 2237 EndRedo(); 2238 } 2239 2240 void __EXPORT ScUndoBorder::Repeat(SfxRepeatTarget& /* rTarget */) 2241 { 2242 //! spaeter (wenn die Funktion aus cellsuno nach docfunc gewandert ist) 2243 } 2244 2245 sal_Bool __EXPORT ScUndoBorder::CanRepeat(SfxRepeatTarget& /* rTarget */) const 2246 { 2247 return sal_False; // s.o. 2248 } 2249 2250 2251 2252 2253