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 <sal/config.h>
24 #include <scitems.hxx>
25 #include <editeng/boxitem.hxx>
26 #include <editeng/justifyitem.hxx>
27 #include <svl/srchitem.hxx>
28 #include <sfx2/linkmgr.hxx>
30 #include <vcl/virdev.hxx>
31 #include <sfx2/app.hxx>
32 #include <svx/svdundo.hxx>
33 #include <osl/diagnose.h>
35 #include <undoblk.hxx>
36 #include <globstr.hrc>
37 #include <scresid.hxx>
39 #include <arealink.hxx>
40 #include <patattr.hxx>
42 #include <document.hxx>
43 #include <docpool.hxx>
45 #include <tabvwsh.hxx>
46 #include <undoolk.hxx>
47 #include <undoutil.hxx>
48 #include <chgtrack.hxx>
49 #include <paramisc.hxx>
51 #include <progress.hxx>
52 #include <editutil.hxx>
53 #include <editdataarray.hxx>
54 #include <rowheightcontext.hxx>
57 /*A*/ // SetOptimalHeight on Document, when no View
59 ScUndoDeleteContents::ScUndoDeleteContents(
60 ScDocShell
* pNewDocShell
,
61 const ScMarkData
& rMark
, const ScRange
& rRange
,
62 ScDocumentUniquePtr
&& pNewUndoDoc
, bool bNewMulti
,
63 InsertDeleteFlags nNewFlags
, bool bObjects
)
64 : ScSimpleUndo( pNewDocShell
),
67 pUndoDoc ( std::move(pNewUndoDoc
) ),
69 bMulti ( bNewMulti
) // unnecessary
72 pDrawUndo
= GetSdrUndoAction( &pDocShell
->GetDocument() );
74 if ( !(aMarkData
.IsMarked() || aMarkData
.IsMultiMarked()) ) // if no cell is selected:
75 aMarkData
.SetMarkArea( aRange
); // select cell under cursor
80 ScUndoDeleteContents::~ScUndoDeleteContents()
86 OUString
ScUndoDeleteContents::GetComment() const
88 return ScResId( STR_UNDO_DELETECONTENTS
); // "Delete"
91 void ScUndoDeleteContents::SetDataSpans( const std::shared_ptr
<DataSpansType
>& pSpans
)
96 void ScUndoDeleteContents::SetChangeTrack()
98 ScChangeTrack
* pChangeTrack
= pDocShell
->GetDocument().GetChangeTrack();
99 if ( pChangeTrack
&& (nFlags
& InsertDeleteFlags::CONTENTS
) )
100 pChangeTrack
->AppendContentRange( aRange
, pUndoDoc
.get(),
101 nStartChangeAction
, nEndChangeAction
);
103 nStartChangeAction
= nEndChangeAction
= 0;
106 void ScUndoDeleteContents::DoChange( const bool bUndo
)
108 ScDocument
& rDoc
= pDocShell
->GetDocument();
110 SetViewMarkData( aMarkData
);
112 sal_uInt16 nExtFlags
= 0;
114 if (bUndo
) // only Undo
116 InsertDeleteFlags nUndoFlags
= InsertDeleteFlags::NONE
; // copy either all or none of the content
117 if (nFlags
& InsertDeleteFlags::CONTENTS
) // (Only the correct ones have been copied into UndoDoc)
118 nUndoFlags
|= InsertDeleteFlags::CONTENTS
;
119 if (nFlags
& InsertDeleteFlags::ATTRIB
)
120 nUndoFlags
|= InsertDeleteFlags::ATTRIB
;
121 if (nFlags
& InsertDeleteFlags::EDITATTR
) // Edit-Engine attribute
122 nUndoFlags
|= InsertDeleteFlags::STRING
; // -> Cells will be changed
123 if (nFlags
& InsertDeleteFlags::SPARKLINES
)
124 nUndoFlags
|= InsertDeleteFlags::SPARKLINES
;
125 // do not create clones of note captions, they will be restored via drawing undo
126 nUndoFlags
|= InsertDeleteFlags::NOCAPTIONS
;
128 ScRange aCopyRange
= aRange
;
129 SCTAB nTabCount
= rDoc
.GetTableCount();
130 aCopyRange
.aStart
.SetTab(0);
131 aCopyRange
.aEnd
.SetTab(nTabCount
-1);
133 pUndoDoc
->CopyToDocument(aCopyRange
, nUndoFlags
, bMulti
, rDoc
, &aMarkData
);
135 DoSdrUndoAction( pDrawUndo
.get(), &rDoc
);
137 ScChangeTrack
* pChangeTrack
= rDoc
.GetChangeTrack();
139 pChangeTrack
->Undo( nStartChangeAction
, nEndChangeAction
);
141 pDocShell
->UpdatePaintExt( nExtFlags
, aRange
); // content after the change
145 pDocShell
->UpdatePaintExt( nExtFlags
, aRange
); // content before the change
147 aMarkData
.MarkToMulti();
148 RedoSdrUndoAction( pDrawUndo
.get() );
149 // do not delete objects and note captions, they have been removed via drawing undo
150 InsertDeleteFlags nRedoFlags
= (nFlags
& ~InsertDeleteFlags::OBJECTS
) | InsertDeleteFlags::NOCAPTIONS
;
151 rDoc
.DeleteSelection( nRedoFlags
, aMarkData
);
152 aMarkData
.MarkToSimple();
157 if (nFlags
& InsertDeleteFlags::CONTENTS
)
159 // Broadcast only when the content changes. fdo#74687
161 BroadcastChanges(*mpDataSpans
);
163 BroadcastChanges(aRange
);
166 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
167 if ( !( pViewShell
&& pViewShell
->AdjustRowHeight(
168 aRange
.aStart
.Row(), aRange
.aEnd
.Row(), true ) ) )
169 /*A*/ pDocShell
->PostPaint( aRange
, PaintPartFlags::Grid
| PaintPartFlags::Extras
, nExtFlags
);
172 pViewShell
->CellContentChanged();
177 void ScUndoDeleteContents::Undo()
183 HelperNotifyChanges::NotifyIfChangesListeners(*pDocShell
, aRange
, u
"undo"_ustr
);
186 void ScUndoDeleteContents::Redo()
192 HelperNotifyChanges::NotifyIfChangesListeners(*pDocShell
, aRange
, u
"redo"_ustr
);
195 void ScUndoDeleteContents::Repeat(SfxRepeatTarget
& rTarget
)
197 if (auto pViewTarget
= dynamic_cast<ScTabViewTarget
*>( &rTarget
))
198 pViewTarget
->GetViewShell()->DeleteContents( nFlags
);
201 bool ScUndoDeleteContents::CanRepeat(SfxRepeatTarget
& rTarget
) const
203 return dynamic_cast<const ScTabViewTarget
*>( &rTarget
) != nullptr;
206 ScUndoFillTable::ScUndoFillTable( ScDocShell
* pNewDocShell
,
207 const ScMarkData
& rMark
,
208 SCCOL nStartX
, SCROW nStartY
, SCTAB nStartZ
,
209 SCCOL nEndX
, SCROW nEndY
, SCTAB nEndZ
,
210 ScDocumentUniquePtr pNewUndoDoc
, bool bNewMulti
, SCTAB nSrc
,
211 InsertDeleteFlags nFlg
, ScPasteFunc nFunc
, bool bSkip
, bool bLink
)
212 : ScSimpleUndo( pNewDocShell
),
213 aRange ( nStartX
, nStartY
, nStartZ
, nEndX
, nEndY
, nEndZ
),
215 pUndoDoc ( std::move(pNewUndoDoc
) ),
219 bMulti ( bNewMulti
),
220 bSkipEmpty ( bSkip
),
226 ScUndoFillTable::~ScUndoFillTable()
230 OUString
ScUndoFillTable::GetComment() const
232 return ScResId( STR_FILL_TAB
);
235 void ScUndoFillTable::SetChangeTrack()
237 ScChangeTrack
* pChangeTrack
= pDocShell
->GetDocument().GetChangeTrack();
240 SCTAB nTabCount
= pDocShell
->GetDocument().GetTableCount();
241 ScRange
aWorkRange(aRange
);
242 nStartChangeAction
= 0;
243 sal_uLong nTmpAction
;
244 for (const auto& rTab
: aMarkData
)
246 if (rTab
>= nTabCount
)
250 aWorkRange
.aStart
.SetTab(rTab
);
251 aWorkRange
.aEnd
.SetTab(rTab
);
252 pChangeTrack
->AppendContentRange( aWorkRange
, pUndoDoc
.get(),
253 nTmpAction
, nEndChangeAction
);
254 if ( !nStartChangeAction
)
255 nStartChangeAction
= nTmpAction
;
260 nStartChangeAction
= nEndChangeAction
= 0;
263 void ScUndoFillTable::DoChange( const bool bUndo
)
265 ScDocument
& rDoc
= pDocShell
->GetDocument();
267 SetViewMarkData( aMarkData
);
269 if (bUndo
) // only Undo
271 SCTAB nTabCount
= rDoc
.GetTableCount();
272 ScRange
aWorkRange(aRange
);
273 for (const auto& rTab
: aMarkData
)
275 if (rTab
>= nTabCount
)
279 aWorkRange
.aStart
.SetTab(rTab
);
280 aWorkRange
.aEnd
.SetTab(rTab
);
282 rDoc
.DeleteSelectionTab( rTab
, InsertDeleteFlags::ALL
, aMarkData
);
284 rDoc
.DeleteAreaTab( aWorkRange
, InsertDeleteFlags::ALL
);
285 pUndoDoc
->CopyToDocument(aWorkRange
, InsertDeleteFlags::ALL
, bMulti
, rDoc
, &aMarkData
);
289 ScChangeTrack
* pChangeTrack
= rDoc
.GetChangeTrack();
291 pChangeTrack
->Undo( nStartChangeAction
, nEndChangeAction
);
295 aMarkData
.MarkToMulti();
296 rDoc
.FillTabMarked( nSrcTab
, aMarkData
, nFlags
, nFunction
, bSkipEmpty
, bAsLink
);
297 aMarkData
.MarkToSimple();
301 pDocShell
->PostPaint(0,0,0,rDoc
.MaxCol(),rDoc
.MaxRow(),MAXTAB
, PaintPartFlags::Grid
|PaintPartFlags::Extras
);
302 pDocShell
->PostDataChanged();
304 // CellContentChanged comes with the selection
306 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
309 SCTAB nTab
= pViewShell
->GetViewData().GetTabNo();
310 if ( !aMarkData
.GetTableSelect(nTab
) )
311 pViewShell
->SetTabNo( nSrcTab
);
313 pViewShell
->DoneBlockMode(); // causes problems otherwise since selection is on the wrong sheet.
317 void ScUndoFillTable::Undo()
324 void ScUndoFillTable::Redo()
331 void ScUndoFillTable::Repeat(SfxRepeatTarget
& rTarget
)
333 if (auto pViewTarget
= dynamic_cast<ScTabViewTarget
*>( &rTarget
))
334 pViewTarget
->GetViewShell()->FillTab( nFlags
, nFunction
, bSkipEmpty
, bAsLink
);
337 bool ScUndoFillTable::CanRepeat(SfxRepeatTarget
& rTarget
) const
339 return dynamic_cast<const ScTabViewTarget
*>( &rTarget
) != nullptr;
342 ScUndoSelectionAttr::ScUndoSelectionAttr( ScDocShell
* pNewDocShell
,
343 const ScMarkData
& rMark
,
344 SCCOL nStartX
, SCROW nStartY
, SCTAB nStartZ
,
345 SCCOL nEndX
, SCROW nEndY
, SCTAB nEndZ
,
346 ScDocumentUniquePtr pNewUndoDoc
, bool bNewMulti
,
347 const ScPatternAttr
* pNewApply
,
348 const SvxBoxItem
* pNewOuter
, const SvxBoxInfoItem
* pNewInner
,
349 const ScRange
* pRangeCover
)
350 : ScSimpleUndo( pNewDocShell
),
352 aRange ( nStartX
, nStartY
, nStartZ
, nEndX
, nEndY
, nEndZ
),
353 mpDataArray(new ScEditDataArray
),
354 pUndoDoc ( std::move(pNewUndoDoc
) ),
355 bMulti ( bNewMulti
),
356 aApplyPattern( pNewApply
),
357 maLineOuter(*pDocShell
->GetDocument().GetPool(), pNewOuter
),
358 maLineInner(*pDocShell
->GetDocument().GetPool(), pNewInner
)
360 aRangeCover
= pRangeCover
? *pRangeCover
: aRange
;
363 ScUndoSelectionAttr::~ScUndoSelectionAttr()
368 OUString
ScUndoSelectionAttr::GetComment() const
370 //"Attribute" "/Lines"
371 return ScResId( maLineOuter
.getItem() ? STR_UNDO_SELATTRLINES
: STR_UNDO_SELATTR
);
374 ScEditDataArray
* ScUndoSelectionAttr::GetDataArray()
376 return mpDataArray
.get();
379 void ScUndoSelectionAttr::DoChange( const bool bUndo
)
381 ScDocument
& rDoc
= pDocShell
->GetDocument();
383 SetViewMarkData( aMarkData
);
385 ScRange
aEffRange( aRangeCover
);
386 if ( rDoc
.HasAttrib( aEffRange
, HasAttrFlags::Merged
) ) // merged cells?
387 rDoc
.ExtendMerge( aEffRange
);
389 sal_uInt16 nExtFlags
= 0;
390 pDocShell
->UpdatePaintExt( nExtFlags
, aEffRange
);
392 ChangeEditData(bUndo
);
394 if (bUndo
) // only for Undo
396 ScRange aCopyRange
= aRangeCover
;
397 SCTAB nTabCount
= rDoc
.GetTableCount();
398 aCopyRange
.aStart
.SetTab(0);
399 aCopyRange
.aEnd
.SetTab(nTabCount
-1);
400 pUndoDoc
->CopyToDocument(aCopyRange
, InsertDeleteFlags::ATTRIB
, bMulti
, rDoc
, &aMarkData
);
402 else // only for Redo
404 aMarkData
.MarkToMulti();
405 rDoc
.ApplySelectionPattern( *aApplyPattern
.getScPatternAttr(), aMarkData
);
406 aMarkData
.MarkToSimple();
408 if (maLineOuter
.getItem())
409 rDoc
.ApplySelectionFrame(aMarkData
,
410 *static_cast<const SvxBoxItem
*>(maLineOuter
.getItem()),
411 static_cast<const SvxBoxInfoItem
*>(maLineInner
.getItem()));
414 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
415 if ( !( pViewShell
&& pViewShell
->AdjustBlockHeight() ) )
416 /*A*/ pDocShell
->PostPaint( aEffRange
, PaintPartFlags::Grid
| PaintPartFlags::Extras
, nExtFlags
);
421 void ScUndoSelectionAttr::ChangeEditData( const bool bUndo
)
423 ScDocument
& rDoc
= pDocShell
->GetDocument();
424 for (const ScEditDataArray::Item
* pItem
= mpDataArray
->First(); pItem
; pItem
= mpDataArray
->Next())
426 ScAddress
aPos(pItem
->GetCol(), pItem
->GetRow(), pItem
->GetTab());
427 if (rDoc
.GetCellType(aPos
) != CELLTYPE_EDIT
)
432 if (pItem
->GetOldData())
433 rDoc
.SetEditText(aPos
, *pItem
->GetOldData(), nullptr);
435 rDoc
.SetEmptyCell(aPos
);
439 if (pItem
->GetNewData())
440 rDoc
.SetEditText(aPos
, *pItem
->GetNewData(), nullptr);
442 rDoc
.SetEmptyCell(aPos
);
447 void ScUndoSelectionAttr::Undo()
454 void ScUndoSelectionAttr::Redo()
461 void ScUndoSelectionAttr::Repeat(SfxRepeatTarget
& rTarget
)
463 if (auto pViewTarget
= dynamic_cast<ScTabViewTarget
*>( &rTarget
))
465 ScTabViewShell
& rViewShell
= *pViewTarget
->GetViewShell();
466 if (maLineOuter
.getItem())
467 rViewShell
.ApplyPatternLines(*aApplyPattern
.getScPatternAttr(),
468 *static_cast<const SvxBoxItem
*>(maLineOuter
.getItem()),
469 static_cast<const SvxBoxInfoItem
*>(maLineInner
.getItem()));
471 rViewShell
.ApplySelectionPattern( *aApplyPattern
.getScPatternAttr() );
475 bool ScUndoSelectionAttr::CanRepeat(SfxRepeatTarget
& rTarget
) const
477 return dynamic_cast<const ScTabViewTarget
*>( &rTarget
) != nullptr;
480 ScUndoAutoFill::ScUndoAutoFill( ScDocShell
* pNewDocShell
,
481 const ScRange
& rRange
, const ScRange
& rSourceArea
,
482 ScDocumentUniquePtr pNewUndoDoc
, const ScMarkData
& rMark
,
483 FillDir eNewFillDir
, FillCmd eNewFillCmd
, FillDateCmd eNewFillDateCmd
,
484 double fNewStartValue
, double fNewStepValue
, double fNewMaxValue
)
485 : ScBlockUndo( pNewDocShell
, rRange
, SC_UNDO_AUTOHEIGHT
),
486 aSource ( rSourceArea
),
488 pUndoDoc ( std::move(pNewUndoDoc
) ),
489 eFillDir ( eNewFillDir
),
490 eFillCmd ( eNewFillCmd
),
491 eFillDateCmd ( eNewFillDateCmd
),
492 fStartValue ( fNewStartValue
),
493 fStepValue ( fNewStepValue
),
494 fMaxValue ( fNewMaxValue
)
499 ScUndoAutoFill::~ScUndoAutoFill()
503 OUString
ScUndoAutoFill::GetComment() const
505 return ScResId( STR_UNDO_AUTOFILL
); //"Fill"
508 void ScUndoAutoFill::SetChangeTrack()
510 ScChangeTrack
* pChangeTrack
= pDocShell
->GetDocument().GetChangeTrack();
512 pChangeTrack
->AppendContentRange( aBlockRange
, pUndoDoc
.get(),
513 nStartChangeAction
, nEndChangeAction
);
515 nStartChangeAction
= nEndChangeAction
= 0;
518 void ScUndoAutoFill::Undo()
522 ScDocument
& rDoc
= pDocShell
->GetDocument();
524 SCTAB nTabCount
= rDoc
.GetTableCount();
525 for (const auto& rTab
: aMarkData
)
527 if (rTab
>= nTabCount
)
529 ScRange aWorkRange
= aBlockRange
;
530 aWorkRange
.aStart
.SetTab(rTab
);
531 aWorkRange
.aEnd
.SetTab(rTab
);
533 sal_uInt16 nExtFlags
= 0;
534 pDocShell
->UpdatePaintExt( nExtFlags
, aWorkRange
);
535 rDoc
.DeleteAreaTab( aWorkRange
, InsertDeleteFlags::AUTOFILL
);
536 pUndoDoc
->CopyToDocument(aWorkRange
, InsertDeleteFlags::AUTOFILL
, false, rDoc
);
538 // Actually we'd only need to broadcast the cells inserted during
539 // CopyToDocument(), as DeleteAreaTab() broadcasts deleted cells. For
540 // this we'd need to either record the span sets or let
541 // CopyToDocument() broadcast.
542 BroadcastChanges( aWorkRange
);
544 rDoc
.ExtendMerge( aWorkRange
, true );
545 pDocShell
->PostPaint( aWorkRange
, PaintPartFlags::Grid
, nExtFlags
);
547 pDocShell
->PostDataChanged();
548 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
550 pViewShell
->CellContentChanged();
552 ScChangeTrack
* pChangeTrack
= rDoc
.GetChangeTrack();
554 pChangeTrack
->Undo( nStartChangeAction
, nEndChangeAction
);
559 void ScUndoAutoFill::Redo()
569 nCount
= aBlockRange
.aEnd
.Row() - aSource
.aEnd
.Row();
572 nCount
= aBlockRange
.aEnd
.Col() - aSource
.aEnd
.Col();
575 nCount
= aSource
.aStart
.Row() - aBlockRange
.aStart
.Row();
578 nCount
= aSource
.aStart
.Col() - aBlockRange
.aStart
.Col();
582 ScDocument
& rDoc
= pDocShell
->GetDocument();
583 if ( fStartValue
!= MAXDOUBLE
)
585 SCCOL nValX
= (eFillDir
== FILL_TO_LEFT
) ? aSource
.aEnd
.Col() : aSource
.aStart
.Col();
586 SCROW nValY
= (eFillDir
== FILL_TO_TOP
) ? aSource
.aEnd
.Row() : aSource
.aStart
.Row();
587 SCTAB nTab
= aSource
.aStart
.Tab();
588 rDoc
.SetValue( nValX
, nValY
, nTab
, fStartValue
);
590 sal_uLong nProgCount
;
591 if (eFillDir
== FILL_TO_BOTTOM
|| eFillDir
== FILL_TO_TOP
)
592 nProgCount
= aSource
.aEnd
.Col() - aSource
.aStart
.Col() + 1;
594 nProgCount
= aSource
.aEnd
.Row() - aSource
.aStart
.Row() + 1;
595 nProgCount
*= nCount
;
596 ScProgress
aProgress( rDoc
.GetDocumentShell(),
597 ScResId(STR_FILL_SERIES_PROGRESS
), nProgCount
, true );
599 rDoc
.Fill( aSource
.aStart
.Col(), aSource
.aStart
.Row(),
600 aSource
.aEnd
.Col(), aSource
.aEnd
.Row(), &aProgress
,
602 eFillDir
, eFillCmd
, eFillDateCmd
,
603 fStepValue
, fMaxValue
);
607 pDocShell
->PostPaint( aBlockRange
, PaintPartFlags::Grid
);
608 pDocShell
->PostDataChanged();
609 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
611 pViewShell
->CellContentChanged();
616 void ScUndoAutoFill::Repeat(SfxRepeatTarget
& rTarget
)
618 if (auto pViewTarget
= dynamic_cast<ScTabViewTarget
*>( &rTarget
))
620 ScTabViewShell
& rViewShell
= *pViewTarget
->GetViewShell();
621 if (eFillCmd
==FILL_SIMPLE
)
622 rViewShell
.FillSimple( eFillDir
);
624 rViewShell
.FillSeries( eFillDir
, eFillCmd
, eFillDateCmd
,
625 fStartValue
, fStepValue
, fMaxValue
);
629 bool ScUndoAutoFill::CanRepeat(SfxRepeatTarget
& rTarget
) const
631 return dynamic_cast<const ScTabViewTarget
*>( &rTarget
) != nullptr;
634 ScUndoMerge::ScUndoMerge(ScDocShell
* pNewDocShell
, ScCellMergeOption aOption
,
635 bool bMergeContents
, ScDocumentUniquePtr pUndoDoc
, std::unique_ptr
<SdrUndoAction
> pDrawUndo
)
636 : ScSimpleUndo(pNewDocShell
)
637 , maOption(std::move(aOption
))
638 , mbMergeContents(bMergeContents
)
639 , mxUndoDoc(std::move(pUndoDoc
))
640 , mpDrawUndo(std::move(pDrawUndo
))
644 ScUndoMerge::~ScUndoMerge()
649 OUString
ScUndoMerge::GetComment() const
651 return ScResId( STR_UNDO_MERGE
);
654 void ScUndoMerge::DoChange( bool bUndo
) const
658 if (maOption
.maTabs
.empty())
662 ScDocument
& rDoc
= pDocShell
->GetDocument();
663 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
665 ScRange aCurRange
= maOption
.getSingleRange(ScDocShell::GetCurTab());
666 ScUndoUtil::MarkSimpleBlock(pDocShell
, aCurRange
);
668 for (const SCTAB nTab
: maOption
.maTabs
)
670 ScRange aRange
= maOption
.getSingleRange(nTab
);
673 // remove merge (contents are copied back below from undo document)
674 rDoc
.RemoveMerge( aRange
.aStart
.Col(), aRange
.aStart
.Row(), aRange
.aStart
.Tab() );
677 // repeat merge, but do not remove note captions (will be done by drawing redo below)
678 rDoc
.DoMerge( aRange
.aStart
.Col(), aRange
.aStart
.Row(),
679 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(),
680 aRange
.aStart
.Tab(), false );
682 if (maOption
.mbCenter
)
684 rDoc
.ApplyAttr( aRange
.aStart
.Col(), aRange
.aStart
.Row(),
686 SvxHorJustifyItem( SvxCellHorJustify::Center
, ATTR_HOR_JUSTIFY
) );
687 rDoc
.ApplyAttr( aRange
.aStart
.Col(), aRange
.aStart
.Row(),
689 SvxVerJustifyItem( SvxCellVerJustify::Center
, ATTR_VER_JUSTIFY
) );
693 // undo -> copy back deleted contents
694 if (bUndo
&& mxUndoDoc
)
696 // If there are note captions to be deleted during Undo they were
697 // kept or moved during the merge and copied to the Undo document
698 // without cloning the caption. Forget the target area's caption
699 // pointer that is identical to the one in the Undo document
700 // instead of deleting it.
701 rDoc
.DeleteAreaTab( aRange
,
702 InsertDeleteFlags::CONTENTS
| InsertDeleteFlags::NOCAPTIONS
| InsertDeleteFlags::FORGETCAPTIONS
);
703 mxUndoDoc
->CopyToDocument(aRange
, InsertDeleteFlags::ALL
|InsertDeleteFlags::NOCAPTIONS
, false, rDoc
);
706 // redo -> merge contents again
707 else if (!bUndo
&& mbMergeContents
)
709 rDoc
.DoMergeContents( aRange
.aStart
.Col(), aRange
.aStart
.Row(),
710 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(),
711 aRange
.aStart
.Tab() );
715 DoSdrUndoAction( mpDrawUndo
.get(), &rDoc
);
717 RedoSdrUndoAction( mpDrawUndo
.get() );
719 bool bDidPaint
= false;
722 pViewShell
->SetTabNo(nTab
);
723 bDidPaint
= pViewShell
->AdjustRowHeight(maOption
.mnStartRow
, maOption
.mnEndRow
, true);
727 ScUndoUtil::PaintMore(pDocShell
, aRange
);
729 rDoc
.BroadcastCells(aRange
, SfxHintId::ScDataChanged
);
732 ShowTable(aCurRange
);
735 void ScUndoMerge::Undo()
742 void ScUndoMerge::Redo()
749 void ScUndoMerge::Repeat(SfxRepeatTarget
& rTarget
)
751 if (auto pViewTarget
= dynamic_cast<ScTabViewTarget
*>( &rTarget
))
753 ScTabViewShell
& rViewShell
= *pViewTarget
->GetViewShell();
754 rViewShell
.MergeCells( false, false, false, 0 );
758 bool ScUndoMerge::CanRepeat(SfxRepeatTarget
& rTarget
) const
760 return dynamic_cast<const ScTabViewTarget
*>( &rTarget
) != nullptr;
763 ScUndoAutoFormat::ScUndoAutoFormat( ScDocShell
* pNewDocShell
,
764 const ScRange
& rRange
, ScDocumentUniquePtr pNewUndoDoc
,
765 const ScMarkData
& rMark
, bool bNewSize
, sal_uInt16 nNewFormatNo
)
766 : ScBlockUndo( pNewDocShell
, rRange
, bNewSize
? SC_UNDO_MANUALHEIGHT
: SC_UNDO_AUTOHEIGHT
),
767 pUndoDoc ( std::move(pNewUndoDoc
) ),
770 nFormatNo ( nNewFormatNo
)
774 ScUndoAutoFormat::~ScUndoAutoFormat()
778 OUString
ScUndoAutoFormat::GetComment() const
780 return ScResId( STR_UNDO_AUTOFORMAT
); //"Auto-Format"
783 void ScUndoAutoFormat::Undo()
787 ScDocument
& rDoc
= pDocShell
->GetDocument();
789 SCTAB nTabCount
= rDoc
.GetTableCount();
790 rDoc
.DeleteArea( aBlockRange
.aStart
.Col(), aBlockRange
.aStart
.Row(),
791 aBlockRange
.aEnd
.Col(), aBlockRange
.aEnd
.Row(),
792 aMarkData
, InsertDeleteFlags::ATTRIB
);
793 ScRange aCopyRange
= aBlockRange
;
794 aCopyRange
.aStart
.SetTab(0);
795 aCopyRange
.aEnd
.SetTab(nTabCount
-1);
796 pUndoDoc
->CopyToDocument(aCopyRange
, InsertDeleteFlags::ATTRIB
, false, rDoc
, &aMarkData
);
798 // cell heights and widths (InsertDeleteFlags::NONE)
801 SCCOL nStartX
= aBlockRange
.aStart
.Col();
802 SCROW nStartY
= aBlockRange
.aStart
.Row();
803 SCTAB nStartZ
= aBlockRange
.aStart
.Tab();
804 SCCOL nEndX
= aBlockRange
.aEnd
.Col();
805 SCROW nEndY
= aBlockRange
.aEnd
.Row();
806 SCTAB nEndZ
= aBlockRange
.aEnd
.Tab();
808 pUndoDoc
->CopyToDocument( nStartX
, 0, 0, nEndX
, rDoc
.MaxRow(), nTabCount
-1,
809 InsertDeleteFlags::NONE
, false, rDoc
, &aMarkData
);
810 pUndoDoc
->CopyToDocument( 0, nStartY
, 0, rDoc
.MaxCol(), nEndY
, nTabCount
-1,
811 InsertDeleteFlags::NONE
, false, rDoc
, &aMarkData
);
812 pDocShell
->PostPaint( 0, 0, nStartZ
, rDoc
.MaxCol(), rDoc
.MaxRow(), nEndZ
,
813 PaintPartFlags::Grid
| PaintPartFlags::Left
| PaintPartFlags::Top
, SC_PF_LINES
);
816 pDocShell
->PostPaint( aBlockRange
, PaintPartFlags::Grid
, SC_PF_LINES
);
821 void ScUndoAutoFormat::Redo()
825 ScDocument
& rDoc
= pDocShell
->GetDocument();
827 SCCOL nStartX
= aBlockRange
.aStart
.Col();
828 SCROW nStartY
= aBlockRange
.aStart
.Row();
829 SCTAB nStartZ
= aBlockRange
.aStart
.Tab();
830 SCCOL nEndX
= aBlockRange
.aEnd
.Col();
831 SCROW nEndY
= aBlockRange
.aEnd
.Row();
832 SCTAB nEndZ
= aBlockRange
.aEnd
.Tab();
834 rDoc
.AutoFormat( nStartX
, nStartY
, nEndX
, nEndY
, nFormatNo
, aMarkData
);
838 ScopedVclPtrInstance
< VirtualDevice
> pVirtDev
;
839 Fraction
aZoomX(1,1);
840 Fraction aZoomY
= aZoomX
;
842 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
845 ScViewData
& rData
= pViewShell
->GetViewData();
846 nPPTX
= rData
.GetPPTX();
847 nPPTY
= rData
.GetPPTY();
848 aZoomX
= rData
.GetZoomX();
849 aZoomY
= rData
.GetZoomY();
854 nPPTX
= ScGlobal::nScreenPPTX
;
855 nPPTY
= ScGlobal::nScreenPPTY
;
858 sc::RowHeightContext
aCxt(rDoc
.MaxRow(), nPPTX
, nPPTY
, aZoomX
, aZoomY
, pVirtDev
);
859 for (SCTAB nTab
=nStartZ
; nTab
<=nEndZ
; nTab
++)
861 ScMarkData
aDestMark(rDoc
.GetSheetLimits());
862 aDestMark
.SelectOneTable( nTab
);
863 aDestMark
.SetMarkArea( ScRange( nStartX
, nStartY
, nTab
, nEndX
, nEndY
, nTab
) );
864 aDestMark
.MarkToMulti();
867 for (SCROW nRow
=nStartY
; nRow
<=nEndY
; nRow
++)
869 CRFlags nOld
= rDoc
.GetRowFlags(nRow
,nTab
);
870 bool bHidden
= rDoc
.RowHidden(nRow
, nTab
);
871 if ( !bHidden
&& ( nOld
& CRFlags::ManualSize
) )
872 rDoc
.SetRowFlags( nRow
, nTab
, nOld
& ~CRFlags::ManualSize
);
875 bool bChanged
= rDoc
.SetOptimalHeight(aCxt
, nStartY
, nEndY
, nTab
, true);
877 for (SCCOL nCol
=nStartX
; nCol
<=nEndX
; nCol
++)
878 if (!rDoc
.ColHidden(nCol
, nTab
))
880 sal_uInt16 nThisSize
= STD_EXTRA_WIDTH
+ rDoc
.GetOptimalColWidth( nCol
, nTab
,
881 pVirtDev
, nPPTX
, nPPTY
, aZoomX
, aZoomY
, false/*bFormula*/,
883 rDoc
.SetColWidth( nCol
, nTab
, nThisSize
);
884 rDoc
.ShowCol( nCol
, nTab
, true );
887 // tdf#76183: recalculate objects' positions
889 rDoc
.SetDrawPageSize(nTab
);
892 pDocShell
->PostPaint( 0, 0, nStartZ
,
893 rDoc
.MaxCol(), rDoc
.MaxRow(), nEndZ
,
894 PaintPartFlags::Grid
| PaintPartFlags::Left
| PaintPartFlags::Top
, SC_PF_LINES
);
897 pDocShell
->PostPaint( aBlockRange
, PaintPartFlags::Grid
, SC_PF_LINES
);
902 void ScUndoAutoFormat::Repeat(SfxRepeatTarget
& rTarget
)
904 if (auto pViewTarget
= dynamic_cast<ScTabViewTarget
*>( &rTarget
))
905 pViewTarget
->GetViewShell()->AutoFormat( nFormatNo
);
908 bool ScUndoAutoFormat::CanRepeat(SfxRepeatTarget
& rTarget
) const
910 return dynamic_cast<const ScTabViewTarget
*>( &rTarget
) != nullptr;
913 ScUndoReplace::ScUndoReplace( ScDocShell
* pNewDocShell
, const ScMarkData
& rMark
,
914 SCCOL nCurX
, SCROW nCurY
, SCTAB nCurZ
,
915 OUString aNewUndoStr
, ScDocumentUniquePtr pNewUndoDoc
,
916 const SvxSearchItem
* pItem
)
917 : ScSimpleUndo( pNewDocShell
),
918 aCursorPos ( nCurX
, nCurY
, nCurZ
),
920 aUndoStr (std::move( aNewUndoStr
)),
921 pUndoDoc ( std::move(pNewUndoDoc
) )
923 pSearchItem
.reset( new SvxSearchItem( *pItem
) );
927 ScUndoReplace::~ScUndoReplace()
933 void ScUndoReplace::SetChangeTrack()
935 ScDocument
& rDoc
= pDocShell
->GetDocument();
936 ScChangeTrack
* pChangeTrack
= rDoc
.GetChangeTrack();
940 { //! UndoDoc includes only the changed cells,
941 // that is why an Iterator can be used
942 pChangeTrack
->AppendContentsIfInRefDoc( *pUndoDoc
,
943 nStartChangeAction
, nEndChangeAction
);
947 nStartChangeAction
= pChangeTrack
->GetActionMax() + 1;
948 ScChangeActionContent
* pContent
= new ScChangeActionContent(
949 ScRange( aCursorPos
) );
951 aCell
.assign(rDoc
, aCursorPos
);
952 pContent
->SetOldValue( aUndoStr
, &rDoc
);
953 pContent
->SetNewValue(aCell
, &rDoc
);
954 pChangeTrack
->Append( pContent
);
955 nEndChangeAction
= pChangeTrack
->GetActionMax();
959 nStartChangeAction
= nEndChangeAction
= 0;
962 OUString
ScUndoReplace::GetComment() const
964 return ScResId( STR_UNDO_REPLACE
); // "Replace"
967 void ScUndoReplace::Undo()
971 ScDocument
& rDoc
= pDocShell
->GetDocument();
972 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
974 ShowTable( aCursorPos
.Tab() );
976 if (pUndoDoc
) // only for ReplaceAll !!
978 OSL_ENSURE(pSearchItem
->GetCommand() == SvxSearchCmd::REPLACE_ALL
,
979 "ScUndoReplace:: Wrong Mode");
981 SetViewMarkData( aMarkData
);
986 // Undo document has no row/column information, thus copy with
987 // bColRowFlags = FALSE to not destroy Outline groups
989 InsertDeleteFlags nUndoFlags
= (pSearchItem
->GetPattern()) ? InsertDeleteFlags::ATTRIB
: InsertDeleteFlags::CONTENTS
;
990 pUndoDoc
->CopyToDocument( 0, 0, 0,
991 rDoc
.MaxCol(), rDoc
.MaxRow(), MAXTAB
,
992 nUndoFlags
, false, rDoc
, nullptr, false ); // without row flags
993 pDocShell
->PostPaintGridAll();
995 else if (pSearchItem
->GetPattern() &&
996 pSearchItem
->GetCommand() == SvxSearchCmd::REPLACE
)
998 OUString aTempStr
= pSearchItem
->GetSearchString(); // toggle
999 pSearchItem
->SetSearchString(pSearchItem
->GetReplaceString());
1000 pSearchItem
->SetReplaceString(aTempStr
);
1001 rDoc
.ReplaceStyle( *pSearchItem
,
1002 aCursorPos
.Col(), aCursorPos
.Row(), aCursorPos
.Tab(),
1004 pSearchItem
->SetReplaceString(pSearchItem
->GetSearchString());
1005 pSearchItem
->SetSearchString(aTempStr
);
1007 pViewShell
->MoveCursorAbs( aCursorPos
.Col(), aCursorPos
.Row(),
1008 SC_FOLLOW_JUMP
, false, false );
1009 pDocShell
->PostPaintGridAll();
1011 else if (pSearchItem
->GetCellType() == SvxSearchCellType::NOTE
)
1013 ScPostIt
* pNote
= rDoc
.GetNote(aCursorPos
);
1014 OSL_ENSURE( pNote
, "ScUndoReplace::Undo - cell does not contain a note" );
1016 pNote
->SetText( aCursorPos
, aUndoStr
);
1018 pViewShell
->MoveCursorAbs( aCursorPos
.Col(), aCursorPos
.Row(),
1019 SC_FOLLOW_JUMP
, false, false );
1023 // aUndoStr may contain line breaks
1024 if ( aUndoStr
.indexOf('\n') != -1 )
1026 ScFieldEditEngine
& rEngine
= rDoc
.GetEditEngine();
1027 rEngine
.SetTextCurrentDefaults(aUndoStr
);
1028 rDoc
.SetEditText(aCursorPos
, rEngine
.CreateTextObject());
1031 rDoc
.SetString( aCursorPos
.Col(), aCursorPos
.Row(), aCursorPos
.Tab(), aUndoStr
);
1033 pViewShell
->MoveCursorAbs( aCursorPos
.Col(), aCursorPos
.Row(),
1034 SC_FOLLOW_JUMP
, false, false );
1035 pDocShell
->PostPaintGridAll();
1038 ScChangeTrack
* pChangeTrack
= rDoc
.GetChangeTrack();
1040 pChangeTrack
->Undo( nStartChangeAction
, nEndChangeAction
);
1045 void ScUndoReplace::Redo()
1049 ScDocument
& rDoc
= pDocShell
->GetDocument();
1050 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
1053 pViewShell
->MoveCursorAbs( aCursorPos
.Col(), aCursorPos
.Row(),
1054 SC_FOLLOW_JUMP
, false, false );
1059 SetViewMarkData( aMarkData
);
1061 pViewShell
->SearchAndReplace( pSearchItem
.get(), false, true );
1064 else if (pSearchItem
->GetPattern() &&
1065 pSearchItem
->GetCommand() == SvxSearchCmd::REPLACE
)
1067 rDoc
.ReplaceStyle( *pSearchItem
,
1068 aCursorPos
.Col(), aCursorPos
.Row(), aCursorPos
.Tab(),
1070 pDocShell
->PostPaintGridAll();
1074 pViewShell
->SearchAndReplace( pSearchItem
.get(), false, true );
1081 void ScUndoReplace::Repeat(SfxRepeatTarget
& rTarget
)
1083 if (auto pViewTarget
= dynamic_cast<ScTabViewTarget
*>( &rTarget
))
1084 pViewTarget
->GetViewShell()->SearchAndReplace( pSearchItem
.get(), true, false );
1087 bool ScUndoReplace::CanRepeat(SfxRepeatTarget
& rTarget
) const
1089 return dynamic_cast<const ScTabViewTarget
*>( &rTarget
) != nullptr;
1092 // multi-operation (only simple blocks)
1093 ScUndoTabOp::ScUndoTabOp( ScDocShell
* pNewDocShell
,
1094 SCCOL nStartX
, SCROW nStartY
, SCTAB nStartZ
,
1095 SCCOL nEndX
, SCROW nEndY
, SCTAB nEndZ
, ScDocumentUniquePtr pNewUndoDoc
,
1096 const ScRefAddress
& rFormulaCell
,
1097 const ScRefAddress
& rFormulaEnd
,
1098 const ScRefAddress
& rRowCell
,
1099 const ScRefAddress
& rColCell
,
1100 ScTabOpParam::Mode eMode
)
1101 : ScSimpleUndo( pNewDocShell
),
1102 aRange ( nStartX
, nStartY
, nStartZ
, nEndX
, nEndY
, nEndZ
),
1103 pUndoDoc ( std::move(pNewUndoDoc
) ),
1104 theFormulaCell ( rFormulaCell
),
1105 theFormulaEnd ( rFormulaEnd
),
1106 theRowCell ( rRowCell
),
1107 theColCell ( rColCell
),
1112 ScUndoTabOp::~ScUndoTabOp()
1116 OUString
ScUndoTabOp::GetComment() const
1118 return ScResId( STR_UNDO_TABOP
); // "Multiple operation"
1121 void ScUndoTabOp::Undo()
1125 ScUndoUtil::MarkSimpleBlock( pDocShell
, aRange
);
1127 sal_uInt16 nExtFlags
= 0;
1128 pDocShell
->UpdatePaintExt( nExtFlags
, aRange
);
1130 ScDocument
& rDoc
= pDocShell
->GetDocument();
1131 rDoc
.DeleteAreaTab( aRange
,InsertDeleteFlags::ALL
& ~InsertDeleteFlags::NOTE
);
1132 pUndoDoc
->CopyToDocument( aRange
, InsertDeleteFlags::ALL
& ~InsertDeleteFlags::NOTE
, false, rDoc
);
1133 pDocShell
->PostPaint( aRange
, PaintPartFlags::Grid
, nExtFlags
);
1134 pDocShell
->PostDataChanged();
1135 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
1137 pViewShell
->CellContentChanged();
1142 void ScUndoTabOp::Redo()
1146 ScUndoUtil::MarkSimpleBlock( pDocShell
, aRange
);
1148 ScTabOpParam
aParam(theFormulaCell
, theFormulaEnd
, theRowCell
, theColCell
, meMode
);
1150 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
1152 pViewShell
->TabOp( aParam
, false);
1157 void ScUndoTabOp::Repeat(SfxRepeatTarget
& /* rTarget */)
1161 bool ScUndoTabOp::CanRepeat(SfxRepeatTarget
& /* rTarget */) const
1166 ScUndoConversion::ScUndoConversion(
1167 ScDocShell
* pNewDocShell
, const ScMarkData
& rMark
,
1168 SCCOL nCurX
, SCROW nCurY
, SCTAB nCurZ
, ScDocumentUniquePtr pNewUndoDoc
,
1169 SCCOL nNewX
, SCROW nNewY
, SCTAB nNewZ
, ScDocumentUniquePtr pNewRedoDoc
,
1170 ScConversionParam aConvParam
) :
1171 ScSimpleUndo( pNewDocShell
),
1173 aCursorPos( nCurX
, nCurY
, nCurZ
),
1174 pUndoDoc( std::move(pNewUndoDoc
) ),
1175 aNewCursorPos( nNewX
, nNewY
, nNewZ
),
1176 pRedoDoc( std::move(pNewRedoDoc
) ),
1177 maConvParam(std::move( aConvParam
))
1182 ScUndoConversion::~ScUndoConversion()
1188 void ScUndoConversion::SetChangeTrack()
1190 ScDocument
& rDoc
= pDocShell
->GetDocument();
1191 ScChangeTrack
* pChangeTrack
= rDoc
.GetChangeTrack();
1195 pChangeTrack
->AppendContentsIfInRefDoc( *pUndoDoc
,
1196 nStartChangeAction
, nEndChangeAction
);
1199 OSL_FAIL( "ScUndoConversion::SetChangeTrack: no UndoDoc" );
1200 nStartChangeAction
= nEndChangeAction
= 0;
1204 nStartChangeAction
= nEndChangeAction
= 0;
1207 OUString
ScUndoConversion::GetComment() const
1210 switch( maConvParam
.GetType() )
1212 case SC_CONVERSION_SPELLCHECK
: aText
= ScResId( STR_UNDO_SPELLING
); break;
1213 case SC_CONVERSION_HANGULHANJA
: aText
= ScResId( STR_UNDO_HANGULHANJA
); break;
1214 case SC_CONVERSION_CHINESE_TRANSL
: aText
= ScResId( STR_UNDO_CHINESE_TRANSLATION
); break;
1219 void ScUndoConversion::DoChange( ScDocument
* pRefDoc
, const ScAddress
& rCursorPos
)
1223 ScDocument
& rDoc
= pDocShell
->GetDocument();
1224 ShowTable( rCursorPos
.Tab() );
1226 SetViewMarkData( aMarkData
);
1228 SCTAB nTabCount
= rDoc
.GetTableCount();
1229 // Undo/Redo-doc has only selected tables
1231 bool bMulti
= aMarkData
.IsMultiMarked();
1232 pRefDoc
->CopyToDocument( 0, 0, 0,
1233 rDoc
.MaxCol(), rDoc
.MaxRow(), nTabCount
-1,
1234 InsertDeleteFlags::CONTENTS
, bMulti
, rDoc
, &aMarkData
);
1236 // Reset the spell checking results to re-check on paint, otherwise
1237 // we show the previous spelling markers (or lack thereof on misspellings).
1238 if (ScViewData
* pViewData
= ScDocShell::GetViewData())
1239 pViewData
->GetActiveWin()->ResetAutoSpell();
1240 pDocShell
->PostPaintGridAll();
1244 OSL_FAIL("no Un-/RedoDoc for Un-/RedoSpelling");
1248 void ScUndoConversion::Undo()
1251 DoChange( pUndoDoc
.get(), aCursorPos
);
1252 ScChangeTrack
* pChangeTrack
= pDocShell
->GetDocument().GetChangeTrack();
1254 pChangeTrack
->Undo( nStartChangeAction
, nEndChangeAction
);
1258 void ScUndoConversion::Redo()
1261 DoChange( pRedoDoc
.get(), aNewCursorPos
);
1266 void ScUndoConversion::Repeat( SfxRepeatTarget
& rTarget
)
1268 if( auto pViewTarget
= dynamic_cast<ScTabViewTarget
*>( &rTarget
) )
1269 pViewTarget
->GetViewShell()->DoSheetConversion( maConvParam
);
1272 bool ScUndoConversion::CanRepeat(SfxRepeatTarget
& rTarget
) const
1274 return dynamic_cast<const ScTabViewTarget
*>( &rTarget
) != nullptr;
1277 ScUndoRefConversion::ScUndoRefConversion( ScDocShell
* pNewDocShell
,
1278 const ScRange
& aMarkRange
, const ScMarkData
& rMark
,
1279 ScDocumentUniquePtr pNewUndoDoc
, ScDocumentUniquePtr pNewRedoDoc
, bool bNewMulti
) :
1280 ScSimpleUndo( pNewDocShell
),
1281 aMarkData ( rMark
),
1282 pUndoDoc ( std::move(pNewUndoDoc
) ),
1283 pRedoDoc ( std::move(pNewRedoDoc
) ),
1284 aRange ( aMarkRange
),
1285 bMulti ( bNewMulti
)
1287 assert(pUndoDoc
&& pRedoDoc
);
1291 ScUndoRefConversion::~ScUndoRefConversion()
1297 OUString
ScUndoRefConversion::GetComment() const
1299 return ScResId( STR_UNDO_ENTERDATA
); // "Input"
1302 void ScUndoRefConversion::SetChangeTrack()
1304 ScChangeTrack
* pChangeTrack
= pDocShell
->GetDocument().GetChangeTrack();
1306 pChangeTrack
->AppendContentsIfInRefDoc( *pUndoDoc
,
1307 nStartChangeAction
, nEndChangeAction
);
1309 nStartChangeAction
= nEndChangeAction
= 0;
1312 void ScUndoRefConversion::DoChange( ScDocument
* pRefDoc
)
1314 ScDocument
& rDoc
= pDocShell
->GetDocument();
1318 SetViewMarkData( aMarkData
);
1320 ScRange aCopyRange
= aRange
;
1321 SCTAB nTabCount
= rDoc
.GetTableCount();
1322 aCopyRange
.aStart
.SetTab(0);
1323 aCopyRange
.aEnd
.SetTab(nTabCount
-1);
1324 pRefDoc
->CopyToDocument( aCopyRange
, InsertDeleteFlags::ALL
, bMulti
, rDoc
, &aMarkData
);
1325 pDocShell
->PostPaint( aRange
, PaintPartFlags::Grid
);
1326 pDocShell
->PostDataChanged();
1327 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
1329 pViewShell
->CellContentChanged();
1332 void ScUndoRefConversion::Undo()
1336 DoChange(pUndoDoc
.get());
1337 ScChangeTrack
* pChangeTrack
= pDocShell
->GetDocument().GetChangeTrack();
1339 pChangeTrack
->Undo( nStartChangeAction
, nEndChangeAction
);
1343 void ScUndoRefConversion::Redo()
1347 DoChange(pRedoDoc
.get());
1352 void ScUndoRefConversion::Repeat(SfxRepeatTarget
& rTarget
)
1354 if (auto pViewTarget
= dynamic_cast<ScTabViewTarget
*>( &rTarget
))
1355 pViewTarget
->GetViewShell()->DoRefConversion();
1358 bool ScUndoRefConversion::CanRepeat(SfxRepeatTarget
& rTarget
) const
1360 return dynamic_cast<const ScTabViewTarget
*>( &rTarget
) != nullptr;
1363 ScUndoRefreshLink::ScUndoRefreshLink(ScDocShell
* pNewDocShell
,
1364 ScDocumentUniquePtr pNewUndoDoc
)
1365 : ScSimpleUndo(pNewDocShell
)
1366 , xUndoDoc(std::move(pNewUndoDoc
))
1370 OUString
ScUndoRefreshLink::GetComment() const
1372 return ScResId( STR_UNDO_UPDATELINK
);
1375 void ScUndoRefreshLink::Undo()
1379 bool bMakeRedo
= !xRedoDoc
;
1381 xRedoDoc
.reset(new ScDocument(SCDOCMODE_UNDO
));
1384 ScDocument
& rDoc
= pDocShell
->GetDocument();
1385 SCTAB nCount
= rDoc
.GetTableCount();
1386 for (SCTAB nTab
=0; nTab
<nCount
; nTab
++)
1387 if (xUndoDoc
->HasTable(nTab
))
1389 ScRange
aRange(0,0,nTab
,rDoc
.MaxCol(),rDoc
.MaxRow(),nTab
);
1393 xRedoDoc
->InitUndo(rDoc
, nTab
, nTab
, true, true);
1395 xRedoDoc
->AddUndoTab(nTab
, nTab
, true, true);
1397 rDoc
.CopyToDocument(aRange
, InsertDeleteFlags::ALL
, false, *xRedoDoc
);
1398 xRedoDoc
->SetLink(nTab
,
1399 rDoc
.GetLinkMode(nTab
),
1400 rDoc
.GetLinkDoc(nTab
),
1401 rDoc
.GetLinkFlt(nTab
),
1402 rDoc
.GetLinkOpt(nTab
),
1403 rDoc
.GetLinkTab(nTab
),
1404 rDoc
.GetLinkRefreshDelay(nTab
));
1405 xRedoDoc
->SetTabBgColor( nTab
, rDoc
.GetTabBgColor(nTab
) );
1408 rDoc
.DeleteAreaTab( aRange
,InsertDeleteFlags::ALL
);
1409 xUndoDoc
->CopyToDocument(aRange
, InsertDeleteFlags::ALL
, false, rDoc
);
1410 rDoc
.SetLink(nTab
, xUndoDoc
->GetLinkMode(nTab
), xUndoDoc
->GetLinkDoc(nTab
),
1411 xUndoDoc
->GetLinkFlt(nTab
), xUndoDoc
->GetLinkOpt(nTab
),
1412 xUndoDoc
->GetLinkTab(nTab
),
1413 xUndoDoc
->GetLinkRefreshDelay(nTab
) );
1414 rDoc
.SetTabBgColor(nTab
, xUndoDoc
->GetTabBgColor(nTab
));
1417 pDocShell
->PostPaintGridAll();
1418 pDocShell
->PostPaintExtras();
1423 void ScUndoRefreshLink::Redo()
1425 OSL_ENSURE(xRedoDoc
, "No RedoDoc for ScUndoRefreshLink::Redo");
1429 ScDocument
& rDoc
= pDocShell
->GetDocument();
1430 SCTAB nCount
= rDoc
.GetTableCount();
1431 for (SCTAB nTab
=0; nTab
<nCount
; nTab
++)
1432 if (xRedoDoc
->HasTable(nTab
))
1434 ScRange
aRange(0,0,nTab
,rDoc
.MaxCol(),rDoc
.MaxRow(),nTab
);
1436 rDoc
.DeleteAreaTab( aRange
, InsertDeleteFlags::ALL
);
1437 xRedoDoc
->CopyToDocument(aRange
, InsertDeleteFlags::ALL
, false, rDoc
);
1439 xRedoDoc
->GetLinkMode(nTab
),
1440 xRedoDoc
->GetLinkDoc(nTab
),
1441 xRedoDoc
->GetLinkFlt(nTab
),
1442 xRedoDoc
->GetLinkOpt(nTab
),
1443 xRedoDoc
->GetLinkTab(nTab
),
1444 xRedoDoc
->GetLinkRefreshDelay(nTab
) );
1445 rDoc
.SetTabBgColor(nTab
, xRedoDoc
->GetTabBgColor(nTab
));
1448 pDocShell
->PostPaintGridAll();
1449 pDocShell
->PostPaintExtras();
1454 void ScUndoRefreshLink::Repeat(SfxRepeatTarget
& /* rTarget */)
1459 bool ScUndoRefreshLink::CanRepeat(SfxRepeatTarget
& /* rTarget */) const
1464 static ScAreaLink
* lcl_FindAreaLink( const sfx2::LinkManager
* pLinkManager
, std::u16string_view rDoc
,
1465 std::u16string_view rFlt
, std::u16string_view rOpt
,
1466 std::u16string_view rSrc
, const ScRange
& rDest
)
1468 const ::sfx2::SvBaseLinks
& rLinks
= pLinkManager
->GetLinks();
1469 sal_uInt16 nCount
= pLinkManager
->GetLinks().size();
1470 for (sal_uInt16 i
=0; i
<nCount
; i
++)
1472 ::sfx2::SvBaseLink
* pBase
= rLinks
[i
].get();
1473 if (auto pAreaLink
= dynamic_cast<ScAreaLink
*>( pBase
))
1474 if ( pAreaLink
->IsEqual( rDoc
, rFlt
, rOpt
, rSrc
, rDest
) )
1478 OSL_FAIL("ScAreaLink not found");
1482 ScUndoInsertAreaLink::ScUndoInsertAreaLink( ScDocShell
* pShell
,
1484 OUString aFlt
, OUString aOpt
,
1485 OUString aArea
, const ScRange
& rDestRange
,
1486 sal_uLong nRefresh
)
1487 : ScSimpleUndo ( pShell
),
1488 aDocName (std::move( aDoc
)),
1489 aFltName (std::move( aFlt
)),
1490 aOptions (std::move( aOpt
)),
1491 aAreaName (std::move( aArea
)),
1492 aRange ( rDestRange
),
1493 nRefreshDelay ( nRefresh
)
1497 ScUndoInsertAreaLink::~ScUndoInsertAreaLink()
1501 OUString
ScUndoInsertAreaLink::GetComment() const
1503 return ScResId( STR_UNDO_INSERTAREALINK
);
1506 void ScUndoInsertAreaLink::Undo()
1508 ScDocument
& rDoc
= pDocShell
->GetDocument();
1509 sfx2::LinkManager
* pLinkManager
= rDoc
.GetLinkManager();
1511 ScAreaLink
* pLink
= lcl_FindAreaLink( pLinkManager
, aDocName
, aFltName
, aOptions
,
1512 aAreaName
, aRange
);
1514 pLinkManager
->Remove( pLink
);
1516 SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScAreaLinksChanged
) ); // Navigator
1519 void ScUndoInsertAreaLink::Redo()
1521 ScDocument
& rDoc
= pDocShell
->GetDocument();
1522 sfx2::LinkManager
* pLinkManager
= rDoc
.GetLinkManager();
1524 ScAreaLink
* pLink
= new ScAreaLink( pDocShell
, aDocName
, aFltName
, aOptions
,
1525 aAreaName
, ScRange(aRange
.aStart
), nRefreshDelay
);
1526 pLink
->SetInCreate( true );
1527 pLink
->SetDestArea( aRange
);
1528 pLinkManager
->InsertFileLink( *pLink
, sfx2::SvBaseLinkObjectType::ClientFile
, aDocName
, &aFltName
, &aAreaName
);
1530 pLink
->SetInCreate( false );
1532 SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScAreaLinksChanged
) ); // Navigator
1535 void ScUndoInsertAreaLink::Repeat(SfxRepeatTarget
& /* rTarget */)
1540 bool ScUndoInsertAreaLink::CanRepeat(SfxRepeatTarget
& /* rTarget */) const
1545 ScUndoRemoveAreaLink::ScUndoRemoveAreaLink( ScDocShell
* pShell
,
1546 OUString aDoc
, OUString aFlt
, OUString aOpt
,
1547 OUString aArea
, const ScRange
& rDestRange
,
1548 sal_uLong nRefresh
)
1549 : ScSimpleUndo ( pShell
),
1550 aDocName (std::move( aDoc
)),
1551 aFltName (std::move( aFlt
)),
1552 aOptions (std::move( aOpt
)),
1553 aAreaName (std::move( aArea
)),
1554 aRange ( rDestRange
),
1555 nRefreshDelay ( nRefresh
)
1559 ScUndoRemoveAreaLink::~ScUndoRemoveAreaLink()
1563 OUString
ScUndoRemoveAreaLink::GetComment() const
1565 return ScResId( STR_UNDO_REMOVELINK
); //! own text ??
1568 void ScUndoRemoveAreaLink::Undo()
1570 ScDocument
& rDoc
= pDocShell
->GetDocument();
1571 sfx2::LinkManager
* pLinkManager
= rDoc
.GetLinkManager();
1573 ScAreaLink
* pLink
= new ScAreaLink( pDocShell
, aDocName
, aFltName
, aOptions
,
1574 aAreaName
, ScRange(aRange
.aStart
), nRefreshDelay
);
1575 pLink
->SetInCreate( true );
1576 pLink
->SetDestArea( aRange
);
1577 pLinkManager
->InsertFileLink( *pLink
, sfx2::SvBaseLinkObjectType::ClientFile
, aDocName
, &aFltName
, &aAreaName
);
1579 pLink
->SetInCreate( false );
1581 SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScAreaLinksChanged
) ); // Navigator
1584 void ScUndoRemoveAreaLink::Redo()
1586 ScDocument
& rDoc
= pDocShell
->GetDocument();
1587 sfx2::LinkManager
* pLinkManager
= rDoc
.GetLinkManager();
1589 ScAreaLink
* pLink
= lcl_FindAreaLink( pLinkManager
, aDocName
, aFltName
, aOptions
,
1590 aAreaName
, aRange
);
1592 pLinkManager
->Remove( pLink
);
1594 SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScAreaLinksChanged
) ); // Navigator
1597 void ScUndoRemoveAreaLink::Repeat(SfxRepeatTarget
& /* rTarget */)
1602 bool ScUndoRemoveAreaLink::CanRepeat(SfxRepeatTarget
& /* rTarget */) const
1607 ScUndoUpdateAreaLink::ScUndoUpdateAreaLink( ScDocShell
* pShell
,
1608 OUString aOldD
, OUString aOldF
, OUString aOldO
,
1609 OUString aOldA
, const ScRange
& rOldR
, sal_uLong nOldRD
,
1610 OUString aNewD
, OUString aNewF
, OUString aNewO
,
1611 OUString aNewA
, const ScRange
& rNewR
, sal_uLong nNewRD
,
1612 ScDocumentUniquePtr pUndo
, ScDocumentUniquePtr pRedo
, bool bDoInsert
)
1613 : ScSimpleUndo( pShell
),
1614 aOldDoc (std::move( aOldD
)),
1615 aOldFlt (std::move( aOldF
)),
1616 aOldOpt (std::move( aOldO
)),
1617 aOldArea (std::move( aOldA
)),
1618 aOldRange ( rOldR
),
1619 aNewDoc (std::move( aNewD
)),
1620 aNewFlt (std::move( aNewF
)),
1621 aNewOpt (std::move( aNewO
)),
1622 aNewArea (std::move( aNewA
)),
1623 aNewRange ( rNewR
),
1624 xUndoDoc ( std::move(pUndo
) ),
1625 xRedoDoc ( std::move(pRedo
) ),
1626 nOldRefresh ( nOldRD
),
1627 nNewRefresh ( nNewRD
),
1628 bWithInsert ( bDoInsert
)
1630 OSL_ENSURE( aOldRange
.aStart
== aNewRange
.aStart
, "AreaLink moved ?" );
1633 OUString
ScUndoUpdateAreaLink::GetComment() const
1635 return ScResId( STR_UNDO_UPDATELINK
); //! own text ??
1638 void ScUndoUpdateAreaLink::DoChange( const bool bUndo
) const
1640 ScDocument
& rDoc
= pDocShell
->GetDocument();
1642 SCCOL nEndX
= std::max( aOldRange
.aEnd
.Col(), aNewRange
.aEnd
.Col() );
1643 SCROW nEndY
= std::max( aOldRange
.aEnd
.Row(), aNewRange
.aEnd
.Row() );
1644 SCTAB nEndZ
= std::max( aOldRange
.aEnd
.Tab(), aNewRange
.aEnd
.Tab() ); //?
1650 rDoc
.FitBlock( aNewRange
, aOldRange
);
1651 rDoc
.DeleteAreaTab( aOldRange
, InsertDeleteFlags::ALL
& ~InsertDeleteFlags::NOTE
);
1652 xUndoDoc
->UndoToDocument(aOldRange
, InsertDeleteFlags::ALL
& ~InsertDeleteFlags::NOTE
, false, rDoc
);
1656 ScRange
aCopyRange( aOldRange
.aStart
, ScAddress(nEndX
,nEndY
,nEndZ
) );
1657 rDoc
.DeleteAreaTab( aCopyRange
, InsertDeleteFlags::ALL
& ~InsertDeleteFlags::NOTE
);
1658 xUndoDoc
->CopyToDocument(aCopyRange
, InsertDeleteFlags::ALL
& ~InsertDeleteFlags::NOTE
, false, rDoc
);
1665 rDoc
.FitBlock( aOldRange
, aNewRange
);
1666 rDoc
.DeleteAreaTab( aNewRange
, InsertDeleteFlags::ALL
& ~InsertDeleteFlags::NOTE
);
1667 xRedoDoc
->CopyToDocument(aNewRange
, InsertDeleteFlags::ALL
& ~InsertDeleteFlags::NOTE
, false, rDoc
);
1671 ScRange
aCopyRange( aOldRange
.aStart
, ScAddress(nEndX
,nEndY
,nEndZ
) );
1672 rDoc
.DeleteAreaTab( aCopyRange
, InsertDeleteFlags::ALL
& ~InsertDeleteFlags::NOTE
);
1673 xRedoDoc
->CopyToDocument(aCopyRange
, InsertDeleteFlags::ALL
& ~InsertDeleteFlags::NOTE
, false, rDoc
);
1677 ScRange
aWorkRange( aNewRange
.aStart
, ScAddress( nEndX
, nEndY
, nEndZ
) );
1678 rDoc
.ExtendMerge( aWorkRange
, true );
1682 if ( aNewRange
.aEnd
.Col() != aOldRange
.aEnd
.Col() )
1683 aWorkRange
.aEnd
.SetCol(rDoc
.MaxCol());
1684 if ( aNewRange
.aEnd
.Row() != aOldRange
.aEnd
.Row() )
1685 aWorkRange
.aEnd
.SetRow(rDoc
.MaxRow());
1687 if ( !pDocShell
->AdjustRowHeight( aWorkRange
.aStart
.Row(), aWorkRange
.aEnd
.Row(), aWorkRange
.aStart
.Tab() ) )
1688 pDocShell
->PostPaint( aWorkRange
, PaintPartFlags::Grid
);
1690 pDocShell
->PostDataChanged();
1691 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
1693 pViewShell
->CellContentChanged();
1696 void ScUndoUpdateAreaLink::Undo()
1698 ScDocument
& rDoc
= pDocShell
->GetDocument();
1699 sfx2::LinkManager
* pLinkManager
= rDoc
.GetLinkManager();
1700 ScAreaLink
* pLink
= lcl_FindAreaLink( pLinkManager
, aNewDoc
, aNewFlt
, aNewOpt
,
1701 aNewArea
, aNewRange
);
1704 pLink
->SetSource( aOldDoc
, aOldFlt
, aOldOpt
, aOldArea
); // old data in Link
1705 pLink
->SetDestArea( aOldRange
);
1706 pLink
->SetRefreshDelay( nOldRefresh
);
1712 void ScUndoUpdateAreaLink::Redo()
1714 ScDocument
& rDoc
= pDocShell
->GetDocument();
1715 sfx2::LinkManager
* pLinkManager
= rDoc
.GetLinkManager();
1716 ScAreaLink
* pLink
= lcl_FindAreaLink( pLinkManager
, aOldDoc
, aOldFlt
, aOldOpt
,
1717 aOldArea
, aOldRange
);
1720 pLink
->SetSource( aNewDoc
, aNewFlt
, aNewOpt
, aNewArea
); // new values in link
1721 pLink
->SetDestArea( aNewRange
);
1722 pLink
->SetRefreshDelay( nNewRefresh
);
1728 void ScUndoUpdateAreaLink::Repeat(SfxRepeatTarget
& /* rTarget */)
1733 bool ScUndoUpdateAreaLink::CanRepeat(SfxRepeatTarget
& /* rTarget */) const
1738 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */