Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / source / ui / undo / undocell.cxx
blob2a22f5991e376c2e81020e68017b5fa5387cb460
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "undocell.hxx"
22 #include "scitems.hxx"
23 #include <editeng/eeitem.hxx>
24 #include <editeng/editobj.hxx>
25 #include <svl/zforlist.hxx>
26 #include "svl/sharedstringpool.hxx"
27 #include <sfx2/app.hxx>
29 #include "document.hxx"
30 #include "docpool.hxx"
31 #include "patattr.hxx"
32 #include "docsh.hxx"
33 #include "tabvwsh.hxx"
34 #include "globstr.hrc"
35 #include "global.hxx"
36 #include "formulacell.hxx"
37 #include "target.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 "sc.hrc"
45 #include "docuno.hxx"
46 #include "stringutil.hxx"
48 using ::boost::shared_ptr;
50 namespace HelperNotifyChanges
52 void NotifyIfChangesListeners(ScDocShell &rDocShell, const ScAddress &rPos,
53 const ScUndoEnterData::ValuesType &rOldValues, const OUString &rType = OUString("cell-change"))
55 if (ScModelObj* pModelObj = getMustPropagateChangesModel(rDocShell))
57 ScRangeList aChangeRanges;
59 for (size_t i = 0, n = rOldValues.size(); i < n; ++i)
61 aChangeRanges.Append( ScRange(rPos.Col(), rPos.Row(), rOldValues[i].mnTab));
64 Notify(*pModelObj, aChangeRanges, rType);
69 TYPEINIT1(ScUndoCursorAttr, ScSimpleUndo);
70 TYPEINIT1(ScUndoEnterData, ScSimpleUndo);
71 TYPEINIT1(ScUndoEnterValue, ScSimpleUndo);
72 TYPEINIT1(ScUndoSetCell, ScSimpleUndo);
73 TYPEINIT1(ScUndoPageBreak, ScSimpleUndo);
74 TYPEINIT1(ScUndoPrintZoom, ScSimpleUndo);
75 TYPEINIT1(ScUndoThesaurus, ScSimpleUndo);
76 TYPEINIT1(ScUndoReplaceNote, ScSimpleUndo);
77 TYPEINIT1(ScUndoShowHideNote, ScSimpleUndo);
78 TYPEINIT1(ScUndoDetective, ScSimpleUndo);
79 TYPEINIT1(ScUndoRangeNames, ScSimpleUndo);
81 ScUndoCursorAttr::ScUndoCursorAttr( ScDocShell* pNewDocShell,
82 SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
83 const ScPatternAttr* pOldPat, const ScPatternAttr* pNewPat,
84 const ScPatternAttr* pApplyPat, sal_Bool bAutomatic ) :
85 ScSimpleUndo( pNewDocShell ),
86 nCol( nNewCol ),
87 nRow( nNewRow ),
88 nTab( nNewTab ),
89 pOldEditData( static_cast<EditTextObject*>(NULL) ),
90 pNewEditData( static_cast<EditTextObject*>(NULL) ),
91 bIsAutomatic( bAutomatic )
93 ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
94 pNewPattern = (ScPatternAttr*) &pPool->Put( *pNewPat );
95 pOldPattern = (ScPatternAttr*) &pPool->Put( *pOldPat );
96 pApplyPattern = (ScPatternAttr*) &pPool->Put( *pApplyPat );
99 ScUndoCursorAttr::~ScUndoCursorAttr()
101 ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
102 pPool->Remove(*pNewPattern);
103 pPool->Remove(*pOldPattern);
104 pPool->Remove(*pApplyPattern);
107 OUString ScUndoCursorAttr::GetComment() const
109 //! own text for automatic attribution
111 sal_uInt16 nId = STR_UNDO_CURSORATTR; // "Attribute"
112 return ScGlobal::GetRscString( nId );
115 void ScUndoCursorAttr::SetEditData( EditTextObject* pOld, EditTextObject* pNew )
117 pOldEditData.reset(pOld);
118 pNewEditData.reset(pNew);
121 void ScUndoCursorAttr::DoChange( const ScPatternAttr* pWhichPattern, const shared_ptr<EditTextObject>& pEditData ) const
123 ScDocument* pDoc = pDocShell->GetDocument();
124 ScAddress aPos(nCol, nRow, nTab);
125 pDoc->SetPattern( nCol, nRow, nTab, *pWhichPattern, true );
127 if (pDoc->GetCellType(aPos) == CELLTYPE_EDIT && pEditData)
128 pDoc->SetEditText(aPos, *pEditData, NULL);
130 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
131 if (pViewShell)
133 pViewShell->SetTabNo( nTab );
134 pViewShell->MoveCursorAbs( nCol, nRow, SC_FOLLOW_JUMP, false, false );
135 pViewShell->AdjustBlockHeight();
138 const SfxItemSet& rApplySet = pApplyPattern->GetItemSet();
139 sal_Bool bPaintExt = ( rApplySet.GetItemState( ATTR_SHADOW, sal_True ) != SFX_ITEM_DEFAULT ||
140 rApplySet.GetItemState( ATTR_CONDITIONAL, sal_True ) != SFX_ITEM_DEFAULT );
141 sal_Bool bPaintRows = ( rApplySet.GetItemState( ATTR_HOR_JUSTIFY, sal_True ) != SFX_ITEM_DEFAULT );
143 sal_uInt16 nFlags = SC_PF_TESTMERGE;
144 if (bPaintExt)
145 nFlags |= SC_PF_LINES;
146 if (bPaintRows)
147 nFlags |= SC_PF_WHOLEROWS;
148 pDocShell->PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PAINT_GRID, nFlags );
151 void ScUndoCursorAttr::Undo()
153 BeginUndo();
154 DoChange(pOldPattern, pOldEditData);
156 if ( bIsAutomatic )
158 // if automatic formatting is reversed, then
159 // automatic formatting should also not continue to be done
161 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
162 if (pViewShell)
163 pViewShell->ForgetFormatArea();
166 EndUndo();
169 void ScUndoCursorAttr::Redo()
171 BeginRedo();
172 DoChange(pNewPattern, pNewEditData);
173 EndRedo();
176 void ScUndoCursorAttr::Repeat(SfxRepeatTarget& rTarget)
178 if (rTarget.ISA(ScTabViewTarget))
179 ((ScTabViewTarget&)rTarget).GetViewShell()->ApplySelectionPattern( *pApplyPattern );
182 bool ScUndoCursorAttr::CanRepeat(SfxRepeatTarget& rTarget) const
184 return rTarget.ISA(ScTabViewTarget);
187 ScUndoEnterData::Value::Value() : mnTab(-1), mbHasFormat(false), mnFormat(0) {}
189 ScUndoEnterData::ScUndoEnterData(
190 ScDocShell* pNewDocShell, const ScAddress& rPos, ValuesType& rOldValues,
191 const OUString& rNewStr, EditTextObject* pObj ) :
192 ScSimpleUndo( pNewDocShell ),
193 maNewString(rNewStr),
194 mpNewEditData(pObj),
195 mnEndChangeAction(0),
196 maPos(rPos)
198 maOldValues.swap(rOldValues);
200 SetChangeTrack();
203 ScUndoEnterData::~ScUndoEnterData() {}
205 OUString ScUndoEnterData::GetComment() const
207 return ScGlobal::GetRscString( STR_UNDO_ENTERDATA ); // "Input"
210 void ScUndoEnterData::DoChange() const
212 // only when needed (old or new Edit cell, or Attribute)?
213 for (size_t i = 0, n = maOldValues.size(); i < n; ++i)
214 pDocShell->AdjustRowHeight(maPos.Row(), maPos.Row(), maOldValues[i].mnTab);
216 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
217 if (pViewShell)
219 pViewShell->SetTabNo(maPos.Tab());
220 pViewShell->MoveCursorAbs(maPos.Col(), maPos.Row(), SC_FOLLOW_JUMP, false, false);
223 pDocShell->PostDataChanged();
226 void ScUndoEnterData::SetChangeTrack()
228 ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
229 if ( pChangeTrack )
231 mnEndChangeAction = pChangeTrack->GetActionMax() + 1;
232 ScAddress aPos(maPos);
233 for (size_t i = 0, n = maOldValues.size(); i < n; ++i)
235 aPos.SetTab(maOldValues[i].mnTab);
236 sal_uLong nFormat = 0;
237 if (maOldValues[i].mbHasFormat)
238 nFormat = maOldValues[i].mnFormat;
239 pChangeTrack->AppendContent(aPos, maOldValues[i].maCell, nFormat);
241 if ( mnEndChangeAction > pChangeTrack->GetActionMax() )
242 mnEndChangeAction = 0; // nothing is appended
244 else
245 mnEndChangeAction = 0;
248 void ScUndoEnterData::Undo()
250 BeginUndo();
252 ScDocument* pDoc = pDocShell->GetDocument();
253 for (size_t i = 0, n = maOldValues.size(); i < n; ++i)
255 Value& rVal = maOldValues[i];
256 ScCellValue aNewCell;
257 aNewCell.assign(rVal.maCell, *pDoc, SC_CLONECELL_STARTLISTENING);
258 ScAddress aPos = maPos;
259 aPos.SetTab(rVal.mnTab);
260 aNewCell.release(*pDoc, aPos);
262 if (rVal.mbHasFormat)
263 pDoc->ApplyAttr(maPos.Col(), maPos.Row(), rVal.mnTab,
264 SfxUInt32Item(ATTR_VALUE_FORMAT, rVal.mnFormat));
265 else
267 ScPatternAttr aPattern(*pDoc->GetPattern(maPos.Col(), maPos.Row(), rVal.mnTab));
268 aPattern.GetItemSet().ClearItem( ATTR_VALUE_FORMAT );
269 pDoc->SetPattern(maPos.Col(), maPos.Row(), rVal.mnTab, aPattern, true);
271 pDocShell->PostPaintCell(maPos.Col(), maPos.Row(), rVal.mnTab);
274 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
275 size_t nCount = maOldValues.size();
276 if ( pChangeTrack && mnEndChangeAction >= sal::static_int_cast<sal_uLong>(nCount) )
277 pChangeTrack->Undo( mnEndChangeAction - nCount + 1, mnEndChangeAction );
279 DoChange();
280 EndUndo();
282 HelperNotifyChanges::NotifyIfChangesListeners(*pDocShell, maPos, maOldValues);
285 void ScUndoEnterData::Redo()
287 BeginRedo();
289 ScDocument* pDoc = pDocShell->GetDocument();
290 for (size_t i = 0, n = maOldValues.size(); i < n; ++i)
292 SCTAB nTab = maOldValues[i].mnTab;
293 if (mpNewEditData)
295 ScAddress aPos = maPos;
296 aPos.SetTab(nTab);
297 // edit text wil be cloned.
298 pDoc->SetEditText(aPos, *mpNewEditData, NULL);
300 else
301 pDoc->SetString(maPos.Col(), maPos.Row(), nTab, maNewString);
303 pDocShell->PostPaintCell(maPos.Col(), maPos.Row(), nTab);
306 SetChangeTrack();
308 DoChange();
309 EndRedo();
311 HelperNotifyChanges::NotifyIfChangesListeners(*pDocShell, maPos, maOldValues);
314 void ScUndoEnterData::Repeat(SfxRepeatTarget& rTarget)
316 if (rTarget.ISA(ScTabViewTarget))
318 OUString aTemp = maNewString;
319 ((ScTabViewTarget&)rTarget).GetViewShell()->EnterDataAtCursor( aTemp );
323 bool ScUndoEnterData::CanRepeat(SfxRepeatTarget& rTarget) const
325 return rTarget.ISA(ScTabViewTarget);
329 ScUndoEnterValue::ScUndoEnterValue(
330 ScDocShell* pNewDocShell, const ScAddress& rNewPos,
331 const ScCellValue& rUndoCell, double nVal ) :
332 ScSimpleUndo( pNewDocShell ),
333 aPos ( rNewPos ),
334 maOldCell(rUndoCell),
335 nValue ( nVal )
337 SetChangeTrack();
340 ScUndoEnterValue::~ScUndoEnterValue()
344 OUString ScUndoEnterValue::GetComment() const
346 return ScGlobal::GetRscString( STR_UNDO_ENTERDATA ); // "Input"
349 void ScUndoEnterValue::SetChangeTrack()
351 ScDocument* pDoc = pDocShell->GetDocument();
352 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
353 if ( pChangeTrack )
355 nEndChangeAction = pChangeTrack->GetActionMax() + 1;
356 pChangeTrack->AppendContent(aPos, maOldCell);
357 if ( nEndChangeAction > pChangeTrack->GetActionMax() )
358 nEndChangeAction = 0; // nothing is appended
360 else
361 nEndChangeAction = 0;
364 void ScUndoEnterValue::Undo()
366 BeginUndo();
368 ScDocument* pDoc = pDocShell->GetDocument();
369 ScCellValue aNewCell;
370 aNewCell.assign(maOldCell, *pDoc, SC_CLONECELL_STARTLISTENING);
371 aNewCell.release(*pDoc, aPos);
373 pDocShell->PostPaintCell( aPos );
375 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
376 if ( pChangeTrack )
377 pChangeTrack->Undo( nEndChangeAction, nEndChangeAction );
379 EndUndo();
382 void ScUndoEnterValue::Redo()
384 BeginRedo();
386 ScDocument* pDoc = pDocShell->GetDocument();
387 pDoc->SetValue( aPos.Col(), aPos.Row(), aPos.Tab(), nValue );
388 pDocShell->PostPaintCell( aPos );
390 SetChangeTrack();
392 EndRedo();
395 void ScUndoEnterValue::Repeat(SfxRepeatTarget& /* rTarget */)
397 // makes no sense
400 bool ScUndoEnterValue::CanRepeat(SfxRepeatTarget& /* rTarget */) const
402 return false;
405 ScUndoSetCell::ScUndoSetCell( ScDocShell* pDocSh, const ScAddress& rPos, const ScCellValue& rOldVal, const ScCellValue& rNewVal ) :
406 ScSimpleUndo(pDocSh), maPos(rPos), maOldValue(rOldVal), maNewValue(rNewVal), mnEndChangeAction(0)
408 SetChangeTrack();
411 ScUndoSetCell::~ScUndoSetCell() {}
413 void ScUndoSetCell::Undo()
415 BeginUndo();
416 SetValue(maOldValue);
417 pDocShell->PostPaintCell(maPos);
419 ScDocument* pDoc = pDocShell->GetDocument();
420 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
421 if (pChangeTrack)
422 pChangeTrack->Undo(mnEndChangeAction, mnEndChangeAction);
424 EndUndo();
427 void ScUndoSetCell::Redo()
429 BeginRedo();
430 SetValue(maNewValue);
431 pDocShell->PostPaintCell(maPos);
432 SetChangeTrack();
433 EndRedo();
436 void ScUndoSetCell::Repeat( SfxRepeatTarget& /*rTarget*/ )
438 // Makes no sense.
441 bool ScUndoSetCell::CanRepeat( SfxRepeatTarget& /*rTarget*/ ) const
443 return false;
446 OUString ScUndoSetCell::GetComment() const
448 return ScGlobal::GetRscString(STR_UNDO_ENTERDATA); // "Input"
451 void ScUndoSetCell::SetChangeTrack()
453 ScDocument* pDoc = pDocShell->GetDocument();
454 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
455 if (pChangeTrack)
457 mnEndChangeAction = pChangeTrack->GetActionMax() + 1;
459 pChangeTrack->AppendContent(maPos, maOldValue);
461 if (mnEndChangeAction > pChangeTrack->GetActionMax())
462 mnEndChangeAction = 0; // Nothing is appended
464 else
465 mnEndChangeAction = 0;
468 void ScUndoSetCell::SetValue( const ScCellValue& rVal )
470 ScDocument* pDoc = pDocShell->GetDocument();
472 switch (rVal.meType)
474 case CELLTYPE_NONE:
475 // empty cell
476 pDoc->SetEmptyCell(maPos);
477 break;
478 case CELLTYPE_VALUE:
479 pDoc->SetValue(maPos, rVal.mfValue);
480 break;
481 case CELLTYPE_STRING:
483 ScSetStringParam aParam;
484 aParam.setTextInput();
485 pDoc->SetString(maPos, rVal.mpString->getString());
487 break;
488 case CELLTYPE_EDIT:
489 pDoc->SetEditText(maPos, rVal.mpEditText->Clone());
490 break;
491 case CELLTYPE_FORMULA:
492 pDoc->SetFormulaCell(maPos, rVal.mpFormula->Clone());
493 break;
494 default:
499 ScUndoPageBreak::ScUndoPageBreak( ScDocShell* pNewDocShell,
500 SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
501 sal_Bool bNewColumn, sal_Bool bNewInsert ) :
502 ScSimpleUndo( pNewDocShell ),
503 nCol( nNewCol ),
504 nRow( nNewRow ),
505 nTab( nNewTab ),
506 bColumn( bNewColumn ),
507 bInsert( bNewInsert )
511 ScUndoPageBreak::~ScUndoPageBreak()
515 OUString ScUndoPageBreak::GetComment() const
517 //"Column break" | "Row break" "insert" | "delete"
518 return OUString ( bColumn ?
519 ( bInsert ?
520 ScGlobal::GetRscString( STR_UNDO_INSCOLBREAK ) :
521 ScGlobal::GetRscString( STR_UNDO_DELCOLBREAK )
523 ( bInsert ?
524 ScGlobal::GetRscString( STR_UNDO_INSROWBREAK ) :
525 ScGlobal::GetRscString( STR_UNDO_DELROWBREAK )
526 ) );
529 void ScUndoPageBreak::DoChange( sal_Bool bInsertP ) const
531 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
533 if (pViewShell)
535 pViewShell->SetTabNo( nTab );
536 pViewShell->MoveCursorAbs( nCol, nRow, SC_FOLLOW_JUMP, false, false );
538 if (bInsertP)
539 pViewShell->InsertPageBreak(bColumn, false);
540 else
541 pViewShell->DeletePageBreak(bColumn, false);
543 pDocShell->GetDocument()->InvalidatePageBreaks(nTab);
547 void ScUndoPageBreak::Undo()
549 BeginUndo();
550 DoChange(!bInsert);
551 EndUndo();
554 void ScUndoPageBreak::Redo()
556 BeginRedo();
557 DoChange(bInsert);
558 EndRedo();
561 void ScUndoPageBreak::Repeat(SfxRepeatTarget& rTarget)
563 if (rTarget.ISA(ScTabViewTarget))
565 ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
567 if (bInsert)
568 rViewShell.InsertPageBreak(bColumn, sal_True);
569 else
570 rViewShell.DeletePageBreak(bColumn, sal_True);
574 bool ScUndoPageBreak::CanRepeat(SfxRepeatTarget& rTarget) const
576 return rTarget.ISA(ScTabViewTarget);
579 ScUndoPrintZoom::ScUndoPrintZoom( ScDocShell* pNewDocShell,
580 SCTAB nT, sal_uInt16 nOS, sal_uInt16 nOP, sal_uInt16 nNS, sal_uInt16 nNP ) :
581 ScSimpleUndo( pNewDocShell ),
582 nTab( nT ),
583 nOldScale( nOS ),
584 nOldPages( nOP ),
585 nNewScale( nNS ),
586 nNewPages( nNP )
590 ScUndoPrintZoom::~ScUndoPrintZoom()
594 OUString ScUndoPrintZoom::GetComment() const
596 return ScGlobal::GetRscString( STR_UNDO_PRINTSCALE );
599 void ScUndoPrintZoom::DoChange( sal_Bool bUndo )
601 sal_uInt16 nScale = bUndo ? nOldScale : nNewScale;
602 sal_uInt16 nPages = bUndo ? nOldPages : nNewPages;
604 ScDocument* pDoc = pDocShell->GetDocument();
605 OUString aStyleName = pDoc->GetPageStyle( nTab );
606 ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
607 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStyleName, SFX_STYLE_FAMILY_PAGE );
608 OSL_ENSURE( pStyleSheet, "PageStyle not found" );
609 if ( pStyleSheet )
611 SfxItemSet& rSet = pStyleSheet->GetItemSet();
612 rSet.Put( SfxUInt16Item( ATTR_PAGE_SCALE, nScale ) );
613 rSet.Put( SfxUInt16Item( ATTR_PAGE_SCALETOPAGES, nPages ) );
615 ScPrintFunc aPrintFunc( pDocShell, pDocShell->GetPrinter(), nTab );
616 aPrintFunc.UpdatePages();
620 void ScUndoPrintZoom::Undo()
622 BeginUndo();
623 DoChange(sal_True);
624 EndUndo();
627 void ScUndoPrintZoom::Redo()
629 BeginRedo();
630 DoChange(false);
631 EndRedo();
634 void ScUndoPrintZoom::Repeat(SfxRepeatTarget& rTarget)
636 if (rTarget.ISA(ScTabViewTarget))
638 ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
639 ScViewData* pViewData = rViewShell.GetViewData();
640 pViewData->GetDocShell()->SetPrintZoom( pViewData->GetTabNo(), nNewScale, nNewPages );
644 bool ScUndoPrintZoom::CanRepeat(SfxRepeatTarget& rTarget) const
646 return rTarget.ISA(ScTabViewTarget);
649 ScUndoThesaurus::ScUndoThesaurus( ScDocShell* pNewDocShell,
650 SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
651 const OUString& rNewUndoStr, const EditTextObject* pUndoTObj,
652 const OUString& rNewRedoStr, const EditTextObject* pRedoTObj) :
653 ScSimpleUndo( pNewDocShell ),
654 nCol( nNewCol ),
655 nRow( nNewRow ),
656 nTab( nNewTab ),
657 aUndoStr( rNewUndoStr ),
658 aRedoStr( rNewRedoStr )
660 pUndoTObject = (pUndoTObj) ? pUndoTObj->Clone() : NULL;
661 pRedoTObject = (pRedoTObj) ? pRedoTObj->Clone() : NULL;
663 ScCellValue aOldCell;
664 if ( pUndoTObject )
666 aOldCell.meType = CELLTYPE_EDIT;
667 aOldCell.mpEditText = pUndoTObject->Clone();
669 else
671 aOldCell.meType = CELLTYPE_STRING;
672 aOldCell.mpString = new svl::SharedString(pDocShell->GetDocument()->GetSharedStringPool().intern(aUndoStr));
674 SetChangeTrack(aOldCell);
677 ScUndoThesaurus::~ScUndoThesaurus()
679 delete pUndoTObject;
680 delete pRedoTObject;
683 OUString ScUndoThesaurus::GetComment() const
685 return ScGlobal::GetRscString( STR_UNDO_THESAURUS ); // "Thesaurus"
688 void ScUndoThesaurus::SetChangeTrack( const ScCellValue& rOldCell )
690 ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
691 if ( pChangeTrack )
693 nEndChangeAction = pChangeTrack->GetActionMax() + 1;
694 pChangeTrack->AppendContent(ScAddress(nCol, nRow, nTab), rOldCell);
695 if ( nEndChangeAction > pChangeTrack->GetActionMax() )
696 nEndChangeAction = 0; // nothing is appended
698 else
699 nEndChangeAction = 0;
702 void ScUndoThesaurus::DoChange( sal_Bool bUndo, const OUString& rStr,
703 const EditTextObject* pTObj )
705 ScDocument* pDoc = pDocShell->GetDocument();
707 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
708 if (pViewShell)
710 pViewShell->SetTabNo( nTab );
711 pViewShell->MoveCursorAbs( nCol, nRow, SC_FOLLOW_JUMP, false, false );
714 ScAddress aPos(nCol, nRow, nTab);
716 if (pTObj)
718 // This is edit text.
719 if (pDoc->GetCellType(aPos) == CELLTYPE_EDIT)
721 ScCellValue aOldCell;
722 if (!bUndo)
723 aOldCell.assign(*pDoc, aPos);
725 // A copy of pTObj will be stored in the cell.
726 pDoc->SetEditText(aPos, *pTObj, pDoc->GetEditPool());
728 if ( !bUndo )
729 SetChangeTrack(aOldCell);
731 else
733 OSL_FAIL("Not CELLTYPE_EDIT for Un/RedoThesaurus");
736 else
738 // This is simple unformatted string.
739 ScCellValue aOldCell;
740 if (!bUndo)
741 aOldCell.assign(*pDoc, aPos);
743 pDoc->SetString( nCol, nRow, nTab, rStr );
745 if (!bUndo)
746 SetChangeTrack(aOldCell);
749 pDocShell->PostPaintCell( nCol, nRow, nTab );
752 void ScUndoThesaurus::Undo()
754 BeginUndo();
755 DoChange( sal_True, aUndoStr, pUndoTObject );
756 ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
757 if ( pChangeTrack )
758 pChangeTrack->Undo( nEndChangeAction, nEndChangeAction );
759 EndUndo();
762 void ScUndoThesaurus::Redo()
764 BeginRedo();
765 DoChange( false, aRedoStr, pRedoTObject );
766 EndRedo();
769 void ScUndoThesaurus::Repeat(SfxRepeatTarget& rTarget)
771 if (rTarget.ISA(ScTabViewTarget))
772 ((ScTabViewTarget&)rTarget).GetViewShell()->DoThesaurus( sal_True );
775 bool ScUndoThesaurus::CanRepeat(SfxRepeatTarget& rTarget) const
777 return rTarget.ISA(ScTabViewTarget);
780 ScUndoReplaceNote::ScUndoReplaceNote( ScDocShell& rDocShell, const ScAddress& rPos,
781 const ScNoteData& rNoteData, bool bInsert, SdrUndoAction* pDrawUndo ) :
782 ScSimpleUndo( &rDocShell ),
783 maPos( rPos ),
784 mpDrawUndo( pDrawUndo )
786 OSL_ENSURE( rNoteData.mpCaption, "ScUndoReplaceNote::ScUndoReplaceNote - missing note caption" );
787 (bInsert ? maNewData : maOldData) = rNoteData;
790 ScUndoReplaceNote::ScUndoReplaceNote( ScDocShell& rDocShell, const ScAddress& rPos,
791 const ScNoteData& rOldData, const ScNoteData& rNewData, SdrUndoAction* pDrawUndo ) :
792 ScSimpleUndo( &rDocShell ),
793 maPos( rPos ),
794 maOldData( rOldData ),
795 maNewData( rNewData ),
796 mpDrawUndo( pDrawUndo )
798 OSL_ENSURE( maOldData.mpCaption || maNewData.mpCaption, "ScUndoReplaceNote::ScUndoReplaceNote - missing note captions" );
799 OSL_ENSURE( !maOldData.mxInitData.get() && !maNewData.mxInitData.get(), "ScUndoReplaceNote::ScUndoReplaceNote - unexpected unitialized note" );
802 ScUndoReplaceNote::~ScUndoReplaceNote()
804 DeleteSdrUndoAction( mpDrawUndo );
807 void ScUndoReplaceNote::Undo()
809 BeginUndo();
810 DoSdrUndoAction( mpDrawUndo, pDocShell->GetDocument() );
811 /* Undo insert -> remove new note.
812 Undo remove -> insert old note.
813 Undo replace -> remove new note, insert old note. */
814 DoRemoveNote( maNewData );
815 DoInsertNote( maOldData );
816 pDocShell->PostPaintCell( maPos );
817 EndUndo();
820 void ScUndoReplaceNote::Redo()
822 BeginRedo();
823 RedoSdrUndoAction( mpDrawUndo );
824 /* Redo insert -> insert new note.
825 Redo remove -> remove old note.
826 Redo replace -> remove old note, insert new note. */
827 DoRemoveNote( maOldData );
828 DoInsertNote( maNewData );
829 pDocShell->PostPaintCell( maPos );
830 EndRedo();
833 void ScUndoReplaceNote::Repeat( SfxRepeatTarget& /*rTarget*/ )
837 bool ScUndoReplaceNote::CanRepeat( SfxRepeatTarget& /*rTarget*/ ) const
839 return false;
842 OUString ScUndoReplaceNote::GetComment() const
844 return ScGlobal::GetRscString( maNewData.mpCaption ?
845 (maOldData.mpCaption ? STR_UNDO_EDITNOTE : STR_UNDO_INSERTNOTE) : STR_UNDO_DELETENOTE );
848 void ScUndoReplaceNote::DoInsertNote( const ScNoteData& rNoteData )
850 if( rNoteData.mpCaption )
852 ScDocument& rDoc = *pDocShell->GetDocument();
853 OSL_ENSURE( !rDoc.GetNote(maPos), "ScUndoReplaceNote::DoInsertNote - unexpected cell note" );
854 ScPostIt* pNote = new ScPostIt( rDoc, maPos, rNoteData, false );
855 rDoc.SetNote( maPos, pNote );
859 void ScUndoReplaceNote::DoRemoveNote( const ScNoteData& rNoteData )
861 if( rNoteData.mpCaption )
863 ScDocument& rDoc = *pDocShell->GetDocument();
864 OSL_ENSURE( rDoc.GetNote(maPos), "ScUndoReplaceNote::DoRemoveNote - missing cell note" );
865 if( ScPostIt* pNote = rDoc.ReleaseNote( maPos ) )
867 /* Forget pointer to caption object to suppress removing the
868 caption object from the drawing layer while deleting pNote
869 (removing the caption is done by a drawing undo action). */
870 pNote->ForgetCaption();
871 delete pNote;
876 ScUndoShowHideNote::ScUndoShowHideNote( ScDocShell& rDocShell, const ScAddress& rPos, bool bShow ) :
877 ScSimpleUndo( &rDocShell ),
878 maPos( rPos ),
879 mbShown( bShow )
883 ScUndoShowHideNote::~ScUndoShowHideNote()
887 void ScUndoShowHideNote::Undo()
889 BeginUndo();
890 if( ScPostIt* pNote = pDocShell->GetDocument()->GetNote(maPos) )
891 pNote->ShowCaption( maPos, !mbShown );
892 EndUndo();
895 void ScUndoShowHideNote::Redo()
897 BeginRedo();
898 if( ScPostIt* pNote = pDocShell->GetDocument()->GetNote(maPos) )
899 pNote->ShowCaption( maPos, mbShown );
900 EndRedo();
903 void ScUndoShowHideNote::Repeat( SfxRepeatTarget& /*rTarget*/ )
907 bool ScUndoShowHideNote::CanRepeat( SfxRepeatTarget& /*rTarget*/ ) const
909 return false;
912 OUString ScUndoShowHideNote::GetComment() const
914 return ScGlobal::GetRscString( mbShown ? STR_UNDO_SHOWNOTE : STR_UNDO_HIDENOTE );
917 ScUndoDetective::ScUndoDetective( ScDocShell* pNewDocShell,
918 SdrUndoAction* pDraw, const ScDetOpData* pOperation,
919 ScDetOpList* pUndoList ) :
920 ScSimpleUndo( pNewDocShell ),
921 pOldList ( pUndoList ),
922 nAction ( 0 ),
923 pDrawUndo ( pDraw )
925 bIsDelete = ( pOperation == NULL );
926 if (!bIsDelete)
928 nAction = (sal_uInt16) pOperation->GetOperation();
929 aPos = pOperation->GetPos();
933 ScUndoDetective::~ScUndoDetective()
935 DeleteSdrUndoAction( pDrawUndo );
936 delete pOldList;
939 OUString ScUndoDetective::GetComment() const
941 sal_uInt16 nId = STR_UNDO_DETDELALL;
942 if ( !bIsDelete )
943 switch ( (ScDetOpType) nAction )
945 case SCDETOP_ADDSUCC: nId = STR_UNDO_DETADDSUCC; break;
946 case SCDETOP_DELSUCC: nId = STR_UNDO_DETDELSUCC; break;
947 case SCDETOP_ADDPRED: nId = STR_UNDO_DETADDPRED; break;
948 case SCDETOP_DELPRED: nId = STR_UNDO_DETDELPRED; break;
949 case SCDETOP_ADDERROR: nId = STR_UNDO_DETADDERROR; break;
952 return ScGlobal::GetRscString( nId );
955 void ScUndoDetective::Undo()
957 BeginUndo();
959 ScDocument* pDoc = pDocShell->GetDocument();
960 DoSdrUndoAction(pDrawUndo, pDoc);
962 if (bIsDelete)
964 if ( pOldList )
965 pDoc->SetDetOpList( new ScDetOpList(*pOldList) );
967 else
969 // Remove entry from list
971 ScDetOpList* pList = pDoc->GetDetOpList();
972 if (pList && pList->Count())
974 ScDetOpDataVector& rVec = pList->GetDataVector();
975 ScDetOpDataVector::iterator it = rVec.begin() + rVec.size() - 1;
976 if ( it->GetOperation() == (ScDetOpType) nAction && it->GetPos() == aPos )
977 rVec.erase( it);
978 else
980 OSL_FAIL("Detective entry could not be found in list");
985 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
986 if (pViewShell)
987 pViewShell->RecalcPPT(); //! use broadcast instead?
989 EndUndo();
992 void ScUndoDetective::Redo()
994 BeginRedo();
996 RedoSdrUndoAction(pDrawUndo);
998 ScDocument* pDoc = pDocShell->GetDocument();
1000 if (bIsDelete)
1001 pDoc->ClearDetectiveOperations();
1002 else
1003 pDoc->AddDetectiveOperation( ScDetOpData( aPos, (ScDetOpType) nAction ) );
1005 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1006 if (pViewShell)
1007 pViewShell->RecalcPPT(); //! use broadcast instead?
1009 EndRedo();
1012 void ScUndoDetective::Repeat(SfxRepeatTarget& /* rTarget */)
1014 // makes no sense
1017 bool ScUndoDetective::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1019 return false;
1022 ScUndoRangeNames::ScUndoRangeNames( ScDocShell* pNewDocShell,
1023 ScRangeName* pOld, ScRangeName* pNew, SCTAB nTab ) :
1024 ScSimpleUndo( pNewDocShell ),
1025 pOldRanges ( pOld ),
1026 pNewRanges ( pNew ),
1027 mnTab ( nTab )
1031 ScUndoRangeNames::~ScUndoRangeNames()
1033 delete pOldRanges;
1034 delete pNewRanges;
1037 OUString ScUndoRangeNames::GetComment() const
1039 return ScGlobal::GetRscString( STR_UNDO_RANGENAMES );
1042 void ScUndoRangeNames::DoChange( sal_Bool bUndo )
1044 ScDocument* pDoc = pDocShell->GetDocument();
1045 pDoc->CompileNameFormula( sal_True ); // CreateFormulaString
1047 if ( bUndo )
1049 if (mnTab >= 0)
1050 pDoc->SetRangeName( mnTab, new ScRangeName( *pOldRanges ) );
1051 else
1052 pDoc->SetRangeName( new ScRangeName( *pOldRanges ) );
1054 else
1056 if (mnTab >= 0)
1057 pDoc->SetRangeName( mnTab, new ScRangeName( *pNewRanges ) );
1058 else
1059 pDoc->SetRangeName( new ScRangeName( *pNewRanges ) );
1062 pDoc->CompileNameFormula( false ); // CompileFormulaString
1064 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
1067 void ScUndoRangeNames::Undo()
1069 BeginUndo();
1070 DoChange( sal_True );
1071 EndUndo();
1074 void ScUndoRangeNames::Redo()
1076 BeginRedo();
1077 DoChange( false );
1078 EndRedo();
1081 void ScUndoRangeNames::Repeat(SfxRepeatTarget& /* rTarget */)
1083 // makes no sense
1086 bool ScUndoRangeNames::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1088 return false;
1091 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */