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 <undocell.hxx>
22 #include <scitems.hxx>
23 #include <editeng/editobj.hxx>
24 #include <sfx2/app.hxx>
25 #include <svx/svdocapt.hxx> //
26 #include <comphelper/lok.hxx>
27 #include <osl/diagnose.h>
29 #include <document.hxx>
30 #include <patattr.hxx>
32 #include <tabvwsh.hxx>
33 #include <globstr.hrc>
34 #include <scresid.hxx>
36 #include <formulacell.hxx>
38 #include <undoolk.hxx>
39 #include <detdata.hxx>
40 #include <stlpool.hxx>
41 #include <printfun.hxx>
42 #include <rangenam.hxx>
43 #include <chgtrack.hxx>
44 #include <stringutil.hxx>
47 namespace HelperNotifyChanges
49 static void NotifyIfChangesListeners(const ScDocShell
& rDocShell
, const ScAddress
&rPos
,
50 const ScUndoEnterData::ValuesType
&rOldValues
, const OUString
& rType
= u
"cell-change"_ustr
)
52 ScModelObj
* pModelObj
= rDocShell
.GetModel();
55 ScRangeList aChangeRanges
;
57 for (const auto & rOldValue
: rOldValues
)
59 aChangeRanges
.push_back( ScRange(rPos
.Col(), rPos
.Row(), rOldValue
.mnTab
));
62 if (getMustPropagateChangesModel(pModelObj
))
63 Notify(*pModelObj
, aChangeRanges
, rType
);
64 if (pModelObj
) // possibly need to invalidate getCellArea results
66 Notify(*pModelObj
, aChangeRanges
, isDataAreaInvalidateType(rType
)
67 ? u
"data-area-invalidate"_ustr
: u
"data-area-extend"_ustr
);
74 ScUndoCursorAttr::ScUndoCursorAttr( ScDocShell
* pNewDocShell
,
75 SCCOL nNewCol
, SCROW nNewRow
, SCTAB nNewTab
,
76 const ScPatternAttr
* pOldPat
, const ScPatternAttr
* pNewPat
,
77 const ScPatternAttr
* pApplyPat
) :
78 ScSimpleUndo( pNewDocShell
),
82 aOldPattern( pOldPat
),
83 aNewPattern( pNewPat
),
84 aApplyPattern( pApplyPat
),
85 pOldEditData( static_cast<EditTextObject
*>(nullptr) ),
86 pNewEditData( static_cast<EditTextObject
*>(nullptr) )
90 ScUndoCursorAttr::~ScUndoCursorAttr()
94 OUString
ScUndoCursorAttr::GetComment() const
96 //! own text for automatic attribution
97 return ScResId( STR_UNDO_CURSORATTR
); // "Attribute"
100 void ScUndoCursorAttr::SetEditData( std::unique_ptr
<EditTextObject
> pOld
, std::unique_ptr
<EditTextObject
> pNew
)
102 pOldEditData
= std::move(pOld
);
103 pNewEditData
= std::move(pNew
);
106 void ScUndoCursorAttr::DoChange( const CellAttributeHolder
& rWhichPattern
, const std::unique_ptr
<EditTextObject
>& pEditData
) const
108 ScDocument
& rDoc
= pDocShell
->GetDocument();
109 ScAddress
aPos(nCol
, nRow
, nTab
);
110 rDoc
.SetPattern( nCol
, nRow
, nTab
, rWhichPattern
);
112 if (rDoc
.GetCellType(aPos
) == CELLTYPE_EDIT
&& pEditData
)
113 rDoc
.SetEditText(aPos
, *pEditData
, nullptr);
115 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
118 pViewShell
->SetTabNo( nTab
);
119 pViewShell
->MoveCursorAbs( nCol
, nRow
, SC_FOLLOW_JUMP
, false, false );
120 pViewShell
->AdjustBlockHeight();
123 const SfxItemSet
& rApplySet
= aApplyPattern
.getScPatternAttr()->GetItemSet();
124 bool bPaintExt
= ( rApplySet
.GetItemState( ATTR_SHADOW
) != SfxItemState::DEFAULT
||
125 rApplySet
.GetItemState( ATTR_CONDITIONAL
) != SfxItemState::DEFAULT
);
126 bool bPaintRows
= ( rApplySet
.GetItemState( ATTR_HOR_JUSTIFY
) != SfxItemState::DEFAULT
);
128 sal_uInt16 nFlags
= SC_PF_TESTMERGE
;
130 nFlags
|= SC_PF_LINES
;
132 nFlags
|= SC_PF_WHOLEROWS
;
133 pDocShell
->PostPaint( nCol
,nRow
,nTab
, nCol
,nRow
,nTab
, PaintPartFlags::Grid
, nFlags
);
136 void ScUndoCursorAttr::Undo()
139 DoChange(aOldPattern
, pOldEditData
);
143 void ScUndoCursorAttr::Redo()
146 DoChange(aNewPattern
, pNewEditData
);
150 void ScUndoCursorAttr::Repeat(SfxRepeatTarget
& rTarget
)
152 if (auto pViewTarget
= dynamic_cast<ScTabViewTarget
*>( &rTarget
))
153 pViewTarget
->GetViewShell()->ApplySelectionPattern( *aApplyPattern
.getScPatternAttr() );
156 bool ScUndoCursorAttr::CanRepeat(SfxRepeatTarget
& rTarget
) const
158 return dynamic_cast<const ScTabViewTarget
*>( &rTarget
) != nullptr;
161 ScUndoEnterData::Value::Value() : mnTab(-1), mbHasFormat(false), mnFormat(0) {}
163 ScUndoEnterData::ScUndoEnterData(
164 ScDocShell
* pNewDocShell
, const ScAddress
& rPos
, ValuesType
& rOldValues
,
165 OUString aNewStr
, std::unique_ptr
<EditTextObject
> pObj
) :
166 ScSimpleUndo( pNewDocShell
),
167 maNewString(std::move(aNewStr
)),
168 mpNewEditData(std::move(pObj
)),
169 mnEndChangeAction(0),
172 maOldValues
.swap(rOldValues
);
177 OUString
ScUndoEnterData::GetComment() const
179 return ScResId( STR_UNDO_ENTERDATA
); // "Input"
182 void ScUndoEnterData::DoChange() const
184 // only when needed (old or new Edit cell, or Attribute)?
185 bool bHeightChanged
= false;
186 for (const auto & i
: maOldValues
)
188 if (pDocShell
->AdjustRowHeight(maPos
.Row(), maPos
.Row(), i
.mnTab
))
189 bHeightChanged
= true;
192 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
195 if (comphelper::LibreOfficeKit::isActive() && bHeightChanged
)
197 ScTabViewShell::notifyAllViewsHeaderInvalidation(pViewShell
, ROW_HEADER
, maPos
.Tab());
198 ScTabViewShell::notifyAllViewsSheetGeomInvalidation(
199 pViewShell
, false /* bColumns */, true /* bRows */, true /* bSizes*/,
200 false /* bHidden */, false /* bFiltered */, false /* bGroups */, maPos
.Tab());
202 pViewShell
->SetTabNo(maPos
.Tab());
203 pViewShell
->MoveCursorAbs(maPos
.Col(), maPos
.Row(), SC_FOLLOW_JUMP
, false, false);
206 pDocShell
->PostDataChanged();
209 void ScUndoEnterData::SetChangeTrack()
211 ScChangeTrack
* pChangeTrack
= pDocShell
->GetDocument().GetChangeTrack();
214 mnEndChangeAction
= pChangeTrack
->GetActionMax() + 1;
215 ScAddress
aPos(maPos
);
216 for (const Value
& rOldValue
: maOldValues
)
218 aPos
.SetTab(rOldValue
.mnTab
);
219 sal_uLong nFormat
= 0;
220 if (rOldValue
.mbHasFormat
)
221 nFormat
= rOldValue
.mnFormat
;
222 pChangeTrack
->AppendContent(aPos
, rOldValue
.maCell
, nFormat
);
224 if ( mnEndChangeAction
> pChangeTrack
->GetActionMax() )
225 mnEndChangeAction
= 0; // nothing is appended
228 mnEndChangeAction
= 0;
231 void ScUndoEnterData::Undo()
235 ScDocument
& rDoc
= pDocShell
->GetDocument();
236 for (const Value
& rVal
: maOldValues
)
238 ScCellValue aNewCell
;
239 aNewCell
.assign(rVal
.maCell
, rDoc
, ScCloneFlags::StartListening
);
240 ScAddress aPos
= maPos
;
241 aPos
.SetTab(rVal
.mnTab
);
242 aNewCell
.release(rDoc
, aPos
);
244 if (rVal
.mbHasFormat
)
245 rDoc
.ApplyAttr(maPos
.Col(), maPos
.Row(), rVal
.mnTab
,
246 SfxUInt32Item(ATTR_VALUE_FORMAT
, rVal
.mnFormat
));
249 ScPatternAttr
* pPattern(new ScPatternAttr(*rDoc
.GetPattern(maPos
.Col(), maPos
.Row(), rVal
.mnTab
)));
250 pPattern
->GetItemSet().ClearItem( ATTR_VALUE_FORMAT
);
251 rDoc
.SetPattern(maPos
.Col(), maPos
.Row(), rVal
.mnTab
, CellAttributeHolder(pPattern
, true));
253 pDocShell
->PostPaintCell(maPos
.Col(), maPos
.Row(), rVal
.mnTab
);
256 ScChangeTrack
* pChangeTrack
= rDoc
.GetChangeTrack();
257 size_t nCount
= maOldValues
.size();
258 if ( pChangeTrack
&& mnEndChangeAction
>= sal::static_int_cast
<sal_uLong
>(nCount
) )
259 pChangeTrack
->Undo( mnEndChangeAction
- nCount
+ 1, mnEndChangeAction
);
264 HelperNotifyChanges::NotifyIfChangesListeners(*pDocShell
, maPos
, maOldValues
, u
"undo"_ustr
);
267 void ScUndoEnterData::Redo()
271 ScDocument
& rDoc
= pDocShell
->GetDocument();
272 for (const Value
& rOldValue
: maOldValues
)
274 SCTAB nTab
= rOldValue
.mnTab
;
277 ScAddress aPos
= maPos
;
279 // edit text will be cloned.
280 rDoc
.SetEditText(aPos
, *mpNewEditData
, nullptr);
283 rDoc
.SetString(maPos
.Col(), maPos
.Row(), nTab
, maNewString
);
285 pDocShell
->PostPaintCell(maPos
.Col(), maPos
.Row(), nTab
);
293 HelperNotifyChanges::NotifyIfChangesListeners(*pDocShell
, maPos
, maOldValues
, u
"redo"_ustr
);
296 void ScUndoEnterData::Repeat(SfxRepeatTarget
& rTarget
)
298 if (auto pViewTarget
= dynamic_cast<ScTabViewTarget
*>( &rTarget
))
300 OUString aTemp
= maNewString
;
301 pViewTarget
->GetViewShell()->EnterDataAtCursor( aTemp
);
305 bool ScUndoEnterData::CanRepeat(SfxRepeatTarget
& rTarget
) const
307 return dynamic_cast<const ScTabViewTarget
*>( &rTarget
) != nullptr;
310 ScUndoEnterValue::ScUndoEnterValue(
311 ScDocShell
* pNewDocShell
, const ScAddress
& rNewPos
,
312 ScCellValue aUndoCell
, double nVal
) :
313 ScSimpleUndo( pNewDocShell
),
315 maOldCell(std::move(aUndoCell
)),
321 ScUndoEnterValue::~ScUndoEnterValue()
325 OUString
ScUndoEnterValue::GetComment() const
327 return ScResId( STR_UNDO_ENTERDATA
); // "Input"
330 void ScUndoEnterValue::SetChangeTrack()
332 ScDocument
& rDoc
= pDocShell
->GetDocument();
333 ScChangeTrack
* pChangeTrack
= rDoc
.GetChangeTrack();
336 nEndChangeAction
= pChangeTrack
->GetActionMax() + 1;
337 pChangeTrack
->AppendContent(aPos
, maOldCell
);
338 if ( nEndChangeAction
> pChangeTrack
->GetActionMax() )
339 nEndChangeAction
= 0; // nothing is appended
342 nEndChangeAction
= 0;
345 void ScUndoEnterValue::Undo()
349 ScDocument
& rDoc
= pDocShell
->GetDocument();
350 ScCellValue aNewCell
;
351 aNewCell
.assign(maOldCell
, rDoc
, ScCloneFlags::StartListening
);
352 aNewCell
.release(rDoc
, aPos
);
354 pDocShell
->PostPaintCell( aPos
);
356 ScChangeTrack
* pChangeTrack
= rDoc
.GetChangeTrack();
358 pChangeTrack
->Undo( nEndChangeAction
, nEndChangeAction
);
363 void ScUndoEnterValue::Redo()
367 ScDocument
& rDoc
= pDocShell
->GetDocument();
368 rDoc
.SetValue( aPos
.Col(), aPos
.Row(), aPos
.Tab(), nValue
);
369 pDocShell
->PostPaintCell( aPos
);
376 void ScUndoEnterValue::Repeat(SfxRepeatTarget
& /* rTarget */)
381 bool ScUndoEnterValue::CanRepeat(SfxRepeatTarget
& /* rTarget */) const
386 ScUndoSetCell::ScUndoSetCell( ScDocShell
* pDocSh
, const ScAddress
& rPos
, ScCellValue aOldVal
, ScCellValue aNewVal
) :
387 ScSimpleUndo(pDocSh
), maPos(rPos
), maOldValue(std::move(aOldVal
)), maNewValue(std::move(aNewVal
)), mnEndChangeAction(0)
392 ScUndoSetCell::~ScUndoSetCell() {}
394 void ScUndoSetCell::Undo()
397 SetValue(maOldValue
);
399 pDocShell
->PostPaintCell(maPos
);
401 ScDocument
& rDoc
= pDocShell
->GetDocument();
402 ScChangeTrack
* pChangeTrack
= rDoc
.GetChangeTrack();
404 pChangeTrack
->Undo(mnEndChangeAction
, mnEndChangeAction
);
409 void ScUndoSetCell::Redo()
412 SetValue(maNewValue
);
414 pDocShell
->PostPaintCell(maPos
);
419 void ScUndoSetCell::Repeat( SfxRepeatTarget
& /*rTarget*/ )
424 bool ScUndoSetCell::CanRepeat( SfxRepeatTarget
& /*rTarget*/ ) const
429 OUString
ScUndoSetCell::GetComment() const
431 return ScResId(STR_UNDO_ENTERDATA
); // "Input"
434 void ScUndoSetCell::SetChangeTrack()
436 ScDocument
& rDoc
= pDocShell
->GetDocument();
437 ScChangeTrack
* pChangeTrack
= rDoc
.GetChangeTrack();
440 mnEndChangeAction
= pChangeTrack
->GetActionMax() + 1;
442 pChangeTrack
->AppendContent(maPos
, maOldValue
);
444 if (mnEndChangeAction
> pChangeTrack
->GetActionMax())
445 mnEndChangeAction
= 0; // Nothing is appended
448 mnEndChangeAction
= 0;
451 void ScUndoSetCell::SetValue( const ScCellValue
& rVal
)
453 ScDocument
& rDoc
= pDocShell
->GetDocument();
455 switch (rVal
.getType())
459 rDoc
.SetEmptyCell(maPos
);
462 rDoc
.SetValue(maPos
, rVal
.getDouble());
464 case CELLTYPE_STRING
:
466 ScSetStringParam aParam
;
467 aParam
.setTextInput();
468 // Undo only cell content, without setting any number format.
469 aParam
.meSetTextNumFormat
= ScSetStringParam::Keep
;
470 rDoc
.SetString(maPos
, rVal
.getSharedString()->getString(), &aParam
);
474 rDoc
.SetEditText(maPos
, rVal
.getEditText()->Clone());
476 case CELLTYPE_FORMULA
:
477 rDoc
.SetFormulaCell(maPos
, rVal
.getFormula()->Clone());
484 void ScUndoSetCell::MoveCursorToCell()
486 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
489 pViewShell
->SetTabNo( maPos
.Tab() );
490 pViewShell
->MoveCursorAbs( maPos
.Col(), maPos
.Row(), SC_FOLLOW_JUMP
, false, false );
494 ScUndoPageBreak::ScUndoPageBreak( ScDocShell
* pNewDocShell
,
495 SCCOL nNewCol
, SCROW nNewRow
, SCTAB nNewTab
,
496 bool bNewColumn
, bool bNewInsert
) :
497 ScSimpleUndo( pNewDocShell
),
501 bColumn( bNewColumn
),
502 bInsert( bNewInsert
)
506 ScUndoPageBreak::~ScUndoPageBreak()
510 OUString
ScUndoPageBreak::GetComment() const
512 //"Column break" | "Row break" "insert" | "delete"
515 ScResId( STR_UNDO_INSCOLBREAK
) :
516 ScResId( STR_UNDO_DELCOLBREAK
)
519 ScResId( STR_UNDO_INSROWBREAK
) :
520 ScResId( STR_UNDO_DELROWBREAK
)
524 void ScUndoPageBreak::DoChange( bool bInsertP
) const
526 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
530 pViewShell
->SetTabNo( nTab
);
531 pViewShell
->MoveCursorAbs( nCol
, nRow
, SC_FOLLOW_JUMP
, false, false );
534 pViewShell
->InsertPageBreak(bColumn
, false);
536 pViewShell
->DeletePageBreak(bColumn
, false);
538 pDocShell
->GetDocument().InvalidatePageBreaks(nTab
);
542 void ScUndoPageBreak::Undo()
549 void ScUndoPageBreak::Redo()
556 void ScUndoPageBreak::Repeat(SfxRepeatTarget
& rTarget
)
558 if (auto pViewTarget
= dynamic_cast<ScTabViewTarget
*>( &rTarget
))
560 ScTabViewShell
& rViewShell
= *pViewTarget
->GetViewShell();
563 rViewShell
.InsertPageBreak(bColumn
);
565 rViewShell
.DeletePageBreak(bColumn
);
569 bool ScUndoPageBreak::CanRepeat(SfxRepeatTarget
& rTarget
) const
571 return dynamic_cast<const ScTabViewTarget
*>( &rTarget
) != nullptr;
574 ScUndoPrintZoom::ScUndoPrintZoom( ScDocShell
* pNewDocShell
,
575 SCTAB nT
, sal_uInt16 nOS
, sal_uInt16 nOP
, sal_uInt16 nNS
, sal_uInt16 nNP
) :
576 ScSimpleUndo( pNewDocShell
),
585 ScUndoPrintZoom::~ScUndoPrintZoom()
589 OUString
ScUndoPrintZoom::GetComment() const
591 return ScResId( STR_UNDO_PRINTSCALE
);
594 void ScUndoPrintZoom::DoChange( bool bUndo
)
596 sal_uInt16 nScale
= bUndo
? nOldScale
: nNewScale
;
597 sal_uInt16 nPages
= bUndo
? nOldPages
: nNewPages
;
599 ScDocument
& rDoc
= pDocShell
->GetDocument();
600 OUString aStyleName
= rDoc
.GetPageStyle( nTab
);
601 ScStyleSheetPool
* pStylePool
= rDoc
.GetStyleSheetPool();
602 SfxStyleSheetBase
* pStyleSheet
= pStylePool
->Find( aStyleName
, SfxStyleFamily::Page
);
603 OSL_ENSURE( pStyleSheet
, "PageStyle not found" );
606 SfxItemSet
& rSet
= pStyleSheet
->GetItemSet();
607 rSet
.Put( SfxUInt16Item( ATTR_PAGE_SCALE
, nScale
) );
608 rSet
.Put( SfxUInt16Item( ATTR_PAGE_SCALETOPAGES
, nPages
) );
610 ScPrintFunc
aPrintFunc( pDocShell
, pDocShell
->GetPrinter(), nTab
);
611 aPrintFunc
.UpdatePages();
615 void ScUndoPrintZoom::Undo()
622 void ScUndoPrintZoom::Redo()
629 void ScUndoPrintZoom::Repeat(SfxRepeatTarget
& rTarget
)
631 if (auto pViewTarget
= dynamic_cast<ScTabViewTarget
*>( &rTarget
))
633 ScTabViewShell
& rViewShell
= *pViewTarget
->GetViewShell();
634 ScViewData
& rViewData
= rViewShell
.GetViewData();
635 rViewData
.GetDocShell()->SetPrintZoom( rViewData
.GetTabNo(), nNewScale
, nNewPages
);
639 bool ScUndoPrintZoom::CanRepeat(SfxRepeatTarget
& rTarget
) const
641 return dynamic_cast<const ScTabViewTarget
*>( &rTarget
) != nullptr;
644 ScUndoThesaurus::ScUndoThesaurus(
645 ScDocShell
* pNewDocShell
, SCCOL nNewCol
, SCROW nNewRow
, SCTAB nNewTab
,
646 ScCellValue aOldText
, ScCellValue aNewText
) :
647 ScSimpleUndo( pNewDocShell
),
651 maOldText(std::move(aOldText
)),
652 maNewText(std::move(aNewText
))
654 SetChangeTrack(maOldText
);
657 ScUndoThesaurus::~ScUndoThesaurus() {}
659 OUString
ScUndoThesaurus::GetComment() const
661 return ScResId( STR_UNDO_THESAURUS
); // "Thesaurus"
664 void ScUndoThesaurus::SetChangeTrack( const ScCellValue
& rOldCell
)
666 ScChangeTrack
* pChangeTrack
= pDocShell
->GetDocument().GetChangeTrack();
669 nEndChangeAction
= pChangeTrack
->GetActionMax() + 1;
670 pChangeTrack
->AppendContent(ScAddress(nCol
, nRow
, nTab
), rOldCell
);
671 if ( nEndChangeAction
> pChangeTrack
->GetActionMax() )
672 nEndChangeAction
= 0; // nothing is appended
675 nEndChangeAction
= 0;
678 void ScUndoThesaurus::DoChange( bool bUndo
, const ScCellValue
& rText
)
680 ScDocument
& rDoc
= pDocShell
->GetDocument();
682 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
685 pViewShell
->SetTabNo( nTab
);
686 pViewShell
->MoveCursorAbs( nCol
, nRow
, SC_FOLLOW_JUMP
, false, false );
689 ScAddress
aPos(nCol
, nRow
, nTab
);
690 rText
.commit(rDoc
, aPos
);
692 SetChangeTrack(maOldText
);
694 pDocShell
->PostPaintCell( nCol
, nRow
, nTab
);
697 void ScUndoThesaurus::Undo()
700 DoChange(true, maOldText
);
701 ScChangeTrack
* pChangeTrack
= pDocShell
->GetDocument().GetChangeTrack();
703 pChangeTrack
->Undo( nEndChangeAction
, nEndChangeAction
);
707 void ScUndoThesaurus::Redo()
710 DoChange(false, maNewText
);
714 void ScUndoThesaurus::Repeat(SfxRepeatTarget
& rTarget
)
716 if (auto pViewTarget
= dynamic_cast<ScTabViewTarget
*>( &rTarget
))
717 pViewTarget
->GetViewShell()->DoThesaurus();
720 bool ScUndoThesaurus::CanRepeat(SfxRepeatTarget
& rTarget
) const
722 return dynamic_cast<const ScTabViewTarget
*>( &rTarget
) != nullptr;
726 ScUndoReplaceNote::ScUndoReplaceNote( ScDocShell
& rDocShell
, const ScAddress
& rPos
,
727 const ScNoteData
& rNoteData
, bool bInsert
, std::unique_ptr
<SdrUndoAction
> pDrawUndo
) :
728 ScSimpleUndo( &rDocShell
),
730 mpDrawUndo( std::move(pDrawUndo
) )
732 OSL_ENSURE( rNoteData
.mxCaption
, "ScUndoReplaceNote::ScUndoReplaceNote - missing note caption" );
735 maNewData
= rNoteData
;
739 maOldData
= rNoteData
;
743 ScUndoReplaceNote::ScUndoReplaceNote( ScDocShell
& rDocShell
, const ScAddress
& rPos
,
744 ScNoteData aOldData
, ScNoteData aNewData
, std::unique_ptr
<SdrUndoAction
> pDrawUndo
) :
745 ScSimpleUndo( &rDocShell
),
747 maOldData(std::move( aOldData
)),
748 maNewData(std::move( aNewData
)),
749 mpDrawUndo( std::move(pDrawUndo
) )
751 OSL_ENSURE( maOldData
.mxCaption
|| maNewData
.mxCaption
, "ScUndoReplaceNote::ScUndoReplaceNote - missing note captions" );
752 OSL_ENSURE( !maOldData
.mxInitData
&& !maNewData
.mxInitData
, "ScUndoReplaceNote::ScUndoReplaceNote - unexpected uninitialized note" );
755 ScUndoReplaceNote::~ScUndoReplaceNote()
760 void ScUndoReplaceNote::Undo()
763 DoSdrUndoAction( mpDrawUndo
.get(), &pDocShell
->GetDocument() );
764 /* Undo insert -> remove new note.
765 Undo remove -> insert old note.
766 Undo replace -> remove new note, insert old note. */
767 DoRemoveNote( maNewData
);
768 DoInsertNote( maOldData
);
769 pDocShell
->PostPaintCell( maPos
);
773 void ScUndoReplaceNote::Redo()
776 RedoSdrUndoAction( mpDrawUndo
.get() );
777 /* Redo insert -> insert new note.
778 Redo remove -> remove old note.
779 Redo replace -> remove old note, insert new note. */
780 DoRemoveNote( maOldData
);
781 DoInsertNote( maNewData
);
782 pDocShell
->PostPaintCell( maPos
);
786 void ScUndoReplaceNote::Repeat( SfxRepeatTarget
& /*rTarget*/ )
790 bool ScUndoReplaceNote::CanRepeat( SfxRepeatTarget
& /*rTarget*/ ) const
795 OUString
ScUndoReplaceNote::GetComment() const
797 return ScResId( maNewData
.mxCaption
?
798 (maOldData
.mxCaption
? STR_UNDO_EDITNOTE
: STR_UNDO_INSERTNOTE
) : STR_UNDO_DELETENOTE
);
801 void ScUndoReplaceNote::DoInsertNote( const ScNoteData
& rNoteData
)
803 if( rNoteData
.mxCaption
)
805 ScDocument
& rDoc
= pDocShell
->GetDocument();
806 OSL_ENSURE( !rDoc
.GetNote(maPos
), "ScUndoReplaceNote::DoInsertNote - unexpected cell note" );
807 ScPostIt
* pNote
= new ScPostIt( rDoc
, maPos
, rNoteData
, false );
808 rDoc
.SetNote( maPos
, std::unique_ptr
<ScPostIt
>(pNote
) );
809 ScDocShell::LOKCommentNotify(LOKCommentNotificationType::Add
, rDoc
, maPos
, pNote
);
813 void ScUndoReplaceNote::DoRemoveNote( const ScNoteData
& rNoteData
)
815 if( !rNoteData
.mxCaption
)
818 ScDocument
& rDoc
= pDocShell
->GetDocument();
819 OSL_ENSURE( rDoc
.GetNote(maPos
), "ScUndoReplaceNote::DoRemoveNote - missing cell note" );
820 if( std::unique_ptr
<ScPostIt
> pNote
= rDoc
.ReleaseNote( maPos
) )
822 /* Forget pointer to caption object to suppress removing the
823 caption object from the drawing layer while deleting pNote
824 (removing the caption is done by a drawing undo action). */
825 pNote
->ForgetCaption();
826 ScDocShell::LOKCommentNotify(LOKCommentNotificationType::Remove
, rDoc
, maPos
, pNote
.get());
830 ScUndoShowHideNote::ScUndoShowHideNote( ScDocShell
& rDocShell
, const ScAddress
& rPos
, bool bShow
) :
831 ScSimpleUndo( &rDocShell
),
837 ScUndoShowHideNote::~ScUndoShowHideNote()
841 void ScUndoShowHideNote::Undo()
844 if( ScPostIt
* pNote
= pDocShell
->GetDocument().GetNote(maPos
) )
845 pNote
->ShowCaption( maPos
, !mbShown
);
849 void ScUndoShowHideNote::Redo()
852 if( ScPostIt
* pNote
= pDocShell
->GetDocument().GetNote(maPos
) )
853 pNote
->ShowCaption( maPos
, mbShown
);
857 void ScUndoShowHideNote::Repeat( SfxRepeatTarget
& /*rTarget*/ )
861 bool ScUndoShowHideNote::CanRepeat( SfxRepeatTarget
& /*rTarget*/ ) const
866 OUString
ScUndoShowHideNote::GetComment() const
868 return ScResId( mbShown
? STR_UNDO_SHOWNOTE
: STR_UNDO_HIDENOTE
);
871 ScUndoDetective::ScUndoDetective( ScDocShell
* pNewDocShell
,
872 std::unique_ptr
<SdrUndoAction
> pDraw
, const ScDetOpData
* pOperation
,
873 std::unique_ptr
<ScDetOpList
> pUndoList
) :
874 ScSimpleUndo( pNewDocShell
),
875 pOldList ( std::move(pUndoList
) ),
877 pDrawUndo ( std::move(pDraw
) )
879 bIsDelete
= ( pOperation
== nullptr );
882 nAction
= static_cast<sal_uInt16
>(pOperation
->GetOperation());
883 aPos
= pOperation
->GetPos();
887 ScUndoDetective::~ScUndoDetective()
893 OUString
ScUndoDetective::GetComment() const
895 TranslateId pId
= STR_UNDO_DETDELALL
;
897 switch ( static_cast<ScDetOpType
>(nAction
) )
899 case SCDETOP_ADDSUCC
: pId
= STR_UNDO_DETADDSUCC
; break;
900 case SCDETOP_DELSUCC
: pId
= STR_UNDO_DETDELSUCC
; break;
901 case SCDETOP_ADDPRED
: pId
= STR_UNDO_DETADDPRED
; break;
902 case SCDETOP_DELPRED
: pId
= STR_UNDO_DETDELPRED
; break;
903 case SCDETOP_ADDERROR
: pId
= STR_UNDO_DETADDERROR
; break;
909 void ScUndoDetective::Undo()
913 ScDocument
& rDoc
= pDocShell
->GetDocument();
914 DoSdrUndoAction(pDrawUndo
.get(), &rDoc
);
919 rDoc
.SetDetOpList( std::unique_ptr
<ScDetOpList
>(new ScDetOpList(*pOldList
)) );
923 // Remove entry from list
925 ScDetOpList
* pList
= rDoc
.GetDetOpList();
926 if (pList
&& pList
->Count())
928 ScDetOpDataVector
& rVec
= pList
->GetDataVector();
929 ScDetOpDataVector::iterator it
= rVec
.begin() + rVec
.size() - 1;
930 if ( it
->GetOperation() == static_cast<ScDetOpType
>(nAction
) && it
->GetPos() == aPos
)
934 OSL_FAIL("Detective entry could not be found in list");
939 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
941 pViewShell
->RecalcPPT(); //! use broadcast instead?
946 void ScUndoDetective::Redo()
950 RedoSdrUndoAction(pDrawUndo
.get());
952 ScDocument
& rDoc
= pDocShell
->GetDocument();
955 rDoc
.ClearDetectiveOperations();
957 rDoc
.AddDetectiveOperation( ScDetOpData( aPos
, static_cast<ScDetOpType
>(nAction
) ) );
959 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
961 pViewShell
->RecalcPPT(); //! use broadcast instead?
966 void ScUndoDetective::Repeat(SfxRepeatTarget
& /* rTarget */)
971 bool ScUndoDetective::CanRepeat(SfxRepeatTarget
& /* rTarget */) const
976 ScUndoRangeNames::ScUndoRangeNames( ScDocShell
* pNewDocShell
,
977 std::unique_ptr
<ScRangeName
> pOld
, std::unique_ptr
<ScRangeName
> pNew
, SCTAB nTab
) :
978 ScSimpleUndo( pNewDocShell
),
979 pOldRanges ( std::move(pOld
) ),
980 pNewRanges ( std::move(pNew
) ),
985 ScUndoRangeNames::~ScUndoRangeNames()
991 OUString
ScUndoRangeNames::GetComment() const
993 return ScResId( STR_UNDO_RANGENAMES
);
996 void ScUndoRangeNames::DoChange( bool bUndo
)
998 ScDocument
& rDoc
= pDocShell
->GetDocument();
999 rDoc
.PreprocessRangeNameUpdate();
1003 auto p
= std::make_unique
<ScRangeName
>(*pOldRanges
);
1005 rDoc
.SetRangeName( mnTab
, std::move(p
) );
1007 rDoc
.SetRangeName( std::move(p
) );
1011 auto p
= std::make_unique
<ScRangeName
>(*pNewRanges
);
1013 rDoc
.SetRangeName( mnTab
, std::move(p
) );
1015 rDoc
.SetRangeName( std::move(p
) );
1018 rDoc
.CompileHybridFormula();
1020 SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScAreasChanged
) );
1023 void ScUndoRangeNames::Undo()
1030 void ScUndoRangeNames::Redo()
1037 void ScUndoRangeNames::Repeat(SfxRepeatTarget
& /* rTarget */)
1042 bool ScUndoRangeNames::CanRepeat(SfxRepeatTarget
& /* rTarget */) const
1047 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */