Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / source / ui / undo / undoblk3.cxx
blobfe94d096e727369aa28f2c9229f16a77948046e7
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 "scitems.hxx"
21 #include <svx/algitem.hxx>
22 #include <editeng/boxitem.hxx>
23 #include <editeng/justifyitem.hxx>
24 #include <svl/srchitem.hxx>
25 #include <sfx2/linkmgr.hxx>
26 #include <sfx2/bindings.hxx>
27 #include <vcl/virdev.hxx>
28 #include <sfx2/app.hxx>
30 #include "undoblk.hxx"
31 #include "sc.hrc"
32 #include "globstr.hrc"
33 #include "global.hxx"
34 #include "rangenam.hxx"
35 #include "arealink.hxx"
36 #include "patattr.hxx"
37 #include "target.hxx"
38 #include "document.hxx"
39 #include "docpool.hxx"
40 #include "table.hxx"
41 #include "docsh.hxx"
42 #include "tabvwsh.hxx"
43 #include "undoolk.hxx"
44 #include "undoutil.hxx"
45 #include "chgtrack.hxx"
46 #include "dociter.hxx"
47 #include "formulacell.hxx"
48 #include "paramisc.hxx"
49 #include "postit.hxx"
50 #include "docuno.hxx"
51 #include "progress.hxx"
52 #include "editutil.hxx"
53 #include "editdataarray.hxx"
55 // STATIC DATA ---------------------------------------------------------------
57 TYPEINIT1(ScUndoDeleteContents, SfxUndoAction);
58 TYPEINIT1(ScUndoFillTable, SfxUndoAction);
59 TYPEINIT1(ScUndoSelectionAttr, SfxUndoAction);
60 TYPEINIT1(ScUndoAutoFill, SfxUndoAction);
61 TYPEINIT1(ScUndoMerge, SfxUndoAction);
62 TYPEINIT1(ScUndoAutoFormat, SfxUndoAction);
63 TYPEINIT1(ScUndoReplace, SfxUndoAction);
64 TYPEINIT1(ScUndoTabOp, SfxUndoAction);
65 TYPEINIT1(ScUndoConversion, SfxUndoAction);
66 TYPEINIT1(ScUndoRefConversion, SfxUndoAction);
67 TYPEINIT1(ScUndoRefreshLink, SfxUndoAction);
68 TYPEINIT1(ScUndoInsertAreaLink, SfxUndoAction);
69 TYPEINIT1(ScUndoRemoveAreaLink, SfxUndoAction);
70 TYPEINIT1(ScUndoUpdateAreaLink, SfxUndoAction);
72 // TODO:
73 /*A*/ // SetOptimalHeight on Document, when no View
75 ScUndoDeleteContents::ScUndoDeleteContents(
76 ScDocShell* pNewDocShell,
77 const ScMarkData& rMark, const ScRange& rRange,
78 ScDocument* pNewUndoDoc, sal_Bool bNewMulti,
79 sal_uInt16 nNewFlags, sal_Bool bObjects )
80 : ScSimpleUndo( pNewDocShell ),
81 aRange ( rRange ),
82 aMarkData ( rMark ),
83 pUndoDoc ( pNewUndoDoc ),
84 pDrawUndo ( NULL ),
85 nFlags ( nNewFlags ),
86 bMulti ( bNewMulti ) // unnecessary
88 if (bObjects)
89 pDrawUndo = GetSdrUndoAction( pDocShell->GetDocument() );
91 if ( !(aMarkData.IsMarked() || aMarkData.IsMultiMarked()) ) // if no cell is selected:
92 aMarkData.SetMarkArea( aRange ); // select cell under cursor
94 SetChangeTrack();
97 ScUndoDeleteContents::~ScUndoDeleteContents()
99 delete pUndoDoc;
100 DeleteSdrUndoAction( pDrawUndo );
103 OUString ScUndoDeleteContents::GetComment() const
105 return ScGlobal::GetRscString( STR_UNDO_DELETECONTENTS ); // "Delete"
108 void ScUndoDeleteContents::SetChangeTrack()
110 ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
111 if ( pChangeTrack && (nFlags & IDF_CONTENTS) )
112 pChangeTrack->AppendContentRange( aRange, pUndoDoc,
113 nStartChangeAction, nEndChangeAction );
114 else
115 nStartChangeAction = nEndChangeAction = 0;
118 void ScUndoDeleteContents::DoChange( const sal_Bool bUndo )
120 ScDocument* pDoc = pDocShell->GetDocument();
122 SetViewMarkData( aMarkData );
124 sal_uInt16 nExtFlags = 0;
126 if (bUndo) // only Undo
128 sal_uInt16 nUndoFlags = IDF_NONE; // copy either all or none of the content
129 if (nFlags & IDF_CONTENTS) // (Only the correct ones have been copied into UndoDoc)
130 nUndoFlags |= IDF_CONTENTS;
131 if (nFlags & IDF_ATTRIB)
132 nUndoFlags |= IDF_ATTRIB;
133 if (nFlags & IDF_EDITATTR) // Edit-Engine attribute
134 nUndoFlags |= IDF_STRING; // -> Cells will be changed
135 // do not create clones of note captions, they will be restored via drawing undo
136 nUndoFlags |= IDF_NOCAPTIONS;
138 ScRange aCopyRange = aRange;
139 SCTAB nTabCount = pDoc->GetTableCount();
140 aCopyRange.aStart.SetTab(0);
141 aCopyRange.aEnd.SetTab(nTabCount-1);
143 pUndoDoc->CopyToDocument( aCopyRange, nUndoFlags, bMulti, pDoc, &aMarkData );
145 DoSdrUndoAction( pDrawUndo, pDoc );
147 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
148 if ( pChangeTrack )
149 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
151 pDocShell->UpdatePaintExt( nExtFlags, aRange ); // content after the change
153 else // only Redo
155 pDocShell->UpdatePaintExt( nExtFlags, aRange ); // content before the change
157 aMarkData.MarkToMulti();
158 RedoSdrUndoAction( pDrawUndo );
159 // do not delete objects and note captions, they have been removed via drawing undo
160 sal_uInt16 nRedoFlags = (nFlags & ~IDF_OBJECTS) | IDF_NOCAPTIONS;
161 pDoc->DeleteSelection( nRedoFlags, aMarkData );
162 aMarkData.MarkToSimple();
164 SetChangeTrack();
167 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
168 if ( !( (pViewShell) && pViewShell->AdjustRowHeight(
169 aRange.aStart.Row(), aRange.aEnd.Row() ) ) )
170 /*A*/ pDocShell->PostPaint( aRange, PAINT_GRID | PAINT_EXTRAS, nExtFlags );
172 pDocShell->PostDataChanged();
173 if (pViewShell)
174 pViewShell->CellContentChanged();
176 ShowTable( aRange );
179 void ScUndoDeleteContents::Undo()
181 BeginUndo();
182 DoChange( sal_True );
183 EndUndo();
185 BroadcastChanges(aRange);
186 HelperNotifyChanges::NotifyIfChangesListeners(*pDocShell, aRange);
189 void ScUndoDeleteContents::Redo()
191 BeginRedo();
192 DoChange( false );
193 EndRedo();
195 BroadcastChanges(aRange);
196 HelperNotifyChanges::NotifyIfChangesListeners(*pDocShell, aRange);
199 void ScUndoDeleteContents::Repeat(SfxRepeatTarget& rTarget)
201 if (rTarget.ISA(ScTabViewTarget))
202 ((ScTabViewTarget&)rTarget).GetViewShell()->DeleteContents( nFlags, sal_True );
205 bool ScUndoDeleteContents::CanRepeat(SfxRepeatTarget& rTarget) const
207 return rTarget.ISA(ScTabViewTarget);
210 ScUndoFillTable::ScUndoFillTable( ScDocShell* pNewDocShell,
211 const ScMarkData& rMark,
212 SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
213 SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
214 ScDocument* pNewUndoDoc, sal_Bool bNewMulti, SCTAB nSrc,
215 sal_uInt16 nFlg, sal_uInt16 nFunc, sal_Bool bSkip, sal_Bool bLink )
216 : ScSimpleUndo( pNewDocShell ),
217 aRange ( nStartX, nStartY, nStartZ, nEndX, nEndY, nEndZ ),
218 aMarkData ( rMark ),
219 pUndoDoc ( pNewUndoDoc ),
220 nFlags ( nFlg ),
221 nFunction ( nFunc ),
222 nSrcTab ( nSrc ),
223 bMulti ( bNewMulti ),
224 bSkipEmpty ( bSkip ),
225 bAsLink ( bLink )
227 SetChangeTrack();
230 ScUndoFillTable::~ScUndoFillTable()
232 delete pUndoDoc;
235 OUString ScUndoFillTable::GetComment() const
237 return ScGlobal::GetRscString( STR_FILL_TAB );
240 void ScUndoFillTable::SetChangeTrack()
242 ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
243 if ( pChangeTrack )
245 SCTAB nTabCount = pDocShell->GetDocument()->GetTableCount();
246 ScRange aWorkRange(aRange);
247 nStartChangeAction = 0;
248 sal_uLong nTmpAction;
249 ScMarkData::iterator itr = aMarkData.begin(), itrEnd = aMarkData.end();
250 for (; itr != itrEnd && *itr < nTabCount; ++itr)
252 if (*itr != nSrcTab)
254 aWorkRange.aStart.SetTab(*itr);
255 aWorkRange.aEnd.SetTab(*itr);
256 pChangeTrack->AppendContentRange( aWorkRange, pUndoDoc,
257 nTmpAction, nEndChangeAction );
258 if ( !nStartChangeAction )
259 nStartChangeAction = nTmpAction;
263 else
264 nStartChangeAction = nEndChangeAction = 0;
267 void ScUndoFillTable::DoChange( const sal_Bool bUndo )
269 ScDocument* pDoc = pDocShell->GetDocument();
271 SetViewMarkData( aMarkData );
273 if (bUndo) // only Undo
275 SCTAB nTabCount = pDoc->GetTableCount();
276 ScRange aWorkRange(aRange);
277 ScMarkData::iterator itr = aMarkData.begin(), itrEnd = aMarkData.end();
278 for (; itr != itrEnd && *itr < nTabCount; ++itr)
279 if (*itr != nSrcTab)
281 aWorkRange.aStart.SetTab(*itr);
282 aWorkRange.aEnd.SetTab(*itr);
283 if (bMulti)
284 pDoc->DeleteSelectionTab( *itr, IDF_ALL, aMarkData );
285 else
286 pDoc->DeleteAreaTab( aWorkRange, IDF_ALL );
287 pUndoDoc->CopyToDocument( aWorkRange, IDF_ALL, bMulti, pDoc, &aMarkData );
290 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
291 if ( pChangeTrack )
292 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
294 else // only Redo
296 aMarkData.MarkToMulti();
297 pDoc->FillTabMarked( nSrcTab, aMarkData, nFlags, nFunction, bSkipEmpty, bAsLink );
298 aMarkData.MarkToSimple();
299 SetChangeTrack();
302 pDocShell->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_GRID|PAINT_EXTRAS);
303 pDocShell->PostDataChanged();
305 // CellContentChanged comes with the selection
307 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
308 if (pViewShell)
310 SCTAB nTab = pViewShell->GetViewData()->GetTabNo();
311 if ( !aMarkData.GetTableSelect(nTab) )
312 pViewShell->SetTabNo( nSrcTab );
314 pViewShell->DoneBlockMode(); // causes problems otherwise since selection is on the wrong sheet.
318 void ScUndoFillTable::Undo()
320 BeginUndo();
321 DoChange( sal_True );
322 EndUndo();
325 void ScUndoFillTable::Redo()
327 BeginRedo();
328 DoChange( false );
329 EndRedo();
332 void ScUndoFillTable::Repeat(SfxRepeatTarget& rTarget)
334 if (rTarget.ISA(ScTabViewTarget))
335 ((ScTabViewTarget&)rTarget).GetViewShell()->FillTab( nFlags, nFunction, bSkipEmpty, bAsLink );
338 bool ScUndoFillTable::CanRepeat(SfxRepeatTarget& rTarget) const
340 return rTarget.ISA(ScTabViewTarget);
343 ScUndoSelectionAttr::ScUndoSelectionAttr( ScDocShell* pNewDocShell,
344 const ScMarkData& rMark,
345 SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
346 SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
347 ScDocument* pNewUndoDoc, sal_Bool bNewMulti,
348 const ScPatternAttr* pNewApply,
349 const SvxBoxItem* pNewOuter, const SvxBoxInfoItem* pNewInner )
350 : ScSimpleUndo( pNewDocShell ),
351 aMarkData ( rMark ),
352 aRange ( nStartX, nStartY, nStartZ, nEndX, nEndY, nEndZ ),
353 mpDataArray(new ScEditDataArray),
354 pUndoDoc ( pNewUndoDoc ),
355 bMulti ( bNewMulti )
357 ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
358 pApplyPattern = (ScPatternAttr*) &pPool->Put( *pNewApply );
359 pLineOuter = pNewOuter ? (SvxBoxItem*) &pPool->Put( *pNewOuter ) : NULL;
360 pLineInner = pNewInner ? (SvxBoxInfoItem*) &pPool->Put( *pNewInner ) : NULL;
363 ScUndoSelectionAttr::~ScUndoSelectionAttr()
365 ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
366 pPool->Remove(*pApplyPattern);
367 if (pLineOuter)
368 pPool->Remove(*pLineOuter);
369 if (pLineInner)
370 pPool->Remove(*pLineInner);
372 delete pUndoDoc;
375 OUString ScUndoSelectionAttr::GetComment() const
377 //"Attribute" "/Lines"
378 return ScGlobal::GetRscString( pLineOuter ? STR_UNDO_SELATTRLINES : STR_UNDO_SELATTR );
381 ScEditDataArray* ScUndoSelectionAttr::GetDataArray()
383 return mpDataArray.get();
386 void ScUndoSelectionAttr::DoChange( const sal_Bool bUndo )
388 ScDocument* pDoc = pDocShell->GetDocument();
390 SetViewMarkData( aMarkData );
392 ScRange aEffRange( aRange );
393 if ( pDoc->HasAttrib( aEffRange, HASATTR_MERGED ) ) // merged cells?
394 pDoc->ExtendMerge( aEffRange );
396 sal_uInt16 nExtFlags = 0;
397 pDocShell->UpdatePaintExt( nExtFlags, aEffRange );
399 ChangeEditData(bUndo);
401 if (bUndo) // only for Undo
403 ScRange aCopyRange = aRange;
404 SCTAB nTabCount = pDoc->GetTableCount();
405 aCopyRange.aStart.SetTab(0);
406 aCopyRange.aEnd.SetTab(nTabCount-1);
407 pUndoDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, bMulti, pDoc, &aMarkData );
409 else // only for Redo
411 aMarkData.MarkToMulti();
412 pDoc->ApplySelectionPattern( *pApplyPattern, aMarkData );
413 aMarkData.MarkToSimple();
415 if (pLineOuter)
416 pDoc->ApplySelectionFrame( aMarkData, pLineOuter, pLineInner );
419 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
420 if ( !( (pViewShell) && pViewShell->AdjustBlockHeight() ) )
421 /*A*/ pDocShell->PostPaint( aEffRange, PAINT_GRID | PAINT_EXTRAS, nExtFlags );
423 ShowTable( aRange );
426 void ScUndoSelectionAttr::ChangeEditData( const bool bUndo )
428 ScDocument* pDoc = pDocShell->GetDocument();
429 for (const ScEditDataArray::Item* pItem = mpDataArray->First(); pItem; pItem = mpDataArray->Next())
431 ScAddress aPos(pItem->GetCol(), pItem->GetRow(), pItem->GetTab());
432 if (pDoc->GetCellType(aPos) != CELLTYPE_EDIT)
433 continue;
435 if (bUndo)
437 if (pItem->GetOldData())
438 pDoc->SetEditText(aPos, *pItem->GetOldData(), NULL);
439 else
440 pDoc->SetEmptyCell(aPos);
442 else
444 if (pItem->GetNewData())
445 pDoc->SetEditText(aPos, *pItem->GetNewData(), NULL);
446 else
447 pDoc->SetEmptyCell(aPos);
452 void ScUndoSelectionAttr::Undo()
454 BeginUndo();
455 DoChange( sal_True );
456 EndUndo();
459 void ScUndoSelectionAttr::Redo()
461 BeginRedo();
462 DoChange( false );
463 EndRedo();
466 void ScUndoSelectionAttr::Repeat(SfxRepeatTarget& rTarget)
468 if (rTarget.ISA(ScTabViewTarget))
470 ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
471 if (pLineOuter)
472 rViewShell.ApplyPatternLines( *pApplyPattern, pLineOuter, pLineInner, sal_True );
473 else
474 rViewShell.ApplySelectionPattern( *pApplyPattern, sal_True );
478 bool ScUndoSelectionAttr::CanRepeat(SfxRepeatTarget& rTarget) const
480 return rTarget.ISA(ScTabViewTarget);
483 ScUndoAutoFill::ScUndoAutoFill( ScDocShell* pNewDocShell,
484 const ScRange& rRange, const ScRange& rSourceArea,
485 ScDocument* pNewUndoDoc, const ScMarkData& rMark,
486 FillDir eNewFillDir, FillCmd eNewFillCmd, FillDateCmd eNewFillDateCmd,
487 double fNewStartValue, double fNewStepValue, double fNewMaxValue )
488 : ScBlockUndo( pNewDocShell, rRange, SC_UNDO_AUTOHEIGHT ),
489 aSource ( rSourceArea ),
490 aMarkData ( rMark ),
491 pUndoDoc ( pNewUndoDoc ),
492 eFillDir ( eNewFillDir ),
493 eFillCmd ( eNewFillCmd ),
494 eFillDateCmd ( eNewFillDateCmd ),
495 fStartValue ( fNewStartValue ),
496 fStepValue ( fNewStepValue ),
497 fMaxValue ( fNewMaxValue )
499 SetChangeTrack();
502 ScUndoAutoFill::~ScUndoAutoFill()
504 delete pUndoDoc;
507 OUString ScUndoAutoFill::GetComment() const
509 return ScGlobal::GetRscString( STR_UNDO_AUTOFILL ); //"Fill"
512 void ScUndoAutoFill::SetChangeTrack()
514 ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
515 if ( pChangeTrack )
516 pChangeTrack->AppendContentRange( aBlockRange, pUndoDoc,
517 nStartChangeAction, nEndChangeAction );
518 else
519 nStartChangeAction = nEndChangeAction = 0;
522 void ScUndoAutoFill::Undo()
524 BeginUndo();
526 ScDocument* pDoc = pDocShell->GetDocument();
528 SCTAB nTabCount = pDoc->GetTableCount();
529 ScMarkData::iterator itr = aMarkData.begin(), itrEnd = aMarkData.end();
530 for (; itr != itrEnd && *itr < nTabCount; ++itr)
532 ScRange aWorkRange = aBlockRange;
533 aWorkRange.aStart.SetTab(*itr);
534 aWorkRange.aEnd.SetTab(*itr);
536 sal_uInt16 nExtFlags = 0;
537 pDocShell->UpdatePaintExt( nExtFlags, aWorkRange );
538 pDoc->DeleteAreaTab( aWorkRange, IDF_AUTOFILL );
539 pUndoDoc->CopyToDocument( aWorkRange, IDF_AUTOFILL, false, pDoc );
541 pDoc->ExtendMerge( aWorkRange, sal_True );
542 pDocShell->PostPaint( aWorkRange, PAINT_GRID, nExtFlags );
544 pDocShell->PostDataChanged();
545 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
546 if (pViewShell)
547 pViewShell->CellContentChanged();
549 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
550 if ( pChangeTrack )
551 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
553 EndUndo();
556 void ScUndoAutoFill::Redo()
558 BeginRedo();
560 //! Select sheet
562 SCCOLROW nCount = 0;
563 switch (eFillDir)
565 case FILL_TO_BOTTOM:
566 nCount = aBlockRange.aEnd.Row() - aSource.aEnd.Row();
567 break;
568 case FILL_TO_RIGHT:
569 nCount = aBlockRange.aEnd.Col() - aSource.aEnd.Col();
570 break;
571 case FILL_TO_TOP:
572 nCount = aSource.aStart.Row() - aBlockRange.aStart.Row();
573 break;
574 case FILL_TO_LEFT:
575 nCount = aSource.aStart.Col() - aBlockRange.aStart.Col();
576 break;
579 ScDocument* pDoc = pDocShell->GetDocument();
580 if ( fStartValue != MAXDOUBLE )
582 SCCOL nValX = (eFillDir == FILL_TO_LEFT) ? aSource.aEnd.Col() : aSource.aStart.Col();
583 SCROW nValY = (eFillDir == FILL_TO_TOP ) ? aSource.aEnd.Row() : aSource.aStart.Row();
584 SCTAB nTab = aSource.aStart.Tab();
585 pDoc->SetValue( nValX, nValY, nTab, fStartValue );
587 sal_uLong nProgCount;
588 if (eFillDir == FILL_TO_BOTTOM || eFillDir == FILL_TO_TOP)
589 nProgCount = aSource.aEnd.Col() - aSource.aStart.Col() + 1;
590 else
591 nProgCount = aSource.aEnd.Row() - aSource.aStart.Row() + 1;
592 nProgCount *= nCount;
593 ScProgress aProgress( pDoc->GetDocumentShell(),
594 ScGlobal::GetRscString(STR_FILL_SERIES_PROGRESS), nProgCount );
596 pDoc->Fill( aSource.aStart.Col(), aSource.aStart.Row(),
597 aSource.aEnd.Col(), aSource.aEnd.Row(), &aProgress,
598 aMarkData, nCount,
599 eFillDir, eFillCmd, eFillDateCmd,
600 fStepValue, fMaxValue );
602 SetChangeTrack();
604 pDocShell->PostPaint( aBlockRange, PAINT_GRID );
605 pDocShell->PostDataChanged();
606 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
607 if (pViewShell)
608 pViewShell->CellContentChanged();
610 EndRedo();
613 void ScUndoAutoFill::Repeat(SfxRepeatTarget& rTarget)
615 if (rTarget.ISA(ScTabViewTarget))
617 ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
618 if (eFillCmd==FILL_SIMPLE)
619 rViewShell.FillSimple( eFillDir, sal_True );
620 else
621 rViewShell.FillSeries( eFillDir, eFillCmd, eFillDateCmd,
622 fStartValue, fStepValue, fMaxValue, sal_True );
626 bool ScUndoAutoFill::CanRepeat(SfxRepeatTarget& rTarget) const
628 return rTarget.ISA(ScTabViewTarget);
631 ScUndoMerge::ScUndoMerge( ScDocShell* pNewDocShell, const ScCellMergeOption& rOption,
632 bool bMergeContents, ScDocument* pUndoDoc, SdrUndoAction* pDrawUndo )
633 : ScSimpleUndo( pNewDocShell ),
634 maOption(rOption),
635 mbMergeContents( bMergeContents ),
636 mpUndoDoc( pUndoDoc ),
637 mpDrawUndo( pDrawUndo )
641 ScUndoMerge::~ScUndoMerge()
643 delete mpUndoDoc;
644 DeleteSdrUndoAction( mpDrawUndo );
647 OUString ScUndoMerge::GetComment() const
649 return ScGlobal::GetRscString( STR_UNDO_MERGE );
652 void ScUndoMerge::DoChange( bool bUndo ) const
654 using ::std::set;
656 if (maOption.maTabs.empty())
657 // Nothing to do.
658 return;
660 ScDocument* pDoc = pDocShell->GetDocument();
661 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
663 ScRange aCurRange = maOption.getSingleRange(pDocShell->GetCurTab());
664 ScUndoUtil::MarkSimpleBlock(pDocShell, aCurRange);
666 for (set<SCTAB>::const_iterator itr = maOption.maTabs.begin(), itrEnd = maOption.maTabs.end();
667 itr != itrEnd; ++itr)
669 SCTAB nTab = *itr;
670 ScRange aRange = maOption.getSingleRange(nTab);
672 if (bUndo)
673 // remove merge (contents are copied back below from undo document)
674 pDoc->RemoveMerge( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aStart.Tab() );
675 else
677 // repeat merge, but do not remove note captions (will be done by drawing redo below)
678 pDoc->DoMerge( aRange.aStart.Tab(),
679 aRange.aStart.Col(), aRange.aStart.Row(),
680 aRange.aEnd.Col(), aRange.aEnd.Row(), false );
682 if (maOption.mbCenter)
684 pDoc->ApplyAttr( aRange.aStart.Col(), aRange.aStart.Row(),
685 aRange.aStart.Tab(),
686 SvxHorJustifyItem( SVX_HOR_JUSTIFY_CENTER, ATTR_HOR_JUSTIFY ) );
687 pDoc->ApplyAttr( aRange.aStart.Col(), aRange.aStart.Row(),
688 aRange.aStart.Tab(),
689 SvxVerJustifyItem( SVX_VER_JUSTIFY_CENTER, ATTR_VER_JUSTIFY ) );
693 // undo -> copy back deleted contents
694 if (bUndo && mpUndoDoc)
696 pDoc->DeleteAreaTab( aRange, IDF_CONTENTS|IDF_NOCAPTIONS );
697 mpUndoDoc->CopyToDocument( aRange, IDF_ALL|IDF_NOCAPTIONS, false, pDoc );
700 // redo -> merge contents again
701 else if (!bUndo && mbMergeContents)
703 pDoc->DoMergeContents( aRange.aStart.Tab(),
704 aRange.aStart.Col(), aRange.aStart.Row(),
705 aRange.aEnd.Col(), aRange.aEnd.Row() );
708 if (bUndo)
709 DoSdrUndoAction( mpDrawUndo, pDoc );
710 else
711 RedoSdrUndoAction( mpDrawUndo );
713 bool bDidPaint = false;
714 if ( pViewShell )
716 pViewShell->SetTabNo(nTab);
717 bDidPaint = pViewShell->AdjustRowHeight(maOption.mnStartRow, maOption.mnEndRow);
720 if (!bDidPaint)
721 ScUndoUtil::PaintMore(pDocShell, aRange);
724 ShowTable(aCurRange);
727 void ScUndoMerge::Undo()
729 BeginUndo();
730 DoChange( true );
731 EndUndo();
734 void ScUndoMerge::Redo()
736 BeginRedo();
737 DoChange( false );
738 EndRedo();
741 void ScUndoMerge::Repeat(SfxRepeatTarget& rTarget)
743 if (rTarget.ISA(ScTabViewTarget))
745 ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
746 sal_Bool bCont = false;
747 rViewShell.MergeCells( false, bCont, sal_True );
751 bool ScUndoMerge::CanRepeat(SfxRepeatTarget& rTarget) const
753 return rTarget.ISA(ScTabViewTarget);
756 ScUndoAutoFormat::ScUndoAutoFormat( ScDocShell* pNewDocShell,
757 const ScRange& rRange, ScDocument* pNewUndoDoc,
758 const ScMarkData& rMark, sal_Bool bNewSize, sal_uInt16 nNewFormatNo )
759 : ScBlockUndo( pNewDocShell, rRange, bNewSize ? SC_UNDO_MANUALHEIGHT : SC_UNDO_AUTOHEIGHT ),
760 pUndoDoc ( pNewUndoDoc ),
761 aMarkData ( rMark ),
762 bSize ( bNewSize ),
763 nFormatNo ( nNewFormatNo )
767 ScUndoAutoFormat::~ScUndoAutoFormat()
769 delete pUndoDoc;
772 OUString ScUndoAutoFormat::GetComment() const
774 return ScGlobal::GetRscString( STR_UNDO_AUTOFORMAT ); //"Auto-Format"
777 void ScUndoAutoFormat::Undo()
779 BeginUndo();
781 ScDocument* pDoc = pDocShell->GetDocument();
783 SCTAB nTabCount = pDoc->GetTableCount();
784 pDoc->DeleteArea( aBlockRange.aStart.Col(), aBlockRange.aStart.Row(),
785 aBlockRange.aEnd.Col(), aBlockRange.aEnd.Row(),
786 aMarkData, IDF_ATTRIB );
787 ScRange aCopyRange = aBlockRange;
788 aCopyRange.aStart.SetTab(0);
789 aCopyRange.aEnd.SetTab(nTabCount-1);
790 pUndoDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, false, pDoc, &aMarkData );
792 // cell heights and widths (IDF_NONE)
793 if (bSize)
795 SCCOL nStartX = aBlockRange.aStart.Col();
796 SCROW nStartY = aBlockRange.aStart.Row();
797 SCTAB nStartZ = aBlockRange.aStart.Tab();
798 SCCOL nEndX = aBlockRange.aEnd.Col();
799 SCROW nEndY = aBlockRange.aEnd.Row();
800 SCTAB nEndZ = aBlockRange.aEnd.Tab();
802 pUndoDoc->CopyToDocument( nStartX, 0, 0, nEndX, MAXROW, nTabCount-1,
803 IDF_NONE, false, pDoc, &aMarkData );
804 pUndoDoc->CopyToDocument( 0, nStartY, 0, MAXCOL, nEndY, nTabCount-1,
805 IDF_NONE, false, pDoc, &aMarkData );
806 pDocShell->PostPaint( 0, 0, nStartZ, MAXCOL, MAXROW, nEndZ,
807 PAINT_GRID | PAINT_LEFT | PAINT_TOP, SC_PF_LINES );
809 else
810 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES );
812 EndUndo();
815 void ScUndoAutoFormat::Redo()
817 BeginRedo();
819 ScDocument* pDoc = pDocShell->GetDocument();
821 SCCOL nStartX = aBlockRange.aStart.Col();
822 SCROW nStartY = aBlockRange.aStart.Row();
823 SCTAB nStartZ = aBlockRange.aStart.Tab();
824 SCCOL nEndX = aBlockRange.aEnd.Col();
825 SCROW nEndY = aBlockRange.aEnd.Row();
826 SCTAB nEndZ = aBlockRange.aEnd.Tab();
828 pDoc->AutoFormat( nStartX, nStartY, nEndX, nEndY, nFormatNo, aMarkData );
830 if (bSize)
832 VirtualDevice aVirtDev;
833 Fraction aZoomX(1,1);
834 Fraction aZoomY = aZoomX;
835 double nPPTX,nPPTY;
836 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
837 if (pViewShell)
839 ScViewData* pData = pViewShell->GetViewData();
840 nPPTX = pData->GetPPTX();
841 nPPTY = pData->GetPPTY();
842 aZoomX = pData->GetZoomX();
843 aZoomY = pData->GetZoomY();
845 else
847 // Keep zoom at 100
848 nPPTX = ScGlobal::nScreenPPTX;
849 nPPTY = ScGlobal::nScreenPPTY;
852 sal_Bool bFormula = false; // remember
854 for (SCTAB nTab=nStartZ; nTab<=nEndZ; nTab++)
856 ScMarkData aDestMark;
857 aDestMark.SelectOneTable( nTab );
858 aDestMark.SetMarkArea( ScRange( nStartX, nStartY, nTab, nEndX, nEndY, nTab ) );
859 aDestMark.MarkToMulti();
861 // as SC_SIZE_VISOPT
862 for (SCROW nRow=nStartY; nRow<=nEndY; nRow++)
864 sal_uInt8 nOld = pDoc->GetRowFlags(nRow,nTab);
865 bool bHidden = pDoc->RowHidden(nRow, nTab);
866 if ( !bHidden && ( nOld & CR_MANUALSIZE ) )
867 pDoc->SetRowFlags( nRow, nTab, nOld & ~CR_MANUALSIZE );
869 pDoc->SetOptimalHeight( nStartY, nEndY, nTab, 0, &aVirtDev,
870 nPPTX, nPPTY, aZoomX, aZoomY, false );
872 for (SCCOL nCol=nStartX; nCol<=nEndX; nCol++)
873 if (!pDoc->ColHidden(nCol, nTab))
875 sal_uInt16 nThisSize = STD_EXTRA_WIDTH + pDoc->GetOptimalColWidth( nCol, nTab,
876 &aVirtDev, nPPTX, nPPTY, aZoomX, aZoomY, bFormula,
877 &aDestMark );
878 pDoc->SetColWidth( nCol, nTab, nThisSize );
879 pDoc->ShowCol( nCol, nTab, sal_True );
883 pDocShell->PostPaint( 0, 0, nStartZ,
884 MAXCOL, MAXROW, nEndZ,
885 PAINT_GRID | PAINT_LEFT | PAINT_TOP, SC_PF_LINES);
887 else
888 pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES );
890 EndRedo();
893 void ScUndoAutoFormat::Repeat(SfxRepeatTarget& rTarget)
895 if (rTarget.ISA(ScTabViewTarget))
896 ((ScTabViewTarget&)rTarget).GetViewShell()->AutoFormat( nFormatNo, sal_True );
899 bool ScUndoAutoFormat::CanRepeat(SfxRepeatTarget& rTarget) const
901 return rTarget.ISA(ScTabViewTarget);
904 ScUndoReplace::ScUndoReplace( ScDocShell* pNewDocShell, const ScMarkData& rMark,
905 SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
906 const OUString& rNewUndoStr, ScDocument* pNewUndoDoc,
907 const SvxSearchItem* pItem )
908 : ScSimpleUndo( pNewDocShell ),
909 aCursorPos ( nCurX, nCurY, nCurZ ),
910 aMarkData ( rMark ),
911 aUndoStr ( rNewUndoStr ),
912 pUndoDoc ( pNewUndoDoc )
914 pSearchItem = new SvxSearchItem( *pItem );
915 SetChangeTrack();
918 ScUndoReplace::~ScUndoReplace()
920 delete pUndoDoc;
921 delete pSearchItem;
924 void ScUndoReplace::SetChangeTrack()
926 ScDocument* pDoc = pDocShell->GetDocument();
927 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
928 if ( pChangeTrack )
930 if ( pUndoDoc )
931 { //! UndoDoc includes only the changed cells,
932 // that is why an Iterator can be used
933 pChangeTrack->AppendContentsIfInRefDoc( pUndoDoc,
934 nStartChangeAction, nEndChangeAction );
936 else
938 nStartChangeAction = pChangeTrack->GetActionMax() + 1;
939 ScChangeActionContent* pContent = new ScChangeActionContent(
940 ScRange( aCursorPos) );
941 ScCellValue aCell;
942 aCell.assign(*pDoc, aCursorPos);
943 pContent->SetOldValue( aUndoStr, pDoc );
944 pContent->SetNewValue(aCell, pDoc);
945 pChangeTrack->Append( pContent );
946 nEndChangeAction = pChangeTrack->GetActionMax();
949 else
950 nStartChangeAction = nEndChangeAction = 0;
953 OUString ScUndoReplace::GetComment() const
955 return ScGlobal::GetRscString( STR_UNDO_REPLACE ); // "Replace"
958 void ScUndoReplace::Undo()
960 BeginUndo();
962 ScDocument* pDoc = pDocShell->GetDocument();
963 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
965 ShowTable( aCursorPos.Tab() );
967 if (pUndoDoc) // only for ReplaceAll !!
969 OSL_ENSURE(pSearchItem->GetCommand() == SVX_SEARCHCMD_REPLACE_ALL,
970 "ScUndoReplace:: Wrong Mode");
972 SetViewMarkData( aMarkData );
974 //! selected sheet
975 //! select range ?
977 // Undo document has no row/column information, thus copy with
978 // bColRowFlags = FALSE to not destroy Outline groups
980 sal_uInt16 nUndoFlags = (pSearchItem->GetPattern()) ? IDF_ATTRIB : IDF_CONTENTS;
981 pUndoDoc->CopyToDocument( 0, 0, 0,
982 MAXCOL, MAXROW, MAXTAB,
983 nUndoFlags, false, pDoc, NULL, false ); // without row flags
984 pDocShell->PostPaintGridAll();
986 else if (pSearchItem->GetPattern() &&
987 pSearchItem->GetCommand() == SVX_SEARCHCMD_REPLACE)
989 OUString aTempStr = pSearchItem->GetSearchString(); // toggle
990 pSearchItem->SetSearchString(pSearchItem->GetReplaceString());
991 pSearchItem->SetReplaceString(aTempStr);
992 pDoc->ReplaceStyle( *pSearchItem,
993 aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(),
994 aMarkData, sal_True);
995 pSearchItem->SetReplaceString(pSearchItem->GetSearchString());
996 pSearchItem->SetSearchString(aTempStr);
997 if (pViewShell)
998 pViewShell->MoveCursorAbs( aCursorPos.Col(), aCursorPos.Row(),
999 SC_FOLLOW_JUMP, false, false );
1000 pDocShell->PostPaintGridAll();
1002 else if (pSearchItem->GetCellType() == SVX_SEARCHIN_NOTE)
1004 ScPostIt* pNote = pDoc->GetNote(aCursorPos);
1005 OSL_ENSURE( pNote, "ScUndoReplace::Undo - cell does not contain a note" );
1006 if (pNote)
1007 pNote->SetText( aCursorPos, aUndoStr );
1008 if (pViewShell)
1009 pViewShell->MoveCursorAbs( aCursorPos.Col(), aCursorPos.Row(),
1010 SC_FOLLOW_JUMP, false, false );
1012 else
1014 // aUndoStr may contain line breaks
1015 if ( aUndoStr.indexOf('\n') != -1 )
1017 ScFieldEditEngine& rEngine = pDoc->GetEditEngine();
1018 rEngine.SetText(aUndoStr);
1019 pDoc->SetEditText(aCursorPos, rEngine.CreateTextObject());
1021 else
1022 pDoc->SetString( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(), aUndoStr );
1023 if (pViewShell)
1024 pViewShell->MoveCursorAbs( aCursorPos.Col(), aCursorPos.Row(),
1025 SC_FOLLOW_JUMP, false, false );
1026 pDocShell->PostPaintGridAll();
1029 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
1030 if ( pChangeTrack )
1031 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
1033 EndUndo();
1036 void ScUndoReplace::Redo()
1038 BeginRedo();
1040 ScDocument* pDoc = pDocShell->GetDocument();
1041 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1043 if (pViewShell)
1044 pViewShell->MoveCursorAbs( aCursorPos.Col(), aCursorPos.Row(),
1045 SC_FOLLOW_JUMP, false, false );
1046 if (pUndoDoc)
1048 if (pViewShell)
1050 SetViewMarkData( aMarkData );
1052 pViewShell->SearchAndReplace( pSearchItem, false, sal_True );
1055 else if (pSearchItem->GetPattern() &&
1056 pSearchItem->GetCommand() == SVX_SEARCHCMD_REPLACE)
1058 pDoc->ReplaceStyle( *pSearchItem,
1059 aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(),
1060 aMarkData, sal_True);
1061 pDocShell->PostPaintGridAll();
1063 else
1064 if (pViewShell)
1065 pViewShell->SearchAndReplace( pSearchItem, false, sal_True );
1067 SetChangeTrack();
1069 EndRedo();
1072 void ScUndoReplace::Repeat(SfxRepeatTarget& rTarget)
1074 if (rTarget.ISA(ScTabViewTarget))
1075 ((ScTabViewTarget&)rTarget).GetViewShell()->SearchAndReplace( pSearchItem, sal_True, false );
1078 bool ScUndoReplace::CanRepeat(SfxRepeatTarget& rTarget) const
1080 return rTarget.ISA(ScTabViewTarget);
1083 // multi-operation (only simple blocks)
1084 ScUndoTabOp::ScUndoTabOp( ScDocShell* pNewDocShell,
1085 SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
1086 SCCOL nEndX, SCROW nEndY, SCTAB nEndZ, ScDocument* pNewUndoDoc,
1087 const ScRefAddress& rFormulaCell,
1088 const ScRefAddress& rFormulaEnd,
1089 const ScRefAddress& rRowCell,
1090 const ScRefAddress& rColCell,
1091 ScTabOpParam::Mode eMode )
1092 : ScSimpleUndo( pNewDocShell ),
1093 aRange ( nStartX, nStartY, nStartZ, nEndX, nEndY, nEndZ ),
1094 pUndoDoc ( pNewUndoDoc ),
1095 theFormulaCell ( rFormulaCell ),
1096 theFormulaEnd ( rFormulaEnd ),
1097 theRowCell ( rRowCell ),
1098 theColCell ( rColCell ),
1099 meMode(eMode)
1103 ScUndoTabOp::~ScUndoTabOp()
1105 delete pUndoDoc;
1108 OUString ScUndoTabOp::GetComment() const
1110 return ScGlobal::GetRscString( STR_UNDO_TABOP ); // "Multiple operation"
1113 void ScUndoTabOp::Undo()
1115 BeginUndo();
1117 ScUndoUtil::MarkSimpleBlock( pDocShell, aRange );
1119 sal_uInt16 nExtFlags = 0;
1120 pDocShell->UpdatePaintExt( nExtFlags, aRange );
1122 ScDocument* pDoc = pDocShell->GetDocument();
1123 pDoc->DeleteAreaTab( aRange,IDF_ALL & ~IDF_NOTE );
1124 pUndoDoc->CopyToDocument( aRange, IDF_ALL & ~IDF_NOTE, false, pDoc );
1125 pDocShell->PostPaint( aRange, PAINT_GRID, nExtFlags );
1126 pDocShell->PostDataChanged();
1127 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1128 if (pViewShell)
1129 pViewShell->CellContentChanged();
1131 EndUndo();
1134 void ScUndoTabOp::Redo()
1136 BeginRedo();
1138 ScUndoUtil::MarkSimpleBlock( pDocShell, aRange );
1140 ScTabOpParam aParam(theFormulaCell, theFormulaEnd, theRowCell, theColCell, meMode);
1142 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1143 if (pViewShell)
1144 pViewShell->TabOp( aParam, false);
1146 EndRedo();
1149 void ScUndoTabOp::Repeat(SfxRepeatTarget& /* rTarget */)
1153 bool ScUndoTabOp::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1155 return false;
1158 ScUndoConversion::ScUndoConversion(
1159 ScDocShell* pNewDocShell, const ScMarkData& rMark,
1160 SCCOL nCurX, SCROW nCurY, SCTAB nCurZ, ScDocument* pNewUndoDoc,
1161 SCCOL nNewX, SCROW nNewY, SCTAB nNewZ, ScDocument* pNewRedoDoc,
1162 const ScConversionParam& rConvParam ) :
1163 ScSimpleUndo( pNewDocShell ),
1164 aMarkData( rMark ),
1165 aCursorPos( nCurX, nCurY, nCurZ ),
1166 pUndoDoc( pNewUndoDoc ),
1167 aNewCursorPos( nNewX, nNewY, nNewZ ),
1168 pRedoDoc( pNewRedoDoc ),
1169 maConvParam( rConvParam )
1171 SetChangeTrack();
1174 ScUndoConversion::~ScUndoConversion()
1176 delete pUndoDoc;
1177 delete pRedoDoc;
1180 void ScUndoConversion::SetChangeTrack()
1182 ScDocument* pDoc = pDocShell->GetDocument();
1183 ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
1184 if ( pChangeTrack )
1186 if ( pUndoDoc )
1187 pChangeTrack->AppendContentsIfInRefDoc( pUndoDoc,
1188 nStartChangeAction, nEndChangeAction );
1189 else
1191 OSL_FAIL( "ScUndoConversion::SetChangeTrack: no UndoDoc" );
1192 nStartChangeAction = nEndChangeAction = 0;
1195 else
1196 nStartChangeAction = nEndChangeAction = 0;
1199 OUString ScUndoConversion::GetComment() const
1201 OUString aText;
1202 switch( maConvParam.GetType() )
1204 case SC_CONVERSION_SPELLCHECK: aText = ScGlobal::GetRscString( STR_UNDO_SPELLING ); break;
1205 case SC_CONVERSION_HANGULHANJA: aText = ScGlobal::GetRscString( STR_UNDO_HANGULHANJA ); break;
1206 case SC_CONVERSION_CHINESE_TRANSL: aText = ScGlobal::GetRscString( STR_UNDO_CHINESE_TRANSLATION ); break;
1207 default: OSL_FAIL( "ScUndoConversion::GetComment - unknown conversion type" );
1209 return aText;
1212 void ScUndoConversion::DoChange( ScDocument* pRefDoc, const ScAddress& rCursorPos )
1214 if (pRefDoc)
1216 ScDocument* pDoc = pDocShell->GetDocument();
1217 ShowTable( rCursorPos.Tab() );
1219 SetViewMarkData( aMarkData );
1221 SCTAB nTabCount = pDoc->GetTableCount();
1222 // Undo/Redo-doc has only selected tables
1224 sal_Bool bMulti = aMarkData.IsMultiMarked();
1225 pRefDoc->CopyToDocument( 0, 0, 0,
1226 MAXCOL, MAXROW, nTabCount-1,
1227 IDF_CONTENTS, bMulti, pDoc, &aMarkData );
1228 pDocShell->PostPaintGridAll();
1230 else
1232 OSL_FAIL("no Un-/RedoDoc for Un-/RedoSpelling");
1236 void ScUndoConversion::Undo()
1238 BeginUndo();
1239 DoChange( pUndoDoc, aCursorPos );
1240 ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
1241 if ( pChangeTrack )
1242 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
1243 EndUndo();
1246 void ScUndoConversion::Redo()
1248 BeginRedo();
1249 DoChange( pRedoDoc, aNewCursorPos );
1250 SetChangeTrack();
1251 EndRedo();
1254 void ScUndoConversion::Repeat( SfxRepeatTarget& rTarget )
1256 if( rTarget.ISA( ScTabViewTarget ) )
1257 ((ScTabViewTarget&)rTarget).GetViewShell()->DoSheetConversion( maConvParam, sal_True );
1260 bool ScUndoConversion::CanRepeat(SfxRepeatTarget& rTarget) const
1262 return rTarget.ISA( ScTabViewTarget );
1265 ScUndoRefConversion::ScUndoRefConversion( ScDocShell* pNewDocShell,
1266 const ScRange& aMarkRange, const ScMarkData& rMark,
1267 ScDocument* pNewUndoDoc, ScDocument* pNewRedoDoc, sal_Bool bNewMulti, sal_uInt16 nNewFlag) :
1268 ScSimpleUndo( pNewDocShell ),
1269 aMarkData ( rMark ),
1270 pUndoDoc ( pNewUndoDoc ),
1271 pRedoDoc ( pNewRedoDoc ),
1272 aRange ( aMarkRange ),
1273 bMulti ( bNewMulti ),
1274 nFlags ( nNewFlag )
1276 SetChangeTrack();
1279 ScUndoRefConversion::~ScUndoRefConversion()
1281 delete pUndoDoc;
1282 delete pRedoDoc;
1285 OUString ScUndoRefConversion::GetComment() const
1287 return ScGlobal::GetRscString( STR_UNDO_ENTERDATA ); // "Input"
1290 void ScUndoRefConversion::SetChangeTrack()
1292 ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
1293 if ( pChangeTrack && (nFlags & IDF_FORMULA) )
1294 pChangeTrack->AppendContentsIfInRefDoc( pUndoDoc,
1295 nStartChangeAction, nEndChangeAction );
1296 else
1297 nStartChangeAction = nEndChangeAction = 0;
1300 void ScUndoRefConversion::DoChange( ScDocument* pRefDoc)
1302 ScDocument* pDoc = pDocShell->GetDocument();
1304 ShowTable(aRange);
1306 SetViewMarkData( aMarkData );
1308 ScRange aCopyRange = aRange;
1309 SCTAB nTabCount = pDoc->GetTableCount();
1310 aCopyRange.aStart.SetTab(0);
1311 aCopyRange.aEnd.SetTab(nTabCount-1);
1312 pRefDoc->CopyToDocument( aCopyRange, nFlags, bMulti, pDoc, &aMarkData );
1313 pDocShell->PostPaint( aRange, PAINT_GRID);
1314 pDocShell->PostDataChanged();
1315 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1316 if (pViewShell)
1317 pViewShell->CellContentChanged();
1320 void ScUndoRefConversion::Undo()
1322 BeginUndo();
1323 if (pUndoDoc)
1324 DoChange(pUndoDoc);
1325 ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
1326 if ( pChangeTrack )
1327 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
1328 EndUndo();
1331 void ScUndoRefConversion::Redo()
1333 BeginRedo();
1334 if (pRedoDoc)
1335 DoChange(pRedoDoc);
1336 SetChangeTrack();
1337 EndRedo();
1340 void ScUndoRefConversion::Repeat(SfxRepeatTarget& rTarget)
1342 if (rTarget.ISA(ScTabViewTarget))
1343 ((ScTabViewTarget&)rTarget).GetViewShell()->DoRefConversion();
1346 bool ScUndoRefConversion::CanRepeat(SfxRepeatTarget& rTarget) const
1348 return rTarget.ISA(ScTabViewTarget);
1351 ScUndoRefreshLink::ScUndoRefreshLink( ScDocShell* pNewDocShell,
1352 ScDocument* pNewUndoDoc )
1353 : ScSimpleUndo( pNewDocShell ),
1354 pUndoDoc( pNewUndoDoc ),
1355 pRedoDoc( NULL )
1359 ScUndoRefreshLink::~ScUndoRefreshLink()
1361 delete pUndoDoc;
1362 delete pRedoDoc;
1365 OUString ScUndoRefreshLink::GetComment() const
1367 return ScGlobal::GetRscString( STR_UNDO_UPDATELINK );
1370 void ScUndoRefreshLink::Undo()
1372 BeginUndo();
1374 sal_Bool bMakeRedo = !pRedoDoc;
1375 if (bMakeRedo)
1376 pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
1378 sal_Bool bFirst = sal_True;
1379 ScDocument* pDoc = pDocShell->GetDocument();
1380 SCTAB nCount = pDoc->GetTableCount();
1381 for (SCTAB nTab=0; nTab<nCount; nTab++)
1382 if (pUndoDoc->HasTable(nTab))
1384 ScRange aRange(0,0,nTab,MAXCOL,MAXROW,nTab);
1385 if (bMakeRedo)
1387 if (bFirst)
1388 pRedoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True );
1389 else
1390 pRedoDoc->AddUndoTab( nTab, nTab, true, true );
1391 bFirst = false;
1392 pDoc->CopyToDocument(aRange, IDF_ALL, false, pRedoDoc);
1393 pRedoDoc->SetLink( nTab,
1394 pDoc->GetLinkMode(nTab),
1395 pDoc->GetLinkDoc(nTab),
1396 pDoc->GetLinkFlt(nTab),
1397 pDoc->GetLinkOpt(nTab),
1398 pDoc->GetLinkTab(nTab),
1399 pDoc->GetLinkRefreshDelay(nTab) );
1400 pRedoDoc->SetTabBgColor( nTab, pDoc->GetTabBgColor(nTab) );
1403 pDoc->DeleteAreaTab( aRange,IDF_ALL );
1404 pUndoDoc->CopyToDocument( aRange, IDF_ALL, false, pDoc );
1405 pDoc->SetLink( nTab, pUndoDoc->GetLinkMode(nTab), pUndoDoc->GetLinkDoc(nTab),
1406 pUndoDoc->GetLinkFlt(nTab), pUndoDoc->GetLinkOpt(nTab),
1407 pUndoDoc->GetLinkTab(nTab),
1408 pUndoDoc->GetLinkRefreshDelay(nTab) );
1409 pDoc->SetTabBgColor( nTab, pUndoDoc->GetTabBgColor(nTab) );
1412 pDocShell->PostPaintGridAll();
1413 pDocShell->PostPaintExtras();
1415 EndUndo();
1418 void ScUndoRefreshLink::Redo()
1420 OSL_ENSURE(pRedoDoc, "No RedoDoc for ScUndoRefreshLink::Redo");
1422 BeginUndo();
1424 ScDocument* pDoc = pDocShell->GetDocument();
1425 SCTAB nCount = pDoc->GetTableCount();
1426 for (SCTAB nTab=0; nTab<nCount; nTab++)
1427 if (pRedoDoc->HasTable(nTab))
1429 ScRange aRange(0,0,nTab,MAXCOL,MAXROW,nTab);
1431 pDoc->DeleteAreaTab( aRange, IDF_ALL );
1432 pRedoDoc->CopyToDocument( aRange, IDF_ALL, false, pDoc );
1433 pDoc->SetLink( nTab,
1434 pRedoDoc->GetLinkMode(nTab),
1435 pRedoDoc->GetLinkDoc(nTab),
1436 pRedoDoc->GetLinkFlt(nTab),
1437 pRedoDoc->GetLinkOpt(nTab),
1438 pRedoDoc->GetLinkTab(nTab),
1439 pRedoDoc->GetLinkRefreshDelay(nTab) );
1440 pDoc->SetTabBgColor( nTab, pRedoDoc->GetTabBgColor(nTab) );
1443 pDocShell->PostPaintGridAll();
1444 pDocShell->PostPaintExtras();
1446 EndUndo();
1449 void ScUndoRefreshLink::Repeat(SfxRepeatTarget& /* rTarget */)
1451 // makes no sense
1454 bool ScUndoRefreshLink::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1456 return false;
1459 static ScAreaLink* lcl_FindAreaLink( sfx2::LinkManager* pLinkManager, const OUString& rDoc,
1460 const OUString& rFlt, const OUString& rOpt,
1461 const OUString& rSrc, const ScRange& rDest )
1463 const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
1464 sal_uInt16 nCount = pLinkManager->GetLinks().size();
1465 for (sal_uInt16 i=0; i<nCount; i++)
1467 ::sfx2::SvBaseLink* pBase = *rLinks[i];
1468 if (pBase->ISA(ScAreaLink))
1469 if ( ((ScAreaLink*)pBase)->IsEqual( rDoc, rFlt, rOpt, rSrc, rDest ) )
1470 return (ScAreaLink*)pBase;
1473 OSL_FAIL("ScAreaLink not found");
1474 return NULL;
1477 ScUndoInsertAreaLink::ScUndoInsertAreaLink( ScDocShell* pShell,
1478 const OUString& rDoc,
1479 const OUString& rFlt, const OUString& rOpt,
1480 const OUString& rArea, const ScRange& rDestRange,
1481 sal_uLong nRefresh )
1482 : ScSimpleUndo ( pShell ),
1483 aDocName ( rDoc ),
1484 aFltName ( rFlt ),
1485 aOptions ( rOpt ),
1486 aAreaName ( rArea ),
1487 aRange ( rDestRange ),
1488 nRefreshDelay ( nRefresh )
1492 ScUndoInsertAreaLink::~ScUndoInsertAreaLink()
1496 OUString ScUndoInsertAreaLink::GetComment() const
1498 return ScGlobal::GetRscString( STR_UNDO_INSERTAREALINK );
1501 void ScUndoInsertAreaLink::Undo()
1503 ScDocument* pDoc = pDocShell->GetDocument();
1504 sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
1506 ScAreaLink* pLink = lcl_FindAreaLink( pLinkManager, aDocName, aFltName, aOptions,
1507 aAreaName, aRange );
1508 if (pLink)
1509 pLinkManager->Remove( pLink );
1511 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) ); // Navigator
1514 void ScUndoInsertAreaLink::Redo()
1516 ScDocument* pDoc = pDocShell->GetDocument();
1517 sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
1519 ScAreaLink* pLink = new ScAreaLink( pDocShell, aDocName, aFltName, aOptions,
1520 aAreaName, aRange.aStart, nRefreshDelay );
1521 pLink->SetInCreate( sal_True );
1522 pLink->SetDestArea( aRange );
1523 pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aDocName, &aFltName, &aAreaName );
1524 pLink->Update();
1525 pLink->SetInCreate( false );
1527 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) ); // Navigator
1530 void ScUndoInsertAreaLink::Repeat(SfxRepeatTarget& /* rTarget */)
1532 // makes no sense
1535 bool ScUndoInsertAreaLink::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1537 return false;
1540 ScUndoRemoveAreaLink::ScUndoRemoveAreaLink( ScDocShell* pShell,
1541 const OUString& rDoc, const OUString& rFlt, const OUString& rOpt,
1542 const OUString& rArea, const ScRange& rDestRange,
1543 sal_uLong nRefresh )
1544 : ScSimpleUndo ( pShell ),
1545 aDocName ( rDoc ),
1546 aFltName ( rFlt ),
1547 aOptions ( rOpt ),
1548 aAreaName ( rArea ),
1549 aRange ( rDestRange ),
1550 nRefreshDelay ( nRefresh )
1554 ScUndoRemoveAreaLink::~ScUndoRemoveAreaLink()
1558 OUString ScUndoRemoveAreaLink::GetComment() const
1560 return ScGlobal::GetRscString( STR_UNDO_REMOVELINK ); //! eigener Text ??
1563 void ScUndoRemoveAreaLink::Undo()
1565 ScDocument* pDoc = pDocShell->GetDocument();
1566 sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
1568 ScAreaLink* pLink = new ScAreaLink( pDocShell, aDocName, aFltName, aOptions,
1569 aAreaName, aRange.aStart, nRefreshDelay );
1570 pLink->SetInCreate( sal_True );
1571 pLink->SetDestArea( aRange );
1572 pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aDocName, &aFltName, &aAreaName );
1573 pLink->Update();
1574 pLink->SetInCreate( false );
1576 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) ); // Navigator
1579 void ScUndoRemoveAreaLink::Redo()
1581 ScDocument* pDoc = pDocShell->GetDocument();
1582 sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
1584 ScAreaLink* pLink = lcl_FindAreaLink( pLinkManager, aDocName, aFltName, aOptions,
1585 aAreaName, aRange );
1586 if (pLink)
1587 pLinkManager->Remove( pLink );
1589 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) ); // Navigator
1592 void ScUndoRemoveAreaLink::Repeat(SfxRepeatTarget& /* rTarget */)
1594 // makes no sense
1597 bool ScUndoRemoveAreaLink::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1599 return false;
1602 ScUndoUpdateAreaLink::ScUndoUpdateAreaLink( ScDocShell* pShell,
1603 const OUString& rOldD, const OUString& rOldF, const OUString& rOldO,
1604 const OUString& rOldA, const ScRange& rOldR, sal_uLong nOldRD,
1605 const OUString& rNewD, const OUString& rNewF, const OUString& rNewO,
1606 const OUString& rNewA, const ScRange& rNewR, sal_uLong nNewRD,
1607 ScDocument* pUndo, ScDocument* pRedo, sal_Bool bDoInsert )
1608 : ScSimpleUndo( pShell ),
1609 aOldDoc ( rOldD ),
1610 aOldFlt ( rOldF ),
1611 aOldOpt ( rOldO ),
1612 aOldArea ( rOldA ),
1613 aOldRange ( rOldR ),
1614 aNewDoc ( rNewD ),
1615 aNewFlt ( rNewF ),
1616 aNewOpt ( rNewO ),
1617 aNewArea ( rNewA ),
1618 aNewRange ( rNewR ),
1619 pUndoDoc ( pUndo ),
1620 pRedoDoc ( pRedo ),
1621 nOldRefresh ( nOldRD ),
1622 nNewRefresh ( nNewRD ),
1623 bWithInsert ( bDoInsert )
1625 OSL_ENSURE( aOldRange.aStart == aNewRange.aStart, "AreaLink moved ?" );
1628 ScUndoUpdateAreaLink::~ScUndoUpdateAreaLink()
1630 delete pUndoDoc;
1631 delete pRedoDoc;
1634 OUString ScUndoUpdateAreaLink::GetComment() const
1636 return ScGlobal::GetRscString( STR_UNDO_UPDATELINK ); //! own text ??
1639 void ScUndoUpdateAreaLink::DoChange( const sal_Bool bUndo ) const
1641 ScDocument* pDoc = pDocShell->GetDocument();
1643 SCCOL nEndX = std::max( aOldRange.aEnd.Col(), aNewRange.aEnd.Col() );
1644 SCROW nEndY = std::max( aOldRange.aEnd.Row(), aNewRange.aEnd.Row() );
1645 SCTAB nEndZ = std::max( aOldRange.aEnd.Tab(), aNewRange.aEnd.Tab() ); //?
1647 if ( bUndo )
1649 if ( bWithInsert )
1651 pDoc->FitBlock( aNewRange, aOldRange );
1652 pDoc->DeleteAreaTab( aOldRange, IDF_ALL & ~IDF_NOTE );
1653 pUndoDoc->UndoToDocument( aOldRange, IDF_ALL & ~IDF_NOTE, false, pDoc );
1655 else
1657 ScRange aCopyRange( aOldRange.aStart, ScAddress(nEndX,nEndY,nEndZ) );
1658 pDoc->DeleteAreaTab( aCopyRange, IDF_ALL & ~IDF_NOTE );
1659 pUndoDoc->CopyToDocument( aCopyRange, IDF_ALL & ~IDF_NOTE, false, pDoc );
1662 else
1664 if ( bWithInsert )
1666 pDoc->FitBlock( aOldRange, aNewRange );
1667 pDoc->DeleteAreaTab( aNewRange, IDF_ALL & ~IDF_NOTE );
1668 pRedoDoc->CopyToDocument( aNewRange, IDF_ALL & ~IDF_NOTE, false, pDoc );
1670 else
1672 ScRange aCopyRange( aOldRange.aStart, ScAddress(nEndX,nEndY,nEndZ) );
1673 pDoc->DeleteAreaTab( aCopyRange, IDF_ALL & ~IDF_NOTE );
1674 pRedoDoc->CopyToDocument( aCopyRange, IDF_ALL & ~IDF_NOTE, false, pDoc );
1678 ScRange aWorkRange( aNewRange.aStart, ScAddress( nEndX, nEndY, nEndZ ) );
1679 pDoc->ExtendMerge( aWorkRange, sal_True );
1681 // Paint
1683 if ( aNewRange.aEnd.Col() != aOldRange.aEnd.Col() )
1684 aWorkRange.aEnd.SetCol(MAXCOL);
1685 if ( aNewRange.aEnd.Row() != aOldRange.aEnd.Row() )
1686 aWorkRange.aEnd.SetRow(MAXROW);
1688 if ( !pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), aWorkRange.aStart.Tab() ) )
1689 pDocShell->PostPaint( aWorkRange, PAINT_GRID );
1691 pDocShell->PostDataChanged();
1692 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1693 if (pViewShell)
1694 pViewShell->CellContentChanged();
1697 void ScUndoUpdateAreaLink::Undo()
1699 ScDocument* pDoc = pDocShell->GetDocument();
1700 sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
1701 ScAreaLink* pLink = lcl_FindAreaLink( pLinkManager, aNewDoc, aNewFlt, aNewOpt,
1702 aNewArea, aNewRange );
1703 if (pLink)
1705 pLink->SetSource( aOldDoc, aOldFlt, aOldOpt, aOldArea ); // old data in Link
1706 pLink->SetDestArea( aOldRange );
1707 pLink->SetRefreshDelay( nOldRefresh );
1710 DoChange(sal_True);
1713 void ScUndoUpdateAreaLink::Redo()
1715 ScDocument* pDoc = pDocShell->GetDocument();
1716 sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
1717 ScAreaLink* pLink = lcl_FindAreaLink( pLinkManager, aOldDoc, aOldFlt, aOldOpt,
1718 aOldArea, aOldRange );
1719 if (pLink)
1721 pLink->SetSource( aNewDoc, aNewFlt, aNewOpt, aNewArea ); // neue Werte im Link
1722 pLink->SetDestArea( aNewRange );
1723 pLink->SetRefreshDelay( nNewRefresh );
1726 DoChange(false);
1729 void ScUndoUpdateAreaLink::Repeat(SfxRepeatTarget& /* rTarget */)
1731 // makes no sense
1734 bool ScUndoUpdateAreaLink::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1736 return false;
1739 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */