fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / ui / undo / undoblk.cxx
blob9cecfa0290458a159bdbfde56b103381ef7709b3
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 <brdcst.hxx>
50 #include "sc.hrc"
51 #include <rowheightcontext.hxx>
52 #include <refhint.hxx>
53 #include <refupdatecontext.hxx>
54 #include <validat.hxx>
55 #include <gridwin.hxx>
56 #include <svl/listener.hxx>
58 #include <set>
59 #include <boost/scoped_ptr.hpp>
61 // STATIC DATA -----------------------------------------------------------
63 TYPEINIT1(ScUndoInsertCells, SfxUndoAction);
64 TYPEINIT1(ScUndoDeleteCells, SfxUndoAction);
65 TYPEINIT1(ScUndoDeleteMulti, SfxUndoAction);
66 TYPEINIT1(ScUndoCut, ScBlockUndo);
67 TYPEINIT1(ScUndoPaste, SfxUndoAction);
68 TYPEINIT1(ScUndoDragDrop, SfxUndoAction);
69 TYPEINIT1(ScUndoListNames, SfxUndoAction);
70 TYPEINIT1(ScUndoConditionalFormat, SfxUndoAction);
71 TYPEINIT1(ScUndoUseScenario, SfxUndoAction);
72 TYPEINIT1(ScUndoSelectionStyle, SfxUndoAction);
73 TYPEINIT1(ScUndoEnterMatrix, ScBlockUndo);
74 TYPEINIT1(ScUndoIndent, ScBlockUndo);
75 TYPEINIT1(ScUndoTransliterate, ScBlockUndo);
76 TYPEINIT1(ScUndoClearItems, ScBlockUndo);
77 TYPEINIT1(ScUndoRemoveBreaks, SfxUndoAction);
78 TYPEINIT1(ScUndoRemoveMerge, ScBlockUndo);
79 TYPEINIT1(ScUndoBorder, ScBlockUndo);
81 // TODO:
82 /*A*/ // SetOptimalHeight on Document, if no View
83 /*B*/ // linked sheets
84 /*C*/ // ScArea
85 //? // check later
87 ScUndoInsertCells::ScUndoInsertCells( ScDocShell* pNewDocShell,
88 const ScRange& rRange, SCTAB nNewCount, SCTAB* pNewTabs, SCTAB* pNewScenarios,
89 InsCellCmd eNewCmd, ScDocument* pUndoDocument, ScRefUndoData* pRefData,
90 bool bNewPartOfPaste ) :
91 ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFLAST ),
92 aEffRange( rRange ),
93 nCount( nNewCount ),
94 pTabs( pNewTabs ),
95 pScenarios( pNewScenarios ),
96 eCmd( eNewCmd ),
97 bPartOfPaste( bNewPartOfPaste ),
98 pPasteUndo( NULL )
100 if (eCmd == INS_INSROWS) // whole row?
102 aEffRange.aStart.SetCol(0);
103 aEffRange.aEnd.SetCol(MAXCOL);
106 if (eCmd == INS_INSCOLS) // whole column?
108 aEffRange.aStart.SetRow(0);
109 aEffRange.aEnd.SetRow(MAXROW);
112 SetChangeTrack();
115 ScUndoInsertCells::~ScUndoInsertCells()
117 delete pPasteUndo;
118 delete []pTabs;
119 delete []pScenarios;
122 OUString ScUndoInsertCells::GetComment() const
124 return ScGlobal::GetRscString( pPasteUndo ? STR_UNDO_PASTE : STR_UNDO_INSERTCELLS );
127 bool ScUndoInsertCells::Merge( SfxUndoAction* pNextAction )
129 // If a paste undo action has already been added, append (detective) action there.
130 if ( pPasteUndo )
131 return pPasteUndo->Merge( pNextAction );
133 if ( bPartOfPaste && pNextAction->ISA( ScUndoWrapper ) )
135 ScUndoWrapper* pWrapper = static_cast<ScUndoWrapper*>(pNextAction);
136 SfxUndoAction* pWrappedAction = pWrapper->GetWrappedUndo();
137 if ( pWrappedAction && pWrappedAction->ISA( ScUndoPaste ) )
139 // Store paste action if this is part of paste with inserting cells.
140 // A list action isn't used because Repeat wouldn't work (insert wrong cells).
142 pPasteUndo = pWrappedAction;
143 pWrapper->ForgetWrappedUndo(); // pWrapper is deleted by UndoManager
144 return true;
148 // Call base class for detective handling
149 return ScMoveUndo::Merge( pNextAction );
152 void ScUndoInsertCells::SetChangeTrack()
154 ScChangeTrack* pChangeTrack = pDocShell->GetDocument().GetChangeTrack();
155 if ( pChangeTrack )
157 pChangeTrack->AppendInsert( aEffRange );
158 nEndChangeAction = pChangeTrack->GetActionMax();
160 else
161 nEndChangeAction = 0;
164 void ScUndoInsertCells::DoChange( const bool bUndo )
166 ScDocument& rDoc = pDocShell->GetDocument();
167 SCTAB i;
169 if ( bUndo )
171 ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
172 if ( pChangeTrack )
173 pChangeTrack->Undo( nEndChangeAction, nEndChangeAction );
175 else
176 SetChangeTrack();
178 // refresh of merged cells has to be after inserting/deleting
180 switch (eCmd)
182 case INS_INSROWS:
183 case INS_CELLSDOWN:
184 for( i=0; i<nCount; i++ )
186 if (bUndo)
187 rDoc.DeleteRow( aEffRange.aStart.Col(), pTabs[i], aEffRange.aEnd.Col(), pTabs[i]+pScenarios[i],
188 aEffRange.aStart.Row(), static_cast<SCSIZE>(aEffRange.aEnd.Row()-aEffRange.aStart.Row()+1));
189 else
190 rDoc.InsertRow( aEffRange.aStart.Col(), pTabs[i], aEffRange.aEnd.Col(), pTabs[i]+pScenarios[i],
191 aEffRange.aStart.Row(), static_cast<SCSIZE>(aEffRange.aEnd.Row()-aEffRange.aStart.Row()+1));
193 break;
194 case INS_INSCOLS:
195 case INS_CELLSRIGHT:
196 for( i=0; i<nCount; i++ )
198 if (bUndo)
199 rDoc.DeleteCol( aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
200 aEffRange.aStart.Col(), static_cast<SCSIZE>(aEffRange.aEnd.Col()-aEffRange.aStart.Col()+1));
201 else
202 rDoc.InsertCol( aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
203 aEffRange.aStart.Col(), static_cast<SCSIZE>(aEffRange.aEnd.Col()-aEffRange.aStart.Col()+1));
205 break;
206 default:
208 // added to avoid warnings
212 ScRange aWorkRange( aEffRange );
213 if ( eCmd == INS_CELLSRIGHT ) // only "shift right" requires refresh of the moved area
214 aWorkRange.aEnd.SetCol(MAXCOL);
215 for( i=0; i<nCount; i++ )
217 if ( rDoc.HasAttrib( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), pTabs[i],
218 aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), pTabs[i], HASATTR_MERGED ) )
220 SCCOL nEndCol = aWorkRange.aEnd.Col();
221 SCROW nEndRow = aWorkRange.aEnd.Row();
222 rDoc.ExtendMerge( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), nEndCol, nEndRow, pTabs[i], true );
226 // Undo for displaced attributes?
228 sal_uInt16 nPaint = PAINT_GRID;
229 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
230 switch (eCmd)
232 case INS_INSROWS:
233 nPaint |= PAINT_LEFT;
234 aWorkRange.aEnd.SetRow(MAXROW);
235 break;
236 case INS_CELLSDOWN:
237 for( i=0; i<nCount; i++ )
239 aWorkRange.aEnd.SetRow(MAXROW);
240 if ( pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), pTabs[i] ))
242 aWorkRange.aStart.SetCol(0);
243 aWorkRange.aEnd.SetCol(MAXCOL);
244 nPaint |= PAINT_LEFT;
247 break;
248 case INS_INSCOLS:
249 nPaint |= PAINT_TOP; // top bar
250 case INS_CELLSRIGHT:
251 for( i=0; i<nCount; i++ )
253 aWorkRange.aEnd.SetCol(MAXCOL); // to the far right
254 if ( pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), pTabs[i]) )
255 { // AdjustDraw does not paint PAINT_TOP,
256 aWorkRange.aStart.SetCol(0); // thus solved like this
257 aWorkRange.aEnd.SetRow(MAXROW);
258 nPaint |= PAINT_LEFT;
261 break;
262 default:
264 // added to avoid warnings
268 for( i=0; i<nCount; i++ )
270 pDocShell->PostPaint( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), pTabs[i],
271 aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), pTabs[i]+pScenarios[i], nPaint );
273 pDocShell->PostDataChanged();
274 if (pViewShell)
275 pViewShell->CellContentChanged();
278 void ScUndoInsertCells::Undo()
280 if ( pPasteUndo )
281 pPasteUndo->Undo(); // undo paste first
283 WaitObject aWait( ScDocShell::GetActiveDialogParent() ); // important due to TrackFormulas in UpdateReference
284 BeginUndo();
285 DoChange( true );
286 EndUndo();
288 ScDocument& rDoc = pDocShell->GetDocument();
289 for (SCTAB i = 0; i < nCount; ++i)
290 rDoc.SetDrawPageSize(pTabs[i]);
293 void ScUndoInsertCells::Redo()
295 WaitObject aWait( ScDocShell::GetActiveDialogParent() ); // important due to TrackFormulas in UpdateReference
296 BeginRedo();
297 DoChange( false );
298 EndRedo();
300 if ( pPasteUndo )
301 pPasteUndo->Redo(); // redo paste last
303 ScDocument& rDoc = pDocShell->GetDocument();
304 for (SCTAB i = 0; i < nCount; ++i)
305 rDoc.SetDrawPageSize(pTabs[i]);
308 void ScUndoInsertCells::Repeat(SfxRepeatTarget& rTarget)
310 if (rTarget.ISA(ScTabViewTarget))
312 if ( pPasteUndo )
314 // Repeat for paste with inserting cells is handled completely
315 // by the Paste undo action
317 pPasteUndo->Repeat( rTarget );
319 else
320 static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->InsertCells( eCmd, true );
324 bool ScUndoInsertCells::CanRepeat(SfxRepeatTarget& rTarget) const
326 return rTarget.ISA(ScTabViewTarget);
329 ScUndoDeleteCells::ScUndoDeleteCells( ScDocShell* pNewDocShell,
330 const ScRange& rRange, SCTAB nNewCount, SCTAB* pNewTabs, SCTAB* pNewScenarios,
331 DelCellCmd eNewCmd, ScDocument* pUndoDocument, ScRefUndoData* pRefData ) :
332 ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFLAST ),
333 aEffRange( rRange ),
334 nCount( nNewCount ),
335 pTabs( pNewTabs ),
336 pScenarios( pNewScenarios ),
337 eCmd( eNewCmd )
339 if (eCmd == DEL_DELROWS) // whole row?
341 aEffRange.aStart.SetCol(0);
342 aEffRange.aEnd.SetCol(MAXCOL);
345 if (eCmd == DEL_DELCOLS) // whole column?
347 aEffRange.aStart.SetRow(0);
348 aEffRange.aEnd.SetRow(MAXROW);
351 SetChangeTrack();
354 ScUndoDeleteCells::~ScUndoDeleteCells()
356 delete []pTabs;
357 delete []pScenarios;
360 OUString ScUndoDeleteCells::GetComment() const
362 return ScGlobal::GetRscString( STR_UNDO_DELETECELLS ); // "Delete"
365 void ScUndoDeleteCells::SetChangeTrack()
367 ScChangeTrack* pChangeTrack = pDocShell->GetDocument().GetChangeTrack();
368 if ( pChangeTrack )
369 pChangeTrack->AppendDeleteRange( aEffRange, pRefUndoDoc,
370 nStartChangeAction, nEndChangeAction );
371 else
372 nStartChangeAction = nEndChangeAction = 0;
375 void ScUndoDeleteCells::DoChange( const bool bUndo )
377 ScDocument& rDoc = pDocShell->GetDocument();
378 SCTAB i;
380 if ( bUndo )
382 ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
383 if ( pChangeTrack )
384 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
386 else
387 SetChangeTrack();
389 switch (eCmd)
391 case DEL_DELROWS:
392 case DEL_CELLSUP:
393 for( i=0; i<nCount; i++ )
395 if (bUndo)
396 rDoc.InsertRow( aEffRange.aStart.Col(), pTabs[i], aEffRange.aEnd.Col(), pTabs[i]+pScenarios[i],
397 aEffRange.aStart.Row(), static_cast<SCSIZE>(aEffRange.aEnd.Row()-aEffRange.aStart.Row()+1));
398 else
399 rDoc.DeleteRow( aEffRange.aStart.Col(), pTabs[i], aEffRange.aEnd.Col(), pTabs[i]+pScenarios[i],
400 aEffRange.aStart.Row(), static_cast<SCSIZE>(aEffRange.aEnd.Row()-aEffRange.aStart.Row()+1));
402 break;
403 case DEL_DELCOLS:
404 case DEL_CELLSLEFT:
405 for( i=0; i<nCount; i++ )
407 if (bUndo)
408 rDoc.InsertCol( aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
409 aEffRange.aStart.Col(), static_cast<SCSIZE>(aEffRange.aEnd.Col()-aEffRange.aStart.Col()+1));
410 else
411 rDoc.DeleteCol( aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
412 aEffRange.aStart.Col(), static_cast<SCSIZE>(aEffRange.aEnd.Col()-aEffRange.aStart.Col()+1));
414 break;
415 default:
417 // added to avoid warnings
421 // if Undo, restore references
422 for( i=0; i<nCount && bUndo; i++ )
424 pRefUndoDoc->CopyToDocument( aEffRange.aStart.Col(), aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Col(), aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
425 IDF_ALL | IDF_NOCAPTIONS, false, &rDoc );
428 ScRange aWorkRange( aEffRange );
429 if ( eCmd == DEL_CELLSLEFT ) // only "shift left" requires refresh of the moved area
430 aWorkRange.aEnd.SetCol(MAXCOL);
432 for( i=0; i<nCount; i++ )
434 if ( rDoc.HasAttrib( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), pTabs[i],
435 aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), pTabs[i], HASATTR_MERGED | HASATTR_OVERLAPPED ) )
437 // #i51445# old merge flag attributes must be deleted also for single cells,
438 // not only for whole columns/rows
440 if ( !bUndo )
442 if ( eCmd==DEL_DELCOLS || eCmd==DEL_CELLSLEFT )
443 aWorkRange.aEnd.SetCol(MAXCOL);
444 if ( eCmd==DEL_DELROWS || eCmd==DEL_CELLSUP )
445 aWorkRange.aEnd.SetRow(MAXROW);
446 ScMarkData aMarkData;
447 aMarkData.SelectOneTable( aWorkRange.aStart.Tab() );
448 ScPatternAttr aPattern( rDoc.GetPool() );
449 aPattern.GetItemSet().Put( ScMergeFlagAttr() );
450 rDoc.ApplyPatternArea( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(),
451 aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(),
452 aMarkData, aPattern );
455 SCCOL nEndCol = aWorkRange.aEnd.Col();
456 SCROW nEndRow = aWorkRange.aEnd.Row();
457 rDoc.ExtendMerge( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), nEndCol, nEndRow, pTabs[i], true );
461 // Zeichnen
462 sal_uInt16 nPaint = PAINT_GRID;
463 switch (eCmd)
465 case DEL_DELROWS:
466 nPaint |= PAINT_LEFT;
467 aWorkRange.aEnd.SetRow(MAXROW);
468 break;
469 case DEL_CELLSUP:
470 for( i=0; i<nCount; i++ )
472 aWorkRange.aEnd.SetRow(MAXROW);
473 if ( pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), pTabs[i] ))
475 aWorkRange.aStart.SetCol(0);
476 aWorkRange.aEnd.SetCol(MAXCOL);
477 nPaint |= PAINT_LEFT;
480 break;
481 case DEL_DELCOLS:
482 nPaint |= PAINT_TOP; // top bar
483 case DEL_CELLSLEFT:
484 for( i=0; i<nCount; i++ )
486 aWorkRange.aEnd.SetCol(MAXCOL); // to the far right
487 if ( pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), pTabs[i] ) )
489 aWorkRange.aStart.SetCol(0);
490 aWorkRange.aEnd.SetRow(MAXROW);
491 nPaint |= PAINT_LEFT;
494 break;
495 default:
497 // added to avoid warnings
501 for( i=0; i<nCount; i++ )
503 pDocShell->PostPaint( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), pTabs[i],
504 aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), pTabs[i]+pScenarios[i], nPaint, SC_PF_LINES );
506 // Selection not until EndUndo
508 pDocShell->PostDataChanged();
509 // CellContentChanged comes with the selection
512 void ScUndoDeleteCells::Undo()
514 WaitObject aWait( ScDocShell::GetActiveDialogParent() ); // important because of TrackFormulas in UpdateReference
515 BeginUndo();
516 DoChange( true );
517 EndUndo();
518 SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
520 // Selection not until EndUndo
521 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
522 if (pViewShell)
524 for( SCTAB i=0; i<nCount; i++ )
526 pViewShell->MarkRange( ScRange(aEffRange.aStart.Col(), aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Col(), aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i]) );
530 ScDocument& rDoc = pDocShell->GetDocument();
531 for (SCTAB i = 0; i < nCount; ++i)
532 rDoc.SetDrawPageSize(pTabs[i]);
535 void ScUndoDeleteCells::Redo()
537 WaitObject aWait( ScDocShell::GetActiveDialogParent() ); // important because of TrackFormulas in UpdateReference
538 BeginRedo();
539 DoChange( false);
540 EndRedo();
541 SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
543 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
544 if (pViewShell)
545 pViewShell->DoneBlockMode(); // current way
547 ScDocument& rDoc = pDocShell->GetDocument();
548 for (SCTAB i = 0; i < nCount; ++i)
549 rDoc.SetDrawPageSize(pTabs[i]);
552 void ScUndoDeleteCells::Repeat(SfxRepeatTarget& rTarget)
554 if (rTarget.ISA(ScTabViewTarget))
555 static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->DeleteCells( eCmd, true );
558 bool ScUndoDeleteCells::CanRepeat(SfxRepeatTarget& rTarget) const
560 return rTarget.ISA(ScTabViewTarget);
563 // delete cells in multiselection
564 ScUndoDeleteMulti::ScUndoDeleteMulti(
565 ScDocShell* pNewDocShell,
566 bool bNewRows, bool bNeedsRefresh, SCTAB nNewTab,
567 const std::vector<sc::ColRowSpan>& rSpans,
568 ScDocument* pUndoDocument, ScRefUndoData* pRefData ) :
569 ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFLAST ),
570 mbRows(bNewRows),
571 mbRefresh(bNeedsRefresh),
572 nTab( nNewTab ),
573 maSpans(rSpans)
575 SetChangeTrack();
578 ScUndoDeleteMulti::~ScUndoDeleteMulti()
582 OUString ScUndoDeleteMulti::GetComment() const
584 return ScGlobal::GetRscString( STR_UNDO_DELETECELLS ); // like DeleteCells
587 void ScUndoDeleteMulti::DoChange() const
589 SCCOL nStartCol;
590 SCROW nStartRow;
591 sal_uInt16 nPaint;
592 if (mbRows)
594 nStartCol = 0;
595 nStartRow = static_cast<SCROW>(maSpans[0].mnStart);
596 nPaint = PAINT_GRID | PAINT_LEFT;
598 else
600 nStartCol = static_cast<SCCOL>(maSpans[0].mnStart);
601 nStartRow = 0;
602 nPaint = PAINT_GRID | PAINT_TOP;
605 if (mbRefresh)
607 ScDocument& rDoc = pDocShell->GetDocument();
608 SCCOL nEndCol = MAXCOL;
609 SCROW nEndRow = MAXROW;
610 rDoc.RemoveFlagsTab( nStartCol, nStartRow, nEndCol, nEndRow, nTab, SC_MF_HOR | SC_MF_VER );
611 rDoc.ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, nTab, true );
614 pDocShell->PostPaint( nStartCol, nStartRow, nTab, MAXCOL, MAXROW, nTab, nPaint );
615 pDocShell->PostDataChanged();
616 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
617 if (pViewShell)
618 pViewShell->CellContentChanged();
620 ShowTable( nTab );
623 void ScUndoDeleteMulti::SetChangeTrack()
625 ScChangeTrack* pChangeTrack = pDocShell->GetDocument().GetChangeTrack();
626 if ( pChangeTrack )
628 nStartChangeAction = pChangeTrack->GetActionMax() + 1;
629 ScRange aRange( 0, 0, nTab, 0, 0, nTab );
630 if (mbRows)
631 aRange.aEnd.SetCol( MAXCOL );
632 else
633 aRange.aEnd.SetRow( MAXROW );
634 // delete in reverse
635 std::vector<sc::ColRowSpan>::const_reverse_iterator ri = maSpans.rbegin(), riEnd = maSpans.rend();
636 for (; ri != riEnd; ++ri)
638 SCCOLROW nEnd = ri->mnEnd;
639 SCCOLROW nStart = ri->mnStart;
640 if (mbRows)
642 aRange.aStart.SetRow( nStart );
643 aRange.aEnd.SetRow( nEnd );
645 else
647 aRange.aStart.SetCol( static_cast<SCCOL>(nStart) );
648 aRange.aEnd.SetCol( static_cast<SCCOL>(nEnd) );
650 sal_uLong nDummyStart;
651 pChangeTrack->AppendDeleteRange( aRange, pRefUndoDoc,
652 nDummyStart, nEndChangeAction );
655 else
656 nStartChangeAction = nEndChangeAction = 0;
659 void ScUndoDeleteMulti::Undo()
661 WaitObject aWait( ScDocShell::GetActiveDialogParent() ); // important because of TrackFormulas in UpdateReference
662 BeginUndo();
664 ScDocument& rDoc = pDocShell->GetDocument();
666 // reverse delete -> forward insert
667 std::vector<sc::ColRowSpan>::const_iterator it = maSpans.begin(), itEnd = maSpans.end();
668 for (; it != itEnd; ++it)
670 SCCOLROW nStart = it->mnStart;
671 SCCOLROW nEnd = it->mnEnd;
672 if (mbRows)
673 rDoc.InsertRow( 0,nTab, MAXCOL,nTab, nStart,static_cast<SCSIZE>(nEnd-nStart+1) );
674 else
675 rDoc.InsertCol( 0,nTab, MAXROW,nTab, static_cast<SCCOL>(nStart), static_cast<SCSIZE>(nEnd-nStart+1) );
678 it = maSpans.begin();
679 for (; it != itEnd; ++it)
681 SCCOLROW nStart = it->mnStart;
682 SCCOLROW nEnd = it->mnEnd;
683 if (mbRows)
684 pRefUndoDoc->CopyToDocument( 0,nStart,nTab, MAXCOL,nEnd,nTab, IDF_ALL,false, &rDoc );
685 else
686 pRefUndoDoc->CopyToDocument( static_cast<SCCOL>(nStart),0,nTab,
687 static_cast<SCCOL>(nEnd),MAXROW,nTab, IDF_ALL,false, &rDoc );
690 ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
691 if ( pChangeTrack )
692 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
694 DoChange();
696 //! redrawing the selection is not possible at the moment
697 //! since no data for selection exist
699 EndUndo();
700 SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
703 void ScUndoDeleteMulti::Redo()
705 WaitObject aWait( ScDocShell::GetActiveDialogParent() ); // important because of TrackFormulas in UpdateReference
706 BeginRedo();
708 ScDocument& rDoc = pDocShell->GetDocument();
710 // reverse delete
711 std::vector<sc::ColRowSpan>::const_reverse_iterator ri = maSpans.rbegin(), riEnd = maSpans.rend();
712 for (; ri != riEnd; ++ri)
714 SCCOLROW nEnd = ri->mnEnd;
715 SCCOLROW nStart = ri->mnStart;
716 if (mbRows)
717 rDoc.DeleteRow( 0,nTab, MAXCOL,nTab, nStart,static_cast<SCSIZE>(nEnd-nStart+1) );
718 else
719 rDoc.DeleteCol( 0,nTab, MAXROW,nTab, static_cast<SCCOL>(nStart), static_cast<SCSIZE>(nEnd-nStart+1) );
722 SetChangeTrack();
724 DoChange();
726 EndRedo();
727 SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
730 void ScUndoDeleteMulti::Repeat(SfxRepeatTarget& rTarget)
732 // if single selection
733 if (rTarget.ISA(ScTabViewTarget))
734 static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->DeleteCells( DEL_DELROWS, true );
737 bool ScUndoDeleteMulti::CanRepeat(SfxRepeatTarget& rTarget) const
739 return rTarget.ISA(ScTabViewTarget);
742 ScUndoCut::ScUndoCut( ScDocShell* pNewDocShell,
743 ScRange aRange, ScAddress aOldEnd, const ScMarkData& rMark,
744 ScDocument* pNewUndoDoc ) :
745 ScBlockUndo( pNewDocShell, ScRange(aRange.aStart, aOldEnd), SC_UNDO_AUTOHEIGHT ),
746 aMarkData( rMark ),
747 pUndoDoc( pNewUndoDoc ),
748 aExtendedRange( aRange )
750 SetChangeTrack();
753 ScUndoCut::~ScUndoCut()
755 delete pUndoDoc;
758 OUString ScUndoCut::GetComment() const
760 return ScGlobal::GetRscString( STR_UNDO_CUT ); // "cut"
763 void ScUndoCut::SetChangeTrack()
765 ScChangeTrack* pChangeTrack = pDocShell->GetDocument().GetChangeTrack();
766 if ( pChangeTrack )
767 pChangeTrack->AppendContentRange( aBlockRange, pUndoDoc,
768 nStartChangeAction, nEndChangeAction, SC_CACM_CUT );
769 else
770 nStartChangeAction = nEndChangeAction = 0;
773 void ScUndoCut::DoChange( const bool bUndo )
775 ScDocument& rDoc = pDocShell->GetDocument();
776 sal_uInt16 nExtFlags = 0;
778 // do not undo/redo objects and note captions, they are handled via drawing undo
779 InsertDeleteFlags nUndoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS;
781 if (bUndo) // only for Undo
783 // all sheets - CopyToDocument skips those that don't exist in pUndoDoc
784 SCTAB nTabCount = rDoc.GetTableCount();
785 ScRange aCopyRange = aExtendedRange;
786 aCopyRange.aStart.SetTab(0);
787 aCopyRange.aEnd.SetTab(nTabCount-1);
788 pUndoDoc->CopyToDocument( aCopyRange, nUndoFlags, false, &rDoc );
789 ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
790 if ( pChangeTrack )
791 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
793 BroadcastChanges(aCopyRange);
795 else // only for Redo
797 pDocShell->UpdatePaintExt( nExtFlags, aExtendedRange );
798 rDoc.DeleteArea( aBlockRange.aStart.Col(), aBlockRange.aStart.Row(),
799 aBlockRange.aEnd.Col(), aBlockRange.aEnd.Row(), aMarkData, nUndoFlags );
800 SetChangeTrack();
803 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
804 if ( !( (pViewShell) && pViewShell->AdjustBlockHeight() ) )
805 /*A*/ pDocShell->PostPaint( aExtendedRange, PAINT_GRID, nExtFlags );
807 if ( !bUndo ) // draw redo after updating row heights
808 RedoSdrUndoAction( pDrawUndo ); //! include in ScBlockUndo?
810 pDocShell->PostDataChanged();
811 if (pViewShell)
812 pViewShell->CellContentChanged();
815 void ScUndoCut::Undo()
817 BeginUndo();
818 DoChange( true );
819 EndUndo();
822 void ScUndoCut::Redo()
824 BeginRedo();
825 ScDocument& rDoc = pDocShell->GetDocument();
826 EnableDrawAdjust( &rDoc, false ); //! include in ScBlockUndo?
827 DoChange( false );
828 EnableDrawAdjust( &rDoc, true ); //! include in ScBlockUndo?
829 EndRedo();
832 void ScUndoCut::Repeat(SfxRepeatTarget& rTarget)
834 if (rTarget.ISA(ScTabViewTarget))
835 static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->CutToClip( NULL, true );
838 bool ScUndoCut::CanRepeat(SfxRepeatTarget& rTarget) const
840 return rTarget.ISA(ScTabViewTarget);
843 ScUndoPaste::ScUndoPaste( ScDocShell* pNewDocShell, const ScRangeList& rRanges,
844 const ScMarkData& rMark,
845 ScDocument* pNewUndoDoc, ScDocument* pNewRedoDoc,
846 InsertDeleteFlags nNewFlags,
847 ScRefUndoData* pRefData,
848 bool bRedoIsFilled, const ScUndoPasteOptions* pOptions ) :
849 ScMultiBlockUndo( pNewDocShell, rRanges, SC_UNDO_SIMPLE ),
850 aMarkData( rMark ),
851 pUndoDoc( pNewUndoDoc ),
852 pRedoDoc( pNewRedoDoc ),
853 nFlags( nNewFlags ),
854 pRefUndoData( pRefData ),
855 pRefRedoData( NULL ),
856 bRedoFilled( bRedoIsFilled )
858 if ( pRefUndoData )
859 pRefUndoData->DeleteUnchanged( &pDocShell->GetDocument() );
861 if ( pOptions )
862 aPasteOptions = *pOptions; // used only for Repeat
864 SetChangeTrack();
867 ScUndoPaste::~ScUndoPaste()
869 delete pUndoDoc;
870 delete pRedoDoc;
871 delete pRefUndoData;
872 delete pRefRedoData;
875 OUString ScUndoPaste::GetComment() const
877 return ScGlobal::GetRscString( STR_UNDO_PASTE ); // "paste"
880 void ScUndoPaste::SetChangeTrack()
882 ScChangeTrack* pChangeTrack = pDocShell->GetDocument().GetChangeTrack();
883 if ( pChangeTrack && (nFlags & IDF_CONTENTS) )
885 for (size_t i = 0, n = maBlockRanges.size(); i < n; ++i)
887 pChangeTrack->AppendContentRange(*maBlockRanges[i], pUndoDoc,
888 nStartChangeAction, nEndChangeAction, SC_CACM_PASTE );
891 else
892 nStartChangeAction = nEndChangeAction = 0;
895 void ScUndoPaste::DoChange(bool bUndo)
897 ScDocument& rDoc = pDocShell->GetDocument();
899 // RefUndoData for redo is created before first undo
900 // (with DeleteUnchanged after the DoUndo call)
901 bool bCreateRedoData = ( bUndo && pRefUndoData && !pRefRedoData );
902 if ( bCreateRedoData )
903 pRefRedoData = new ScRefUndoData( &rDoc );
905 ScRefUndoData* pWorkRefData = bUndo ? pRefUndoData : pRefRedoData;
907 // Always back-up either all or none of the content for Undo
908 InsertDeleteFlags nUndoFlags = IDF_NONE;
909 if (nFlags & IDF_CONTENTS)
910 nUndoFlags |= IDF_CONTENTS;
911 if (nFlags & IDF_ATTRIB)
912 nUndoFlags |= IDF_ATTRIB;
914 // do not undo/redo objects and note captions, they are handled via drawing undo
915 (nUndoFlags &= ~IDF_OBJECTS) |= IDF_NOCAPTIONS;
917 bool bPaintAll = false;
919 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
921 SCTAB nTabCount = rDoc.GetTableCount();
922 if ( bUndo && !bRedoFilled )
924 if (!pRedoDoc)
926 bool bColInfo = true;
927 bool bRowInfo = true;
928 for (size_t i = 0, n = maBlockRanges.size(); i < n; ++i)
930 const ScRange& r = *maBlockRanges[i];
931 bColInfo &= (r.aStart.Row() == 0 && r.aEnd.Row() == MAXROW);
932 bRowInfo &= (r.aStart.Col() == 0 && r.aEnd.Col() == MAXCOL);
933 if (!bColInfo && !bRowInfo)
934 break;
937 pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
938 pRedoDoc->InitUndoSelected( &rDoc, aMarkData, bColInfo, bRowInfo );
940 // read "redo" data from the document in the first undo
941 // all sheets - CopyToDocument skips those that don't exist in pRedoDoc
942 for (size_t i = 0, n = maBlockRanges.size(); i < n; ++i)
944 ScRange aCopyRange = *maBlockRanges[i];
945 aCopyRange.aStart.SetTab(0);
946 aCopyRange.aEnd.SetTab(nTabCount-1);
947 rDoc.CopyToDocument( aCopyRange, nUndoFlags, false, pRedoDoc );
948 bRedoFilled = true;
952 sal_uInt16 nExtFlags = 0;
953 pDocShell->UpdatePaintExt(nExtFlags, maBlockRanges.Combine());
955 rDoc.ForgetNoteCaptions(maBlockRanges);
956 aMarkData.MarkToMulti();
957 rDoc.DeleteSelection(nUndoFlags, aMarkData, false); // no broadcasting here
958 for (size_t i = 0, n = maBlockRanges.size(); i < n; ++i)
959 rDoc.BroadcastCells(*maBlockRanges[i], SC_HINT_DATACHANGED);
961 aMarkData.MarkToSimple();
963 SCTAB nFirstSelected = aMarkData.GetFirstSelected();
965 if ( !bUndo && pRedoDoc ) // Redo: UndoToDocument before handling RefData
967 for (size_t i = 0, n = maBlockRanges.size(); i < n; ++i)
969 ScRange aRange = *maBlockRanges[i];
970 aRange.aStart.SetTab(nFirstSelected);
971 aRange.aEnd.SetTab(nFirstSelected);
972 pRedoDoc->UndoToDocument(aRange, nUndoFlags, false, &rDoc);
973 ScMarkData::iterator itr = aMarkData.begin(), itrEnd = aMarkData.end();
974 for (; itr != itrEnd && *itr < nTabCount; ++itr)
976 if (*itr == nFirstSelected)
977 continue;
979 aRange.aStart.SetTab(*itr);
980 aRange.aEnd.SetTab(*itr);
981 pRedoDoc->CopyToDocument( aRange, nUndoFlags, false, &rDoc );
986 if (pWorkRefData)
988 pWorkRefData->DoUndo( &rDoc, true ); // true = bSetChartRangeLists for SetChartListenerCollection
989 if (!maBlockRanges.empty() &&
990 rDoc.RefreshAutoFilter(0, 0, MAXCOL, MAXROW, maBlockRanges[0]->aStart.Tab()))
991 bPaintAll = true;
994 if ( bCreateRedoData && pRefRedoData )
995 pRefRedoData->DeleteUnchanged( &rDoc );
997 if (bUndo) // Undo: UndoToDocument after handling RefData
999 for (size_t i = 0, n = maBlockRanges.size(); i < n; ++i)
1001 ScRange aRange = *maBlockRanges[i];
1002 ScMarkData::iterator itr = aMarkData.begin(), itrEnd = aMarkData.end();
1003 for (; itr != itrEnd && *itr < nTabCount; ++itr)
1005 aRange.aStart.SetTab(*itr);
1006 aRange.aEnd.SetTab(*itr);
1007 pUndoDoc->UndoToDocument(aRange, nUndoFlags, false, &rDoc);
1012 if ( bUndo )
1014 ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
1015 if ( pChangeTrack )
1016 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
1018 else
1019 SetChangeTrack();
1021 ScRangeList aDrawRanges(maBlockRanges);
1022 sal_uInt16 nPaint = PAINT_GRID;
1023 for (size_t i = 0, n = aDrawRanges.size(); i < n; ++i)
1025 ScRange& rDrawRange = *aDrawRanges[i];
1026 rDoc.ExtendMerge(rDrawRange, true); // only needed for single sheet (text/rtf etc.)
1027 if (bPaintAll)
1029 rDrawRange.aStart.SetCol(0);
1030 rDrawRange.aStart.SetRow(0);
1031 rDrawRange.aEnd.SetCol(MAXCOL);
1032 rDrawRange.aEnd.SetRow(MAXROW);
1033 nPaint |= PAINT_TOP | PAINT_LEFT;
1034 if (pViewShell)
1035 pViewShell->AdjustBlockHeight(false);
1037 else
1039 if (maBlockRanges[i]->aStart.Row() == 0 && maBlockRanges[i]->aEnd.Row() == MAXROW) // whole column
1041 nPaint |= PAINT_TOP;
1042 rDrawRange.aEnd.SetCol(MAXCOL);
1044 if (maBlockRanges[i]->aStart.Col() == 0 && maBlockRanges[i]->aEnd.Col() == MAXCOL) // whole row
1046 nPaint |= PAINT_LEFT;
1047 rDrawRange.aEnd.SetRow(MAXROW);
1049 if (pViewShell && pViewShell->AdjustBlockHeight(false))
1051 rDrawRange.aStart.SetCol(0);
1052 rDrawRange.aStart.SetRow(0);
1053 rDrawRange.aEnd.SetCol(MAXCOL);
1054 rDrawRange.aEnd.SetRow(MAXROW);
1055 nPaint |= PAINT_LEFT;
1057 pDocShell->UpdatePaintExt(nExtFlags, rDrawRange);
1061 if ( !bUndo ) // draw redo after updating row heights
1062 RedoSdrUndoAction(mpDrawUndo);
1064 pDocShell->PostPaint(aDrawRanges, nPaint, nExtFlags);
1066 pDocShell->PostDataChanged();
1067 if (pViewShell)
1068 pViewShell->CellContentChanged();
1071 void ScUndoPaste::Undo()
1073 BeginUndo();
1074 DoChange(true);
1075 if (!maBlockRanges.empty())
1076 ShowTable(*maBlockRanges.front());
1077 EndUndo();
1078 SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
1081 void ScUndoPaste::Redo()
1083 BeginRedo();
1084 ScDocument& rDoc = pDocShell->GetDocument();
1085 EnableDrawAdjust( &rDoc, false ); //! include in ScBlockUndo?
1086 DoChange( false );
1087 EnableDrawAdjust( &rDoc, true ); //! include in ScBlockUndo?
1088 EndRedo();
1089 SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
1092 void ScUndoPaste::Repeat(SfxRepeatTarget& rTarget)
1094 if (rTarget.ISA(ScTabViewTarget))
1096 ScTabViewShell* pViewSh = static_cast<ScTabViewTarget&>(rTarget).GetViewShell();
1097 ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pViewSh->GetActiveWin() );
1098 if (pOwnClip)
1100 // keep a reference in case the clipboard is changed during PasteFromClip
1101 com::sun::star::uno::Reference<com::sun::star::datatransfer::XTransferable> aOwnClipRef( pOwnClip );
1102 pViewSh->PasteFromClip( nFlags, pOwnClip->GetDocument(),
1103 aPasteOptions.nFunction, aPasteOptions.bSkipEmpty, aPasteOptions.bTranspose,
1104 aPasteOptions.bAsLink, aPasteOptions.eMoveMode, IDF_NONE,
1105 true ); // allow warning dialog
1110 bool ScUndoPaste::CanRepeat(SfxRepeatTarget& rTarget) const
1112 return rTarget.ISA(ScTabViewTarget);
1115 ScUndoDragDrop::ScUndoDragDrop( ScDocShell* pNewDocShell,
1116 const ScRange& rRange, ScAddress aNewDestPos, bool bNewCut,
1117 ScDocument* pUndoDocument, ScRefUndoData* pRefData, bool bScenario ) :
1118 ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFFIRST ),
1119 mnPaintExtFlags( 0 ),
1120 aSrcRange( rRange ),
1121 bCut( bNewCut ),
1122 bKeepScenarioFlags( bScenario )
1124 ScAddress aDestEnd(aNewDestPos);
1125 aDestEnd.IncRow(aSrcRange.aEnd.Row() - aSrcRange.aStart.Row());
1126 aDestEnd.IncCol(aSrcRange.aEnd.Col() - aSrcRange.aStart.Col());
1127 aDestEnd.IncTab(aSrcRange.aEnd.Tab() - aSrcRange.aStart.Tab());
1129 bool bIncludeFiltered = bCut;
1130 if ( !bIncludeFiltered )
1132 // find number of non-filtered rows
1133 SCROW nPastedCount = pDocShell->GetDocument().CountNonFilteredRows(
1134 aSrcRange.aStart.Row(), aSrcRange.aEnd.Row(), aSrcRange.aStart.Tab());
1136 if ( nPastedCount == 0 )
1137 nPastedCount = 1;
1138 aDestEnd.SetRow( aNewDestPos.Row() + nPastedCount - 1 );
1141 aDestRange.aStart = aNewDestPos;
1142 aDestRange.aEnd = aDestEnd;
1144 SetChangeTrack();
1147 ScUndoDragDrop::~ScUndoDragDrop()
1151 OUString ScUndoDragDrop::GetComment() const
1152 { // "Move" : "Copy"
1153 return bCut ?
1154 ScGlobal::GetRscString( STR_UNDO_MOVE ) :
1155 ScGlobal::GetRscString( STR_UNDO_COPY );
1158 void ScUndoDragDrop::SetChangeTrack()
1160 ScChangeTrack* pChangeTrack = pDocShell->GetDocument().GetChangeTrack();
1161 if ( pChangeTrack )
1163 if ( bCut )
1165 nStartChangeAction = pChangeTrack->GetActionMax() + 1;
1166 pChangeTrack->AppendMove( aSrcRange, aDestRange, pRefUndoDoc );
1167 nEndChangeAction = pChangeTrack->GetActionMax();
1169 else
1170 pChangeTrack->AppendContentRange( aDestRange, pRefUndoDoc,
1171 nStartChangeAction, nEndChangeAction );
1173 else
1174 nStartChangeAction = nEndChangeAction = 0;
1177 void ScUndoDragDrop::PaintArea( ScRange aRange, sal_uInt16 nExtFlags ) const
1179 sal_uInt16 nPaint = PAINT_GRID;
1180 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1181 ScDocument& rDoc = pDocShell->GetDocument();
1183 if (pViewShell)
1185 ScopedVclPtrInstance< VirtualDevice > pVirtDev;
1186 ScViewData& rViewData = pViewShell->GetViewData();
1187 sc::RowHeightContext aCxt(
1188 rViewData.GetPPTX(), rViewData.GetPPTY(), rViewData.GetZoomX(), rViewData.GetZoomY(),
1189 pVirtDev);
1191 if (rDoc.SetOptimalHeight(aCxt, aRange.aStart.Row(), aRange.aEnd.Row(), aRange.aStart.Tab()))
1193 aRange.aStart.SetCol(0);
1194 aRange.aEnd.SetCol(MAXCOL);
1195 aRange.aEnd.SetRow(MAXROW);
1196 nPaint |= PAINT_LEFT;
1200 if ( bKeepScenarioFlags )
1202 // Copy scenario -> also paint scenario boarder
1203 aRange.aStart.SetCol(0);
1204 aRange.aStart.SetRow(0);
1205 aRange.aEnd.SetCol(MAXCOL);
1206 aRange.aEnd.SetRow(MAXROW);
1209 // column/row info (width/height) included if whole columns/rows were copied
1210 if ( aSrcRange.aStart.Col() == 0 && aSrcRange.aEnd.Col() == MAXCOL )
1212 nPaint |= PAINT_LEFT;
1213 aRange.aEnd.SetRow(MAXROW);
1215 if ( aSrcRange.aStart.Row() == 0 && aSrcRange.aEnd.Row() == MAXROW )
1217 nPaint |= PAINT_TOP;
1218 aRange.aEnd.SetCol(MAXCOL);
1221 pDocShell->PostPaint( aRange, nPaint, nExtFlags );
1224 void ScUndoDragDrop::DoUndo( ScRange aRange )
1226 ScDocument& rDoc = pDocShell->GetDocument();
1228 ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
1229 if ( pChangeTrack )
1230 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
1232 // Database range before data, so that the Autofilter button match up in ExtendMerge
1234 ScRange aPaintRange = aRange;
1235 rDoc.ExtendMerge( aPaintRange ); // before deleting
1237 pDocShell->UpdatePaintExt(mnPaintExtFlags, aPaintRange);
1239 // do not undo objects and note captions, they are handled via drawing undo
1240 InsertDeleteFlags nUndoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS;
1242 // Additionally discard/forget caption ownership during deletion, as
1243 // Drag&Drop is a special case in that the Undo holds captions of the
1244 // transfered target range, which would get deleted and
1245 // SdrGroupUndo::Undo() would attempt to access invalidated captions and
1246 // crash, tdf#92995
1247 InsertDeleteFlags nDelFlags = nUndoFlags | IDF_FORGETCAPTIONS;
1249 rDoc.DeleteAreaTab( aRange, nDelFlags );
1250 pRefUndoDoc->CopyToDocument( aRange, nUndoFlags, false, &rDoc );
1251 if ( rDoc.HasAttrib( aRange, HASATTR_MERGED ) )
1252 rDoc.ExtendMerge( aRange, true );
1254 aPaintRange.aEnd.SetCol( std::max( aPaintRange.aEnd.Col(), aRange.aEnd.Col() ) );
1255 aPaintRange.aEnd.SetRow( std::max( aPaintRange.aEnd.Row(), aRange.aEnd.Row() ) );
1257 pDocShell->UpdatePaintExt(mnPaintExtFlags, aPaintRange);
1258 maPaintRanges.Join(aPaintRange);
1261 namespace {
1263 class DataChangeNotifier : std::unary_function<SvtListener*, void>
1265 ScHint maHint;
1266 public:
1267 DataChangeNotifier() : maHint(SC_HINT_DATACHANGED, ScAddress()) {}
1269 void operator() ( SvtListener* p )
1271 p->Notify(maHint);
1277 void ScUndoDragDrop::Undo()
1279 mnPaintExtFlags = 0;
1280 maPaintRanges.RemoveAll();
1282 BeginUndo();
1284 if (bCut)
1286 // During undo, we move cells from aDestRange to aSrcRange.
1288 ScDocument& rDoc = pDocShell->GetDocument();
1290 SCCOL nColDelta = aSrcRange.aStart.Col() - aDestRange.aStart.Col();
1291 SCROW nRowDelta = aSrcRange.aStart.Row() - aDestRange.aStart.Row();
1292 SCTAB nTabDelta = aSrcRange.aStart.Tab() - aDestRange.aStart.Tab();
1294 sc::RefUpdateContext aCxt(rDoc);
1295 aCxt.meMode = URM_MOVE;
1296 aCxt.maRange = aSrcRange;
1297 aCxt.mnColDelta = nColDelta;
1298 aCxt.mnRowDelta = nRowDelta;
1299 aCxt.mnTabDelta = nTabDelta;
1301 // Global range names.
1302 ScRangeName* pName = rDoc.GetRangeName();
1303 if (pName)
1304 pName->UpdateReference(aCxt);
1306 SCTAB nTabCount = rDoc.GetTableCount();
1307 for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
1309 // Sheet-local range names.
1310 pName = rDoc.GetRangeName(nTab);
1311 if (pName)
1312 pName->UpdateReference(aCxt, nTab);
1315 // Notify all listeners of the destination range, and have them update their references.
1316 sc::RefMovedHint aHint(aDestRange, ScAddress(nColDelta, nRowDelta, nTabDelta), aCxt);
1317 rDoc.BroadcastRefMoved(aHint);
1319 ScValidationDataList* pValidList = rDoc.GetValidationList();
1320 if (pValidList)
1322 // Update the references of validation entries.
1323 pValidList->UpdateReference(aCxt);
1326 DoUndo(aDestRange);
1327 DoUndo(aSrcRange);
1329 // Notify all area listeners whose listened areas are partially moved, to
1330 // recalculate.
1331 std::vector<SvtListener*> aListeners;
1332 rDoc.CollectAllAreaListeners(aListeners, aSrcRange, sc::AreaPartialOverlap);
1334 // Remove any duplicate listener entries. We must ensure that we notify
1335 // each unique listener only once.
1336 std::sort(aListeners.begin(), aListeners.end());
1337 aListeners.erase(std::unique(aListeners.begin(), aListeners.end()), aListeners.end());
1339 std::for_each(aListeners.begin(), aListeners.end(), DataChangeNotifier());
1341 else
1342 DoUndo(aDestRange);
1344 for (size_t i = 0; i < maPaintRanges.size(); ++i)
1346 const ScRange* p = maPaintRanges[i];
1347 PaintArea(*p, mnPaintExtFlags);
1350 EndUndo();
1351 SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
1354 void ScUndoDragDrop::Redo()
1356 BeginRedo();
1358 ScDocument& rDoc = pDocShell->GetDocument();
1359 boost::scoped_ptr<ScDocument> pClipDoc(new ScDocument( SCDOCMODE_CLIP ));
1361 EnableDrawAdjust( &rDoc, false ); //! include in ScBlockUndo?
1363 // do not undo/redo objects and note captions, they are handled via drawing undo
1364 InsertDeleteFlags nRedoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS;
1366 /* TODO: Redoing note captions is quite tricky due to the fact that a
1367 helper clip document is used. While (re-)pasting the contents to the
1368 destination area, the original pointers to the captions created while
1369 dropping have to be restored. A simple CopyFromClip() would create new
1370 caption objects that are not tracked by drawing undo, and the captions
1371 restored by drawing redo would live without cell note objects pointing
1372 to them. So, first, CopyToClip() and CopyFromClip() are called without
1373 cloning the caption objects. This leads to cell notes pointing to the
1374 wrong captions from source area that will be removed by drawing redo
1375 later. Second, the pointers to the new captions have to be restored.
1376 Sadly, currently these pointers are not stored anywhere but in the list
1377 of drawing undo actions. */
1379 SCTAB nTab;
1380 ScMarkData aSourceMark;
1381 for (nTab=aSrcRange.aStart.Tab(); nTab<=aSrcRange.aEnd.Tab(); nTab++)
1382 aSourceMark.SelectTable( nTab, true );
1384 // do not clone objects and note captions into clipdoc (see above)
1385 // but at least copy notes
1386 ScClipParam aClipParam(aSrcRange, bCut);
1387 rDoc.CopyToClip(aClipParam, pClipDoc.get(), &aSourceMark, false, bKeepScenarioFlags, false, true);
1389 if (bCut)
1391 ScRange aSrcPaintRange = aSrcRange;
1392 rDoc.ExtendMerge( aSrcPaintRange ); // before deleting
1393 sal_uInt16 nExtFlags = 0;
1394 pDocShell->UpdatePaintExt( nExtFlags, aSrcPaintRange );
1395 rDoc.DeleteAreaTab( aSrcRange, nRedoFlags );
1396 PaintArea( aSrcPaintRange, nExtFlags );
1399 ScMarkData aDestMark;
1400 for (nTab=aDestRange.aStart.Tab(); nTab<=aDestRange.aEnd.Tab(); nTab++)
1401 aDestMark.SelectTable( nTab, true );
1403 bool bIncludeFiltered = bCut;
1404 // TODO: restore old note captions instead of cloning new captions...
1405 rDoc.CopyFromClip( aDestRange, aDestMark, IDF_ALL & ~IDF_OBJECTS, NULL, pClipDoc.get(), true, false, bIncludeFiltered );
1407 if (bCut)
1408 for (nTab=aSrcRange.aStart.Tab(); nTab<=aSrcRange.aEnd.Tab(); nTab++)
1409 rDoc.RefreshAutoFilter( aSrcRange.aStart.Col(), aSrcRange.aStart.Row(),
1410 aSrcRange.aEnd.Col(), aSrcRange.aEnd.Row(), nTab );
1412 // skipped rows and merged cells don't mix
1413 if ( !bIncludeFiltered && pClipDoc->HasClipFilteredRows() )
1414 pDocShell->GetDocFunc().UnmergeCells( aDestRange, false );
1416 for (nTab=aDestRange.aStart.Tab(); nTab<=aDestRange.aEnd.Tab(); nTab++)
1418 SCCOL nEndCol = aDestRange.aEnd.Col();
1419 SCROW nEndRow = aDestRange.aEnd.Row();
1420 rDoc.ExtendMerge( aDestRange.aStart.Col(), aDestRange.aStart.Row(),
1421 nEndCol, nEndRow, nTab, true );
1422 PaintArea( ScRange( aDestRange.aStart.Col(), aDestRange.aStart.Row(), nTab,
1423 nEndCol, nEndRow, nTab ), 0 );
1426 SetChangeTrack();
1428 pClipDoc.reset();
1429 ShowTable( aDestRange.aStart.Tab() );
1431 RedoSdrUndoAction( pDrawUndo ); //! include in ScBlockUndo?
1432 EnableDrawAdjust( &rDoc, true ); //! include in ScBlockUndo?
1434 EndRedo();
1435 SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
1438 void ScUndoDragDrop::Repeat(SfxRepeatTarget& /* rTarget */)
1442 bool ScUndoDragDrop::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1444 return false; // not possible
1447 // Insert list containing range names
1448 // (Insert|Name|Insert =>[List])
1449 ScUndoListNames::ScUndoListNames( ScDocShell* pNewDocShell, const ScRange& rRange,
1450 ScDocument* pNewUndoDoc, ScDocument* pNewRedoDoc ) :
1451 ScBlockUndo( pNewDocShell, rRange, SC_UNDO_AUTOHEIGHT ),
1452 pUndoDoc( pNewUndoDoc ),
1453 pRedoDoc( pNewRedoDoc )
1457 ScUndoListNames::~ScUndoListNames()
1459 delete pUndoDoc;
1460 delete pRedoDoc;
1463 OUString ScUndoListNames::GetComment() const
1465 return ScGlobal::GetRscString( STR_UNDO_LISTNAMES );
1468 void ScUndoListNames::DoChange( ScDocument* pSrcDoc ) const
1470 ScDocument& rDoc = pDocShell->GetDocument();
1472 rDoc.DeleteAreaTab( aBlockRange, IDF_ALL );
1473 pSrcDoc->CopyToDocument( aBlockRange, IDF_ALL, false, &rDoc );
1474 pDocShell->PostPaint( aBlockRange, PAINT_GRID );
1475 pDocShell->PostDataChanged();
1476 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1477 if (pViewShell)
1478 pViewShell->CellContentChanged();
1481 void ScUndoListNames::Undo()
1483 BeginUndo();
1484 DoChange(pUndoDoc);
1485 EndUndo();
1488 void ScUndoListNames::Redo()
1490 BeginRedo();
1491 DoChange(pRedoDoc);
1492 EndRedo();
1495 void ScUndoListNames::Repeat(SfxRepeatTarget& rTarget)
1497 if (rTarget.ISA(ScTabViewTarget))
1498 static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->InsertNameList();
1501 bool ScUndoListNames::CanRepeat(SfxRepeatTarget& rTarget) const
1503 return rTarget.ISA(ScTabViewTarget);
1506 ScUndoConditionalFormat::ScUndoConditionalFormat(ScDocShell* pNewDocShell,
1507 ScDocument* pUndoDoc, ScDocument* pRedoDoc, const ScRange& rRange):
1508 ScSimpleUndo( pNewDocShell ),
1509 mpUndoDoc(pUndoDoc),
1510 mpRedoDoc(pRedoDoc),
1511 maRange(rRange)
1515 ScUndoConditionalFormat::~ScUndoConditionalFormat()
1519 OUString ScUndoConditionalFormat::GetComment() const
1521 return ScGlobal::GetRscString( STR_UNDO_CONDFORMAT );
1524 void ScUndoConditionalFormat::Undo()
1526 DoChange(mpUndoDoc.get());
1529 void ScUndoConditionalFormat::Redo()
1531 DoChange(mpRedoDoc.get());
1534 void ScUndoConditionalFormat::DoChange(ScDocument* pSrcDoc)
1536 ScDocument& rDoc = pDocShell->GetDocument();
1538 rDoc.DeleteAreaTab( maRange, IDF_ALL );
1539 pSrcDoc->CopyToDocument( maRange, IDF_ALL, false, &rDoc );
1540 pDocShell->PostPaint( maRange, PAINT_GRID );
1541 pDocShell->PostDataChanged();
1542 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1543 if (pViewShell)
1544 pViewShell->CellContentChanged();
1547 void ScUndoConditionalFormat::Repeat(SfxRepeatTarget& )
1551 bool ScUndoConditionalFormat::CanRepeat(SfxRepeatTarget& ) const
1553 return false;
1556 ScUndoUseScenario::ScUndoUseScenario( ScDocShell* pNewDocShell,
1557 const ScMarkData& rMark,
1558 /*C*/ const ScArea& rDestArea,
1559 ScDocument* pNewUndoDoc,
1560 const OUString& rNewName ) :
1561 ScSimpleUndo( pNewDocShell ),
1562 pUndoDoc( pNewUndoDoc ),
1563 aMarkData( rMark ),
1564 aName( rNewName )
1566 aRange.aStart.SetCol(rDestArea.nColStart);
1567 aRange.aStart.SetRow(rDestArea.nRowStart);
1568 aRange.aStart.SetTab(rDestArea.nTab);
1569 aRange.aEnd.SetCol(rDestArea.nColEnd);
1570 aRange.aEnd.SetRow(rDestArea.nRowEnd);
1571 aRange.aEnd.SetTab(rDestArea.nTab);
1574 ScUndoUseScenario::~ScUndoUseScenario()
1576 delete pUndoDoc;
1579 OUString ScUndoUseScenario::GetComment() const
1581 return ScGlobal::GetRscString( STR_UNDO_USESCENARIO );
1584 void ScUndoUseScenario::Undo()
1586 BeginUndo();
1588 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1589 if (pViewShell)
1591 pViewShell->DoneBlockMode();
1592 pViewShell->InitOwnBlockMode();
1595 ScDocument& rDoc = pDocShell->GetDocument();
1596 rDoc.DeleteSelection( IDF_ALL, aMarkData );
1597 pUndoDoc->CopyToDocument( aRange, IDF_ALL, true, &rDoc, &aMarkData );
1599 // scenario table
1600 bool bFrame = false;
1601 SCTAB nTab = aRange.aStart.Tab();
1602 SCTAB nEndTab = nTab;
1603 while ( pUndoDoc->HasTable(nEndTab+1) && pUndoDoc->IsScenario(nEndTab+1) )
1604 ++nEndTab;
1605 for (SCTAB i = nTab+1; i<=nEndTab; i++)
1607 // Flags always
1608 OUString aComment;
1609 Color aColor;
1610 sal_uInt16 nScenFlags;
1611 pUndoDoc->GetScenarioData( i, aComment, aColor, nScenFlags );
1612 rDoc.SetScenarioData( i, aComment, aColor, nScenFlags );
1613 bool bActive = pUndoDoc->IsActiveScenario( i );
1614 rDoc.SetActiveScenario( i, bActive );
1615 // For copy-back scenario also consider content
1616 if ( nScenFlags & SC_SCENARIO_TWOWAY )
1618 rDoc.DeleteAreaTab( 0,0, MAXCOL,MAXROW, i, IDF_ALL );
1619 pUndoDoc->CopyToDocument( 0,0,i, MAXCOL,MAXROW,i, IDF_ALL,false, &rDoc );
1621 if ( nScenFlags & SC_SCENARIO_SHOWFRAME )
1622 bFrame = true;
1625 // if visible borders, then paint all
1626 if (bFrame)
1627 pDocShell->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID | PAINT_EXTRAS );
1628 else
1629 pDocShell->PostPaint( aRange, PAINT_GRID | PAINT_EXTRAS );
1630 pDocShell->PostDataChanged();
1631 if (pViewShell)
1632 pViewShell->CellContentChanged();
1634 ShowTable( aRange.aStart.Tab() );
1636 EndUndo();
1639 void ScUndoUseScenario::Redo()
1641 SCTAB nTab = aRange.aStart.Tab();
1642 BeginRedo();
1644 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1645 if (pViewShell)
1647 pViewShell->SetTabNo( nTab );
1648 pViewShell->DoneBlockMode();
1649 pViewShell->InitOwnBlockMode();
1652 pDocShell->UseScenario( nTab, aName, false );
1654 EndRedo();
1657 void ScUndoUseScenario::Repeat(SfxRepeatTarget& rTarget)
1659 if (rTarget.ISA(ScTabViewTarget))
1661 OUString aTemp = aName;
1662 static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->UseScenario(aTemp);
1666 bool ScUndoUseScenario::CanRepeat(SfxRepeatTarget& rTarget) const
1668 if (rTarget.ISA(ScTabViewTarget))
1670 ScViewData& rViewData = static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->GetViewData();
1671 return !rViewData.GetDocument()->IsScenario( rViewData.GetTabNo() );
1673 return false;
1676 ScUndoSelectionStyle::ScUndoSelectionStyle( ScDocShell* pNewDocShell,
1677 const ScMarkData& rMark,
1678 const ScRange& rRange,
1679 const OUString& rName,
1680 ScDocument* pNewUndoDoc ) :
1681 ScSimpleUndo( pNewDocShell ),
1682 aMarkData( rMark ),
1683 pUndoDoc( pNewUndoDoc ),
1684 aStyleName( rName ),
1685 aRange( rRange )
1687 aMarkData.MarkToMulti();
1690 ScUndoSelectionStyle::~ScUndoSelectionStyle()
1692 delete pUndoDoc;
1695 OUString ScUndoSelectionStyle::GetComment() const
1697 return ScGlobal::GetRscString( STR_UNDO_APPLYCELLSTYLE );
1700 void ScUndoSelectionStyle::DoChange( const bool bUndo )
1702 ScDocument& rDoc = pDocShell->GetDocument();
1704 SetViewMarkData( aMarkData );
1706 ScRange aWorkRange( aRange );
1707 if ( rDoc.HasAttrib( aWorkRange, HASATTR_MERGED ) ) // Merged cells?
1708 rDoc.ExtendMerge( aWorkRange, true );
1710 sal_uInt16 nExtFlags = 0;
1711 pDocShell->UpdatePaintExt( nExtFlags, aWorkRange );
1713 if (bUndo) // if Undo then push back all old data again
1715 SCTAB nTabCount = rDoc.GetTableCount();
1716 ScRange aCopyRange = aWorkRange;
1717 aCopyRange.aStart.SetTab(0);
1718 aCopyRange.aEnd.SetTab(nTabCount-1);
1719 pUndoDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, true, &rDoc, &aMarkData );
1721 else // if Redo, then reapply style
1723 ScStyleSheetPool* pStlPool = rDoc.GetStyleSheetPool();
1724 ScStyleSheet* pStyleSheet =
1725 static_cast<ScStyleSheet*>( pStlPool->Find( aStyleName, SFX_STYLE_FAMILY_PARA ) );
1726 if (!pStyleSheet)
1728 OSL_FAIL("StyleSheet not found");
1729 return;
1731 rDoc.ApplySelectionStyle( *pStyleSheet, aMarkData );
1734 pDocShell->UpdatePaintExt( nExtFlags, aWorkRange );
1736 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1737 if ( !( (pViewShell) && pViewShell->AdjustBlockHeight() ) )
1738 /*A*/ pDocShell->PostPaint( aWorkRange, PAINT_GRID | PAINT_EXTRAS, nExtFlags );
1740 ShowTable( aWorkRange.aStart.Tab() );
1743 void ScUndoSelectionStyle::Undo()
1745 BeginUndo();
1746 DoChange( true );
1747 EndUndo();
1750 void ScUndoSelectionStyle::Redo()
1752 BeginRedo();
1753 DoChange( false );
1754 EndRedo();
1757 void ScUndoSelectionStyle::Repeat(SfxRepeatTarget& rTarget)
1759 if (rTarget.ISA(ScTabViewTarget))
1761 ScDocument& rDoc = pDocShell->GetDocument();
1762 ScStyleSheetPool* pStlPool = rDoc.GetStyleSheetPool();
1763 ScStyleSheet* pStyleSheet = static_cast<ScStyleSheet*>( pStlPool->
1764 Find( aStyleName, SFX_STYLE_FAMILY_PARA ));
1765 if (!pStyleSheet)
1767 OSL_FAIL("StyleSheet not found");
1768 return;
1771 ScTabViewShell& rViewShell = *static_cast<ScTabViewTarget&>(rTarget).GetViewShell();
1772 rViewShell.SetStyleSheetToMarked( pStyleSheet, true );
1776 bool ScUndoSelectionStyle::CanRepeat(SfxRepeatTarget& rTarget) const
1778 return rTarget.ISA(ScTabViewTarget);
1781 sal_uInt16 ScUndoSelectionStyle::GetId() const
1783 return STR_UNDO_APPLYCELLSTYLE;
1786 ScUndoEnterMatrix::ScUndoEnterMatrix( ScDocShell* pNewDocShell, const ScRange& rArea,
1787 ScDocument* pNewUndoDoc, const OUString& rForm ) :
1788 ScBlockUndo( pNewDocShell, rArea, SC_UNDO_SIMPLE ),
1789 pUndoDoc( pNewUndoDoc ),
1790 aFormula( rForm )
1792 SetChangeTrack();
1795 ScUndoEnterMatrix::~ScUndoEnterMatrix()
1797 delete pUndoDoc;
1800 OUString ScUndoEnterMatrix::GetComment() const
1802 return ScGlobal::GetRscString( STR_UNDO_ENTERMATRIX );
1805 void ScUndoEnterMatrix::SetChangeTrack()
1807 ScDocument& rDoc = pDocShell->GetDocument();
1808 ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
1809 if ( pChangeTrack )
1810 pChangeTrack->AppendContentRange( aBlockRange, pUndoDoc,
1811 nStartChangeAction, nEndChangeAction );
1812 else
1813 nStartChangeAction = nEndChangeAction = 0;
1816 void ScUndoEnterMatrix::Undo()
1818 BeginUndo();
1820 ScDocument& rDoc = pDocShell->GetDocument();
1822 rDoc.DeleteAreaTab( aBlockRange, IDF_ALL & ~IDF_NOTE );
1823 pUndoDoc->CopyToDocument( aBlockRange, IDF_ALL & ~IDF_NOTE, false, &rDoc );
1824 pDocShell->PostPaint( aBlockRange, PAINT_GRID );
1825 pDocShell->PostDataChanged();
1826 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1827 if (pViewShell)
1828 pViewShell->CellContentChanged();
1830 ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
1831 if ( pChangeTrack )
1832 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
1834 EndUndo();
1837 void ScUndoEnterMatrix::Redo()
1839 BeginRedo();
1841 ScDocument& rDoc = pDocShell->GetDocument();
1843 ScMarkData aDestMark;
1844 aDestMark.SelectOneTable( aBlockRange.aStart.Tab() );
1845 aDestMark.SetMarkArea( aBlockRange );
1847 rDoc.InsertMatrixFormula( aBlockRange.aStart.Col(), aBlockRange.aStart.Row(),
1848 aBlockRange.aEnd.Col(), aBlockRange.aEnd.Row(),
1849 aDestMark, aFormula );
1851 SetChangeTrack();
1853 EndRedo();
1856 void ScUndoEnterMatrix::Repeat(SfxRepeatTarget& rTarget)
1858 if (rTarget.ISA(ScTabViewTarget))
1860 OUString aTemp = aFormula;
1861 ScDocument& rDoc = pDocShell->GetDocument();
1862 static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->EnterMatrix(aTemp, rDoc.GetGrammar());
1866 bool ScUndoEnterMatrix::CanRepeat(SfxRepeatTarget& rTarget) const
1868 return rTarget.ISA(ScTabViewTarget);
1871 static ScRange lcl_GetMultiMarkRange( const ScMarkData& rMark )
1873 OSL_ENSURE( rMark.IsMultiMarked(), "wrong mark type" );
1875 ScRange aRange;
1876 rMark.GetMultiMarkArea( aRange );
1877 return aRange;
1880 ScUndoIndent::ScUndoIndent( ScDocShell* pNewDocShell, const ScMarkData& rMark,
1881 ScDocument* pNewUndoDoc, bool bIncrement ) :
1882 ScBlockUndo( pNewDocShell, lcl_GetMultiMarkRange(rMark), SC_UNDO_AUTOHEIGHT ),
1883 aMarkData( rMark ),
1884 pUndoDoc( pNewUndoDoc ),
1885 bIsIncrement( bIncrement )
1889 ScUndoIndent::~ScUndoIndent()
1891 delete pUndoDoc;
1894 OUString ScUndoIndent::GetComment() const
1896 sal_uInt16 nId = bIsIncrement ? STR_UNDO_INC_INDENT : STR_UNDO_DEC_INDENT;
1897 return ScGlobal::GetRscString( nId );
1900 void ScUndoIndent::Undo()
1902 BeginUndo();
1904 ScDocument& rDoc = pDocShell->GetDocument();
1905 SCTAB nTabCount = rDoc.GetTableCount();
1906 ScRange aCopyRange = aBlockRange;
1907 aCopyRange.aStart.SetTab(0);
1908 aCopyRange.aEnd.SetTab(nTabCount-1);
1909 pUndoDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, true, &rDoc, &aMarkData );
1910 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
1912 EndUndo();
1915 void ScUndoIndent::Redo()
1917 BeginRedo();
1919 ScDocument& rDoc = pDocShell->GetDocument();
1920 rDoc.ChangeSelectionIndent( bIsIncrement, aMarkData );
1921 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
1923 EndRedo();
1926 void ScUndoIndent::Repeat(SfxRepeatTarget& rTarget)
1928 if (rTarget.ISA(ScTabViewTarget))
1929 static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->ChangeIndent( bIsIncrement );
1932 bool ScUndoIndent::CanRepeat(SfxRepeatTarget& rTarget) const
1934 return rTarget.ISA(ScTabViewTarget);
1937 ScUndoTransliterate::ScUndoTransliterate( ScDocShell* pNewDocShell, const ScMarkData& rMark,
1938 ScDocument* pNewUndoDoc, sal_Int32 nType ) :
1939 ScBlockUndo( pNewDocShell, lcl_GetMultiMarkRange(rMark), SC_UNDO_AUTOHEIGHT ),
1940 aMarkData( rMark ),
1941 pUndoDoc( pNewUndoDoc ),
1942 nTransliterationType( nType )
1946 ScUndoTransliterate::~ScUndoTransliterate()
1948 delete pUndoDoc;
1951 OUString ScUndoTransliterate::GetComment() const
1953 return ScGlobal::GetRscString( STR_UNDO_TRANSLITERATE );
1956 void ScUndoTransliterate::Undo()
1958 BeginUndo();
1960 ScDocument& rDoc = pDocShell->GetDocument();
1961 SCTAB nTabCount = rDoc.GetTableCount();
1962 ScRange aCopyRange = aBlockRange;
1963 aCopyRange.aStart.SetTab(0);
1964 aCopyRange.aEnd.SetTab(nTabCount-1);
1965 pUndoDoc->CopyToDocument( aCopyRange, IDF_CONTENTS, true, &rDoc, &aMarkData );
1966 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
1968 EndUndo();
1971 void ScUndoTransliterate::Redo()
1973 BeginRedo();
1975 ScDocument& rDoc = pDocShell->GetDocument();
1976 rDoc.TransliterateText( aMarkData, nTransliterationType );
1977 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
1979 EndRedo();
1982 void ScUndoTransliterate::Repeat(SfxRepeatTarget& rTarget)
1984 if (rTarget.ISA(ScTabViewTarget))
1985 static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->TransliterateText( nTransliterationType );
1988 bool ScUndoTransliterate::CanRepeat(SfxRepeatTarget& rTarget) const
1990 return rTarget.ISA(ScTabViewTarget);
1993 ScUndoClearItems::ScUndoClearItems( ScDocShell* pNewDocShell, const ScMarkData& rMark,
1994 ScDocument* pNewUndoDoc, const sal_uInt16* pW ) :
1995 ScBlockUndo( pNewDocShell, lcl_GetMultiMarkRange(rMark), SC_UNDO_AUTOHEIGHT ),
1996 aMarkData( rMark ),
1997 pUndoDoc( pNewUndoDoc ),
1998 pWhich( NULL )
2000 OSL_ENSURE( pW, "ScUndoClearItems: Which-Pointer ist 0" );
2002 sal_uInt16 nCount = 0;
2003 while ( pW[nCount] )
2004 ++nCount;
2005 pWhich = new sal_uInt16[nCount+1];
2006 for (sal_uInt16 i=0; i<=nCount; i++)
2007 pWhich[i] = pW[i];
2010 ScUndoClearItems::~ScUndoClearItems()
2012 delete pUndoDoc;
2013 delete pWhich;
2016 OUString ScUndoClearItems::GetComment() const
2018 return ScGlobal::GetRscString( STR_UNDO_DELETECONTENTS );
2021 void ScUndoClearItems::Undo()
2023 BeginUndo();
2025 ScDocument& rDoc = pDocShell->GetDocument();
2026 pUndoDoc->CopyToDocument( aBlockRange, IDF_ATTRIB, true, &rDoc, &aMarkData );
2027 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
2029 EndUndo();
2032 void ScUndoClearItems::Redo()
2034 BeginRedo();
2036 ScDocument& rDoc = pDocShell->GetDocument();
2037 rDoc.ClearSelectionItems( pWhich, aMarkData );
2038 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
2040 EndRedo();
2043 void ScUndoClearItems::Repeat(SfxRepeatTarget& rTarget)
2045 if (rTarget.ISA(ScTabViewTarget))
2047 ScViewData& rViewData = static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->GetViewData();
2048 rViewData.GetDocFunc().ClearItems( rViewData.GetMarkData(), pWhich, false );
2052 bool ScUndoClearItems::CanRepeat(SfxRepeatTarget& rTarget) const
2054 return rTarget.ISA(ScTabViewTarget);
2057 // remove all line breaks of a table
2058 ScUndoRemoveBreaks::ScUndoRemoveBreaks( ScDocShell* pNewDocShell,
2059 SCTAB nNewTab, ScDocument* pNewUndoDoc ) :
2060 ScSimpleUndo( pNewDocShell ),
2061 nTab( nNewTab ),
2062 pUndoDoc( pNewUndoDoc )
2066 ScUndoRemoveBreaks::~ScUndoRemoveBreaks()
2068 delete pUndoDoc;
2071 OUString ScUndoRemoveBreaks::GetComment() const
2073 return ScGlobal::GetRscString( STR_UNDO_REMOVEBREAKS );
2076 void ScUndoRemoveBreaks::Undo()
2078 BeginUndo();
2080 ScDocument& rDoc = pDocShell->GetDocument();
2081 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
2083 pUndoDoc->CopyToDocument( 0,0,nTab, MAXCOL,MAXROW,nTab, IDF_NONE, false, &rDoc );
2084 if (pViewShell)
2085 pViewShell->UpdatePageBreakData( true );
2086 pDocShell->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
2088 EndUndo();
2091 void ScUndoRemoveBreaks::Redo()
2093 BeginRedo();
2095 ScDocument& rDoc = pDocShell->GetDocument();
2096 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
2098 rDoc.RemoveManualBreaks(nTab);
2099 rDoc.UpdatePageBreaks(nTab);
2100 if (pViewShell)
2101 pViewShell->UpdatePageBreakData( true );
2102 pDocShell->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
2104 EndRedo();
2107 void ScUndoRemoveBreaks::Repeat(SfxRepeatTarget& rTarget)
2109 if (rTarget.ISA(ScTabViewTarget))
2111 ScTabViewShell& rViewShell = *static_cast<ScTabViewTarget&>(rTarget).GetViewShell();
2112 rViewShell.RemoveManualBreaks();
2116 bool ScUndoRemoveBreaks::CanRepeat(SfxRepeatTarget& rTarget) const
2118 return rTarget.ISA(ScTabViewTarget);
2121 ScUndoRemoveMerge::ScUndoRemoveMerge( ScDocShell* pNewDocShell,
2122 const ScCellMergeOption& rOption, ScDocument* pNewUndoDoc ) :
2123 ScBlockUndo( pNewDocShell, rOption.getFirstSingleRange(), SC_UNDO_SIMPLE ),
2124 maOption(rOption),
2125 pUndoDoc( pNewUndoDoc )
2129 ScUndoRemoveMerge::~ScUndoRemoveMerge()
2131 delete pUndoDoc;
2134 OUString ScUndoRemoveMerge::GetComment() const
2136 return ScGlobal::GetRscString( STR_UNDO_REMERGE ); // "remove merge"
2139 void ScUndoRemoveMerge::Undo()
2141 using ::std::set;
2143 SetCurTab();
2144 BeginUndo();
2146 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
2148 ScDocument& rDoc = pDocShell->GetDocument();
2149 for (set<SCTAB>::const_iterator itr = maOption.maTabs.begin(), itrEnd = maOption.maTabs.end();
2150 itr != itrEnd; ++itr)
2152 OSL_ENSURE(pUndoDoc, "NULL pUndoDoc!");
2153 if (!pUndoDoc)
2154 continue;
2155 // There is no need to extend merge area because it's already been extended.
2156 ScRange aRange = maOption.getSingleRange(*itr);
2157 rDoc.DeleteAreaTab(aRange, IDF_ATTRIB);
2158 pUndoDoc->CopyToDocument(aRange, IDF_ATTRIB, false, &rDoc);
2160 bool bDidPaint = false;
2161 if ( pViewShell )
2163 pViewShell->SetTabNo(*itr);
2164 bDidPaint = pViewShell->AdjustRowHeight(maOption.mnStartRow, maOption.mnEndRow);
2166 if (!bDidPaint)
2167 ScUndoUtil::PaintMore(pDocShell, aRange);
2170 EndUndo();
2173 void ScUndoRemoveMerge::Redo()
2175 using ::std::set;
2177 SetCurTab();
2178 BeginRedo();
2180 ScDocument& rDoc = pDocShell->GetDocument();
2181 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
2183 for (set<SCTAB>::const_iterator itr = maOption.maTabs.begin(), itrEnd = maOption.maTabs.end();
2184 itr != itrEnd; ++itr)
2186 SCTAB nTab = *itr;
2187 // There is no need to extend merge area because it's already been extended.
2188 ScRange aRange = maOption.getSingleRange(nTab);
2190 const SfxPoolItem& rDefAttr = rDoc.GetPool()->GetDefaultItem( ATTR_MERGE );
2191 ScPatternAttr aPattern( rDoc.GetPool() );
2192 aPattern.GetItemSet().Put( rDefAttr );
2193 rDoc.ApplyPatternAreaTab( maOption.mnStartCol, maOption.mnStartRow,
2194 maOption.mnEndCol, maOption.mnEndRow, nTab,
2195 aPattern );
2197 rDoc.RemoveFlagsTab( maOption.mnStartCol, maOption.mnStartRow,
2198 maOption.mnEndCol, maOption.mnEndRow, nTab,
2199 SC_MF_HOR | SC_MF_VER );
2201 rDoc.ExtendMerge(aRange, true);
2203 // Paint
2205 bool bDidPaint = false;
2206 if ( pViewShell )
2208 pViewShell->SetTabNo(nTab);
2209 bDidPaint = pViewShell->AdjustRowHeight(maOption.mnStartRow, maOption.mnEndRow);
2211 if (!bDidPaint)
2212 ScUndoUtil::PaintMore(pDocShell, aRange);
2215 EndRedo();
2218 void ScUndoRemoveMerge::Repeat(SfxRepeatTarget& rTarget)
2220 if (rTarget.ISA(ScTabViewTarget))
2221 static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->RemoveMerge();
2224 bool ScUndoRemoveMerge::CanRepeat(SfxRepeatTarget& rTarget) const
2226 return rTarget.ISA(ScTabViewTarget);
2229 void ScUndoRemoveMerge::SetCurTab()
2231 SCTAB nCurTab = ScDocShell::GetCurTab();
2232 aBlockRange.aStart.SetTab(nCurTab);
2233 aBlockRange.aEnd.SetTab(nCurTab);
2236 /** set only border, for ScRangeList (StarOne) */
2237 static ScRange lcl_TotalRange( const ScRangeList& rRanges )
2239 ScRange aTotal;
2240 if ( !rRanges.empty() )
2242 aTotal = *rRanges[ 0 ];
2243 for ( size_t i = 1, nCount = rRanges.size(); i < nCount; ++i )
2245 ScRange aRange = *rRanges[ i ];
2246 if (aRange.aStart.Col() < aTotal.aStart.Col()) aTotal.aStart.SetCol(aRange.aStart.Col());
2247 if (aRange.aStart.Row() < aTotal.aStart.Row()) aTotal.aStart.SetRow(aRange.aStart.Row());
2248 if (aRange.aStart.Tab() < aTotal.aStart.Tab()) aTotal.aStart.SetTab(aRange.aStart.Tab());
2249 if (aRange.aEnd.Col() > aTotal.aEnd.Col() ) aTotal.aEnd.SetCol( aRange.aEnd.Col() );
2250 if (aRange.aEnd.Row() > aTotal.aEnd.Row() ) aTotal.aEnd.SetRow( aRange.aEnd.Row() );
2251 if (aRange.aEnd.Tab() > aTotal.aEnd.Tab() ) aTotal.aEnd.SetTab(aRange.aEnd.Tab() );
2254 return aTotal;
2257 ScUndoBorder::ScUndoBorder( ScDocShell* pNewDocShell,
2258 const ScRangeList& rRangeList, ScDocument* pNewUndoDoc,
2259 const SvxBoxItem& rNewOuter, const SvxBoxInfoItem& rNewInner ) :
2260 ScBlockUndo( pNewDocShell, lcl_TotalRange(rRangeList), SC_UNDO_SIMPLE ),
2261 pUndoDoc( pNewUndoDoc )
2263 pRanges = new ScRangeList(rRangeList);
2264 pOuter = new SvxBoxItem(rNewOuter);
2265 pInner = new SvxBoxInfoItem(rNewInner);
2268 ScUndoBorder::~ScUndoBorder()
2270 delete pUndoDoc;
2271 delete pRanges;
2272 delete pOuter;
2273 delete pInner;
2276 OUString ScUndoBorder::GetComment() const
2278 return ScGlobal::GetRscString( STR_UNDO_SELATTRLINES ); //! eigener String?
2281 void ScUndoBorder::Undo()
2283 BeginUndo();
2285 ScDocument& rDoc = pDocShell->GetDocument();
2286 ScMarkData aMarkData;
2287 aMarkData.MarkFromRangeList( *pRanges, false );
2288 pUndoDoc->CopyToDocument( aBlockRange, IDF_ATTRIB, true, &rDoc, &aMarkData );
2289 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
2291 EndUndo();
2294 void ScUndoBorder::Redo()
2296 BeginRedo();
2298 ScDocument& rDoc = pDocShell->GetDocument(); // call function at docfunc
2299 size_t nCount = pRanges->size();
2300 for (size_t i = 0; i < nCount; ++i )
2302 ScRange aRange = *(*pRanges)[i];
2303 SCTAB nTab = aRange.aStart.Tab();
2305 ScMarkData aMark;
2306 aMark.SetMarkArea( aRange );
2307 aMark.SelectTable( nTab, true );
2309 rDoc.ApplySelectionFrame( aMark, pOuter, pInner );
2311 for (size_t i = 0; i < nCount; ++i)
2312 pDocShell->PostPaint( *(*pRanges)[i], PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
2314 EndRedo();
2317 void ScUndoBorder::Repeat(SfxRepeatTarget& /* rTarget */)
2319 //TODO later (when the function has moved from cellsuno to docfunc)
2322 bool ScUndoBorder::CanRepeat(SfxRepeatTarget& /* rTarget */) const
2324 return false; // See above
2327 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */