Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / source / ui / undo / undoblk.cxx
blob946ed998d7513ad2500041d69249e063229acb4f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "scitems.hxx"
21 #include <vcl/virdev.hxx>
22 #include <vcl/waitobj.hxx>
23 #include <editeng/boxitem.hxx>
24 #include <editeng/justifyitem.hxx>
25 #include <sfx2/app.hxx>
27 #include "undoblk.hxx"
28 #include "undoutil.hxx"
29 #include "document.hxx"
30 #include "patattr.hxx"
31 #include "docsh.hxx"
32 #include "tabvwsh.hxx"
33 #include "rangenam.hxx"
34 #include "rangeutl.hxx"
35 #include "dbdata.hxx"
36 #include "stlpool.hxx"
37 #include "stlsheet.hxx"
38 #include "globstr.hrc"
39 #include "global.hxx"
40 #include "target.hxx"
41 #include "docpool.hxx"
42 #include "docfunc.hxx"
43 #include "attrib.hxx"
44 #include "chgtrack.hxx"
45 #include "transobj.hxx"
46 #include "refundo.hxx"
47 #include "undoolk.hxx"
48 #include "clipparam.hxx"
49 #include "sc.hrc"
51 #include <set>
53 // STATIC DATA -----------------------------------------------------------
55 TYPEINIT1(ScUndoInsertCells, SfxUndoAction);
56 TYPEINIT1(ScUndoDeleteCells, SfxUndoAction);
57 TYPEINIT1(ScUndoDeleteMulti, SfxUndoAction);
58 TYPEINIT1(ScUndoCut, ScBlockUndo);
59 TYPEINIT1(ScUndoPaste, SfxUndoAction);
60 TYPEINIT1(ScUndoDragDrop, SfxUndoAction);
61 TYPEINIT1(ScUndoListNames, SfxUndoAction);
62 TYPEINIT1(ScUndoUseScenario, SfxUndoAction);
63 TYPEINIT1(ScUndoSelectionStyle, SfxUndoAction);
64 TYPEINIT1(ScUndoEnterMatrix, ScBlockUndo);
65 TYPEINIT1(ScUndoIndent, ScBlockUndo);
66 TYPEINIT1(ScUndoTransliterate, ScBlockUndo);
67 TYPEINIT1(ScUndoClearItems, ScBlockUndo);
68 TYPEINIT1(ScUndoRemoveBreaks, SfxUndoAction);
69 TYPEINIT1(ScUndoRemoveMerge, ScBlockUndo);
70 TYPEINIT1(ScUndoBorder, ScBlockUndo);
72 // TODO:
73 /*A*/ // SetOptimalHeight on Document, if no View
74 /*B*/ // linked sheets
75 /*C*/ // ScArea
76 //? // check later
78 ScUndoInsertCells::ScUndoInsertCells( ScDocShell* pNewDocShell,
79 const ScRange& rRange, SCTAB nNewCount, SCTAB* pNewTabs, SCTAB* pNewScenarios,
80 InsCellCmd eNewCmd, ScDocument* pUndoDocument, ScRefUndoData* pRefData,
81 sal_Bool bNewPartOfPaste ) :
82 ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFLAST ),
83 aEffRange( rRange ),
84 nCount( nNewCount ),
85 pTabs( pNewTabs ),
86 pScenarios( pNewScenarios ),
87 eCmd( eNewCmd ),
88 bPartOfPaste( bNewPartOfPaste ),
89 pPasteUndo( NULL )
91 if (eCmd == INS_INSROWS) // whole row?
93 aEffRange.aStart.SetCol(0);
94 aEffRange.aEnd.SetCol(MAXCOL);
97 if (eCmd == INS_INSCOLS) // whole column?
99 aEffRange.aStart.SetRow(0);
100 aEffRange.aEnd.SetRow(MAXROW);
103 SetChangeTrack();
106 ScUndoInsertCells::~ScUndoInsertCells()
108 delete pPasteUndo;
109 delete []pTabs;
110 delete []pScenarios;
113 OUString ScUndoInsertCells::GetComment() const
115 return ScGlobal::GetRscString( pPasteUndo ? STR_UNDO_PASTE : STR_UNDO_INSERTCELLS );
118 bool ScUndoInsertCells::Merge( SfxUndoAction* pNextAction )
120 // If a paste undo action has already been added, append (detective) action there.
121 if ( pPasteUndo )
122 return pPasteUndo->Merge( pNextAction );
124 if ( bPartOfPaste && pNextAction->ISA( ScUndoWrapper ) )
126 ScUndoWrapper* pWrapper = (ScUndoWrapper*)pNextAction;
127 SfxUndoAction* pWrappedAction = pWrapper->GetWrappedUndo();
128 if ( pWrappedAction && pWrappedAction->ISA( ScUndoPaste ) )
130 // Store paste action if this is part of paste with inserting cells.
131 // A list action isn't used because Repeat wouldn't work (insert wrong cells).
133 pPasteUndo = pWrappedAction;
134 pWrapper->ForgetWrappedUndo(); // pWrapper is deleted by UndoManager
135 return true;
139 // Call base class for detective handling
140 return ScMoveUndo::Merge( pNextAction );
143 void ScUndoInsertCells::SetChangeTrack()
145 ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
146 if ( pChangeTrack )
148 pChangeTrack->AppendInsert( aEffRange );
149 nEndChangeAction = pChangeTrack->GetActionMax();
151 else
152 nEndChangeAction = 0;
155 void ScUndoInsertCells::DoChange( const sal_Bool bUndo )
157 ScDocument* pDoc = pDocShell->GetDocument();
158 SCTAB i;
160 if ( bUndo )
162 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
163 if ( pChangeTrack )
164 pChangeTrack->Undo( nEndChangeAction, nEndChangeAction );
166 else
167 SetChangeTrack();
169 // refresh of merged cells has to be after inserting/deleting
171 switch (eCmd)
173 case INS_INSROWS:
174 case INS_CELLSDOWN:
175 for( i=0; i<nCount; i++ )
177 if (bUndo)
178 pDoc->DeleteRow( aEffRange.aStart.Col(), pTabs[i], aEffRange.aEnd.Col(), pTabs[i]+pScenarios[i],
179 aEffRange.aStart.Row(), static_cast<SCSIZE>(aEffRange.aEnd.Row()-aEffRange.aStart.Row()+1));
180 else
181 pDoc->InsertRow( aEffRange.aStart.Col(), pTabs[i], aEffRange.aEnd.Col(), pTabs[i]+pScenarios[i],
182 aEffRange.aStart.Row(), static_cast<SCSIZE>(aEffRange.aEnd.Row()-aEffRange.aStart.Row()+1));
184 break;
185 case INS_INSCOLS:
186 case INS_CELLSRIGHT:
187 for( i=0; i<nCount; i++ )
189 if (bUndo)
190 pDoc->DeleteCol( aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
191 aEffRange.aStart.Col(), static_cast<SCSIZE>(aEffRange.aEnd.Col()-aEffRange.aStart.Col()+1));
192 else
193 pDoc->InsertCol( aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
194 aEffRange.aStart.Col(), static_cast<SCSIZE>(aEffRange.aEnd.Col()-aEffRange.aStart.Col()+1));
196 break;
197 default:
199 // added to avoid warnings
203 ScRange aWorkRange( aEffRange );
204 if ( eCmd == INS_CELLSRIGHT ) // only "shift right" requires refresh of the moved area
205 aWorkRange.aEnd.SetCol(MAXCOL);
206 for( i=0; i<nCount; i++ )
208 if ( pDoc->HasAttrib( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), pTabs[i],
209 aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), pTabs[i], HASATTR_MERGED ) )
211 SCCOL nEndCol = aWorkRange.aEnd.Col();
212 SCROW nEndRow = aWorkRange.aEnd.Row();
213 pDoc->ExtendMerge( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), nEndCol, nEndRow, pTabs[i], sal_True );
217 // Undo for displaced attributes?
219 sal_uInt16 nPaint = PAINT_GRID;
220 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
221 switch (eCmd)
223 case INS_INSROWS:
224 nPaint |= PAINT_LEFT;
225 aWorkRange.aEnd.SetRow(MAXROW);
226 break;
227 case INS_CELLSDOWN:
228 for( i=0; i<nCount; i++ )
230 aWorkRange.aEnd.SetRow(MAXROW);
231 if ( pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), pTabs[i] ))
233 aWorkRange.aStart.SetCol(0);
234 aWorkRange.aEnd.SetCol(MAXCOL);
235 nPaint |= PAINT_LEFT;
238 break;
239 case INS_INSCOLS:
240 nPaint |= PAINT_TOP; // top bar
241 case INS_CELLSRIGHT:
242 for( i=0; i<nCount; i++ )
244 aWorkRange.aEnd.SetCol(MAXCOL); // to the far right
245 if ( pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), pTabs[i]) )
246 { // AdjustDraw does not paint PAINT_TOP,
247 aWorkRange.aStart.SetCol(0); // thus solved like this
248 aWorkRange.aEnd.SetRow(MAXROW);
249 nPaint |= PAINT_LEFT;
252 break;
253 default:
255 // added to avoid warnings
259 for( i=0; i<nCount; i++ )
261 pDocShell->PostPaint( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), pTabs[i],
262 aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), pTabs[i]+pScenarios[i], nPaint );
264 pDocShell->PostDataChanged();
265 if (pViewShell)
266 pViewShell->CellContentChanged();
269 void ScUndoInsertCells::Undo()
271 if ( pPasteUndo )
272 pPasteUndo->Undo(); // undo paste first
274 WaitObject aWait( pDocShell->GetActiveDialogParent() ); // important due to TrackFormulas in UpdateReference
275 BeginUndo();
276 DoChange( sal_True );
277 EndUndo();
279 ScDocument* pDoc = pDocShell->GetDocument();
280 for (SCTAB i = 0; i < nCount; ++i)
281 pDoc->SetDrawPageSize(pTabs[i]);
284 void ScUndoInsertCells::Redo()
286 WaitObject aWait( pDocShell->GetActiveDialogParent() ); // important due to TrackFormulas in UpdateReference
287 BeginRedo();
288 DoChange( false );
289 EndRedo();
291 if ( pPasteUndo )
292 pPasteUndo->Redo(); // redo paste last
294 ScDocument* pDoc = pDocShell->GetDocument();
295 for (SCTAB i = 0; i < nCount; ++i)
296 pDoc->SetDrawPageSize(pTabs[i]);
299 void ScUndoInsertCells::Repeat(SfxRepeatTarget& rTarget)
301 if (rTarget.ISA(ScTabViewTarget))
303 if ( pPasteUndo )
305 // Repeat for paste with inserting cells is handled completely
306 // by the Paste undo action
308 pPasteUndo->Repeat( rTarget );
310 else
311 ((ScTabViewTarget&)rTarget).GetViewShell()->InsertCells( eCmd, sal_True );
315 bool ScUndoInsertCells::CanRepeat(SfxRepeatTarget& rTarget) const
317 return rTarget.ISA(ScTabViewTarget);
321 ScUndoDeleteCells::ScUndoDeleteCells( ScDocShell* pNewDocShell,
322 const ScRange& rRange, SCTAB nNewCount, SCTAB* pNewTabs, SCTAB* pNewScenarios,
323 DelCellCmd eNewCmd, ScDocument* pUndoDocument, ScRefUndoData* pRefData ) :
324 ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFLAST ),
325 aEffRange( rRange ),
326 nCount( nNewCount ),
327 pTabs( pNewTabs ),
328 pScenarios( pNewScenarios ),
329 eCmd( eNewCmd )
331 if (eCmd == DEL_DELROWS) // whole row?
333 aEffRange.aStart.SetCol(0);
334 aEffRange.aEnd.SetCol(MAXCOL);
337 if (eCmd == DEL_DELCOLS) // whole column?
339 aEffRange.aStart.SetRow(0);
340 aEffRange.aEnd.SetRow(MAXROW);
343 SetChangeTrack();
346 ScUndoDeleteCells::~ScUndoDeleteCells()
348 delete []pTabs;
349 delete []pScenarios;
352 OUString ScUndoDeleteCells::GetComment() const
354 return ScGlobal::GetRscString( STR_UNDO_DELETECELLS ); // "Delete"
357 void ScUndoDeleteCells::SetChangeTrack()
359 ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
360 if ( pChangeTrack )
361 pChangeTrack->AppendDeleteRange( aEffRange, pRefUndoDoc,
362 nStartChangeAction, nEndChangeAction );
363 else
364 nStartChangeAction = nEndChangeAction = 0;
367 void ScUndoDeleteCells::DoChange( const sal_Bool bUndo )
369 ScDocument* pDoc = pDocShell->GetDocument();
370 SCTAB i;
372 if ( bUndo )
374 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
375 if ( pChangeTrack )
376 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
378 else
379 SetChangeTrack();
381 switch (eCmd)
383 case DEL_DELROWS:
384 case DEL_CELLSUP:
385 for( i=0; i<nCount; i++ )
387 if (bUndo)
388 pDoc->InsertRow( aEffRange.aStart.Col(), pTabs[i], aEffRange.aEnd.Col(), pTabs[i]+pScenarios[i],
389 aEffRange.aStart.Row(), static_cast<SCSIZE>(aEffRange.aEnd.Row()-aEffRange.aStart.Row()+1));
390 else
391 pDoc->DeleteRow( aEffRange.aStart.Col(), pTabs[i], aEffRange.aEnd.Col(), pTabs[i]+pScenarios[i],
392 aEffRange.aStart.Row(), static_cast<SCSIZE>(aEffRange.aEnd.Row()-aEffRange.aStart.Row()+1));
394 break;
395 case DEL_DELCOLS:
396 case DEL_CELLSLEFT:
397 for( i=0; i<nCount; i++ )
399 if (bUndo)
400 pDoc->InsertCol( aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
401 aEffRange.aStart.Col(), static_cast<SCSIZE>(aEffRange.aEnd.Col()-aEffRange.aStart.Col()+1));
402 else
403 pDoc->DeleteCol( aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
404 aEffRange.aStart.Col(), static_cast<SCSIZE>(aEffRange.aEnd.Col()-aEffRange.aStart.Col()+1));
406 break;
407 default:
409 // added to avoid warnings
413 // if Undo, restore references
414 for( i=0; i<nCount && bUndo; i++ )
416 pRefUndoDoc->CopyToDocument( aEffRange.aStart.Col(), aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Col(), aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
417 IDF_ALL | IDF_NOCAPTIONS, false, pDoc );
420 ScRange aWorkRange( aEffRange );
421 if ( eCmd == DEL_CELLSLEFT ) // only "shift left" requires refresh of the moved area
422 aWorkRange.aEnd.SetCol(MAXCOL);
424 for( i=0; i<nCount; i++ )
426 if ( pDoc->HasAttrib( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), pTabs[i],
427 aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), pTabs[i], HASATTR_MERGED | HASATTR_OVERLAPPED ) )
429 // #i51445# old merge flag attributes must be deleted also for single cells,
430 // not only for whole columns/rows
432 if ( !bUndo )
434 if ( eCmd==DEL_DELCOLS || eCmd==DEL_CELLSLEFT )
435 aWorkRange.aEnd.SetCol(MAXCOL);
436 if ( eCmd==DEL_DELROWS || eCmd==DEL_CELLSUP )
437 aWorkRange.aEnd.SetRow(MAXROW);
438 ScMarkData aMarkData;
439 aMarkData.SelectOneTable( aWorkRange.aStart.Tab() );
440 ScPatternAttr aPattern( pDoc->GetPool() );
441 aPattern.GetItemSet().Put( ScMergeFlagAttr() );
442 pDoc->ApplyPatternArea( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(),
443 aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(),
444 aMarkData, aPattern );
447 SCCOL nEndCol = aWorkRange.aEnd.Col();
448 SCROW nEndRow = aWorkRange.aEnd.Row();
449 pDoc->ExtendMerge( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), nEndCol, nEndRow, pTabs[i], sal_True );
453 // Zeichnen
454 sal_uInt16 nPaint = PAINT_GRID;
455 switch (eCmd)
457 case DEL_DELROWS:
458 nPaint |= PAINT_LEFT;
459 aWorkRange.aEnd.SetRow(MAXROW);
460 break;
461 case DEL_CELLSUP:
462 for( i=0; i<nCount; i++ )
464 aWorkRange.aEnd.SetRow(MAXROW);
465 if ( pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), pTabs[i] ))
467 aWorkRange.aStart.SetCol(0);
468 aWorkRange.aEnd.SetCol(MAXCOL);
469 nPaint |= PAINT_LEFT;
472 break;
473 case DEL_DELCOLS:
474 nPaint |= PAINT_TOP; // top bar
475 case DEL_CELLSLEFT:
476 for( i=0; i<nCount; i++ )
478 aWorkRange.aEnd.SetCol(MAXCOL); // to the far right
479 if ( pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), pTabs[i] ) )
481 aWorkRange.aStart.SetCol(0);
482 aWorkRange.aEnd.SetRow(MAXROW);
483 nPaint |= PAINT_LEFT;
486 break;
487 default:
489 // added to avoid warnings
493 for( i=0; i<nCount; i++ )
495 pDocShell->PostPaint( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), pTabs[i],
496 aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), pTabs[i]+pScenarios[i], nPaint, SC_PF_LINES );
498 // Selection not until EndUndo
500 pDocShell->PostDataChanged();
501 // CellContentChanged comes with the selection
504 void ScUndoDeleteCells::Undo()
506 WaitObject aWait( pDocShell->GetActiveDialogParent() ); // important because of TrackFormulas in UpdateReference
507 BeginUndo();
508 DoChange( sal_True );
509 EndUndo();
510 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
512 // Selection not until EndUndo
513 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
514 if (pViewShell)
516 for( SCTAB i=0; i<nCount; i++ )
518 pViewShell->MarkRange( ScRange(aEffRange.aStart.Col(), aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Col(), aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i]) );
522 ScDocument* pDoc = pDocShell->GetDocument();
523 for (SCTAB i = 0; i < nCount; ++i)
524 pDoc->SetDrawPageSize(pTabs[i]);
527 void ScUndoDeleteCells::Redo()
529 WaitObject aWait( pDocShell->GetActiveDialogParent() ); // important because of TrackFormulas in UpdateReference
530 BeginRedo();
531 DoChange( false);
532 EndRedo();
533 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
535 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
536 if (pViewShell)
537 pViewShell->DoneBlockMode(); // current way
539 ScDocument* pDoc = pDocShell->GetDocument();
540 for (SCTAB i = 0; i < nCount; ++i)
541 pDoc->SetDrawPageSize(pTabs[i]);
544 void ScUndoDeleteCells::Repeat(SfxRepeatTarget& rTarget)
546 if (rTarget.ISA(ScTabViewTarget))
547 ((ScTabViewTarget&)rTarget).GetViewShell()->DeleteCells( eCmd, sal_True );
550 bool ScUndoDeleteCells::CanRepeat(SfxRepeatTarget& rTarget) const
552 return rTarget.ISA(ScTabViewTarget);
555 // delete cells in multiselection
556 ScUndoDeleteMulti::ScUndoDeleteMulti( ScDocShell* pNewDocShell,
557 sal_Bool bNewRows, sal_Bool bNeedsRefresh, SCTAB nNewTab,
558 const SCCOLROW* pRng, SCCOLROW nRngCnt,
559 ScDocument* pUndoDocument, ScRefUndoData* pRefData ) :
560 ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFLAST ),
561 bRows( bNewRows ),
562 bRefresh( bNeedsRefresh ),
563 nTab( nNewTab ),
564 nRangeCnt( nRngCnt )
566 pRanges = new SCCOLROW[ 2 * nRangeCnt ];
567 memcpy(pRanges,pRng,nRangeCnt*2*sizeof(SCCOLROW));
568 SetChangeTrack();
571 ScUndoDeleteMulti::~ScUndoDeleteMulti()
573 delete [] pRanges;
576 OUString ScUndoDeleteMulti::GetComment() const
578 return ScGlobal::GetRscString( STR_UNDO_DELETECELLS ); // like DeleteCells
581 void ScUndoDeleteMulti::DoChange() const
583 SCCOL nStartCol;
584 SCROW nStartRow;
585 sal_uInt16 nPaint;
586 if (bRows)
588 nStartCol = 0;
589 nStartRow = static_cast<SCROW>(pRanges[0]);
590 nPaint = PAINT_GRID | PAINT_LEFT;
592 else
594 nStartCol = static_cast<SCCOL>(pRanges[0]);
595 nStartRow = 0;
596 nPaint = PAINT_GRID | PAINT_TOP;
599 if ( bRefresh )
601 ScDocument* pDoc = pDocShell->GetDocument();
602 SCCOL nEndCol = MAXCOL;
603 SCROW nEndRow = MAXROW;
604 pDoc->RemoveFlagsTab( nStartCol, nStartRow, nEndCol, nEndRow, nTab, SC_MF_HOR | SC_MF_VER );
605 pDoc->ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, nTab, sal_True );
608 pDocShell->PostPaint( nStartCol, nStartRow, nTab, MAXCOL, MAXROW, nTab, nPaint );
609 pDocShell->PostDataChanged();
610 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
611 if (pViewShell)
612 pViewShell->CellContentChanged();
614 ShowTable( nTab );
617 void ScUndoDeleteMulti::SetChangeTrack()
619 ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
620 if ( pChangeTrack )
622 nStartChangeAction = pChangeTrack->GetActionMax() + 1;
623 ScRange aRange( 0, 0, nTab, 0, 0, nTab );
624 if ( bRows )
625 aRange.aEnd.SetCol( MAXCOL );
626 else
627 aRange.aEnd.SetRow( MAXROW );
628 // delete in reverse
629 SCCOLROW* pOneRange = &pRanges[2*nRangeCnt];
630 for ( SCCOLROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++ )
632 SCCOLROW nEnd = *(--pOneRange);
633 SCCOLROW nStart = *(--pOneRange);
634 if ( bRows )
636 aRange.aStart.SetRow( nStart );
637 aRange.aEnd.SetRow( nEnd );
639 else
641 aRange.aStart.SetCol( static_cast<SCCOL>(nStart) );
642 aRange.aEnd.SetCol( static_cast<SCCOL>(nEnd) );
644 sal_uLong nDummyStart;
645 pChangeTrack->AppendDeleteRange( aRange, pRefUndoDoc,
646 nDummyStart, nEndChangeAction );
649 else
650 nStartChangeAction = nEndChangeAction = 0;
653 void ScUndoDeleteMulti::Undo()
655 WaitObject aWait( pDocShell->GetActiveDialogParent() ); // important because of TrackFormulas in UpdateReference
656 BeginUndo();
658 ScDocument* pDoc = pDocShell->GetDocument();
659 SCCOLROW* pOneRange;
660 SCCOLROW nRangeNo;
662 // reverse delete -> forward insert
663 pOneRange = pRanges;
664 for (nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
666 SCCOLROW nStart = *(pOneRange++);
667 SCCOLROW nEnd = *(pOneRange++);
668 if (bRows)
669 pDoc->InsertRow( 0,nTab, MAXCOL,nTab, nStart,static_cast<SCSIZE>(nEnd-nStart+1) );
670 else
671 pDoc->InsertCol( 0,nTab, MAXROW,nTab, static_cast<SCCOL>(nStart), static_cast<SCSIZE>(nEnd-nStart+1) );
674 pOneRange = pRanges;
675 for (nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
677 SCCOLROW nStart = *(pOneRange++);
678 SCCOLROW nEnd = *(pOneRange++);
679 if (bRows)
680 pRefUndoDoc->CopyToDocument( 0,nStart,nTab, MAXCOL,nEnd,nTab, IDF_ALL,false,pDoc );
681 else
682 pRefUndoDoc->CopyToDocument( static_cast<SCCOL>(nStart),0,nTab,
683 static_cast<SCCOL>(nEnd),MAXROW,nTab, IDF_ALL,false,pDoc );
686 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
687 if ( pChangeTrack )
688 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
690 DoChange();
692 //! redrawing the selection is not possible at the moment
693 //! since no data for selection exist
695 EndUndo();
696 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
699 void ScUndoDeleteMulti::Redo()
701 WaitObject aWait( pDocShell->GetActiveDialogParent() ); // important because of TrackFormulas in UpdateReference
702 BeginRedo();
704 ScDocument* pDoc = pDocShell->GetDocument();
706 // reverese delet
707 SCCOLROW* pOneRange = &pRanges[2*nRangeCnt];
708 for (SCCOLROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
710 SCCOLROW nEnd = *(--pOneRange);
711 SCCOLROW nStart = *(--pOneRange);
712 if (bRows)
713 pDoc->DeleteRow( 0,nTab, MAXCOL,nTab, nStart,static_cast<SCSIZE>(nEnd-nStart+1) );
714 else
715 pDoc->DeleteCol( 0,nTab, MAXROW,nTab, static_cast<SCCOL>(nStart), static_cast<SCSIZE>(nEnd-nStart+1) );
718 SetChangeTrack();
720 DoChange();
722 EndRedo();
723 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
726 void ScUndoDeleteMulti::Repeat(SfxRepeatTarget& rTarget)
728 // if single selection
729 if (rTarget.ISA(ScTabViewTarget))
730 ((ScTabViewTarget&)rTarget).GetViewShell()->DeleteCells( DEL_DELROWS, sal_True );
733 bool ScUndoDeleteMulti::CanRepeat(SfxRepeatTarget& rTarget) const
735 return rTarget.ISA(ScTabViewTarget);
739 ScUndoCut::ScUndoCut( ScDocShell* pNewDocShell,
740 ScRange aRange, ScAddress aOldEnd, const ScMarkData& rMark,
741 ScDocument* pNewUndoDoc ) :
742 ScBlockUndo( pNewDocShell, ScRange(aRange.aStart, aOldEnd), SC_UNDO_AUTOHEIGHT ),
743 aMarkData( rMark ),
744 pUndoDoc( pNewUndoDoc ),
745 aExtendedRange( aRange )
747 SetChangeTrack();
750 ScUndoCut::~ScUndoCut()
752 delete pUndoDoc;
755 OUString ScUndoCut::GetComment() const
757 return ScGlobal::GetRscString( STR_UNDO_CUT ); // "cut"
760 void ScUndoCut::SetChangeTrack()
762 ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
763 if ( pChangeTrack )
764 pChangeTrack->AppendContentRange( aBlockRange, pUndoDoc,
765 nStartChangeAction, nEndChangeAction, SC_CACM_CUT );
766 else
767 nStartChangeAction = nEndChangeAction = 0;
770 void ScUndoCut::DoChange( const sal_Bool bUndo )
772 ScDocument* pDoc = pDocShell->GetDocument();
773 sal_uInt16 nExtFlags = 0;
775 // do not undo/redo objects and note captions, they are handled via drawing undo
776 sal_uInt16 nUndoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS;
778 if (bUndo) // only for Undo
780 // all sheets - CopyToDocument skips those that don't exist in pUndoDoc
781 SCTAB nTabCount = pDoc->GetTableCount();
782 ScRange aCopyRange = aExtendedRange;
783 aCopyRange.aStart.SetTab(0);
784 aCopyRange.aEnd.SetTab(nTabCount-1);
785 pUndoDoc->CopyToDocument( aCopyRange, nUndoFlags, false, pDoc );
786 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
787 if ( pChangeTrack )
788 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
790 else // only for Redo
792 pDocShell->UpdatePaintExt( nExtFlags, aExtendedRange );
793 pDoc->DeleteArea( aBlockRange.aStart.Col(), aBlockRange.aStart.Row(),
794 aBlockRange.aEnd.Col(), aBlockRange.aEnd.Row(), aMarkData, nUndoFlags );
795 SetChangeTrack();
798 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
799 if ( !( (pViewShell) && pViewShell->AdjustBlockHeight() ) )
800 /*A*/ pDocShell->PostPaint( aExtendedRange, PAINT_GRID, nExtFlags );
802 if ( !bUndo ) // draw redo after updating row heights
803 RedoSdrUndoAction( pDrawUndo ); //! include in ScBlockUndo?
805 pDocShell->PostDataChanged();
806 if (pViewShell)
807 pViewShell->CellContentChanged();
810 void ScUndoCut::Undo()
812 BeginUndo();
813 DoChange( sal_True );
814 EndUndo();
817 void ScUndoCut::Redo()
819 BeginRedo();
820 ScDocument* pDoc = pDocShell->GetDocument();
821 EnableDrawAdjust( pDoc, false ); //! include in ScBlockUndo?
822 DoChange( false );
823 EnableDrawAdjust( pDoc, sal_True ); //! include in ScBlockUndo?
824 EndRedo();
827 void ScUndoCut::Repeat(SfxRepeatTarget& rTarget)
829 if (rTarget.ISA(ScTabViewTarget))
830 ((ScTabViewTarget&)rTarget).GetViewShell()->CutToClip( NULL, sal_True );
833 bool ScUndoCut::CanRepeat(SfxRepeatTarget& rTarget) const
835 return rTarget.ISA(ScTabViewTarget);
838 ScUndoPaste::ScUndoPaste( ScDocShell* pNewDocShell, const ScRangeList& rRanges,
839 const ScMarkData& rMark,
840 ScDocument* pNewUndoDoc, ScDocument* pNewRedoDoc,
841 sal_uInt16 nNewFlags,
842 ScRefUndoData* pRefData,
843 bool bRedoIsFilled, const ScUndoPasteOptions* pOptions ) :
844 ScMultiBlockUndo( pNewDocShell, rRanges, SC_UNDO_SIMPLE ),
845 aMarkData( rMark ),
846 pUndoDoc( pNewUndoDoc ),
847 pRedoDoc( pNewRedoDoc ),
848 nFlags( nNewFlags ),
849 pRefUndoData( pRefData ),
850 pRefRedoData( NULL ),
851 bRedoFilled( bRedoIsFilled )
853 if ( pRefUndoData )
854 pRefUndoData->DeleteUnchanged( pDocShell->GetDocument() );
856 if ( pOptions )
857 aPasteOptions = *pOptions; // used only for Repeat
859 SetChangeTrack();
862 ScUndoPaste::~ScUndoPaste()
864 delete pUndoDoc;
865 delete pRedoDoc;
866 delete pRefUndoData;
867 delete pRefRedoData;
870 OUString ScUndoPaste::GetComment() const
872 return ScGlobal::GetRscString( STR_UNDO_PASTE ); // "paste"
875 void ScUndoPaste::SetChangeTrack()
877 ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
878 if ( pChangeTrack && (nFlags & IDF_CONTENTS) )
880 for (size_t i = 0, n = maBlockRanges.size(); i < n; ++i)
882 pChangeTrack->AppendContentRange(*maBlockRanges[i], pUndoDoc,
883 nStartChangeAction, nEndChangeAction, SC_CACM_PASTE );
886 else
887 nStartChangeAction = nEndChangeAction = 0;
890 void ScUndoPaste::DoChange(bool bUndo)
892 ScDocument* pDoc = pDocShell->GetDocument();
894 // RefUndoData for redo is created before first undo
895 // (with DeleteUnchanged after the DoUndo call)
896 bool bCreateRedoData = ( bUndo && pRefUndoData && !pRefRedoData );
897 if ( bCreateRedoData )
898 pRefRedoData = new ScRefUndoData( pDoc );
900 ScRefUndoData* pWorkRefData = bUndo ? pRefUndoData : pRefRedoData;
902 // Always back-up either all or none of the content for Undo
903 sal_uInt16 nUndoFlags = IDF_NONE;
904 if (nFlags & IDF_CONTENTS)
905 nUndoFlags |= IDF_CONTENTS;
906 if (nFlags & IDF_ATTRIB)
907 nUndoFlags |= IDF_ATTRIB;
909 // do not undo/redo objects and note captions, they are handled via drawing undo
910 (nUndoFlags &= ~IDF_OBJECTS) |= IDF_NOCAPTIONS;
912 bool bPaintAll = false;
914 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
916 SCTAB nTabCount = pDoc->GetTableCount();
917 if ( bUndo && !bRedoFilled )
919 if (!pRedoDoc)
921 bool bColInfo = true;
922 bool bRowInfo = true;
923 for (size_t i = 0, n = maBlockRanges.size(); i < n; ++i)
925 const ScRange& r = *maBlockRanges[i];
926 bColInfo &= (r.aStart.Row() == 0 && r.aEnd.Row() == MAXROW);
927 bRowInfo &= (r.aStart.Col() == 0 && r.aEnd.Col() == MAXCOL);
928 if (!bColInfo && !bRowInfo)
929 break;
932 pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
933 pRedoDoc->InitUndoSelected( pDoc, aMarkData, bColInfo, bRowInfo );
935 // read "redo" data from the document in the first undo
936 // all sheets - CopyToDocument skips those that don't exist in pRedoDoc
937 for (size_t i = 0, n = maBlockRanges.size(); i < n; ++i)
939 ScRange aCopyRange = *maBlockRanges[i];
940 aCopyRange.aStart.SetTab(0);
941 aCopyRange.aEnd.SetTab(nTabCount-1);
942 pDoc->CopyToDocument( aCopyRange, nUndoFlags, false, pRedoDoc );
943 bRedoFilled = true;
947 sal_uInt16 nExtFlags = 0;
948 pDocShell->UpdatePaintExt(nExtFlags, maBlockRanges.Combine());
950 aMarkData.MarkToMulti();
951 pDoc->DeleteSelection( nUndoFlags, aMarkData );
952 aMarkData.MarkToSimple();
954 SCTAB nFirstSelected = aMarkData.GetFirstSelected();
956 if ( !bUndo && pRedoDoc ) // Redo: UndoToDocument before handling RefData
958 for (size_t i = 0, n = maBlockRanges.size(); i < n; ++i)
960 ScRange aRange = *maBlockRanges[i];
961 aRange.aStart.SetTab(nFirstSelected);
962 aRange.aEnd.SetTab(nFirstSelected);
963 pRedoDoc->UndoToDocument(aRange, nUndoFlags, false, pDoc);
964 ScMarkData::iterator itr = aMarkData.begin(), itrEnd = aMarkData.end();
965 for (; itr != itrEnd && *itr < nTabCount; ++itr)
967 if (*itr == nFirstSelected)
968 continue;
970 aRange.aStart.SetTab(*itr);
971 aRange.aEnd.SetTab(*itr);
972 pRedoDoc->CopyToDocument( aRange, nUndoFlags, false, pDoc );
977 if (pWorkRefData)
979 pWorkRefData->DoUndo( pDoc, true ); // true = bSetChartRangeLists for SetChartListenerCollection
980 if (!maBlockRanges.empty() &&
981 pDoc->RefreshAutoFilter(0, 0, MAXCOL, MAXROW, maBlockRanges[0]->aStart.Tab()))
982 bPaintAll = true;
985 if ( bCreateRedoData && pRefRedoData )
986 pRefRedoData->DeleteUnchanged( pDoc );
988 if (bUndo) // Undo: UndoToDocument after handling RefData
990 for (size_t i = 0, n = maBlockRanges.size(); i < n; ++i)
992 ScRange aRange = *maBlockRanges[i];
993 ScMarkData::iterator itr = aMarkData.begin(), itrEnd = aMarkData.end();
994 for (; itr != itrEnd && *itr < nTabCount; ++itr)
996 aRange.aStart.SetTab(*itr);
997 aRange.aEnd.SetTab(*itr);
998 pUndoDoc->UndoToDocument(aRange, nUndoFlags, false, pDoc);
1003 if ( bUndo )
1005 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
1006 if ( pChangeTrack )
1007 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
1009 else
1010 SetChangeTrack();
1012 ScRangeList aDrawRanges(maBlockRanges);
1013 sal_uInt16 nPaint = PAINT_GRID;
1014 for (size_t i = 0, n = aDrawRanges.size(); i < n; ++i)
1016 ScRange& rDrawRange = *aDrawRanges[i];
1017 pDoc->ExtendMerge(rDrawRange, true); // only needed for single sheet (text/rtf etc.)
1018 if (bPaintAll)
1020 rDrawRange.aStart.SetCol(0);
1021 rDrawRange.aStart.SetRow(0);
1022 rDrawRange.aEnd.SetCol(MAXCOL);
1023 rDrawRange.aEnd.SetRow(MAXROW);
1024 nPaint |= PAINT_TOP | PAINT_LEFT;
1025 if (pViewShell)
1026 pViewShell->AdjustBlockHeight(false);
1028 else
1030 if (maBlockRanges[i]->aStart.Row() == 0 && maBlockRanges[i]->aEnd.Row() == MAXROW) // whole column
1032 nPaint |= PAINT_TOP;
1033 rDrawRange.aEnd.SetCol(MAXCOL);
1035 if (maBlockRanges[i]->aStart.Col() == 0 && maBlockRanges[i]->aEnd.Col() == MAXCOL) // whole row
1037 nPaint |= PAINT_LEFT;
1038 rDrawRange.aEnd.SetRow(MAXROW);
1040 if (pViewShell && pViewShell->AdjustBlockHeight(false))
1042 rDrawRange.aStart.SetCol(0);
1043 rDrawRange.aStart.SetRow(0);
1044 rDrawRange.aEnd.SetCol(MAXCOL);
1045 rDrawRange.aEnd.SetRow(MAXROW);
1046 nPaint |= PAINT_LEFT;
1048 pDocShell->UpdatePaintExt(nExtFlags, rDrawRange);
1052 if ( !bUndo ) // draw redo after updating row heights
1053 RedoSdrUndoAction(mpDrawUndo);
1055 pDocShell->PostPaint(aDrawRanges, nPaint, nExtFlags);
1057 pDocShell->PostDataChanged();
1058 if (pViewShell)
1059 pViewShell->CellContentChanged();
1062 void ScUndoPaste::Undo()
1064 BeginUndo();
1065 DoChange(true);
1066 if (!maBlockRanges.empty())
1067 ShowTable(*maBlockRanges.front());
1068 EndUndo();
1069 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
1072 void ScUndoPaste::Redo()
1074 BeginRedo();
1075 ScDocument* pDoc = pDocShell->GetDocument();
1076 EnableDrawAdjust( pDoc, false ); //! include in ScBlockUndo?
1077 DoChange( false );
1078 EnableDrawAdjust( pDoc, sal_True ); //! include in ScBlockUndo?
1079 EndRedo();
1080 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
1083 void ScUndoPaste::Repeat(SfxRepeatTarget& rTarget)
1085 if (rTarget.ISA(ScTabViewTarget))
1087 ScTabViewShell* pViewSh = ((ScTabViewTarget&)rTarget).GetViewShell();
1088 ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pViewSh->GetActiveWin() );
1089 if (pOwnClip)
1091 // keep a reference in case the clipboard is changed during PasteFromClip
1092 com::sun::star::uno::Reference<com::sun::star::datatransfer::XTransferable> aOwnClipRef( pOwnClip );
1093 pViewSh->PasteFromClip( nFlags, pOwnClip->GetDocument(),
1094 aPasteOptions.nFunction, aPasteOptions.bSkipEmpty, aPasteOptions.bTranspose,
1095 aPasteOptions.bAsLink, aPasteOptions.eMoveMode, IDF_NONE,
1096 sal_True ); // allow warning dialog
1101 bool ScUndoPaste::CanRepeat(SfxRepeatTarget& rTarget) const
1103 return rTarget.ISA(ScTabViewTarget);
1106 ScUndoDragDrop::ScUndoDragDrop( ScDocShell* pNewDocShell,
1107 const ScRange& rRange, ScAddress aNewDestPos, sal_Bool bNewCut,
1108 ScDocument* pUndoDocument, ScRefUndoData* pRefData, sal_Bool bScenario ) :
1109 ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFFIRST ),
1110 aSrcRange( rRange ),
1111 bCut( bNewCut ),
1112 bKeepScenarioFlags( bScenario )
1114 ScAddress aDestEnd(aNewDestPos);
1115 aDestEnd.IncRow(aSrcRange.aEnd.Row() - aSrcRange.aStart.Row());
1116 aDestEnd.IncCol(aSrcRange.aEnd.Col() - aSrcRange.aStart.Col());
1117 aDestEnd.IncTab(aSrcRange.aEnd.Tab() - aSrcRange.aStart.Tab());
1119 sal_Bool bIncludeFiltered = bCut;
1120 if ( !bIncludeFiltered )
1122 // find number of non-filtered rows
1123 SCROW nPastedCount = pDocShell->GetDocument()->CountNonFilteredRows(
1124 aSrcRange.aStart.Row(), aSrcRange.aEnd.Row(), aSrcRange.aStart.Tab());
1126 if ( nPastedCount == 0 )
1127 nPastedCount = 1;
1128 aDestEnd.SetRow( aNewDestPos.Row() + nPastedCount - 1 );
1131 aDestRange.aStart = aNewDestPos;
1132 aDestRange.aEnd = aDestEnd;
1134 SetChangeTrack();
1137 ScUndoDragDrop::~ScUndoDragDrop()
1141 OUString ScUndoDragDrop::GetComment() const
1142 { // "Move" : "Copy"
1143 return bCut ?
1144 ScGlobal::GetRscString( STR_UNDO_MOVE ) :
1145 ScGlobal::GetRscString( STR_UNDO_COPY );
1148 void ScUndoDragDrop::SetChangeTrack()
1150 ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
1151 if ( pChangeTrack )
1153 if ( bCut )
1155 nStartChangeAction = pChangeTrack->GetActionMax() + 1;
1156 pChangeTrack->AppendMove( aSrcRange, aDestRange, pRefUndoDoc );
1157 nEndChangeAction = pChangeTrack->GetActionMax();
1159 else
1160 pChangeTrack->AppendContentRange( aDestRange, pRefUndoDoc,
1161 nStartChangeAction, nEndChangeAction );
1163 else
1164 nStartChangeAction = nEndChangeAction = 0;
1167 void ScUndoDragDrop::PaintArea( ScRange aRange, sal_uInt16 nExtFlags ) const
1169 sal_uInt16 nPaint = PAINT_GRID;
1170 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1171 ScDocument* pDoc = pDocShell->GetDocument();
1173 if (pViewShell)
1175 VirtualDevice aVirtDev;
1176 ScViewData* pViewData = pViewShell->GetViewData();
1178 if ( pDoc->SetOptimalHeight( aRange.aStart.Row(), aRange.aEnd.Row(),
1179 aRange.aStart.Tab(), 0, &aVirtDev,
1180 pViewData->GetPPTX(), pViewData->GetPPTY(),
1181 pViewData->GetZoomX(), pViewData->GetZoomY(),
1182 false ) )
1184 aRange.aStart.SetCol(0);
1185 aRange.aEnd.SetCol(MAXCOL);
1186 aRange.aEnd.SetRow(MAXROW);
1187 nPaint |= PAINT_LEFT;
1191 if ( bKeepScenarioFlags )
1193 // Copy scenario -> also paint scenario boarder
1194 aRange.aStart.SetCol(0);
1195 aRange.aStart.SetRow(0);
1196 aRange.aEnd.SetCol(MAXCOL);
1197 aRange.aEnd.SetRow(MAXROW);
1200 // column/row info (width/height) included if whole columns/rows were copied
1201 if ( aSrcRange.aStart.Col() == 0 && aSrcRange.aEnd.Col() == MAXCOL )
1203 nPaint |= PAINT_LEFT;
1204 aRange.aEnd.SetRow(MAXROW);
1206 if ( aSrcRange.aStart.Row() == 0 && aSrcRange.aEnd.Row() == MAXROW )
1208 nPaint |= PAINT_TOP;
1209 aRange.aEnd.SetCol(MAXCOL);
1212 pDocShell->PostPaint( aRange, nPaint, nExtFlags );
1215 void ScUndoDragDrop::DoUndo( ScRange aRange ) const
1217 ScDocument* pDoc = pDocShell->GetDocument();
1219 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
1220 if ( pChangeTrack )
1221 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
1223 // Database range before data, so that the Autofilter button match up in ExtendMerge
1225 ScRange aPaintRange = aRange;
1226 pDoc->ExtendMerge( aPaintRange ); // before deleting
1228 sal_uInt16 nExtFlags = 0;
1229 pDocShell->UpdatePaintExt( nExtFlags, aPaintRange );
1231 // do not undo objects and note captions, they are handled via drawing undo
1232 sal_uInt16 nUndoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS;
1234 pDoc->DeleteAreaTab( aRange, nUndoFlags );
1235 pRefUndoDoc->CopyToDocument( aRange, nUndoFlags, false, pDoc );
1236 if ( pDoc->HasAttrib( aRange, HASATTR_MERGED ) )
1237 pDoc->ExtendMerge( aRange, sal_True );
1239 aPaintRange.aEnd.SetCol( std::max( aPaintRange.aEnd.Col(), aRange.aEnd.Col() ) );
1240 aPaintRange.aEnd.SetRow( std::max( aPaintRange.aEnd.Row(), aRange.aEnd.Row() ) );
1242 pDocShell->UpdatePaintExt( nExtFlags, aPaintRange );
1243 PaintArea( aPaintRange, nExtFlags );
1246 void ScUndoDragDrop::Undo()
1248 BeginUndo();
1249 DoUndo(aDestRange);
1250 if (bCut)
1251 DoUndo(aSrcRange);
1252 EndUndo();
1253 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
1256 void ScUndoDragDrop::Redo()
1258 BeginRedo();
1260 ScDocument* pDoc = pDocShell->GetDocument();
1261 ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
1263 EnableDrawAdjust( pDoc, false ); //! include in ScBlockUndo?
1265 // do not undo/redo objects and note captions, they are handled via drawing undo
1266 sal_uInt16 nRedoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS;
1268 /* TODO: Redoing note captions is quite tricky due to the fact that a
1269 helper clip document is used. While (re-)pasting the contents to the
1270 destination area, the original pointers to the captions created while
1271 dropping have to be restored. A simple CopyFromClip() would create new
1272 caption objects that are not tracked by drawing undo, and the captions
1273 restored by drawing redo would live without cell note objects pointing
1274 to them. So, first, CopyToClip() and CopyFromClip() are called without
1275 cloning the caption objects. This leads to cell notes pointing to the
1276 wrong captions from source area that will be removed by drawing redo
1277 later. Second, the pointers to the new captions have to be restored.
1278 Sadly, currently these pointers are not stored anywhere but in the list
1279 of drawing undo actions. */
1281 SCTAB nTab;
1282 ScMarkData aSourceMark;
1283 for (nTab=aSrcRange.aStart.Tab(); nTab<=aSrcRange.aEnd.Tab(); nTab++)
1284 aSourceMark.SelectTable( nTab, sal_True );
1286 // do not clone objects and note captions into clipdoc (see above)
1287 // but at least copy notes
1288 ScClipParam aClipParam(aSrcRange, bCut);
1289 pDoc->CopyToClip(aClipParam, pClipDoc, &aSourceMark, false, bKeepScenarioFlags, false, true);
1291 if (bCut)
1293 ScRange aSrcPaintRange = aSrcRange;
1294 pDoc->ExtendMerge( aSrcPaintRange ); // before deleting
1295 sal_uInt16 nExtFlags = 0;
1296 pDocShell->UpdatePaintExt( nExtFlags, aSrcPaintRange );
1297 pDoc->DeleteAreaTab( aSrcRange, nRedoFlags );
1298 PaintArea( aSrcPaintRange, nExtFlags );
1301 ScMarkData aDestMark;
1302 for (nTab=aDestRange.aStart.Tab(); nTab<=aDestRange.aEnd.Tab(); nTab++)
1303 aDestMark.SelectTable( nTab, sal_True );
1305 sal_Bool bIncludeFiltered = bCut;
1306 // TODO: restore old note captions instead of cloning new captions...
1307 pDoc->CopyFromClip( aDestRange, aDestMark, IDF_ALL & ~IDF_OBJECTS, NULL, pClipDoc, sal_True, false, bIncludeFiltered );
1309 if (bCut)
1310 for (nTab=aSrcRange.aStart.Tab(); nTab<=aSrcRange.aEnd.Tab(); nTab++)
1311 pDoc->RefreshAutoFilter( aSrcRange.aStart.Col(), aSrcRange.aStart.Row(),
1312 aSrcRange.aEnd.Col(), aSrcRange.aEnd.Row(), nTab );
1314 // skipped rows and merged cells don't mix
1315 if ( !bIncludeFiltered && pClipDoc->HasClipFilteredRows() )
1316 pDocShell->GetDocFunc().UnmergeCells( aDestRange, false );
1318 for (nTab=aDestRange.aStart.Tab(); nTab<=aDestRange.aEnd.Tab(); nTab++)
1320 SCCOL nEndCol = aDestRange.aEnd.Col();
1321 SCROW nEndRow = aDestRange.aEnd.Row();
1322 pDoc->ExtendMerge( aDestRange.aStart.Col(), aDestRange.aStart.Row(),
1323 nEndCol, nEndRow, nTab, sal_True );
1324 PaintArea( ScRange( aDestRange.aStart.Col(), aDestRange.aStart.Row(), nTab,
1325 nEndCol, nEndRow, nTab ), 0 );
1328 SetChangeTrack();
1330 delete pClipDoc;
1331 ShowTable( aDestRange.aStart.Tab() );
1333 RedoSdrUndoAction( pDrawUndo ); //! include in ScBlockUndo?
1334 EnableDrawAdjust( pDoc, sal_True ); //! include in ScBlockUndo?
1336 EndRedo();
1337 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
1340 void ScUndoDragDrop::Repeat(SfxRepeatTarget& /* rTarget */)
1344 bool ScUndoDragDrop::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1346 return false; // not possible
1349 // Insert list containing range names
1350 // (Insert|Name|Insert =>[List])
1351 ScUndoListNames::ScUndoListNames( ScDocShell* pNewDocShell, const ScRange& rRange,
1352 ScDocument* pNewUndoDoc, ScDocument* pNewRedoDoc ) :
1353 ScBlockUndo( pNewDocShell, rRange, SC_UNDO_AUTOHEIGHT ),
1354 pUndoDoc( pNewUndoDoc ),
1355 pRedoDoc( pNewRedoDoc )
1359 ScUndoListNames::~ScUndoListNames()
1361 delete pUndoDoc;
1362 delete pRedoDoc;
1365 OUString ScUndoListNames::GetComment() const
1367 return ScGlobal::GetRscString( STR_UNDO_LISTNAMES );
1370 void ScUndoListNames::DoChange( ScDocument* pSrcDoc ) const
1372 ScDocument* pDoc = pDocShell->GetDocument();
1374 pDoc->DeleteAreaTab( aBlockRange, IDF_ALL );
1375 pSrcDoc->CopyToDocument( aBlockRange, IDF_ALL, false, pDoc );
1376 pDocShell->PostPaint( aBlockRange, PAINT_GRID );
1377 pDocShell->PostDataChanged();
1378 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1379 if (pViewShell)
1380 pViewShell->CellContentChanged();
1383 void ScUndoListNames::Undo()
1385 BeginUndo();
1386 DoChange(pUndoDoc);
1387 EndUndo();
1390 void ScUndoListNames::Redo()
1392 BeginRedo();
1393 DoChange(pRedoDoc);
1394 EndRedo();
1397 void ScUndoListNames::Repeat(SfxRepeatTarget& rTarget)
1399 if (rTarget.ISA(ScTabViewTarget))
1400 ((ScTabViewTarget&)rTarget).GetViewShell()->InsertNameList();
1403 bool ScUndoListNames::CanRepeat(SfxRepeatTarget& rTarget) const
1405 return rTarget.ISA(ScTabViewTarget);
1408 ScUndoUseScenario::ScUndoUseScenario( ScDocShell* pNewDocShell,
1409 const ScMarkData& rMark,
1410 /*C*/ const ScArea& rDestArea,
1411 ScDocument* pNewUndoDoc,
1412 const OUString& rNewName ) :
1413 ScSimpleUndo( pNewDocShell ),
1414 pUndoDoc( pNewUndoDoc ),
1415 aMarkData( rMark ),
1416 aName( rNewName )
1418 aRange.aStart.SetCol(rDestArea.nColStart);
1419 aRange.aStart.SetRow(rDestArea.nRowStart);
1420 aRange.aStart.SetTab(rDestArea.nTab);
1421 aRange.aEnd.SetCol(rDestArea.nColEnd);
1422 aRange.aEnd.SetRow(rDestArea.nRowEnd);
1423 aRange.aEnd.SetTab(rDestArea.nTab);
1426 ScUndoUseScenario::~ScUndoUseScenario()
1428 delete pUndoDoc;
1431 OUString ScUndoUseScenario::GetComment() const
1433 return ScGlobal::GetRscString( STR_UNDO_USESCENARIO );
1436 void ScUndoUseScenario::Undo()
1438 BeginUndo();
1440 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1441 if (pViewShell)
1443 pViewShell->DoneBlockMode();
1444 pViewShell->InitOwnBlockMode();
1447 ScDocument* pDoc = pDocShell->GetDocument();
1448 pDoc->DeleteSelection( IDF_ALL, aMarkData );
1449 pUndoDoc->CopyToDocument( aRange, IDF_ALL, sal_True, pDoc, &aMarkData );
1451 // scenario table
1452 sal_Bool bFrame = false;
1453 SCTAB nTab = aRange.aStart.Tab();
1454 SCTAB nEndTab = nTab;
1455 while ( pUndoDoc->HasTable(nEndTab+1) && pUndoDoc->IsScenario(nEndTab+1) )
1456 ++nEndTab;
1457 for (SCTAB i = nTab+1; i<=nEndTab; i++)
1459 // Flags always
1460 OUString aComment;
1461 Color aColor;
1462 sal_uInt16 nScenFlags;
1463 pUndoDoc->GetScenarioData( i, aComment, aColor, nScenFlags );
1464 pDoc->SetScenarioData( i, aComment, aColor, nScenFlags );
1465 sal_Bool bActive = pUndoDoc->IsActiveScenario( i );
1466 pDoc->SetActiveScenario( i, bActive );
1467 // For copy-back scenario also consider content
1468 if ( nScenFlags & SC_SCENARIO_TWOWAY )
1470 pDoc->DeleteAreaTab( 0,0, MAXCOL,MAXROW, i, IDF_ALL );
1471 pUndoDoc->CopyToDocument( 0,0,i, MAXCOL,MAXROW,i, IDF_ALL,false, pDoc );
1473 if ( nScenFlags & SC_SCENARIO_SHOWFRAME )
1474 bFrame = sal_True;
1477 // if visible borders, then paint all
1478 if (bFrame)
1479 pDocShell->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID | PAINT_EXTRAS );
1480 else
1481 pDocShell->PostPaint( aRange, PAINT_GRID | PAINT_EXTRAS );
1482 pDocShell->PostDataChanged();
1483 if (pViewShell)
1484 pViewShell->CellContentChanged();
1486 ShowTable( aRange.aStart.Tab() );
1488 EndUndo();
1491 void ScUndoUseScenario::Redo()
1493 SCTAB nTab = aRange.aStart.Tab();
1494 BeginRedo();
1496 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1497 if (pViewShell)
1499 pViewShell->SetTabNo( nTab );
1500 pViewShell->DoneBlockMode();
1501 pViewShell->InitOwnBlockMode();
1504 pDocShell->UseScenario( nTab, aName, false );
1506 EndRedo();
1509 void ScUndoUseScenario::Repeat(SfxRepeatTarget& rTarget)
1511 if (rTarget.ISA(ScTabViewTarget))
1513 OUString aTemp = aName;
1514 ((ScTabViewTarget&)rTarget).GetViewShell()->UseScenario(aTemp);
1518 bool ScUndoUseScenario::CanRepeat(SfxRepeatTarget& rTarget) const
1520 if (rTarget.ISA(ScTabViewTarget))
1522 ScViewData* pViewData = ((ScTabViewTarget&)rTarget).GetViewShell()->GetViewData();
1523 return !pViewData->GetDocument()->IsScenario( pViewData->GetTabNo() );
1525 return false;
1528 ScUndoSelectionStyle::ScUndoSelectionStyle( ScDocShell* pNewDocShell,
1529 const ScMarkData& rMark,
1530 const ScRange& rRange,
1531 const OUString& rName,
1532 ScDocument* pNewUndoDoc ) :
1533 ScSimpleUndo( pNewDocShell ),
1534 aMarkData( rMark ),
1535 pUndoDoc( pNewUndoDoc ),
1536 aStyleName( rName ),
1537 aRange( rRange )
1539 aMarkData.MarkToMulti();
1542 ScUndoSelectionStyle::~ScUndoSelectionStyle()
1544 delete pUndoDoc;
1547 OUString ScUndoSelectionStyle::GetComment() const
1549 return ScGlobal::GetRscString( STR_UNDO_APPLYCELLSTYLE );
1552 void ScUndoSelectionStyle::DoChange( const sal_Bool bUndo )
1554 ScDocument* pDoc = pDocShell->GetDocument();
1556 SetViewMarkData( aMarkData );
1558 ScRange aWorkRange( aRange );
1559 if ( pDoc->HasAttrib( aWorkRange, HASATTR_MERGED ) ) // Merged cells?
1560 pDoc->ExtendMerge( aWorkRange, sal_True );
1562 sal_uInt16 nExtFlags = 0;
1563 pDocShell->UpdatePaintExt( nExtFlags, aWorkRange );
1565 if (bUndo) // if Undo then push back all old data again
1567 SCTAB nTabCount = pDoc->GetTableCount();
1568 ScRange aCopyRange = aWorkRange;
1569 aCopyRange.aStart.SetTab(0);
1570 aCopyRange.aEnd.SetTab(nTabCount-1);
1571 pUndoDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, sal_True, pDoc, &aMarkData );
1573 else // if Redo, then reapply style
1575 ScStyleSheetPool* pStlPool = pDoc->GetStyleSheetPool();
1576 ScStyleSheet* pStyleSheet =
1577 (ScStyleSheet*) pStlPool->Find( aStyleName, SFX_STYLE_FAMILY_PARA );
1578 if (!pStyleSheet)
1580 OSL_FAIL("StyleSheet not found");
1581 return;
1583 pDoc->ApplySelectionStyle( *pStyleSheet, aMarkData );
1586 pDocShell->UpdatePaintExt( nExtFlags, aWorkRange );
1588 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1589 if ( !( (pViewShell) && pViewShell->AdjustBlockHeight() ) )
1590 /*A*/ pDocShell->PostPaint( aWorkRange, PAINT_GRID | PAINT_EXTRAS, nExtFlags );
1592 ShowTable( aWorkRange.aStart.Tab() );
1595 void ScUndoSelectionStyle::Undo()
1597 BeginUndo();
1598 DoChange( sal_True );
1599 EndUndo();
1602 void ScUndoSelectionStyle::Redo()
1604 BeginRedo();
1605 DoChange( false );
1606 EndRedo();
1609 void ScUndoSelectionStyle::Repeat(SfxRepeatTarget& rTarget)
1611 if (rTarget.ISA(ScTabViewTarget))
1613 ScDocument* pDoc = pDocShell->GetDocument();
1614 ScStyleSheetPool* pStlPool = pDoc->GetStyleSheetPool();
1615 ScStyleSheet* pStyleSheet = (ScStyleSheet*) pStlPool->
1616 Find( aStyleName, SFX_STYLE_FAMILY_PARA );
1617 if (!pStyleSheet)
1619 OSL_FAIL("StyleSheet not found");
1620 return;
1623 ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
1624 rViewShell.SetStyleSheetToMarked( pStyleSheet, sal_True );
1628 bool ScUndoSelectionStyle::CanRepeat(SfxRepeatTarget& rTarget) const
1630 return rTarget.ISA(ScTabViewTarget);
1633 sal_uInt16 ScUndoSelectionStyle::GetId() const
1635 return STR_UNDO_APPLYCELLSTYLE;
1638 ScUndoEnterMatrix::ScUndoEnterMatrix( ScDocShell* pNewDocShell, const ScRange& rArea,
1639 ScDocument* pNewUndoDoc, const OUString& rForm ) :
1640 ScBlockUndo( pNewDocShell, rArea, SC_UNDO_SIMPLE ),
1641 pUndoDoc( pNewUndoDoc ),
1642 aFormula( rForm )
1644 SetChangeTrack();
1647 ScUndoEnterMatrix::~ScUndoEnterMatrix()
1649 delete pUndoDoc;
1652 OUString ScUndoEnterMatrix::GetComment() const
1654 return ScGlobal::GetRscString( STR_UNDO_ENTERMATRIX );
1657 void ScUndoEnterMatrix::SetChangeTrack()
1659 ScDocument* pDoc = pDocShell->GetDocument();
1660 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
1661 if ( pChangeTrack )
1662 pChangeTrack->AppendContentRange( aBlockRange, pUndoDoc,
1663 nStartChangeAction, nEndChangeAction );
1664 else
1665 nStartChangeAction = nEndChangeAction = 0;
1668 void ScUndoEnterMatrix::Undo()
1670 BeginUndo();
1672 ScDocument* pDoc = pDocShell->GetDocument();
1674 pDoc->DeleteAreaTab( aBlockRange, IDF_ALL & ~IDF_NOTE );
1675 pUndoDoc->CopyToDocument( aBlockRange, IDF_ALL & ~IDF_NOTE, false, pDoc );
1676 pDocShell->PostPaint( aBlockRange, PAINT_GRID );
1677 pDocShell->PostDataChanged();
1678 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1679 if (pViewShell)
1680 pViewShell->CellContentChanged();
1682 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
1683 if ( pChangeTrack )
1684 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
1686 EndUndo();
1689 void ScUndoEnterMatrix::Redo()
1691 BeginRedo();
1693 ScDocument* pDoc = pDocShell->GetDocument();
1695 ScMarkData aDestMark;
1696 aDestMark.SelectOneTable( aBlockRange.aStart.Tab() );
1697 aDestMark.SetMarkArea( aBlockRange );
1699 pDoc->InsertMatrixFormula( aBlockRange.aStart.Col(), aBlockRange.aStart.Row(),
1700 aBlockRange.aEnd.Col(), aBlockRange.aEnd.Row(),
1701 aDestMark, aFormula );
1703 SetChangeTrack();
1705 EndRedo();
1708 void ScUndoEnterMatrix::Repeat(SfxRepeatTarget& rTarget)
1710 if (rTarget.ISA(ScTabViewTarget))
1712 OUString aTemp = aFormula;
1713 ScDocument* pDoc = pDocShell->GetDocument();
1714 ((ScTabViewTarget&)rTarget).GetViewShell()->EnterMatrix(aTemp, pDoc->GetGrammar());
1718 bool ScUndoEnterMatrix::CanRepeat(SfxRepeatTarget& rTarget) const
1720 return rTarget.ISA(ScTabViewTarget);
1723 static ScRange lcl_GetMultiMarkRange( const ScMarkData& rMark )
1725 OSL_ENSURE( rMark.IsMultiMarked(), "wrong mark type" );
1727 ScRange aRange;
1728 rMark.GetMultiMarkArea( aRange );
1729 return aRange;
1732 ScUndoIndent::ScUndoIndent( ScDocShell* pNewDocShell, const ScMarkData& rMark,
1733 ScDocument* pNewUndoDoc, sal_Bool bIncrement ) :
1734 ScBlockUndo( pNewDocShell, lcl_GetMultiMarkRange(rMark), SC_UNDO_AUTOHEIGHT ),
1735 aMarkData( rMark ),
1736 pUndoDoc( pNewUndoDoc ),
1737 bIsIncrement( bIncrement )
1741 ScUndoIndent::~ScUndoIndent()
1743 delete pUndoDoc;
1746 OUString ScUndoIndent::GetComment() const
1748 sal_uInt16 nId = bIsIncrement ? STR_UNDO_INC_INDENT : STR_UNDO_DEC_INDENT;
1749 return ScGlobal::GetRscString( nId );
1752 void ScUndoIndent::Undo()
1754 BeginUndo();
1756 ScDocument* pDoc = pDocShell->GetDocument();
1757 SCTAB nTabCount = pDoc->GetTableCount();
1758 ScRange aCopyRange = aBlockRange;
1759 aCopyRange.aStart.SetTab(0);
1760 aCopyRange.aEnd.SetTab(nTabCount-1);
1761 pUndoDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, sal_True, pDoc, &aMarkData );
1762 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
1764 EndUndo();
1767 void ScUndoIndent::Redo()
1769 BeginRedo();
1771 ScDocument* pDoc = pDocShell->GetDocument();
1772 pDoc->ChangeSelectionIndent( bIsIncrement, aMarkData );
1773 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
1775 EndRedo();
1778 void ScUndoIndent::Repeat(SfxRepeatTarget& rTarget)
1780 if (rTarget.ISA(ScTabViewTarget))
1781 ((ScTabViewTarget&)rTarget).GetViewShell()->ChangeIndent( bIsIncrement );
1784 bool ScUndoIndent::CanRepeat(SfxRepeatTarget& rTarget) const
1786 return rTarget.ISA(ScTabViewTarget);
1789 ScUndoTransliterate::ScUndoTransliterate( ScDocShell* pNewDocShell, const ScMarkData& rMark,
1790 ScDocument* pNewUndoDoc, sal_Int32 nType ) :
1791 ScBlockUndo( pNewDocShell, lcl_GetMultiMarkRange(rMark), SC_UNDO_AUTOHEIGHT ),
1792 aMarkData( rMark ),
1793 pUndoDoc( pNewUndoDoc ),
1794 nTransliterationType( nType )
1798 ScUndoTransliterate::~ScUndoTransliterate()
1800 delete pUndoDoc;
1803 OUString ScUndoTransliterate::GetComment() const
1805 return ScGlobal::GetRscString( STR_UNDO_TRANSLITERATE );
1808 void ScUndoTransliterate::Undo()
1810 BeginUndo();
1812 ScDocument* pDoc = pDocShell->GetDocument();
1813 SCTAB nTabCount = pDoc->GetTableCount();
1814 ScRange aCopyRange = aBlockRange;
1815 aCopyRange.aStart.SetTab(0);
1816 aCopyRange.aEnd.SetTab(nTabCount-1);
1817 pUndoDoc->CopyToDocument( aCopyRange, IDF_CONTENTS, sal_True, pDoc, &aMarkData );
1818 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
1820 EndUndo();
1823 void ScUndoTransliterate::Redo()
1825 BeginRedo();
1827 ScDocument* pDoc = pDocShell->GetDocument();
1828 pDoc->TransliterateText( aMarkData, nTransliterationType );
1829 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
1831 EndRedo();
1834 void ScUndoTransliterate::Repeat(SfxRepeatTarget& rTarget)
1836 if (rTarget.ISA(ScTabViewTarget))
1837 ((ScTabViewTarget&)rTarget).GetViewShell()->TransliterateText( nTransliterationType );
1840 bool ScUndoTransliterate::CanRepeat(SfxRepeatTarget& rTarget) const
1842 return rTarget.ISA(ScTabViewTarget);
1845 ScUndoClearItems::ScUndoClearItems( ScDocShell* pNewDocShell, const ScMarkData& rMark,
1846 ScDocument* pNewUndoDoc, const sal_uInt16* pW ) :
1847 ScBlockUndo( pNewDocShell, lcl_GetMultiMarkRange(rMark), SC_UNDO_AUTOHEIGHT ),
1848 aMarkData( rMark ),
1849 pUndoDoc( pNewUndoDoc ),
1850 pWhich( NULL )
1852 OSL_ENSURE( pW, "ScUndoClearItems: Which-Pointer ist 0" );
1854 sal_uInt16 nCount = 0;
1855 while ( pW[nCount] )
1856 ++nCount;
1857 pWhich = new sal_uInt16[nCount+1];
1858 for (sal_uInt16 i=0; i<=nCount; i++)
1859 pWhich[i] = pW[i];
1862 ScUndoClearItems::~ScUndoClearItems()
1864 delete pUndoDoc;
1865 delete pWhich;
1868 OUString ScUndoClearItems::GetComment() const
1870 return ScGlobal::GetRscString( STR_UNDO_DELETECONTENTS );
1873 void ScUndoClearItems::Undo()
1875 BeginUndo();
1877 ScDocument* pDoc = pDocShell->GetDocument();
1878 pUndoDoc->CopyToDocument( aBlockRange, IDF_ATTRIB, sal_True, pDoc, &aMarkData );
1879 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
1881 EndUndo();
1884 void ScUndoClearItems::Redo()
1886 BeginRedo();
1888 ScDocument* pDoc = pDocShell->GetDocument();
1889 pDoc->ClearSelectionItems( pWhich, aMarkData );
1890 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
1892 EndRedo();
1895 void ScUndoClearItems::Repeat(SfxRepeatTarget& rTarget)
1897 if (rTarget.ISA(ScTabViewTarget))
1899 ScViewData* pViewData = ((ScTabViewTarget&)rTarget).GetViewShell()->GetViewData();
1900 pViewData->GetDocFunc().ClearItems( pViewData->GetMarkData(), pWhich, false );
1904 bool ScUndoClearItems::CanRepeat(SfxRepeatTarget& rTarget) const
1906 return rTarget.ISA(ScTabViewTarget);
1909 // remove all line breaks of a table
1910 ScUndoRemoveBreaks::ScUndoRemoveBreaks( ScDocShell* pNewDocShell,
1911 SCTAB nNewTab, ScDocument* pNewUndoDoc ) :
1912 ScSimpleUndo( pNewDocShell ),
1913 nTab( nNewTab ),
1914 pUndoDoc( pNewUndoDoc )
1918 ScUndoRemoveBreaks::~ScUndoRemoveBreaks()
1920 delete pUndoDoc;
1923 OUString ScUndoRemoveBreaks::GetComment() const
1925 return ScGlobal::GetRscString( STR_UNDO_REMOVEBREAKS );
1928 void ScUndoRemoveBreaks::Undo()
1930 BeginUndo();
1932 ScDocument* pDoc = pDocShell->GetDocument();
1933 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1935 pUndoDoc->CopyToDocument( 0,0,nTab, MAXCOL,MAXROW,nTab, IDF_NONE, false, pDoc );
1936 if (pViewShell)
1937 pViewShell->UpdatePageBreakData( sal_True );
1938 pDocShell->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
1940 EndUndo();
1943 void ScUndoRemoveBreaks::Redo()
1945 BeginRedo();
1947 ScDocument* pDoc = pDocShell->GetDocument();
1948 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1950 pDoc->RemoveManualBreaks(nTab);
1951 pDoc->UpdatePageBreaks(nTab);
1952 if (pViewShell)
1953 pViewShell->UpdatePageBreakData( sal_True );
1954 pDocShell->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
1956 EndRedo();
1959 void ScUndoRemoveBreaks::Repeat(SfxRepeatTarget& rTarget)
1961 if (rTarget.ISA(ScTabViewTarget))
1963 ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
1964 rViewShell.RemoveManualBreaks();
1968 bool ScUndoRemoveBreaks::CanRepeat(SfxRepeatTarget& rTarget) const
1970 return rTarget.ISA(ScTabViewTarget);
1973 ScUndoRemoveMerge::ScUndoRemoveMerge( ScDocShell* pNewDocShell,
1974 const ScCellMergeOption& rOption, ScDocument* pNewUndoDoc ) :
1975 ScBlockUndo( pNewDocShell, rOption.getFirstSingleRange(), SC_UNDO_SIMPLE ),
1976 maOption(rOption),
1977 pUndoDoc( pNewUndoDoc )
1981 ScUndoRemoveMerge::~ScUndoRemoveMerge()
1983 delete pUndoDoc;
1986 OUString ScUndoRemoveMerge::GetComment() const
1988 return ScGlobal::GetRscString( STR_UNDO_REMERGE ); // "remove merge"
1991 void ScUndoRemoveMerge::Undo()
1993 using ::std::set;
1995 SetCurTab();
1996 BeginUndo();
1998 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
2000 ScDocument* pDoc = pDocShell->GetDocument();
2001 for (set<SCTAB>::const_iterator itr = maOption.maTabs.begin(), itrEnd = maOption.maTabs.end();
2002 itr != itrEnd; ++itr)
2004 OSL_ENSURE(pUndoDoc, "NULL pUndoDoc!");
2005 if (!pUndoDoc)
2006 continue;
2007 // There is no need to extend merge area because it's already been extended.
2008 ScRange aRange = maOption.getSingleRange(*itr);
2009 pDoc->DeleteAreaTab(aRange, IDF_ATTRIB);
2010 pUndoDoc->CopyToDocument(aRange, IDF_ATTRIB, false, pDoc);
2012 bool bDidPaint = false;
2013 if ( pViewShell )
2015 pViewShell->SetTabNo(*itr);
2016 bDidPaint = pViewShell->AdjustRowHeight(maOption.mnStartRow, maOption.mnEndRow);
2018 if (!bDidPaint)
2019 ScUndoUtil::PaintMore(pDocShell, aRange);
2022 EndUndo();
2025 void ScUndoRemoveMerge::Redo()
2027 using ::std::set;
2029 SetCurTab();
2030 BeginRedo();
2032 ScDocument* pDoc = pDocShell->GetDocument();
2033 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
2035 for (set<SCTAB>::const_iterator itr = maOption.maTabs.begin(), itrEnd = maOption.maTabs.end();
2036 itr != itrEnd; ++itr)
2038 SCTAB nTab = *itr;
2039 // There is no need to extend merge area because it's already been extended.
2040 ScRange aRange = maOption.getSingleRange(nTab);
2042 const SfxPoolItem& rDefAttr = pDoc->GetPool()->GetDefaultItem( ATTR_MERGE );
2043 ScPatternAttr aPattern( pDoc->GetPool() );
2044 aPattern.GetItemSet().Put( rDefAttr );
2045 pDoc->ApplyPatternAreaTab( maOption.mnStartCol, maOption.mnStartRow,
2046 maOption.mnEndCol, maOption.mnEndRow, nTab,
2047 aPattern );
2049 pDoc->RemoveFlagsTab( maOption.mnStartCol, maOption.mnStartRow,
2050 maOption.mnEndCol, maOption.mnEndRow, nTab,
2051 SC_MF_HOR | SC_MF_VER );
2053 pDoc->ExtendMerge(aRange, true);
2055 // Paint
2057 sal_Bool bDidPaint = false;
2058 if ( pViewShell )
2060 pViewShell->SetTabNo(nTab);
2061 bDidPaint = pViewShell->AdjustRowHeight(maOption.mnStartRow, maOption.mnEndRow);
2063 if (!bDidPaint)
2064 ScUndoUtil::PaintMore(pDocShell, aRange);
2067 EndRedo();
2070 void ScUndoRemoveMerge::Repeat(SfxRepeatTarget& rTarget)
2072 if (rTarget.ISA(ScTabViewTarget))
2073 ((ScTabViewTarget&)rTarget).GetViewShell()->RemoveMerge();
2076 bool ScUndoRemoveMerge::CanRepeat(SfxRepeatTarget& rTarget) const
2078 return rTarget.ISA(ScTabViewTarget);
2081 void ScUndoRemoveMerge::SetCurTab()
2083 SCTAB nCurTab = pDocShell->GetCurTab();
2084 aBlockRange.aStart.SetTab(nCurTab);
2085 aBlockRange.aEnd.SetTab(nCurTab);
2088 /** set only border, for ScRangeList (StarOne) */
2089 static ScRange lcl_TotalRange( const ScRangeList& rRanges )
2091 ScRange aTotal;
2092 if ( !rRanges.empty() )
2094 aTotal = *rRanges[ 0 ];
2095 for ( size_t i = 1, nCount = rRanges.size(); i < nCount; ++i )
2097 ScRange aRange = *rRanges[ i ];
2098 if (aRange.aStart.Col() < aTotal.aStart.Col()) aTotal.aStart.SetCol(aRange.aStart.Col());
2099 if (aRange.aStart.Row() < aTotal.aStart.Row()) aTotal.aStart.SetRow(aRange.aStart.Row());
2100 if (aRange.aStart.Tab() < aTotal.aStart.Tab()) aTotal.aStart.SetTab(aRange.aStart.Tab());
2101 if (aRange.aEnd.Col() > aTotal.aEnd.Col() ) aTotal.aEnd.SetCol( aRange.aEnd.Col() );
2102 if (aRange.aEnd.Row() > aTotal.aEnd.Row() ) aTotal.aEnd.SetRow( aRange.aEnd.Row() );
2103 if (aRange.aEnd.Tab() > aTotal.aEnd.Tab() ) aTotal.aEnd.SetTab(aRange.aEnd.Tab() );
2106 return aTotal;
2109 ScUndoBorder::ScUndoBorder( ScDocShell* pNewDocShell,
2110 const ScRangeList& rRangeList, ScDocument* pNewUndoDoc,
2111 const SvxBoxItem& rNewOuter, const SvxBoxInfoItem& rNewInner ) :
2112 ScBlockUndo( pNewDocShell, lcl_TotalRange(rRangeList), SC_UNDO_SIMPLE ),
2113 pUndoDoc( pNewUndoDoc )
2115 pRanges = new ScRangeList(rRangeList);
2116 pOuter = new SvxBoxItem(rNewOuter);
2117 pInner = new SvxBoxInfoItem(rNewInner);
2120 ScUndoBorder::~ScUndoBorder()
2122 delete pUndoDoc;
2123 delete pRanges;
2124 delete pOuter;
2125 delete pInner;
2128 OUString ScUndoBorder::GetComment() const
2130 return ScGlobal::GetRscString( STR_UNDO_SELATTRLINES ); //! eigener String?
2133 void ScUndoBorder::Undo()
2135 BeginUndo();
2137 ScDocument* pDoc = pDocShell->GetDocument();
2138 ScMarkData aMarkData;
2139 aMarkData.MarkFromRangeList( *pRanges, false );
2140 pUndoDoc->CopyToDocument( aBlockRange, IDF_ATTRIB, sal_True, pDoc, &aMarkData );
2141 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
2143 EndUndo();
2146 void ScUndoBorder::Redo()
2148 BeginRedo();
2150 ScDocument* pDoc = pDocShell->GetDocument(); // call function at docfunc
2151 size_t nCount = pRanges->size();
2152 for (size_t i = 0; i < nCount; ++i )
2154 ScRange aRange = *(*pRanges)[i];
2155 SCTAB nTab = aRange.aStart.Tab();
2157 ScMarkData aMark;
2158 aMark.SetMarkArea( aRange );
2159 aMark.SelectTable( nTab, sal_True );
2161 pDoc->ApplySelectionFrame( aMark, pOuter, pInner );
2163 for (size_t i = 0; i < nCount; ++i)
2164 pDocShell->PostPaint( *(*pRanges)[i], PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
2166 EndRedo();
2169 void ScUndoBorder::Repeat(SfxRepeatTarget& /* rTarget */)
2171 //TODO later (when the function has moved from cellsuno to docfunc)
2174 bool ScUndoBorder::CanRepeat(SfxRepeatTarget& /* rTarget */) const
2176 return false; // See above
2179 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */