1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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"
32 #include "tabvwsh.hxx"
33 #include "rangenam.hxx"
34 #include "rangeutl.hxx"
36 #include "stlpool.hxx"
37 #include "stlsheet.hxx"
38 #include "globstr.hrc"
41 #include "docpool.hxx"
42 #include "docfunc.hxx"
44 #include "chgtrack.hxx"
45 #include "transobj.hxx"
46 #include "refundo.hxx"
47 #include "undoolk.hxx"
48 #include "clipparam.hxx"
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>
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
);
82 /*A*/ // SetOptimalHeight on Document, if no View
83 /*B*/ // linked sheets
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
),
95 pScenarios( pNewScenarios
),
97 bPartOfPaste( bNewPartOfPaste
),
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
);
115 ScUndoInsertCells::~ScUndoInsertCells()
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.
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
148 // Call base class for detective handling
149 return ScMoveUndo::Merge( pNextAction
);
152 void ScUndoInsertCells::SetChangeTrack()
154 ScChangeTrack
* pChangeTrack
= pDocShell
->GetDocument().GetChangeTrack();
157 pChangeTrack
->AppendInsert( aEffRange
);
158 nEndChangeAction
= pChangeTrack
->GetActionMax();
161 nEndChangeAction
= 0;
164 void ScUndoInsertCells::DoChange( const bool bUndo
)
166 ScDocument
& rDoc
= pDocShell
->GetDocument();
171 ScChangeTrack
* pChangeTrack
= rDoc
.GetChangeTrack();
173 pChangeTrack
->Undo( nEndChangeAction
, nEndChangeAction
);
178 // refresh of merged cells has to be after inserting/deleting
184 for( i
=0; i
<nCount
; i
++ )
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));
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));
196 for( i
=0; i
<nCount
; i
++ )
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));
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));
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();
233 nPaint
|= PAINT_LEFT
;
234 aWorkRange
.aEnd
.SetRow(MAXROW
);
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
;
249 nPaint
|= PAINT_TOP
; // top bar
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
;
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();
275 pViewShell
->CellContentChanged();
278 void ScUndoInsertCells::Undo()
281 pPasteUndo
->Undo(); // undo paste first
283 WaitObject
aWait( ScDocShell::GetActiveDialogParent() ); // important due to TrackFormulas in UpdateReference
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
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
))
314 // Repeat for paste with inserting cells is handled completely
315 // by the Paste undo action
317 pPasteUndo
->Repeat( rTarget
);
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
),
336 pScenarios( pNewScenarios
),
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
);
354 ScUndoDeleteCells::~ScUndoDeleteCells()
360 OUString
ScUndoDeleteCells::GetComment() const
362 return ScGlobal::GetRscString( STR_UNDO_DELETECELLS
); // "Delete"
365 void ScUndoDeleteCells::SetChangeTrack()
367 ScChangeTrack
* pChangeTrack
= pDocShell
->GetDocument().GetChangeTrack();
369 pChangeTrack
->AppendDeleteRange( aEffRange
, pRefUndoDoc
,
370 nStartChangeAction
, nEndChangeAction
);
372 nStartChangeAction
= nEndChangeAction
= 0;
375 void ScUndoDeleteCells::DoChange( const bool bUndo
)
377 ScDocument
& rDoc
= pDocShell
->GetDocument();
382 ScChangeTrack
* pChangeTrack
= rDoc
.GetChangeTrack();
384 pChangeTrack
->Undo( nStartChangeAction
, nEndChangeAction
);
393 for( i
=0; i
<nCount
; i
++ )
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));
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));
405 for( i
=0; i
<nCount
; i
++ )
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));
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));
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
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 );
462 sal_uInt16 nPaint
= PAINT_GRID
;
466 nPaint
|= PAINT_LEFT
;
467 aWorkRange
.aEnd
.SetRow(MAXROW
);
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
;
482 nPaint
|= PAINT_TOP
; // top bar
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
;
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
518 SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED
) );
520 // Selection not until EndUndo
521 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
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
541 SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED
) );
543 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
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
),
571 mbRefresh(bNeedsRefresh
),
578 ScUndoDeleteMulti::~ScUndoDeleteMulti()
582 OUString
ScUndoDeleteMulti::GetComment() const
584 return ScGlobal::GetRscString( STR_UNDO_DELETECELLS
); // like DeleteCells
587 void ScUndoDeleteMulti::DoChange() const
595 nStartRow
= static_cast<SCROW
>(maSpans
[0].mnStart
);
596 nPaint
= PAINT_GRID
| PAINT_LEFT
;
600 nStartCol
= static_cast<SCCOL
>(maSpans
[0].mnStart
);
602 nPaint
= PAINT_GRID
| PAINT_TOP
;
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();
618 pViewShell
->CellContentChanged();
623 void ScUndoDeleteMulti::SetChangeTrack()
625 ScChangeTrack
* pChangeTrack
= pDocShell
->GetDocument().GetChangeTrack();
628 nStartChangeAction
= pChangeTrack
->GetActionMax() + 1;
629 ScRange
aRange( 0, 0, nTab
, 0, 0, nTab
);
631 aRange
.aEnd
.SetCol( MAXCOL
);
633 aRange
.aEnd
.SetRow( MAXROW
);
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
;
642 aRange
.aStart
.SetRow( nStart
);
643 aRange
.aEnd
.SetRow( nEnd
);
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
);
656 nStartChangeAction
= nEndChangeAction
= 0;
659 void ScUndoDeleteMulti::Undo()
661 WaitObject
aWait( ScDocShell::GetActiveDialogParent() ); // important because of TrackFormulas in UpdateReference
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
;
673 rDoc
.InsertRow( 0,nTab
, MAXCOL
,nTab
, nStart
,static_cast<SCSIZE
>(nEnd
-nStart
+1) );
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
;
684 pRefUndoDoc
->CopyToDocument( 0,nStart
,nTab
, MAXCOL
,nEnd
,nTab
, IDF_ALL
,false, &rDoc
);
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();
692 pChangeTrack
->Undo( nStartChangeAction
, nEndChangeAction
);
696 //! redrawing the selection is not possible at the moment
697 //! since no data for selection exist
700 SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED
) );
703 void ScUndoDeleteMulti::Redo()
705 WaitObject
aWait( ScDocShell::GetActiveDialogParent() ); // important because of TrackFormulas in UpdateReference
708 ScDocument
& rDoc
= pDocShell
->GetDocument();
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
;
717 rDoc
.DeleteRow( 0,nTab
, MAXCOL
,nTab
, nStart
,static_cast<SCSIZE
>(nEnd
-nStart
+1) );
719 rDoc
.DeleteCol( 0,nTab
, MAXROW
,nTab
, static_cast<SCCOL
>(nStart
), static_cast<SCSIZE
>(nEnd
-nStart
+1) );
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
),
747 pUndoDoc( pNewUndoDoc
),
748 aExtendedRange( aRange
)
753 ScUndoCut::~ScUndoCut()
758 OUString
ScUndoCut::GetComment() const
760 return ScGlobal::GetRscString( STR_UNDO_CUT
); // "cut"
763 void ScUndoCut::SetChangeTrack()
765 ScChangeTrack
* pChangeTrack
= pDocShell
->GetDocument().GetChangeTrack();
767 pChangeTrack
->AppendContentRange( aBlockRange
, pUndoDoc
,
768 nStartChangeAction
, nEndChangeAction
, SC_CACM_CUT
);
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();
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
);
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();
812 pViewShell
->CellContentChanged();
815 void ScUndoCut::Undo()
822 void ScUndoCut::Redo()
825 ScDocument
& rDoc
= pDocShell
->GetDocument();
826 EnableDrawAdjust( &rDoc
, false ); //! include in ScBlockUndo?
828 EnableDrawAdjust( &rDoc
, true ); //! include in ScBlockUndo?
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
),
851 pUndoDoc( pNewUndoDoc
),
852 pRedoDoc( pNewRedoDoc
),
854 pRefUndoData( pRefData
),
855 pRefRedoData( NULL
),
856 bRedoFilled( bRedoIsFilled
)
859 pRefUndoData
->DeleteUnchanged( &pDocShell
->GetDocument() );
862 aPasteOptions
= *pOptions
; // used only for Repeat
867 ScUndoPaste::~ScUndoPaste()
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
);
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
)
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
)
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
);
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
)
979 aRange
.aStart
.SetTab(*itr
);
980 aRange
.aEnd
.SetTab(*itr
);
981 pRedoDoc
->CopyToDocument( aRange
, nUndoFlags
, false, &rDoc
);
988 pWorkRefData
->DoUndo( &rDoc
, true ); // true = bSetChartRangeLists for SetChartListenerCollection
989 if (!maBlockRanges
.empty() &&
990 rDoc
.RefreshAutoFilter(0, 0, MAXCOL
, MAXROW
, maBlockRanges
[0]->aStart
.Tab()))
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
);
1014 ScChangeTrack
* pChangeTrack
= rDoc
.GetChangeTrack();
1016 pChangeTrack
->Undo( nStartChangeAction
, nEndChangeAction
);
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.)
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
;
1035 pViewShell
->AdjustBlockHeight(false);
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();
1068 pViewShell
->CellContentChanged();
1071 void ScUndoPaste::Undo()
1075 if (!maBlockRanges
.empty())
1076 ShowTable(*maBlockRanges
.front());
1078 SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED
) );
1081 void ScUndoPaste::Redo()
1084 ScDocument
& rDoc
= pDocShell
->GetDocument();
1085 EnableDrawAdjust( &rDoc
, false ); //! include in ScBlockUndo?
1087 EnableDrawAdjust( &rDoc
, true ); //! include in ScBlockUndo?
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() );
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
),
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 )
1138 aDestEnd
.SetRow( aNewDestPos
.Row() + nPastedCount
- 1 );
1141 aDestRange
.aStart
= aNewDestPos
;
1142 aDestRange
.aEnd
= aDestEnd
;
1147 ScUndoDragDrop::~ScUndoDragDrop()
1151 OUString
ScUndoDragDrop::GetComment() const
1152 { // "Move" : "Copy"
1154 ScGlobal::GetRscString( STR_UNDO_MOVE
) :
1155 ScGlobal::GetRscString( STR_UNDO_COPY
);
1158 void ScUndoDragDrop::SetChangeTrack()
1160 ScChangeTrack
* pChangeTrack
= pDocShell
->GetDocument().GetChangeTrack();
1165 nStartChangeAction
= pChangeTrack
->GetActionMax() + 1;
1166 pChangeTrack
->AppendMove( aSrcRange
, aDestRange
, pRefUndoDoc
);
1167 nEndChangeAction
= pChangeTrack
->GetActionMax();
1170 pChangeTrack
->AppendContentRange( aDestRange
, pRefUndoDoc
,
1171 nStartChangeAction
, nEndChangeAction
);
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();
1185 ScopedVclPtrInstance
< VirtualDevice
> pVirtDev
;
1186 ScViewData
& rViewData
= pViewShell
->GetViewData();
1187 sc::RowHeightContext
aCxt(
1188 rViewData
.GetPPTX(), rViewData
.GetPPTY(), rViewData
.GetZoomX(), rViewData
.GetZoomY(),
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();
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
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
);
1263 class DataChangeNotifier
: std::unary_function
<SvtListener
*, void>
1267 DataChangeNotifier() : maHint(SC_HINT_DATACHANGED
, ScAddress()) {}
1269 void operator() ( SvtListener
* p
)
1277 void ScUndoDragDrop::Undo()
1279 mnPaintExtFlags
= 0;
1280 maPaintRanges
.RemoveAll();
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();
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
);
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();
1322 // Update the references of validation entries.
1323 pValidList
->UpdateReference(aCxt
);
1329 // Notify all area listeners whose listened areas are partially moved, to
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());
1344 for (size_t i
= 0; i
< maPaintRanges
.size(); ++i
)
1346 const ScRange
* p
= maPaintRanges
[i
];
1347 PaintArea(*p
, mnPaintExtFlags
);
1351 SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED
) );
1354 void ScUndoDragDrop::Redo()
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. */
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);
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
);
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 );
1429 ShowTable( aDestRange
.aStart
.Tab() );
1431 RedoSdrUndoAction( pDrawUndo
); //! include in ScBlockUndo?
1432 EnableDrawAdjust( &rDoc
, true ); //! include in ScBlockUndo?
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()
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();
1478 pViewShell
->CellContentChanged();
1481 void ScUndoListNames::Undo()
1488 void ScUndoListNames::Redo()
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
),
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();
1544 pViewShell
->CellContentChanged();
1547 void ScUndoConditionalFormat::Repeat(SfxRepeatTarget
& )
1551 bool ScUndoConditionalFormat::CanRepeat(SfxRepeatTarget
& ) const
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
),
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()
1579 OUString
ScUndoUseScenario::GetComment() const
1581 return ScGlobal::GetRscString( STR_UNDO_USESCENARIO
);
1584 void ScUndoUseScenario::Undo()
1588 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
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
);
1600 bool bFrame
= false;
1601 SCTAB nTab
= aRange
.aStart
.Tab();
1602 SCTAB nEndTab
= nTab
;
1603 while ( pUndoDoc
->HasTable(nEndTab
+1) && pUndoDoc
->IsScenario(nEndTab
+1) )
1605 for (SCTAB i
= nTab
+1; i
<=nEndTab
; i
++)
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
)
1625 // if visible borders, then paint all
1627 pDocShell
->PostPaint( 0,0,nTab
, MAXCOL
,MAXROW
,nTab
, PAINT_GRID
| PAINT_EXTRAS
);
1629 pDocShell
->PostPaint( aRange
, PAINT_GRID
| PAINT_EXTRAS
);
1630 pDocShell
->PostDataChanged();
1632 pViewShell
->CellContentChanged();
1634 ShowTable( aRange
.aStart
.Tab() );
1639 void ScUndoUseScenario::Redo()
1641 SCTAB nTab
= aRange
.aStart
.Tab();
1644 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
1647 pViewShell
->SetTabNo( nTab
);
1648 pViewShell
->DoneBlockMode();
1649 pViewShell
->InitOwnBlockMode();
1652 pDocShell
->UseScenario( nTab
, aName
, false );
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() );
1676 ScUndoSelectionStyle::ScUndoSelectionStyle( ScDocShell
* pNewDocShell
,
1677 const ScMarkData
& rMark
,
1678 const ScRange
& rRange
,
1679 const OUString
& rName
,
1680 ScDocument
* pNewUndoDoc
) :
1681 ScSimpleUndo( pNewDocShell
),
1683 pUndoDoc( pNewUndoDoc
),
1684 aStyleName( rName
),
1687 aMarkData
.MarkToMulti();
1690 ScUndoSelectionStyle::~ScUndoSelectionStyle()
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
) );
1728 OSL_FAIL("StyleSheet not found");
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()
1750 void ScUndoSelectionStyle::Redo()
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
));
1767 OSL_FAIL("StyleSheet not found");
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
),
1795 ScUndoEnterMatrix::~ScUndoEnterMatrix()
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();
1810 pChangeTrack
->AppendContentRange( aBlockRange
, pUndoDoc
,
1811 nStartChangeAction
, nEndChangeAction
);
1813 nStartChangeAction
= nEndChangeAction
= 0;
1816 void ScUndoEnterMatrix::Undo()
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();
1828 pViewShell
->CellContentChanged();
1830 ScChangeTrack
* pChangeTrack
= rDoc
.GetChangeTrack();
1832 pChangeTrack
->Undo( nStartChangeAction
, nEndChangeAction
);
1837 void ScUndoEnterMatrix::Redo()
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
);
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" );
1876 rMark
.GetMultiMarkArea( aRange
);
1880 ScUndoIndent::ScUndoIndent( ScDocShell
* pNewDocShell
, const ScMarkData
& rMark
,
1881 ScDocument
* pNewUndoDoc
, bool bIncrement
) :
1882 ScBlockUndo( pNewDocShell
, lcl_GetMultiMarkRange(rMark
), SC_UNDO_AUTOHEIGHT
),
1884 pUndoDoc( pNewUndoDoc
),
1885 bIsIncrement( bIncrement
)
1889 ScUndoIndent::~ScUndoIndent()
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()
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
);
1915 void ScUndoIndent::Redo()
1919 ScDocument
& rDoc
= pDocShell
->GetDocument();
1920 rDoc
.ChangeSelectionIndent( bIsIncrement
, aMarkData
);
1921 pDocShell
->PostPaint( aBlockRange
, PAINT_GRID
, SC_PF_LINES
| SC_PF_TESTMERGE
);
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
),
1941 pUndoDoc( pNewUndoDoc
),
1942 nTransliterationType( nType
)
1946 ScUndoTransliterate::~ScUndoTransliterate()
1951 OUString
ScUndoTransliterate::GetComment() const
1953 return ScGlobal::GetRscString( STR_UNDO_TRANSLITERATE
);
1956 void ScUndoTransliterate::Undo()
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
);
1971 void ScUndoTransliterate::Redo()
1975 ScDocument
& rDoc
= pDocShell
->GetDocument();
1976 rDoc
.TransliterateText( aMarkData
, nTransliterationType
);
1977 pDocShell
->PostPaint( aBlockRange
, PAINT_GRID
, SC_PF_LINES
| SC_PF_TESTMERGE
);
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
),
1997 pUndoDoc( pNewUndoDoc
),
2000 OSL_ENSURE( pW
, "ScUndoClearItems: Which-Pointer ist 0" );
2002 sal_uInt16 nCount
= 0;
2003 while ( pW
[nCount
] )
2005 pWhich
= new sal_uInt16
[nCount
+1];
2006 for (sal_uInt16 i
=0; i
<=nCount
; i
++)
2010 ScUndoClearItems::~ScUndoClearItems()
2016 OUString
ScUndoClearItems::GetComment() const
2018 return ScGlobal::GetRscString( STR_UNDO_DELETECONTENTS
);
2021 void ScUndoClearItems::Undo()
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
);
2032 void ScUndoClearItems::Redo()
2036 ScDocument
& rDoc
= pDocShell
->GetDocument();
2037 rDoc
.ClearSelectionItems( pWhich
, aMarkData
);
2038 pDocShell
->PostPaint( aBlockRange
, PAINT_GRID
, SC_PF_LINES
| SC_PF_TESTMERGE
);
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
),
2062 pUndoDoc( pNewUndoDoc
)
2066 ScUndoRemoveBreaks::~ScUndoRemoveBreaks()
2071 OUString
ScUndoRemoveBreaks::GetComment() const
2073 return ScGlobal::GetRscString( STR_UNDO_REMOVEBREAKS
);
2076 void ScUndoRemoveBreaks::Undo()
2080 ScDocument
& rDoc
= pDocShell
->GetDocument();
2081 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
2083 pUndoDoc
->CopyToDocument( 0,0,nTab
, MAXCOL
,MAXROW
,nTab
, IDF_NONE
, false, &rDoc
);
2085 pViewShell
->UpdatePageBreakData( true );
2086 pDocShell
->PostPaint( 0,0,nTab
, MAXCOL
,MAXROW
,nTab
, PAINT_GRID
);
2091 void ScUndoRemoveBreaks::Redo()
2095 ScDocument
& rDoc
= pDocShell
->GetDocument();
2096 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
2098 rDoc
.RemoveManualBreaks(nTab
);
2099 rDoc
.UpdatePageBreaks(nTab
);
2101 pViewShell
->UpdatePageBreakData( true );
2102 pDocShell
->PostPaint( 0,0,nTab
, MAXCOL
,MAXROW
,nTab
, PAINT_GRID
);
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
),
2125 pUndoDoc( pNewUndoDoc
)
2129 ScUndoRemoveMerge::~ScUndoRemoveMerge()
2134 OUString
ScUndoRemoveMerge::GetComment() const
2136 return ScGlobal::GetRscString( STR_UNDO_REMERGE
); // "remove merge"
2139 void ScUndoRemoveMerge::Undo()
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!");
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;
2163 pViewShell
->SetTabNo(*itr
);
2164 bDidPaint
= pViewShell
->AdjustRowHeight(maOption
.mnStartRow
, maOption
.mnEndRow
);
2167 ScUndoUtil::PaintMore(pDocShell
, aRange
);
2173 void ScUndoRemoveMerge::Redo()
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
)
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
,
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);
2205 bool bDidPaint
= false;
2208 pViewShell
->SetTabNo(nTab
);
2209 bDidPaint
= pViewShell
->AdjustRowHeight(maOption
.mnStartRow
, maOption
.mnEndRow
);
2212 ScUndoUtil::PaintMore(pDocShell
, aRange
);
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
)
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() );
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()
2276 OUString
ScUndoBorder::GetComment() const
2278 return ScGlobal::GetRscString( STR_UNDO_SELATTRLINES
); //! eigener String?
2281 void ScUndoBorder::Undo()
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
);
2294 void ScUndoBorder::Redo()
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();
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
);
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: */