update dev300-m58
[ooovba.git] / sc / source / ui / undo / undoblk.cxx
blob002aa14cde66c8c1727e3283e4ddd36774ad81f5
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: undoblk.cxx,v $
10 * $Revision: 1.27.128.4 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 //------------------------------------------------------------------
38 // INCLUDE ---------------------------------------------------------------
40 #include "scitems.hxx"
41 #include <vcl/virdev.hxx>
42 #include <vcl/waitobj.hxx>
43 #include <svx/boxitem.hxx>
44 #include <sfx2/app.hxx>
46 #include "undoblk.hxx"
47 #include "undoutil.hxx"
48 #include "document.hxx"
49 #include "patattr.hxx"
50 #include "docsh.hxx"
51 #include "tabvwsh.hxx"
52 #include "rangenam.hxx"
53 #include "rangeutl.hxx"
54 #include "dbcolect.hxx"
55 #include "stlpool.hxx"
56 #include "stlsheet.hxx"
57 #include "globstr.hrc"
58 #include "global.hxx"
59 #include "target.hxx"
60 #include "docpool.hxx"
61 #include "docfunc.hxx"
62 #include "attrib.hxx"
63 #include "chgtrack.hxx"
64 #include "transobj.hxx"
65 #include "refundo.hxx"
66 #include "undoolk.hxx"
67 #include "clipparam.hxx"
68 #include "sc.hrc"
70 #include <set>
72 // STATIC DATA -----------------------------------------------------------
74 TYPEINIT1(ScUndoInsertCells, SfxUndoAction);
75 TYPEINIT1(ScUndoDeleteCells, SfxUndoAction);
76 TYPEINIT1(ScUndoDeleteMulti, SfxUndoAction);
77 TYPEINIT1(ScUndoCut, ScBlockUndo);
78 TYPEINIT1(ScUndoPaste, SfxUndoAction);
79 TYPEINIT1(ScUndoDragDrop, SfxUndoAction);
80 TYPEINIT1(ScUndoListNames, SfxUndoAction);
81 TYPEINIT1(ScUndoUseScenario, SfxUndoAction);
82 TYPEINIT1(ScUndoSelectionStyle, SfxUndoAction);
83 TYPEINIT1(ScUndoEnterMatrix, ScBlockUndo);
84 TYPEINIT1(ScUndoIndent, ScBlockUndo);
85 TYPEINIT1(ScUndoTransliterate, ScBlockUndo);
86 TYPEINIT1(ScUndoClearItems, ScBlockUndo);
87 TYPEINIT1(ScUndoRemoveBreaks, SfxUndoAction);
88 TYPEINIT1(ScUndoRemoveMerge, ScBlockUndo);
89 TYPEINIT1(ScUndoBorder, ScBlockUndo);
93 // To Do:
94 /*A*/ // SetOptimalHeight auf Dokument, wenn keine View
95 /*B*/ // gelinkte Tabellen
96 /*C*/ // ScArea
97 //? // spaeter mal pruefen
100 // -----------------------------------------------------------------------
102 // Zellen einfuegen
103 // Zeilen einfuegen
104 // einzeln oder Block
107 ScUndoInsertCells::ScUndoInsertCells( ScDocShell* pNewDocShell,
108 const ScRange& rRange, SCTAB nNewCount, SCTAB* pNewTabs, SCTAB* pNewScenarios,
109 InsCellCmd eNewCmd, ScDocument* pUndoDocument, ScRefUndoData* pRefData,
110 BOOL bNewPartOfPaste ) :
111 ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFLAST ),
112 aEffRange( rRange ),
113 nCount( nNewCount ),
114 pTabs( pNewTabs ),
115 pScenarios( pNewScenarios ),
116 eCmd( eNewCmd ),
117 bPartOfPaste( bNewPartOfPaste ),
118 pPasteUndo( NULL )
120 if (eCmd == INS_INSROWS) // ganze Zeilen?
122 aEffRange.aStart.SetCol(0);
123 aEffRange.aEnd.SetCol(MAXCOL);
126 if (eCmd == INS_INSCOLS) // ganze Spalten?
128 aEffRange.aStart.SetRow(0);
129 aEffRange.aEnd.SetRow(MAXROW);
132 SetChangeTrack();
135 __EXPORT ScUndoInsertCells::~ScUndoInsertCells()
137 delete pPasteUndo;
138 delete []pTabs;
139 delete []pScenarios;
142 String __EXPORT ScUndoInsertCells::GetComment() const
144 return ScGlobal::GetRscString( pPasteUndo ? STR_UNDO_PASTE : STR_UNDO_INSERTCELLS );
147 BOOL ScUndoInsertCells::Merge( SfxUndoAction* pNextAction )
149 // If a paste undo action has already been added, append (detective) action there.
150 if ( pPasteUndo )
151 return pPasteUndo->Merge( pNextAction );
153 if ( bPartOfPaste && pNextAction->ISA( ScUndoWrapper ) )
155 ScUndoWrapper* pWrapper = (ScUndoWrapper*)pNextAction;
156 SfxUndoAction* pWrappedAction = pWrapper->GetWrappedUndo();
157 if ( pWrappedAction && pWrappedAction->ISA( ScUndoPaste ) )
159 // Store paste action if this is part of paste with inserting cells.
160 // A list action isn't used because Repeat wouldn't work (insert wrong cells).
162 pPasteUndo = pWrappedAction;
163 pWrapper->ForgetWrappedUndo(); // pWrapper is deleted by UndoManager
164 return TRUE;
168 // Call base class for detective handling
169 return ScMoveUndo::Merge( pNextAction );
172 void ScUndoInsertCells::SetChangeTrack()
174 ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
175 if ( pChangeTrack )
177 pChangeTrack->AppendInsert( aEffRange );
178 nEndChangeAction = pChangeTrack->GetActionMax();
180 else
181 nEndChangeAction = 0;
184 void ScUndoInsertCells::DoChange( const BOOL bUndo )
186 ScDocument* pDoc = pDocShell->GetDocument();
187 SCTAB i;
189 if ( bUndo )
191 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
192 if ( pChangeTrack )
193 pChangeTrack->Undo( nEndChangeAction, nEndChangeAction );
195 else
196 SetChangeTrack();
198 // refresh of merged cells has to be after inserting/deleting
200 switch (eCmd)
202 case INS_INSROWS:
203 case INS_CELLSDOWN:
204 for( i=0; i<nCount; i++ )
206 if (bUndo)
207 pDoc->DeleteRow( aEffRange.aStart.Col(), pTabs[i], aEffRange.aEnd.Col(), pTabs[i]+pScenarios[i],
208 aEffRange.aStart.Row(), static_cast<SCSIZE>(aEffRange.aEnd.Row()-aEffRange.aStart.Row()+1));
209 else
210 pDoc->InsertRow( aEffRange.aStart.Col(), pTabs[i], aEffRange.aEnd.Col(), pTabs[i]+pScenarios[i],
211 aEffRange.aStart.Row(), static_cast<SCSIZE>(aEffRange.aEnd.Row()-aEffRange.aStart.Row()+1));
213 break;
214 case INS_INSCOLS:
215 case INS_CELLSRIGHT:
216 for( i=0; i<nCount; i++ )
218 if (bUndo)
219 pDoc->DeleteCol( aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
220 aEffRange.aStart.Col(), static_cast<SCSIZE>(aEffRange.aEnd.Col()-aEffRange.aStart.Col()+1));
221 else
222 pDoc->InsertCol( aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
223 aEffRange.aStart.Col(), static_cast<SCSIZE>(aEffRange.aEnd.Col()-aEffRange.aStart.Col()+1));
225 break;
226 default:
228 // added to avoid warnings
232 ScRange aWorkRange( aEffRange );
233 if ( eCmd == INS_CELLSRIGHT ) // only "shift right" requires refresh of the moved area
234 aWorkRange.aEnd.SetCol(MAXCOL);
235 for( i=0; i<nCount; i++ )
237 if ( pDoc->HasAttrib( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), pTabs[i],
238 aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), pTabs[i], HASATTR_MERGED ) )
240 SCCOL nEndCol = aWorkRange.aEnd.Col();
241 SCROW nEndRow = aWorkRange.aEnd.Row();
242 pDoc->ExtendMerge( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), nEndCol, nEndRow, pTabs[i], TRUE );
246 //? Undo fuer herausgeschobene Attribute ?
248 USHORT nPaint = PAINT_GRID;
249 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
250 switch (eCmd)
252 case INS_INSROWS:
253 nPaint |= PAINT_LEFT;
254 aWorkRange.aEnd.SetRow(MAXROW);
255 break;
256 case INS_CELLSDOWN:
257 for( i=0; i<nCount; i++ )
259 aWorkRange.aEnd.SetRow(MAXROW);
260 if ( pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), pTabs[i] ))
262 aWorkRange.aStart.SetCol(0);
263 aWorkRange.aEnd.SetCol(MAXCOL);
264 nPaint |= PAINT_LEFT;
267 break;
268 case INS_INSCOLS:
269 nPaint |= PAINT_TOP; // obere Leiste
270 case INS_CELLSRIGHT:
271 for( i=0; i<nCount; i++ )
273 aWorkRange.aEnd.SetCol(MAXCOL); // bis ganz nach rechts
274 if ( pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), pTabs[i]) )
275 { // AdjustDraw zeichnet PAINT_TOP nicht,
276 aWorkRange.aStart.SetCol(0); // daher so geloest
277 aWorkRange.aEnd.SetRow(MAXROW);
278 nPaint |= PAINT_LEFT;
281 break;
282 default:
284 // added to avoid warnings
288 for( i=0; i<nCount; i++ )
290 pDocShell->PostPaint( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), pTabs[i],
291 aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), pTabs[i]+pScenarios[i], nPaint );
293 pDocShell->PostDataChanged();
294 if (pViewShell)
295 pViewShell->CellContentChanged();
298 void __EXPORT ScUndoInsertCells::Undo()
300 if ( pPasteUndo )
301 pPasteUndo->Undo(); // undo paste first
303 WaitObject aWait( pDocShell->GetActiveDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference
304 BeginUndo();
305 DoChange( TRUE );
306 EndUndo();
309 void __EXPORT ScUndoInsertCells::Redo()
311 WaitObject aWait( pDocShell->GetActiveDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference
312 BeginRedo();
313 DoChange( FALSE );
314 EndRedo();
316 if ( pPasteUndo )
317 pPasteUndo->Redo(); // redo paste last
320 void __EXPORT ScUndoInsertCells::Repeat(SfxRepeatTarget& rTarget)
322 if (rTarget.ISA(ScTabViewTarget))
324 if ( pPasteUndo )
326 // #94115# Repeat for paste with inserting cells is handled completely
327 // by the Paste undo action
329 pPasteUndo->Repeat( rTarget );
331 else
332 ((ScTabViewTarget&)rTarget).GetViewShell()->InsertCells( eCmd, TRUE );
336 BOOL __EXPORT ScUndoInsertCells::CanRepeat(SfxRepeatTarget& rTarget) const
338 return (rTarget.ISA(ScTabViewTarget));
342 // -----------------------------------------------------------------------
344 // Zellen loeschen
345 // Zeilen loeschen
346 // einzeln oder Block
349 ScUndoDeleteCells::ScUndoDeleteCells( ScDocShell* pNewDocShell,
350 const ScRange& rRange, SCTAB nNewCount, SCTAB* pNewTabs, SCTAB* pNewScenarios,
351 DelCellCmd eNewCmd, ScDocument* pUndoDocument, ScRefUndoData* pRefData ) :
352 ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFLAST ),
353 aEffRange( rRange ),
354 nCount( nNewCount ),
355 pTabs( pNewTabs ),
356 pScenarios( pNewScenarios ),
357 eCmd( eNewCmd )
359 if (eCmd == DEL_DELROWS) // gaze Zeilen?
361 aEffRange.aStart.SetCol(0);
362 aEffRange.aEnd.SetCol(MAXCOL);
365 if (eCmd == DEL_DELCOLS) // ganze Spalten?
367 aEffRange.aStart.SetRow(0);
368 aEffRange.aEnd.SetRow(MAXROW);
371 SetChangeTrack();
374 __EXPORT ScUndoDeleteCells::~ScUndoDeleteCells()
376 delete []pTabs;
377 delete []pScenarios;
380 String __EXPORT ScUndoDeleteCells::GetComment() const
382 return ScGlobal::GetRscString( STR_UNDO_DELETECELLS ); // "Loeschen"
385 void ScUndoDeleteCells::SetChangeTrack()
387 ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
388 if ( pChangeTrack )
389 pChangeTrack->AppendDeleteRange( aEffRange, pRefUndoDoc,
390 nStartChangeAction, nEndChangeAction );
391 else
392 nStartChangeAction = nEndChangeAction = 0;
395 void ScUndoDeleteCells::DoChange( const BOOL bUndo )
397 ScDocument* pDoc = pDocShell->GetDocument();
398 SCTAB i;
400 if ( bUndo )
402 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
403 if ( pChangeTrack )
404 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
406 else
407 SetChangeTrack();
409 // Ausfuehren
410 switch (eCmd)
412 case DEL_DELROWS:
413 case DEL_CELLSUP:
414 for( i=0; i<nCount; i++ )
416 if (bUndo)
417 pDoc->InsertRow( aEffRange.aStart.Col(), pTabs[i], aEffRange.aEnd.Col(), pTabs[i]+pScenarios[i],
418 aEffRange.aStart.Row(), static_cast<SCSIZE>(aEffRange.aEnd.Row()-aEffRange.aStart.Row()+1));
419 else
420 pDoc->DeleteRow( aEffRange.aStart.Col(), pTabs[i], aEffRange.aEnd.Col(), pTabs[i]+pScenarios[i],
421 aEffRange.aStart.Row(), static_cast<SCSIZE>(aEffRange.aEnd.Row()-aEffRange.aStart.Row()+1));
423 break;
424 case DEL_DELCOLS:
425 case DEL_CELLSLEFT:
426 for( i=0; i<nCount; i++ )
428 if (bUndo)
429 pDoc->InsertCol( aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
430 aEffRange.aStart.Col(), static_cast<SCSIZE>(aEffRange.aEnd.Col()-aEffRange.aStart.Col()+1));
431 else
432 pDoc->DeleteCol( aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
433 aEffRange.aStart.Col(), static_cast<SCSIZE>(aEffRange.aEnd.Col()-aEffRange.aStart.Col()+1));
435 break;
436 default:
438 // added to avoid warnings
442 // bei Undo Referenzen wiederherstellen
443 for( i=0; i<nCount && bUndo; i++ )
445 pRefUndoDoc->CopyToDocument( aEffRange.aStart.Col(), aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Col(), aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
446 IDF_ALL, FALSE, pDoc );
449 ScRange aWorkRange( aEffRange );
450 if ( eCmd == DEL_CELLSLEFT ) // only "shift left" requires refresh of the moved area
451 aWorkRange.aEnd.SetCol(MAXCOL);
453 for( i=0; i<nCount; i++ )
455 if ( pDoc->HasAttrib( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), pTabs[i],
456 aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), pTabs[i], HASATTR_MERGED | HASATTR_OVERLAPPED ) )
458 // #i51445# old merge flag attributes must be deleted also for single cells,
459 // not only for whole columns/rows
461 if ( !bUndo )
463 if ( eCmd==DEL_DELCOLS || eCmd==DEL_CELLSLEFT )
464 aWorkRange.aEnd.SetCol(MAXCOL);
465 if ( eCmd==DEL_DELROWS || eCmd==DEL_CELLSUP )
466 aWorkRange.aEnd.SetRow(MAXROW);
467 ScMarkData aMarkData;
468 aMarkData.SelectOneTable( aWorkRange.aStart.Tab() );
469 ScPatternAttr aPattern( pDoc->GetPool() );
470 aPattern.GetItemSet().Put( ScMergeFlagAttr() );
471 pDoc->ApplyPatternArea( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(),
472 aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(),
473 aMarkData, aPattern );
476 SCCOL nEndCol = aWorkRange.aEnd.Col();
477 SCROW nEndRow = aWorkRange.aEnd.Row();
478 pDoc->ExtendMerge( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), nEndCol, nEndRow, pTabs[i], TRUE );
482 // Zeichnen
483 USHORT nPaint = PAINT_GRID;
484 switch (eCmd)
486 case DEL_DELROWS:
487 nPaint |= PAINT_LEFT;
488 aWorkRange.aEnd.SetRow(MAXROW);
489 break;
490 case DEL_CELLSUP:
491 for( i=0; i<nCount; i++ )
493 aWorkRange.aEnd.SetRow(MAXROW);
494 if ( pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), pTabs[i] ))
496 aWorkRange.aStart.SetCol(0);
497 aWorkRange.aEnd.SetCol(MAXCOL);
498 nPaint |= PAINT_LEFT;
501 break;
502 case DEL_DELCOLS:
503 nPaint |= PAINT_TOP; // obere Leiste
504 case DEL_CELLSLEFT:
505 for( i=0; i<nCount; i++ )
507 aWorkRange.aEnd.SetCol(MAXCOL); // bis ganz nach rechts
508 if ( pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), pTabs[i] ) )
510 aWorkRange.aStart.SetCol(0);
511 aWorkRange.aEnd.SetRow(MAXROW);
512 nPaint |= PAINT_LEFT;
515 break;
516 default:
518 // added to avoid warnings
522 for( i=0; i<nCount; i++ )
524 pDocShell->PostPaint( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), pTabs[i],
525 aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), pTabs[i]+pScenarios[i], nPaint, SC_PF_LINES );
527 // Markierung erst nach EndUndo
529 pDocShell->PostDataChanged();
530 // CellContentChanged kommt mit der Markierung
533 void __EXPORT ScUndoDeleteCells::Undo()
535 WaitObject aWait( pDocShell->GetActiveDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference
536 BeginUndo();
537 DoChange( TRUE );
538 EndUndo();
539 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
541 // Markierung erst nach EndUndo
542 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
543 if (pViewShell)
545 for( SCTAB i=0; i<nCount; i++ )
547 pViewShell->MarkRange( ScRange(aEffRange.aStart.Col(), aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Col(), aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i]) );
552 void __EXPORT ScUndoDeleteCells::Redo()
554 WaitObject aWait( pDocShell->GetActiveDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference
555 BeginRedo();
556 DoChange( FALSE);
557 EndRedo();
558 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
560 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
561 if (pViewShell)
562 pViewShell->DoneBlockMode(); // aktuelle weg
565 void __EXPORT ScUndoDeleteCells::Repeat(SfxRepeatTarget& rTarget)
567 if (rTarget.ISA(ScTabViewTarget))
568 ((ScTabViewTarget&)rTarget).GetViewShell()->DeleteCells( eCmd, TRUE );
571 BOOL __EXPORT ScUndoDeleteCells::CanRepeat(SfxRepeatTarget& rTarget) const
573 return (rTarget.ISA(ScTabViewTarget));
577 // -----------------------------------------------------------------------
579 // Zellen loeschen auf Mehrfachselektion
582 ScUndoDeleteMulti::ScUndoDeleteMulti( ScDocShell* pNewDocShell,
583 BOOL bNewRows, BOOL bNeedsRefresh, SCTAB nNewTab,
584 const SCCOLROW* pRng, SCCOLROW nRngCnt,
585 ScDocument* pUndoDocument, ScRefUndoData* pRefData ) :
586 ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFLAST ),
587 bRows( bNewRows ),
588 bRefresh( bNeedsRefresh ),
589 nTab( nNewTab ),
590 nRangeCnt( nRngCnt )
592 pRanges = new SCCOLROW[ 2 * nRangeCnt ];
593 memcpy(pRanges,pRng,nRangeCnt*2*sizeof(SCCOLROW));
594 SetChangeTrack();
597 __EXPORT ScUndoDeleteMulti::~ScUndoDeleteMulti()
599 delete pRanges;
602 String __EXPORT ScUndoDeleteMulti::GetComment() const
604 return ScGlobal::GetRscString( STR_UNDO_DELETECELLS ); // wie DeleteCells
607 void ScUndoDeleteMulti::DoChange() const
609 SCCOL nStartCol;
610 SCROW nStartRow;
611 USHORT nPaint;
612 if (bRows)
614 nStartCol = 0;
615 nStartRow = static_cast<SCROW>(pRanges[0]);
616 nPaint = PAINT_GRID | PAINT_LEFT;
618 else
620 nStartCol = static_cast<SCCOL>(pRanges[0]);
621 nStartRow = 0;
622 nPaint = PAINT_GRID | PAINT_TOP;
625 if ( bRefresh )
627 ScDocument* pDoc = pDocShell->GetDocument();
628 SCCOL nEndCol = MAXCOL;
629 SCROW nEndRow = MAXROW;
630 pDoc->RemoveFlagsTab( nStartCol, nStartRow, nEndCol, nEndRow, nTab, SC_MF_HOR | SC_MF_VER );
631 pDoc->ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, nTab, TRUE );
634 pDocShell->PostPaint( nStartCol, nStartRow, nTab, MAXCOL, MAXROW, nTab, nPaint );
635 pDocShell->PostDataChanged();
636 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
637 if (pViewShell)
638 pViewShell->CellContentChanged();
640 ShowTable( nTab );
643 void ScUndoDeleteMulti::SetChangeTrack()
645 ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
646 if ( pChangeTrack )
648 nStartChangeAction = pChangeTrack->GetActionMax() + 1;
649 ScRange aRange( 0, 0, nTab, 0, 0, nTab );
650 if ( bRows )
651 aRange.aEnd.SetCol( MAXCOL );
652 else
653 aRange.aEnd.SetRow( MAXROW );
654 // rueckwaerts loeschen
655 SCCOLROW* pOneRange = &pRanges[2*nRangeCnt];
656 for ( SCCOLROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++ )
658 SCCOLROW nEnd = *(--pOneRange);
659 SCCOLROW nStart = *(--pOneRange);
660 if ( bRows )
662 aRange.aStart.SetRow( nStart );
663 aRange.aEnd.SetRow( nEnd );
665 else
667 aRange.aStart.SetCol( static_cast<SCCOL>(nStart) );
668 aRange.aEnd.SetCol( static_cast<SCCOL>(nEnd) );
670 ULONG nDummyStart;
671 pChangeTrack->AppendDeleteRange( aRange, pRefUndoDoc,
672 nDummyStart, nEndChangeAction );
675 else
676 nStartChangeAction = nEndChangeAction = 0;
679 void __EXPORT ScUndoDeleteMulti::Undo()
681 WaitObject aWait( pDocShell->GetActiveDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference
682 BeginUndo();
684 ScDocument* pDoc = pDocShell->GetDocument();
685 SCCOLROW* pOneRange;
686 SCCOLROW nRangeNo;
688 // rueckwaerts geloescht -> vorwaerts einfuegen
689 pOneRange = pRanges;
690 for (nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
692 SCCOLROW nStart = *(pOneRange++);
693 SCCOLROW nEnd = *(pOneRange++);
694 if (bRows)
695 pDoc->InsertRow( 0,nTab, MAXCOL,nTab, nStart,static_cast<SCSIZE>(nEnd-nStart+1) );
696 else
697 pDoc->InsertCol( 0,nTab, MAXROW,nTab, static_cast<SCCOL>(nStart), static_cast<SCSIZE>(nEnd-nStart+1) );
700 pOneRange = pRanges;
701 for (nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
703 SCCOLROW nStart = *(pOneRange++);
704 SCCOLROW nEnd = *(pOneRange++);
705 if (bRows)
706 pRefUndoDoc->CopyToDocument( 0,nStart,nTab, MAXCOL,nEnd,nTab, IDF_ALL,FALSE,pDoc );
707 else
708 pRefUndoDoc->CopyToDocument( static_cast<SCCOL>(nStart),0,nTab,
709 static_cast<SCCOL>(nEnd),MAXROW,nTab, IDF_ALL,FALSE,pDoc );
712 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
713 if ( pChangeTrack )
714 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
716 DoChange();
718 //! Markierung wieder einzeichnen
719 //! geht im Moment nicht, da keine Daten fuer Markierung vorhanden!
721 EndUndo();
722 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
725 void __EXPORT ScUndoDeleteMulti::Redo()
727 WaitObject aWait( pDocShell->GetActiveDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference
728 BeginRedo();
730 ScDocument* pDoc = pDocShell->GetDocument();
732 // rueckwaerts loeschen
733 SCCOLROW* pOneRange = &pRanges[2*nRangeCnt];
734 for (SCCOLROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
736 SCCOLROW nEnd = *(--pOneRange);
737 SCCOLROW nStart = *(--pOneRange);
738 if (bRows)
739 pDoc->DeleteRow( 0,nTab, MAXCOL,nTab, nStart,static_cast<SCSIZE>(nEnd-nStart+1) );
740 else
741 pDoc->DeleteCol( 0,nTab, MAXROW,nTab, static_cast<SCCOL>(nStart), static_cast<SCSIZE>(nEnd-nStart+1) );
744 SetChangeTrack();
746 DoChange();
748 //! Markierung loeschen, derzeit unnoetig (s.o.)
749 //! ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
750 //! if (pViewShell)
751 //! DoneBlockMode();
753 EndRedo();
754 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
757 void __EXPORT ScUndoDeleteMulti::Repeat(SfxRepeatTarget& rTarget)
759 // DeleteCells, falls einfache Selektion
760 if (rTarget.ISA(ScTabViewTarget))
761 ((ScTabViewTarget&)rTarget).GetViewShell()->DeleteCells( DEL_DELROWS, TRUE );
764 BOOL __EXPORT ScUndoDeleteMulti::CanRepeat(SfxRepeatTarget& rTarget) const
766 return (rTarget.ISA(ScTabViewTarget));
770 // -----------------------------------------------------------------------
772 // Ausschneiden (Cut)
775 ScUndoCut::ScUndoCut( ScDocShell* pNewDocShell,
776 ScRange aRange, ScAddress aOldEnd, const ScMarkData& rMark,
777 ScDocument* pNewUndoDoc ) :
778 ScBlockUndo( pNewDocShell, ScRange(aRange.aStart, aOldEnd), SC_UNDO_AUTOHEIGHT ),
779 aMarkData( rMark ),
780 pUndoDoc( pNewUndoDoc ),
781 aExtendedRange( aRange )
783 SetChangeTrack();
786 __EXPORT ScUndoCut::~ScUndoCut()
788 delete pUndoDoc;
791 String __EXPORT ScUndoCut::GetComment() const
793 return ScGlobal::GetRscString( STR_UNDO_CUT ); // "Ausschneiden"
796 void ScUndoCut::SetChangeTrack()
798 ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
799 if ( pChangeTrack )
800 pChangeTrack->AppendContentRange( aBlockRange, pUndoDoc,
801 nStartChangeAction, nEndChangeAction, SC_CACM_CUT );
802 else
803 nStartChangeAction = nEndChangeAction = 0;
806 void ScUndoCut::DoChange( const BOOL bUndo )
808 ScDocument* pDoc = pDocShell->GetDocument();
809 USHORT nExtFlags = 0;
811 // do not undo/redo objects and note captions, they are handled via drawing undo
812 USHORT nUndoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS;
814 if (bUndo) // nur bei Undo
816 // all sheets - CopyToDocument skips those that don't exist in pUndoDoc
817 SCTAB nTabCount = pDoc->GetTableCount();
818 ScRange aCopyRange = aExtendedRange;
819 aCopyRange.aStart.SetTab(0);
820 aCopyRange.aEnd.SetTab(nTabCount-1);
821 pUndoDoc->CopyToDocument( aCopyRange, nUndoFlags, FALSE, pDoc );
822 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
823 if ( pChangeTrack )
824 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
826 else // nur bei Redo
828 pDocShell->UpdatePaintExt( nExtFlags, aExtendedRange );
829 pDoc->DeleteArea( aBlockRange.aStart.Col(), aBlockRange.aStart.Row(),
830 aBlockRange.aEnd.Col(), aBlockRange.aEnd.Row(), aMarkData, nUndoFlags );
831 SetChangeTrack();
834 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
835 if ( !( (pViewShell) && pViewShell->AdjustBlockHeight() ) )
836 /*A*/ pDocShell->PostPaint( aExtendedRange, PAINT_GRID, nExtFlags );
838 if ( !bUndo ) // draw redo after updating row heights
839 RedoSdrUndoAction( pDrawUndo ); //! include in ScBlockUndo?
841 pDocShell->PostDataChanged();
842 if (pViewShell)
843 pViewShell->CellContentChanged();
846 void __EXPORT ScUndoCut::Undo()
848 BeginUndo();
849 DoChange( TRUE );
850 EndUndo();
853 void __EXPORT ScUndoCut::Redo()
855 BeginRedo();
856 ScDocument* pDoc = pDocShell->GetDocument();
857 EnableDrawAdjust( pDoc, FALSE ); //! include in ScBlockUndo?
858 DoChange( FALSE );
859 EnableDrawAdjust( pDoc, TRUE ); //! include in ScBlockUndo?
860 EndRedo();
863 void __EXPORT ScUndoCut::Repeat(SfxRepeatTarget& rTarget)
865 if (rTarget.ISA(ScTabViewTarget))
866 ((ScTabViewTarget&)rTarget).GetViewShell()->CutToClip( NULL, TRUE );
869 BOOL __EXPORT ScUndoCut::CanRepeat(SfxRepeatTarget& rTarget) const
871 return (rTarget.ISA(ScTabViewTarget));
875 // -----------------------------------------------------------------------
877 // Einfuegen (Paste)
880 ScUndoPaste::ScUndoPaste( ScDocShell* pNewDocShell,
881 SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
882 SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
883 const ScMarkData& rMark,
884 ScDocument* pNewUndoDoc, ScDocument* pNewRedoDoc,
885 USHORT nNewFlags,
886 ScRefUndoData* pRefData,
887 void* /* pFill1 */, void* /* pFill2 */, void* /* pFill3 */,
888 BOOL bRedoIsFilled, const ScUndoPasteOptions* pOptions ) :
889 ScBlockUndo( pNewDocShell, ScRange( nStartX, nStartY, nStartZ, nEndX, nEndY, nEndZ ), SC_UNDO_SIMPLE ),
890 aMarkData( rMark ),
891 pUndoDoc( pNewUndoDoc ),
892 pRedoDoc( pNewRedoDoc ),
893 nFlags( nNewFlags ),
894 pRefUndoData( pRefData ),
895 pRefRedoData( NULL ),
896 bRedoFilled( bRedoIsFilled )
898 // pFill1,pFill2,pFill3 are there so the ctor calls for simple paste (without cutting)
899 // don't have to be changed and branched for 641.
900 // They can be removed later.
902 if ( !aMarkData.IsMarked() ) // no cell marked:
903 aMarkData.SetMarkArea( aBlockRange ); // mark paste block
905 if ( pRefUndoData )
906 pRefUndoData->DeleteUnchanged( pDocShell->GetDocument() );
908 if ( pOptions )
909 aPasteOptions = *pOptions; // used only for Repeat
911 SetChangeTrack();
914 __EXPORT ScUndoPaste::~ScUndoPaste()
916 delete pUndoDoc;
917 delete pRedoDoc;
918 delete pRefUndoData;
919 delete pRefRedoData;
922 String __EXPORT ScUndoPaste::GetComment() const
924 return ScGlobal::GetRscString( STR_UNDO_PASTE ); // "Einfuegen"
927 void ScUndoPaste::SetChangeTrack()
929 ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
930 if ( pChangeTrack && (nFlags & IDF_CONTENTS) )
931 pChangeTrack->AppendContentRange( aBlockRange, pUndoDoc,
932 nStartChangeAction, nEndChangeAction, SC_CACM_PASTE );
933 else
934 nStartChangeAction = nEndChangeAction = 0;
937 void ScUndoPaste::DoChange( const BOOL bUndo )
939 ScDocument* pDoc = pDocShell->GetDocument();
941 // RefUndoData for redo is created before first undo
942 // (with DeleteUnchanged after the DoUndo call)
943 BOOL bCreateRedoData = ( bUndo && pRefUndoData && !pRefRedoData );
944 if ( bCreateRedoData )
945 pRefRedoData = new ScRefUndoData( pDoc );
947 ScRefUndoData* pWorkRefData = bUndo ? pRefUndoData : pRefRedoData;
949 // fuer Undo immer alle oder keine Inhalte sichern
950 USHORT nUndoFlags = IDF_NONE;
951 if (nFlags & IDF_CONTENTS)
952 nUndoFlags |= IDF_CONTENTS;
953 if (nFlags & IDF_ATTRIB)
954 nUndoFlags |= IDF_ATTRIB;
956 // do not undo/redo objects and note captions, they are handled via drawing undo
957 (nUndoFlags &= ~IDF_OBJECTS) |= IDF_NOCAPTIONS;
959 BOOL bPaintAll = FALSE;
961 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
963 // marking is in ScBlockUndo...
964 ScUndoUtil::MarkSimpleBlock( pDocShell, aBlockRange );
966 SCTAB nTabCount = pDoc->GetTableCount();
967 if ( bUndo && !bRedoFilled )
969 if (!pRedoDoc)
971 BOOL bColInfo = ( aBlockRange.aStart.Row()==0 && aBlockRange.aEnd.Row()==MAXROW );
972 BOOL bRowInfo = ( aBlockRange.aStart.Col()==0 && aBlockRange.aEnd.Col()==MAXCOL );
974 pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
975 pRedoDoc->InitUndoSelected( pDoc, aMarkData, bColInfo, bRowInfo );
977 // read "redo" data from the document in the first undo
978 // all sheets - CopyToDocument skips those that don't exist in pRedoDoc
979 ScRange aCopyRange = aBlockRange;
980 aCopyRange.aStart.SetTab(0);
981 aCopyRange.aEnd.SetTab(nTabCount-1);
982 pDoc->CopyToDocument( aCopyRange, nUndoFlags, FALSE, pRedoDoc );
983 bRedoFilled = TRUE;
986 USHORT nExtFlags = 0;
987 pDocShell->UpdatePaintExt( nExtFlags, aBlockRange );
989 aMarkData.MarkToMulti();
990 pDoc->DeleteSelection( nUndoFlags, aMarkData );
991 aMarkData.MarkToSimple();
993 SCTAB nFirstSelected = aMarkData.GetFirstSelected();
994 ScRange aTabSelectRange = aBlockRange;
995 SCTAB nTab;
997 if ( !bUndo && pRedoDoc ) // Redo: UndoToDocument before handling RefData
999 aTabSelectRange.aStart.SetTab( nFirstSelected );
1000 aTabSelectRange.aEnd.SetTab( nFirstSelected );
1001 pRedoDoc->UndoToDocument( aTabSelectRange, nUndoFlags, FALSE, pDoc );
1002 for (nTab=0; nTab<nTabCount; nTab++)
1003 if (nTab != nFirstSelected && aMarkData.GetTableSelect(nTab))
1005 aTabSelectRange.aStart.SetTab( nTab );
1006 aTabSelectRange.aEnd.SetTab( nTab );
1007 pRedoDoc->CopyToDocument( aTabSelectRange, nUndoFlags, FALSE, pDoc );
1011 if (pWorkRefData)
1013 pWorkRefData->DoUndo( pDoc, TRUE ); // TRUE = bSetChartRangeLists for SetChartListenerCollection
1014 if ( pDoc->RefreshAutoFilter( 0,0, MAXCOL,MAXROW, aBlockRange.aStart.Tab() ) )
1015 bPaintAll = TRUE;
1018 if ( bCreateRedoData && pRefRedoData )
1019 pRefRedoData->DeleteUnchanged( pDoc );
1021 if (bUndo) // Undo: UndoToDocument after handling RefData
1023 aTabSelectRange.aStart.SetTab( nFirstSelected );
1024 aTabSelectRange.aEnd.SetTab( nFirstSelected );
1025 pUndoDoc->UndoToDocument( aTabSelectRange, nUndoFlags, FALSE, pDoc );
1026 for (nTab=0; nTab<nTabCount; nTab++)
1027 if (nTab != nFirstSelected && aMarkData.GetTableSelect(nTab))
1029 aTabSelectRange.aStart.SetTab( nTab );
1030 aTabSelectRange.aEnd.SetTab( nTab );
1031 pUndoDoc->UndoToDocument( aTabSelectRange, nUndoFlags, FALSE, pDoc );
1035 if ( bUndo )
1037 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
1038 if ( pChangeTrack )
1039 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
1041 else
1042 SetChangeTrack();
1044 ScRange aDrawRange( aBlockRange );
1045 pDoc->ExtendMerge( aDrawRange, TRUE ); // only needed for single sheet (text/rtf etc.)
1046 USHORT nPaint = PAINT_GRID;
1047 if (bPaintAll)
1049 aDrawRange.aStart.SetCol(0);
1050 aDrawRange.aStart.SetRow(0);
1051 aDrawRange.aEnd.SetCol(MAXCOL);
1052 aDrawRange.aEnd.SetRow(MAXROW);
1053 nPaint |= PAINT_TOP | PAINT_LEFT;
1054 /*A*/ if (pViewShell)
1055 pViewShell->AdjustBlockHeight(FALSE);
1057 else
1059 if ( aBlockRange.aStart.Row() == 0 && aBlockRange.aEnd.Row() == MAXROW ) // ganze Spalte
1061 nPaint |= PAINT_TOP;
1062 aDrawRange.aEnd.SetCol(MAXCOL);
1064 if ( aBlockRange.aStart.Col() == 0 && aBlockRange.aEnd.Col() == MAXCOL ) // ganze Zeile
1066 nPaint |= PAINT_LEFT;
1067 aDrawRange.aEnd.SetRow(MAXROW);
1069 /*A*/ if ((pViewShell) && pViewShell->AdjustBlockHeight(FALSE))
1071 aDrawRange.aStart.SetCol(0);
1072 aDrawRange.aStart.SetRow(0);
1073 aDrawRange.aEnd.SetCol(MAXCOL);
1074 aDrawRange.aEnd.SetRow(MAXROW);
1075 nPaint |= PAINT_LEFT;
1077 pDocShell->UpdatePaintExt( nExtFlags, aDrawRange );
1080 if ( !bUndo ) // draw redo after updating row heights
1081 RedoSdrUndoAction( pDrawUndo ); //! include in ScBlockUndo?
1083 pDocShell->PostPaint( aDrawRange, nPaint, nExtFlags );
1085 pDocShell->PostDataChanged();
1086 if (pViewShell)
1087 pViewShell->CellContentChanged();
1090 void __EXPORT ScUndoPaste::Undo()
1092 BeginUndo();
1093 DoChange( TRUE );
1094 ShowTable( aBlockRange );
1095 EndUndo();
1096 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
1099 void __EXPORT ScUndoPaste::Redo()
1101 BeginRedo();
1102 ScDocument* pDoc = pDocShell->GetDocument();
1103 EnableDrawAdjust( pDoc, FALSE ); //! include in ScBlockUndo?
1104 DoChange( FALSE );
1105 EnableDrawAdjust( pDoc, TRUE ); //! include in ScBlockUndo?
1106 EndRedo();
1107 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
1110 void __EXPORT ScUndoPaste::Repeat(SfxRepeatTarget& rTarget)
1112 if (rTarget.ISA(ScTabViewTarget))
1114 ScTabViewShell* pViewSh = ((ScTabViewTarget&)rTarget).GetViewShell();
1115 ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pViewSh->GetActiveWin() );
1116 if (pOwnClip)
1118 // #129384# keep a reference in case the clipboard is changed during PasteFromClip
1119 com::sun::star::uno::Reference<com::sun::star::datatransfer::XTransferable> aOwnClipRef( pOwnClip );
1120 pViewSh->PasteFromClip( nFlags, pOwnClip->GetDocument(),
1121 aPasteOptions.nFunction, aPasteOptions.bSkipEmpty, aPasteOptions.bTranspose,
1122 aPasteOptions.bAsLink, aPasteOptions.eMoveMode, IDF_NONE,
1123 TRUE ); // allow warning dialog
1128 BOOL __EXPORT ScUndoPaste::CanRepeat(SfxRepeatTarget& rTarget) const
1130 return (rTarget.ISA(ScTabViewTarget));
1134 // -----------------------------------------------------------------------
1136 // Verschieben/Kopieren (Drag & Drop)
1139 ScUndoDragDrop::ScUndoDragDrop( ScDocShell* pNewDocShell,
1140 const ScRange& rRange, ScAddress aNewDestPos, BOOL bNewCut,
1141 ScDocument* pUndoDocument, ScRefUndoData* pRefData, BOOL bScenario ) :
1142 ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFFIRST ),
1143 aSrcRange( rRange ),
1144 bCut( bNewCut ),
1145 bKeepScenarioFlags( bScenario )
1147 ScAddress aDestEnd(aNewDestPos);
1148 aDestEnd.IncRow(aSrcRange.aEnd.Row() - aSrcRange.aStart.Row());
1149 aDestEnd.IncCol(aSrcRange.aEnd.Col() - aSrcRange.aStart.Col());
1150 aDestEnd.IncTab(aSrcRange.aEnd.Tab() - aSrcRange.aStart.Tab());
1152 BOOL bIncludeFiltered = bCut;
1153 if ( !bIncludeFiltered )
1155 // find number of non-filtered rows
1156 SCROW nPastedCount = pDocShell->GetDocument()->CountNonFilteredRows(
1157 aSrcRange.aStart.Row(), aSrcRange.aEnd.Row(), aSrcRange.aStart.Tab());
1159 if ( nPastedCount == 0 )
1160 nPastedCount = 1;
1161 aDestEnd.SetRow( aNewDestPos.Row() + nPastedCount - 1 );
1164 aDestRange.aStart = aNewDestPos;
1165 aDestRange.aEnd = aDestEnd;
1167 SetChangeTrack();
1170 __EXPORT ScUndoDragDrop::~ScUndoDragDrop()
1174 String __EXPORT ScUndoDragDrop::GetComment() const
1175 { // "Verschieben" : "Kopieren"
1176 return bCut ?
1177 ScGlobal::GetRscString( STR_UNDO_MOVE ) :
1178 ScGlobal::GetRscString( STR_UNDO_COPY );
1181 void ScUndoDragDrop::SetChangeTrack()
1183 ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
1184 if ( pChangeTrack )
1186 if ( bCut )
1188 nStartChangeAction = pChangeTrack->GetActionMax() + 1;
1189 pChangeTrack->AppendMove( aSrcRange, aDestRange, pRefUndoDoc );
1190 nEndChangeAction = pChangeTrack->GetActionMax();
1192 else
1193 pChangeTrack->AppendContentRange( aDestRange, pRefUndoDoc,
1194 nStartChangeAction, nEndChangeAction );
1196 else
1197 nStartChangeAction = nEndChangeAction = 0;
1200 void ScUndoDragDrop::PaintArea( ScRange aRange, USHORT nExtFlags ) const
1202 USHORT nPaint = PAINT_GRID;
1203 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1204 ScDocument* pDoc = pDocShell->GetDocument();
1206 if (pViewShell)
1208 VirtualDevice aVirtDev;
1209 ScViewData* pViewData = pViewShell->GetViewData();
1211 if ( pDoc->SetOptimalHeight( aRange.aStart.Row(), aRange.aEnd.Row(),
1212 aRange.aStart.Tab(), 0, &aVirtDev,
1213 pViewData->GetPPTX(), pViewData->GetPPTY(),
1214 pViewData->GetZoomX(), pViewData->GetZoomY(),
1215 FALSE ) )
1217 aRange.aStart.SetCol(0);
1218 aRange.aEnd.SetCol(MAXCOL);
1219 aRange.aEnd.SetRow(MAXROW);
1220 nPaint |= PAINT_LEFT;
1224 if ( bKeepScenarioFlags )
1226 // Szenarien mitkopiert -> auch Szenario-Rahmen painten
1227 aRange.aStart.SetCol(0);
1228 aRange.aStart.SetRow(0);
1229 aRange.aEnd.SetCol(MAXCOL);
1230 aRange.aEnd.SetRow(MAXROW);
1233 // column/row info (width/height) included if whole columns/rows were copied
1234 if ( aSrcRange.aStart.Col() == 0 && aSrcRange.aEnd.Col() == MAXCOL )
1236 nPaint |= PAINT_LEFT;
1237 aRange.aEnd.SetRow(MAXROW);
1239 if ( aSrcRange.aStart.Row() == 0 && aSrcRange.aEnd.Row() == MAXROW )
1241 nPaint |= PAINT_TOP;
1242 aRange.aEnd.SetCol(MAXCOL);
1245 pDocShell->PostPaint( aRange, nPaint, nExtFlags );
1249 void ScUndoDragDrop::DoUndo( ScRange aRange ) const
1251 ScDocument* pDoc = pDocShell->GetDocument();
1253 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
1254 if ( pChangeTrack )
1255 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
1257 //? DB-Areas vor Daten, damit bei ExtendMerge die Autofilter-Knoepfe stimmen
1259 ScRange aPaintRange = aRange;
1260 pDoc->ExtendMerge( aPaintRange ); // before deleting
1262 USHORT nExtFlags = 0;
1263 pDocShell->UpdatePaintExt( nExtFlags, aPaintRange );
1265 // do not undo objects and note captions, they are handled via drawing undo
1266 USHORT nUndoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS;
1268 pDoc->DeleteAreaTab( aRange, nUndoFlags );
1269 pRefUndoDoc->CopyToDocument( aRange, nUndoFlags, FALSE, pDoc );
1270 if ( pDoc->HasAttrib( aRange, HASATTR_MERGED ) )
1271 pDoc->ExtendMerge( aRange, TRUE );
1273 aPaintRange.aEnd.SetCol( Max( aPaintRange.aEnd.Col(), aRange.aEnd.Col() ) );
1274 aPaintRange.aEnd.SetRow( Max( aPaintRange.aEnd.Row(), aRange.aEnd.Row() ) );
1276 pDocShell->UpdatePaintExt( nExtFlags, aPaintRange );
1277 PaintArea( aPaintRange, nExtFlags );
1280 void __EXPORT ScUndoDragDrop::Undo()
1282 BeginUndo();
1283 DoUndo(aDestRange);
1284 if (bCut)
1285 DoUndo(aSrcRange);
1286 EndUndo();
1287 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
1290 void __EXPORT ScUndoDragDrop::Redo()
1292 BeginRedo();
1294 ScDocument* pDoc = pDocShell->GetDocument();
1295 ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
1297 EnableDrawAdjust( pDoc, FALSE ); //! include in ScBlockUndo?
1299 // do not undo/redo objects and note captions, they are handled via drawing undo
1300 USHORT nRedoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS;
1302 /* TODO: Redoing note captions is quite tricky due to the fact that a
1303 helper clip document is used. While (re-)pasting the contents to the
1304 destination area, the original pointers to the captions created while
1305 dropping have to be restored. A simple CopyFromClip() would create new
1306 caption objects that are not tracked by drawing undo, and the captions
1307 restored by drawing redo would live without cell note objects pointing
1308 to them. So, first, CopyToClip() and CopyFromClip() are called without
1309 cloning the caption objects. This leads to cell notes pointing to the
1310 wrong captions from source area that will be removed by drawing redo
1311 later. Second, the pointers to the new captions have to be restored.
1312 Sadly, currently these pointers are not stored anywhere but in the list
1313 of drawing undo actions. */
1315 SCTAB nTab;
1316 ScMarkData aSourceMark;
1317 for (nTab=aSrcRange.aStart.Tab(); nTab<=aSrcRange.aEnd.Tab(); nTab++)
1318 aSourceMark.SelectTable( nTab, TRUE );
1320 // do not clone objects and note captions into clipdoc (see above)
1321 ScClipParam aClipParam(aSrcRange, bCut);
1322 pDoc->CopyToClip(aClipParam, pClipDoc, &aSourceMark, false, bKeepScenarioFlags, false, false);
1324 if (bCut)
1326 ScRange aSrcPaintRange = aSrcRange;
1327 pDoc->ExtendMerge( aSrcPaintRange ); // before deleting
1328 USHORT nExtFlags = 0;
1329 pDocShell->UpdatePaintExt( nExtFlags, aSrcPaintRange );
1330 pDoc->DeleteAreaTab( aSrcRange, nRedoFlags );
1331 PaintArea( aSrcPaintRange, nExtFlags );
1334 ScMarkData aDestMark;
1335 for (nTab=aDestRange.aStart.Tab(); nTab<=aDestRange.aEnd.Tab(); nTab++)
1336 aDestMark.SelectTable( nTab, TRUE );
1338 BOOL bIncludeFiltered = bCut;
1339 // TODO: restore old note captions instead of cloning new captions...
1340 pDoc->CopyFromClip( aDestRange, aDestMark, IDF_ALL & ~IDF_OBJECTS, NULL, pClipDoc, TRUE, FALSE, bIncludeFiltered );
1342 if (bCut)
1343 for (nTab=aSrcRange.aStart.Tab(); nTab<=aSrcRange.aEnd.Tab(); nTab++)
1344 pDoc->RefreshAutoFilter( aSrcRange.aStart.Col(), aSrcRange.aStart.Row(),
1345 aSrcRange.aEnd.Col(), aSrcRange.aEnd.Row(), nTab );
1347 // skipped rows and merged cells don't mix
1348 if ( !bIncludeFiltered && pClipDoc->HasClipFilteredRows() )
1349 pDocShell->GetDocFunc().UnmergeCells( aDestRange, FALSE, TRUE );
1351 for (nTab=aDestRange.aStart.Tab(); nTab<=aDestRange.aEnd.Tab(); nTab++)
1353 SCCOL nEndCol = aDestRange.aEnd.Col();
1354 SCROW nEndRow = aDestRange.aEnd.Row();
1355 pDoc->ExtendMerge( aDestRange.aStart.Col(), aDestRange.aStart.Row(),
1356 nEndCol, nEndRow, nTab, TRUE );
1357 PaintArea( ScRange( aDestRange.aStart.Col(), aDestRange.aStart.Row(), nTab,
1358 nEndCol, nEndRow, nTab ), 0 );
1361 SetChangeTrack();
1363 delete pClipDoc;
1364 ShowTable( aDestRange.aStart.Tab() );
1366 RedoSdrUndoAction( pDrawUndo ); //! include in ScBlockUndo?
1367 EnableDrawAdjust( pDoc, TRUE ); //! include in ScBlockUndo?
1369 EndRedo();
1370 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
1373 void __EXPORT ScUndoDragDrop::Repeat(SfxRepeatTarget& /* rTarget */)
1377 BOOL __EXPORT ScUndoDragDrop::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1379 return FALSE; // geht nicht
1383 // -----------------------------------------------------------------------
1385 // Liste der Bereichsnamen einfuegen
1386 // (Einfuegen|Name|Einfuegen =>[Liste])
1389 ScUndoListNames::ScUndoListNames( ScDocShell* pNewDocShell, const ScRange& rRange,
1390 ScDocument* pNewUndoDoc, ScDocument* pNewRedoDoc ) :
1391 ScBlockUndo( pNewDocShell, rRange, SC_UNDO_AUTOHEIGHT ),
1392 pUndoDoc( pNewUndoDoc ),
1393 pRedoDoc( pNewRedoDoc )
1397 __EXPORT ScUndoListNames::~ScUndoListNames()
1399 delete pUndoDoc;
1400 delete pRedoDoc;
1403 String __EXPORT ScUndoListNames::GetComment() const
1405 return ScGlobal::GetRscString( STR_UNDO_LISTNAMES );
1408 void ScUndoListNames::DoChange( ScDocument* pSrcDoc ) const
1410 ScDocument* pDoc = pDocShell->GetDocument();
1412 pDoc->DeleteAreaTab( aBlockRange, IDF_ALL );
1413 pSrcDoc->CopyToDocument( aBlockRange, IDF_ALL, FALSE, pDoc );
1414 pDocShell->PostPaint( aBlockRange, PAINT_GRID );
1415 pDocShell->PostDataChanged();
1416 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1417 if (pViewShell)
1418 pViewShell->CellContentChanged();
1421 void __EXPORT ScUndoListNames::Undo()
1423 BeginUndo();
1424 DoChange(pUndoDoc);
1425 EndUndo();
1428 void __EXPORT ScUndoListNames::Redo()
1430 BeginRedo();
1431 DoChange(pRedoDoc);
1432 EndRedo();
1435 void __EXPORT ScUndoListNames::Repeat(SfxRepeatTarget& rTarget)
1437 if (rTarget.ISA(ScTabViewTarget))
1438 ((ScTabViewTarget&)rTarget).GetViewShell()->InsertNameList();
1441 BOOL __EXPORT ScUndoListNames::CanRepeat(SfxRepeatTarget& rTarget) const
1443 return (rTarget.ISA(ScTabViewTarget));
1447 // -----------------------------------------------------------------------
1449 // Szenario anwenden
1450 // (Extras|Szenarien)
1453 ScUndoUseScenario::ScUndoUseScenario( ScDocShell* pNewDocShell,
1454 const ScMarkData& rMark,
1455 /*C*/ const ScArea& rDestArea,
1456 ScDocument* pNewUndoDoc,
1457 const String& rNewName ) :
1458 ScSimpleUndo( pNewDocShell ),
1459 pUndoDoc( pNewUndoDoc ),
1460 aMarkData( rMark ),
1461 aName( rNewName )
1463 aRange.aStart.SetCol(rDestArea.nColStart);
1464 aRange.aStart.SetRow(rDestArea.nRowStart);
1465 aRange.aStart.SetTab(rDestArea.nTab);
1466 aRange.aEnd.SetCol(rDestArea.nColEnd);
1467 aRange.aEnd.SetRow(rDestArea.nRowEnd);
1468 aRange.aEnd.SetTab(rDestArea.nTab);
1471 __EXPORT ScUndoUseScenario::~ScUndoUseScenario()
1473 delete pUndoDoc;
1476 String __EXPORT ScUndoUseScenario::GetComment() const
1478 return ScGlobal::GetRscString( STR_UNDO_USESCENARIO );
1481 void __EXPORT ScUndoUseScenario::Undo()
1483 BeginUndo();
1485 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1486 if (pViewShell)
1488 pViewShell->DoneBlockMode();
1489 pViewShell->InitOwnBlockMode();
1492 ScDocument* pDoc = pDocShell->GetDocument();
1493 pDoc->DeleteSelection( IDF_ALL, aMarkData );
1494 pUndoDoc->CopyToDocument( aRange, IDF_ALL, TRUE, pDoc, &aMarkData );
1496 // Szenario-Tabellen
1497 BOOL bFrame = FALSE;
1498 SCTAB nTab = aRange.aStart.Tab();
1499 SCTAB nEndTab = nTab;
1500 while ( pUndoDoc->HasTable(nEndTab+1) && pUndoDoc->IsScenario(nEndTab+1) )
1501 ++nEndTab;
1502 for (SCTAB i = nTab+1; i<=nEndTab; i++)
1504 // Flags immer
1505 String aComment;
1506 Color aColor;
1507 USHORT nScenFlags;
1508 pUndoDoc->GetScenarioData( i, aComment, aColor, nScenFlags );
1509 pDoc->SetScenarioData( i, aComment, aColor, nScenFlags );
1510 BOOL bActive = pUndoDoc->IsActiveScenario( i );
1511 pDoc->SetActiveScenario( i, bActive );
1512 // Bei Zurueckkopier-Szenarios auch Inhalte
1513 if ( nScenFlags & SC_SCENARIO_TWOWAY )
1515 pDoc->DeleteAreaTab( 0,0, MAXCOL,MAXROW, i, IDF_ALL );
1516 pUndoDoc->CopyToDocument( 0,0,i, MAXCOL,MAXROW,i, IDF_ALL,FALSE, pDoc );
1518 if ( nScenFlags & SC_SCENARIO_SHOWFRAME )
1519 bFrame = TRUE;
1522 // Wenn sichtbare Rahmen, dann alles painten
1523 if (bFrame)
1524 pDocShell->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID | PAINT_EXTRAS );
1525 else
1526 pDocShell->PostPaint( aRange, PAINT_GRID | PAINT_EXTRAS );
1527 pDocShell->PostDataChanged();
1528 if (pViewShell)
1529 pViewShell->CellContentChanged();
1531 ShowTable( aRange.aStart.Tab() );
1533 EndUndo();
1536 void __EXPORT ScUndoUseScenario::Redo()
1538 SCTAB nTab = aRange.aStart.Tab();
1539 BeginRedo();
1541 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1542 if (pViewShell)
1544 pViewShell->SetTabNo( nTab );
1545 pViewShell->DoneBlockMode();
1546 pViewShell->InitOwnBlockMode();
1549 pDocShell->UseScenario( nTab, aName, FALSE );
1551 EndRedo();
1554 void __EXPORT ScUndoUseScenario::Repeat(SfxRepeatTarget& rTarget)
1556 if (rTarget.ISA(ScTabViewTarget))
1558 String aTemp = aName;
1559 ((ScTabViewTarget&)rTarget).GetViewShell()->UseScenario(aTemp);
1563 BOOL __EXPORT ScUndoUseScenario::CanRepeat(SfxRepeatTarget& rTarget) const
1565 if (rTarget.ISA(ScTabViewTarget))
1567 ScViewData* pViewData = ((ScTabViewTarget&)rTarget).GetViewShell()->GetViewData();
1568 return !pViewData->GetDocument()->IsScenario( pViewData->GetTabNo() );
1570 return FALSE;
1574 // -----------------------------------------------------------------------
1576 // Vorlage anwenden
1577 // (Format|Vorlagenkatalog)
1580 ScUndoSelectionStyle::ScUndoSelectionStyle( ScDocShell* pNewDocShell,
1581 const ScMarkData& rMark,
1582 const ScRange& rRange,
1583 const String& rName,
1584 ScDocument* pNewUndoDoc ) :
1585 ScSimpleUndo( pNewDocShell ),
1586 aMarkData( rMark ),
1587 pUndoDoc( pNewUndoDoc ),
1588 aStyleName( rName ),
1589 aRange( rRange )
1591 aMarkData.MarkToMulti();
1594 __EXPORT ScUndoSelectionStyle::~ScUndoSelectionStyle()
1596 delete pUndoDoc;
1599 String __EXPORT ScUndoSelectionStyle::GetComment() const
1601 return ScGlobal::GetRscString( STR_UNDO_APPLYCELLSTYLE );
1604 void ScUndoSelectionStyle::DoChange( const BOOL bUndo )
1606 ScDocument* pDoc = pDocShell->GetDocument();
1607 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1609 if (pViewShell)
1610 pViewShell->SetMarkData( aMarkData );
1612 ScRange aWorkRange( aRange );
1613 if ( pDoc->HasAttrib( aWorkRange, HASATTR_MERGED ) ) // zusammengefasste Zellen?
1614 pDoc->ExtendMerge( aWorkRange, TRUE );
1616 USHORT nExtFlags = 0;
1617 pDocShell->UpdatePaintExt( nExtFlags, aWorkRange );
1619 if (bUndo) // bei Undo alte Daten wieder reinschubsen
1621 SCTAB nTabCount = pDoc->GetTableCount();
1622 ScRange aCopyRange = aWorkRange;
1623 aCopyRange.aStart.SetTab(0);
1624 aCopyRange.aEnd.SetTab(nTabCount-1);
1625 pUndoDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, TRUE, pDoc, &aMarkData );
1627 else // bei Redo Style wieder zuweisen
1629 ScStyleSheetPool* pStlPool = pDoc->GetStyleSheetPool();
1630 ScStyleSheet* pStyleSheet =
1631 (ScStyleSheet*) pStlPool->Find( aStyleName, SFX_STYLE_FAMILY_PARA );
1632 if (!pStyleSheet)
1634 DBG_ERROR("StyleSheet not found");
1635 return;
1637 pDoc->ApplySelectionStyle( *pStyleSheet, aMarkData );
1640 pDocShell->UpdatePaintExt( nExtFlags, aWorkRange );
1642 if ( !( (pViewShell) && pViewShell->AdjustBlockHeight() ) )
1643 /*A*/ pDocShell->PostPaint( aWorkRange, PAINT_GRID | PAINT_EXTRAS, nExtFlags );
1645 ShowTable( aWorkRange.aStart.Tab() );
1648 void __EXPORT ScUndoSelectionStyle::Undo()
1650 BeginUndo();
1651 DoChange( TRUE );
1652 EndUndo();
1655 void __EXPORT ScUndoSelectionStyle::Redo()
1657 BeginRedo();
1658 DoChange( FALSE );
1659 EndRedo();
1662 void __EXPORT ScUndoSelectionStyle::Repeat(SfxRepeatTarget& rTarget)
1664 if (rTarget.ISA(ScTabViewTarget))
1666 ScDocument* pDoc = pDocShell->GetDocument();
1667 ScStyleSheetPool* pStlPool = pDoc->GetStyleSheetPool();
1668 ScStyleSheet* pStyleSheet = (ScStyleSheet*) pStlPool->
1669 Find( aStyleName, SFX_STYLE_FAMILY_PARA );
1670 if (!pStyleSheet)
1672 DBG_ERROR("StyleSheet not found");
1673 return;
1676 ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
1677 rViewShell.SetStyleSheetToMarked( pStyleSheet, TRUE );
1681 BOOL __EXPORT ScUndoSelectionStyle::CanRepeat(SfxRepeatTarget& rTarget) const
1683 return (rTarget.ISA(ScTabViewTarget));
1686 USHORT __EXPORT ScUndoSelectionStyle::GetId() const
1688 return STR_UNDO_APPLYCELLSTYLE;
1692 // -----------------------------------------------------------------------
1694 // Matrix-Formel eingeben
1697 ScUndoEnterMatrix::ScUndoEnterMatrix( ScDocShell* pNewDocShell, const ScRange& rArea,
1698 ScDocument* pNewUndoDoc, const String& rForm ) :
1699 ScBlockUndo( pNewDocShell, rArea, SC_UNDO_SIMPLE ),
1700 pUndoDoc( pNewUndoDoc ),
1701 aFormula( rForm )
1703 SetChangeTrack();
1706 __EXPORT ScUndoEnterMatrix::~ScUndoEnterMatrix()
1708 delete pUndoDoc;
1711 String __EXPORT ScUndoEnterMatrix::GetComment() const
1713 return ScGlobal::GetRscString( STR_UNDO_ENTERMATRIX );
1716 void ScUndoEnterMatrix::SetChangeTrack()
1718 ScDocument* pDoc = pDocShell->GetDocument();
1719 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
1720 if ( pChangeTrack )
1721 pChangeTrack->AppendContentRange( aBlockRange, pUndoDoc,
1722 nStartChangeAction, nEndChangeAction );
1723 else
1724 nStartChangeAction = nEndChangeAction = 0;
1727 void __EXPORT ScUndoEnterMatrix::Undo()
1729 BeginUndo();
1731 ScDocument* pDoc = pDocShell->GetDocument();
1733 pDoc->DeleteAreaTab( aBlockRange, IDF_ALL );
1734 pUndoDoc->CopyToDocument( aBlockRange, IDF_ALL, FALSE, pDoc );
1735 pDocShell->PostPaint( aBlockRange, PAINT_GRID );
1736 pDocShell->PostDataChanged();
1737 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1738 if (pViewShell)
1739 pViewShell->CellContentChanged();
1741 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
1742 if ( pChangeTrack )
1743 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
1745 EndUndo();
1748 void __EXPORT ScUndoEnterMatrix::Redo()
1750 BeginRedo();
1752 ScDocument* pDoc = pDocShell->GetDocument();
1754 ScMarkData aDestMark;
1755 aDestMark.SelectOneTable( aBlockRange.aStart.Tab() );
1756 aDestMark.SetMarkArea( aBlockRange );
1758 pDoc->InsertMatrixFormula( aBlockRange.aStart.Col(), aBlockRange.aStart.Row(),
1759 aBlockRange.aEnd.Col(), aBlockRange.aEnd.Row(),
1760 aDestMark, aFormula );
1761 // pDocShell->PostPaint( aBlockRange, PAINT_GRID ); // nicht noetig ???
1763 SetChangeTrack();
1765 EndRedo();
1768 void __EXPORT ScUndoEnterMatrix::Repeat(SfxRepeatTarget& rTarget)
1770 if (rTarget.ISA(ScTabViewTarget))
1772 String aTemp = aFormula;
1773 ((ScTabViewTarget&)rTarget).GetViewShell()->EnterMatrix(aTemp);
1777 BOOL __EXPORT ScUndoEnterMatrix::CanRepeat(SfxRepeatTarget& rTarget) const
1779 return (rTarget.ISA(ScTabViewTarget));
1782 // -----------------------------------------------------------------------
1784 // Einzug vermindern / erhoehen
1787 ScRange lcl_GetMultiMarkRange( const ScMarkData& rMark )
1789 DBG_ASSERT( rMark.IsMultiMarked(), "wrong mark type" );
1791 ScRange aRange;
1792 rMark.GetMultiMarkArea( aRange );
1793 return aRange;
1796 ScUndoIndent::ScUndoIndent( ScDocShell* pNewDocShell, const ScMarkData& rMark,
1797 ScDocument* pNewUndoDoc, BOOL bIncrement ) :
1798 ScBlockUndo( pNewDocShell, lcl_GetMultiMarkRange(rMark), SC_UNDO_AUTOHEIGHT ),
1799 aMarkData( rMark ),
1800 pUndoDoc( pNewUndoDoc ),
1801 bIsIncrement( bIncrement )
1805 __EXPORT ScUndoIndent::~ScUndoIndent()
1807 delete pUndoDoc;
1810 String __EXPORT ScUndoIndent::GetComment() const
1812 USHORT nId = bIsIncrement ? STR_UNDO_INC_INDENT : STR_UNDO_DEC_INDENT;
1813 return ScGlobal::GetRscString( nId );
1816 void __EXPORT ScUndoIndent::Undo()
1818 BeginUndo();
1820 ScDocument* pDoc = pDocShell->GetDocument();
1821 SCTAB nTabCount = pDoc->GetTableCount();
1822 ScRange aCopyRange = aBlockRange;
1823 aCopyRange.aStart.SetTab(0);
1824 aCopyRange.aEnd.SetTab(nTabCount-1);
1825 pUndoDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, TRUE, pDoc, &aMarkData );
1826 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
1828 EndUndo();
1831 void __EXPORT ScUndoIndent::Redo()
1833 BeginRedo();
1835 ScDocument* pDoc = pDocShell->GetDocument();
1836 pDoc->ChangeSelectionIndent( bIsIncrement, aMarkData );
1837 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
1839 EndRedo();
1842 void __EXPORT ScUndoIndent::Repeat(SfxRepeatTarget& rTarget)
1844 if (rTarget.ISA(ScTabViewTarget))
1845 ((ScTabViewTarget&)rTarget).GetViewShell()->ChangeIndent( bIsIncrement );
1848 BOOL __EXPORT ScUndoIndent::CanRepeat(SfxRepeatTarget& rTarget) const
1850 return (rTarget.ISA(ScTabViewTarget));
1853 // -----------------------------------------------------------------------
1855 // Transliteration for cells
1858 ScUndoTransliterate::ScUndoTransliterate( ScDocShell* pNewDocShell, const ScMarkData& rMark,
1859 ScDocument* pNewUndoDoc, sal_Int32 nType ) :
1860 ScBlockUndo( pNewDocShell, lcl_GetMultiMarkRange(rMark), SC_UNDO_AUTOHEIGHT ),
1861 aMarkData( rMark ),
1862 pUndoDoc( pNewUndoDoc ),
1863 nTransliterationType( nType )
1867 __EXPORT ScUndoTransliterate::~ScUndoTransliterate()
1869 delete pUndoDoc;
1872 String __EXPORT ScUndoTransliterate::GetComment() const
1874 return ScGlobal::GetRscString( STR_UNDO_TRANSLITERATE );
1877 void __EXPORT ScUndoTransliterate::Undo()
1879 BeginUndo();
1881 ScDocument* pDoc = pDocShell->GetDocument();
1882 SCTAB nTabCount = pDoc->GetTableCount();
1883 ScRange aCopyRange = aBlockRange;
1884 aCopyRange.aStart.SetTab(0);
1885 aCopyRange.aEnd.SetTab(nTabCount-1);
1886 pUndoDoc->CopyToDocument( aCopyRange, IDF_CONTENTS, TRUE, pDoc, &aMarkData );
1887 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
1889 EndUndo();
1892 void __EXPORT ScUndoTransliterate::Redo()
1894 BeginRedo();
1896 ScDocument* pDoc = pDocShell->GetDocument();
1897 pDoc->TransliterateText( aMarkData, nTransliterationType );
1898 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
1900 EndRedo();
1903 void __EXPORT ScUndoTransliterate::Repeat(SfxRepeatTarget& rTarget)
1905 if (rTarget.ISA(ScTabViewTarget))
1906 ((ScTabViewTarget&)rTarget).GetViewShell()->TransliterateText( nTransliterationType );
1909 BOOL __EXPORT ScUndoTransliterate::CanRepeat(SfxRepeatTarget& rTarget) const
1911 return (rTarget.ISA(ScTabViewTarget));
1914 // -----------------------------------------------------------------------
1916 // einzelne Items per Which-IDs aus Bereich loeschen
1919 ScUndoClearItems::ScUndoClearItems( ScDocShell* pNewDocShell, const ScMarkData& rMark,
1920 ScDocument* pNewUndoDoc, const USHORT* pW ) :
1921 ScBlockUndo( pNewDocShell, lcl_GetMultiMarkRange(rMark), SC_UNDO_AUTOHEIGHT ),
1922 aMarkData( rMark ),
1923 pUndoDoc( pNewUndoDoc ),
1924 pWhich( NULL )
1926 DBG_ASSERT( pW, "ScUndoClearItems: Which-Pointer ist 0" );
1928 USHORT nCount = 0;
1929 while ( pW[nCount] )
1930 ++nCount;
1931 pWhich = new USHORT[nCount+1];
1932 for (USHORT i=0; i<=nCount; i++)
1933 pWhich[i] = pW[i];
1936 __EXPORT ScUndoClearItems::~ScUndoClearItems()
1938 delete pUndoDoc;
1939 delete pWhich;
1942 String __EXPORT ScUndoClearItems::GetComment() const
1944 return ScGlobal::GetRscString( STR_UNDO_DELETECONTENTS );
1947 void __EXPORT ScUndoClearItems::Undo()
1949 BeginUndo();
1951 ScDocument* pDoc = pDocShell->GetDocument();
1952 pUndoDoc->CopyToDocument( aBlockRange, IDF_ATTRIB, TRUE, pDoc, &aMarkData );
1953 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
1955 EndUndo();
1958 void __EXPORT ScUndoClearItems::Redo()
1960 BeginRedo();
1962 ScDocument* pDoc = pDocShell->GetDocument();
1963 pDoc->ClearSelectionItems( pWhich, aMarkData );
1964 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
1966 EndRedo();
1969 void __EXPORT ScUndoClearItems::Repeat(SfxRepeatTarget& rTarget)
1971 if (rTarget.ISA(ScTabViewTarget))
1973 ScViewData* pViewData = ((ScTabViewTarget&)rTarget).GetViewShell()->GetViewData();
1974 ScDocFunc aFunc(*pViewData->GetDocShell());
1975 aFunc.ClearItems( pViewData->GetMarkData(), pWhich, FALSE );
1979 BOOL __EXPORT ScUndoClearItems::CanRepeat(SfxRepeatTarget& rTarget) const
1981 return (rTarget.ISA(ScTabViewTarget));
1984 // -----------------------------------------------------------------------
1986 // Alle Umbrueche einer Tabelle loeschen
1989 ScUndoRemoveBreaks::ScUndoRemoveBreaks( ScDocShell* pNewDocShell,
1990 SCTAB nNewTab, ScDocument* pNewUndoDoc ) :
1991 ScSimpleUndo( pNewDocShell ),
1992 nTab( nNewTab ),
1993 pUndoDoc( pNewUndoDoc )
1997 __EXPORT ScUndoRemoveBreaks::~ScUndoRemoveBreaks()
1999 delete pUndoDoc;
2002 String __EXPORT ScUndoRemoveBreaks::GetComment() const
2004 return ScGlobal::GetRscString( STR_UNDO_REMOVEBREAKS );
2007 void __EXPORT ScUndoRemoveBreaks::Undo()
2009 BeginUndo();
2011 ScDocument* pDoc = pDocShell->GetDocument();
2012 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
2014 pUndoDoc->CopyToDocument( 0,0,nTab, MAXCOL,MAXROW,nTab, IDF_NONE, FALSE, pDoc );
2015 if (pViewShell)
2016 pViewShell->UpdatePageBreakData( TRUE );
2017 pDocShell->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
2019 EndUndo();
2022 void __EXPORT ScUndoRemoveBreaks::Redo()
2024 BeginRedo();
2026 ScDocument* pDoc = pDocShell->GetDocument();
2027 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
2029 pDoc->RemoveManualBreaks(nTab);
2030 pDoc->UpdatePageBreaks(nTab);
2031 if (pViewShell)
2032 pViewShell->UpdatePageBreakData( TRUE );
2033 pDocShell->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
2035 EndRedo();
2038 void __EXPORT ScUndoRemoveBreaks::Repeat(SfxRepeatTarget& rTarget)
2040 if (rTarget.ISA(ScTabViewTarget))
2042 ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
2043 rViewShell.RemoveManualBreaks();
2047 BOOL __EXPORT ScUndoRemoveBreaks::CanRepeat(SfxRepeatTarget& rTarget) const
2049 return (rTarget.ISA(ScTabViewTarget));
2052 // -----------------------------------------------------------------------
2054 // Zusammenfassung aufheben (fuer einen ganzen Bereich)
2057 ScUndoRemoveMerge::ScUndoRemoveMerge( ScDocShell* pNewDocShell,
2058 const ScCellMergeOption& rOption, ScDocument* pNewUndoDoc ) :
2059 ScBlockUndo( pNewDocShell, rOption.getFirstSingleRange(), SC_UNDO_SIMPLE ),
2060 maOption(rOption),
2061 pUndoDoc( pNewUndoDoc )
2065 __EXPORT ScUndoRemoveMerge::~ScUndoRemoveMerge()
2067 delete pUndoDoc;
2070 String __EXPORT ScUndoRemoveMerge::GetComment() const
2072 return ScGlobal::GetRscString( STR_UNDO_REMERGE ); // "Zusammenfassung aufheben"
2075 void __EXPORT ScUndoRemoveMerge::Undo()
2077 using ::std::set;
2079 SetCurTab();
2080 BeginUndo();
2082 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
2084 ScDocument* pDoc = pDocShell->GetDocument();
2085 for (set<SCTAB>::const_iterator itr = maOption.maTabs.begin(), itrEnd = maOption.maTabs.end();
2086 itr != itrEnd; ++itr)
2088 // There is no need to extend merge area because it's already been extended.
2089 ScRange aRange = maOption.getSingleRange(*itr);
2090 pDoc->DeleteAreaTab(aRange, IDF_ATTRIB);
2091 pUndoDoc->CopyToDocument(aRange, IDF_ATTRIB, FALSE, pDoc);
2093 bool bDidPaint = false;
2094 if ( pViewShell )
2096 pViewShell->SetTabNo(*itr);
2097 bDidPaint = pViewShell->AdjustRowHeight(maOption.mnStartRow, maOption.mnEndRow);
2099 if (!bDidPaint)
2100 ScUndoUtil::PaintMore(pDocShell, aRange);
2103 EndUndo();
2106 void __EXPORT ScUndoRemoveMerge::Redo()
2108 using ::std::set;
2110 SetCurTab();
2111 BeginRedo();
2113 ScDocument* pDoc = pDocShell->GetDocument();
2114 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
2116 for (set<SCTAB>::const_iterator itr = maOption.maTabs.begin(), itrEnd = maOption.maTabs.end();
2117 itr != itrEnd; ++itr)
2119 SCTAB nTab = *itr;
2120 // There is no need to extend merge area because it's already been extended.
2121 ScRange aRange = maOption.getSingleRange(nTab);
2123 // ausfuehren
2125 const SfxPoolItem& rDefAttr = pDoc->GetPool()->GetDefaultItem( ATTR_MERGE );
2126 ScPatternAttr aPattern( pDoc->GetPool() );
2127 aPattern.GetItemSet().Put( rDefAttr );
2128 pDoc->ApplyPatternAreaTab( maOption.mnStartCol, maOption.mnStartRow,
2129 maOption.mnEndCol, maOption.mnEndRow, nTab,
2130 aPattern );
2132 pDoc->RemoveFlagsTab( maOption.mnStartCol, maOption.mnStartRow,
2133 maOption.mnEndCol, maOption.mnEndRow, nTab,
2134 SC_MF_HOR | SC_MF_VER );
2136 pDoc->ExtendMerge(aRange, TRUE, FALSE);
2138 // Paint
2140 BOOL bDidPaint = FALSE;
2141 if ( pViewShell )
2143 pViewShell->SetTabNo(nTab);
2144 bDidPaint = pViewShell->AdjustRowHeight(maOption.mnStartRow, maOption.mnEndRow);
2146 if (!bDidPaint)
2147 ScUndoUtil::PaintMore(pDocShell, aRange);
2150 EndRedo();
2153 void __EXPORT ScUndoRemoveMerge::Repeat(SfxRepeatTarget& rTarget)
2155 if (rTarget.ISA(ScTabViewTarget))
2156 ((ScTabViewTarget&)rTarget).GetViewShell()->RemoveMerge();
2159 BOOL __EXPORT ScUndoRemoveMerge::CanRepeat(SfxRepeatTarget& rTarget) const
2161 return (rTarget.ISA(ScTabViewTarget));
2164 void ScUndoRemoveMerge::SetCurTab()
2166 SCTAB nCurTab = pDocShell->GetCurTab();
2167 aBlockRange.aStart.SetTab(nCurTab);
2168 aBlockRange.aEnd.SetTab(nCurTab);
2171 // -----------------------------------------------------------------------
2173 // nur Umrandung setzen, per ScRangeList (StarOne)
2176 ScRange lcl_TotalRange( const ScRangeList& rRanges )
2178 ScRange aTotal;
2179 ULONG nCount = rRanges.Count();
2180 for (ULONG i=0; i<nCount; i++)
2182 ScRange aRange = *rRanges.GetObject(i);
2183 if (i==0)
2184 aTotal = aRange;
2185 else
2187 if (aRange.aStart.Col() < aTotal.aStart.Col())
2188 aTotal.aStart.SetCol(aRange.aStart.Col());
2189 if (aRange.aStart.Row() < aTotal.aStart.Row())
2190 aTotal.aStart.SetRow(aRange.aStart.Row());
2191 if (aRange.aStart.Tab() < aTotal.aStart.Tab())
2192 aTotal.aStart.SetTab(aRange.aStart.Tab());
2193 if (aRange.aEnd.Col() > aTotal.aEnd.Col())
2194 aTotal.aEnd.SetCol(aRange.aEnd.Col());
2195 if (aRange.aEnd.Row() > aTotal.aEnd.Row())
2196 aTotal.aEnd.SetRow(aRange.aEnd.Row());
2197 if (aRange.aEnd.Tab() > aTotal.aEnd.Tab())
2198 aTotal.aEnd.SetTab(aRange.aEnd.Tab());
2201 return aTotal;
2204 ScUndoBorder::ScUndoBorder( ScDocShell* pNewDocShell,
2205 const ScRangeList& rRangeList, ScDocument* pNewUndoDoc,
2206 const SvxBoxItem& rNewOuter, const SvxBoxInfoItem& rNewInner ) :
2207 ScBlockUndo( pNewDocShell, lcl_TotalRange(rRangeList), SC_UNDO_SIMPLE ),
2208 pUndoDoc( pNewUndoDoc )
2210 pRanges = new ScRangeList(rRangeList);
2211 pOuter = new SvxBoxItem(rNewOuter);
2212 pInner = new SvxBoxInfoItem(rNewInner);
2215 __EXPORT ScUndoBorder::~ScUndoBorder()
2217 delete pUndoDoc;
2218 delete pRanges;
2219 delete pOuter;
2220 delete pInner;
2223 String __EXPORT ScUndoBorder::GetComment() const
2225 return ScGlobal::GetRscString( STR_UNDO_SELATTRLINES ); //! eigener String?
2228 void __EXPORT ScUndoBorder::Undo()
2230 BeginUndo();
2232 ScDocument* pDoc = pDocShell->GetDocument();
2233 ScMarkData aMarkData;
2234 aMarkData.MarkFromRangeList( *pRanges, FALSE );
2235 pUndoDoc->CopyToDocument( aBlockRange, IDF_ATTRIB, TRUE, pDoc, &aMarkData );
2236 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
2238 EndUndo();
2241 void __EXPORT ScUndoBorder::Redo()
2243 BeginRedo();
2245 ScDocument* pDoc = pDocShell->GetDocument(); //! Funktion an docfunc aufrufen
2246 ULONG nCount = pRanges->Count();
2247 ULONG i;
2248 for (i=0; i<nCount; i++)
2250 ScRange aRange = *pRanges->GetObject(i);
2251 SCTAB nTab = aRange.aStart.Tab();
2253 ScMarkData aMark;
2254 aMark.SetMarkArea( aRange );
2255 aMark.SelectTable( nTab, TRUE );
2257 pDoc->ApplySelectionFrame( aMark, pOuter, pInner );
2259 for (i=0; i<nCount; i++)
2260 pDocShell->PostPaint( *pRanges->GetObject(i), PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
2262 EndRedo();
2265 void __EXPORT ScUndoBorder::Repeat(SfxRepeatTarget& /* rTarget */)
2267 //! spaeter (wenn die Funktion aus cellsuno nach docfunc gewandert ist)
2270 BOOL __EXPORT ScUndoBorder::CanRepeat(SfxRepeatTarget& /* rTarget */) const
2272 return FALSE; // s.o.