xref: /trunk/main/sc/source/ui/undo/undoblk3.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 
31 // INCLUDE -------------------------------------------------------------------
32 
33 #include "scitems.hxx"
34 #include <editeng/boxitem.hxx>
35 #include <svl/srchitem.hxx>
36 #include <sfx2/linkmgr.hxx>
37 #include <sfx2/bindings.hxx>
38 #include <vcl/virdev.hxx>
39 #include <sfx2/app.hxx>
40 
41 #include "undoblk.hxx"
42 #include "sc.hrc"
43 #include "globstr.hrc"
44 #include "global.hxx"
45 #include "rangenam.hxx"
46 #include "arealink.hxx"
47 #include "patattr.hxx"
48 #include "target.hxx"
49 #include "document.hxx"
50 #include "docpool.hxx"
51 #include "table.hxx"
52 #include "docsh.hxx"
53 #include "tabvwsh.hxx"
54 #include "undoolk.hxx"
55 #include "undoutil.hxx"
56 #include "chgtrack.hxx"
57 #include "dociter.hxx"
58 #include "cell.hxx"
59 #include "paramisc.hxx"
60 #include "postit.hxx"
61 #include "docuno.hxx"
62 
63 // STATIC DATA ---------------------------------------------------------------
64 
65 TYPEINIT1(ScUndoDeleteContents,     SfxUndoAction);
66 TYPEINIT1(ScUndoFillTable,          SfxUndoAction);
67 TYPEINIT1(ScUndoSelectionAttr,      SfxUndoAction);
68 TYPEINIT1(ScUndoAutoFill,           SfxUndoAction);
69 TYPEINIT1(ScUndoMerge,              SfxUndoAction);
70 TYPEINIT1(ScUndoAutoFormat,         SfxUndoAction);
71 TYPEINIT1(ScUndoReplace,            SfxUndoAction);
72 TYPEINIT1(ScUndoTabOp,              SfxUndoAction);
73 TYPEINIT1(ScUndoConversion,         SfxUndoAction);
74 TYPEINIT1(ScUndoRefConversion,      SfxUndoAction);
75 TYPEINIT1(ScUndoRefreshLink,        SfxUndoAction);
76 TYPEINIT1(ScUndoInsertAreaLink,     SfxUndoAction);
77 TYPEINIT1(ScUndoRemoveAreaLink,     SfxUndoAction);
78 TYPEINIT1(ScUndoUpdateAreaLink,     SfxUndoAction);
79 
80 
81 // To Do:
82 /*A*/   // SetOptimalHeight auf Dokument, wenn keine View
83 
84 
85 //============================================================================
86 //  class ScUndoDeleteContents
87 //
88 //  Inhalte loeschen
89 
90 //----------------------------------------------------------------------------
91 
92 ScUndoDeleteContents::ScUndoDeleteContents(
93                 ScDocShell* pNewDocShell,
94                 const ScMarkData& rMark, const ScRange& rRange,
95                 ScDocument* pNewUndoDoc, sal_Bool bNewMulti,
96                 sal_uInt16 nNewFlags, sal_Bool bObjects )
97         //
98     :   ScSimpleUndo( pNewDocShell ),
99         //
100         aRange      ( rRange ),
101         aMarkData   ( rMark ),
102         pUndoDoc    ( pNewUndoDoc ),
103         pDrawUndo   ( NULL ),
104         nFlags      ( nNewFlags ),
105         bMulti      ( bNewMulti )   // ueberliquid
106 {
107     if (bObjects)
108         pDrawUndo = GetSdrUndoAction( pDocShell->GetDocument() );
109 
110     if ( !(aMarkData.IsMarked() || aMarkData.IsMultiMarked()) )     // keine Zelle markiert:
111         aMarkData.SetMarkArea( aRange );                            // Zelle unter Cursor markieren
112 
113     SetChangeTrack();
114 }
115 
116 
117 //----------------------------------------------------------------------------
118 
119 __EXPORT ScUndoDeleteContents::~ScUndoDeleteContents()
120 {
121     delete pUndoDoc;
122     DeleteSdrUndoAction( pDrawUndo );
123 }
124 
125 
126 //----------------------------------------------------------------------------
127 
128 String __EXPORT ScUndoDeleteContents::GetComment() const
129 {
130     return ScGlobal::GetRscString( STR_UNDO_DELETECONTENTS );    // "Loeschen"
131 }
132 
133 
134 void ScUndoDeleteContents::SetChangeTrack()
135 {
136     ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
137     if ( pChangeTrack && (nFlags & IDF_CONTENTS) )
138         pChangeTrack->AppendContentRange( aRange, pUndoDoc,
139             nStartChangeAction, nEndChangeAction );
140     else
141         nStartChangeAction = nEndChangeAction = 0;
142 }
143 
144 
145 //----------------------------------------------------------------------------
146 
147 void ScUndoDeleteContents::DoChange( const sal_Bool bUndo )
148 {
149     ScDocument* pDoc = pDocShell->GetDocument();
150 
151     SetViewMarkData( aMarkData );
152 
153     sal_uInt16 nExtFlags = 0;
154 
155     if (bUndo)  // nur Undo
156     {
157         sal_uInt16 nUndoFlags = IDF_NONE;       //  entweder alle oder keine Inhalte kopieren
158         if (nFlags & IDF_CONTENTS)          //  (es sind nur die richtigen ins UndoDoc kopiert worden)
159             nUndoFlags |= IDF_CONTENTS;
160         if (nFlags & IDF_ATTRIB)
161             nUndoFlags |= IDF_ATTRIB;
162         if (nFlags & IDF_EDITATTR)          // Edit-Engine-Attribute
163             nUndoFlags |= IDF_STRING;       // -> Zellen werden geaendert
164         // do not create clones of note captions, they will be restored via drawing undo
165         nUndoFlags |= IDF_NOCAPTIONS;
166 
167         ScRange aCopyRange = aRange;
168         SCTAB nTabCount = pDoc->GetTableCount();
169         aCopyRange.aStart.SetTab(0);
170         aCopyRange.aEnd.SetTab(nTabCount-1);
171 
172         pUndoDoc->CopyToDocument( aCopyRange, nUndoFlags, bMulti, pDoc, &aMarkData );
173 
174         DoSdrUndoAction( pDrawUndo, pDoc );
175 
176         ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
177         if ( pChangeTrack )
178             pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
179 
180         pDocShell->UpdatePaintExt( nExtFlags, aRange );             // content after the change
181     }
182     else        // nur Redo
183     {
184         pDocShell->UpdatePaintExt( nExtFlags, aRange );             // content before the change
185 
186         aMarkData.MarkToMulti();
187         RedoSdrUndoAction( pDrawUndo );
188         // do not delete objects and note captions, they have been removed via drawing undo
189         sal_uInt16 nRedoFlags = (nFlags & ~IDF_OBJECTS) | IDF_NOCAPTIONS;
190         pDoc->DeleteSelection( nRedoFlags, aMarkData );
191         aMarkData.MarkToSimple();
192 
193         SetChangeTrack();
194     }
195 
196     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
197     if ( !( (pViewShell) && pViewShell->AdjustRowHeight(
198                                 aRange.aStart.Row(), aRange.aEnd.Row() ) ) )
199 /*A*/   pDocShell->PostPaint( aRange, PAINT_GRID | PAINT_EXTRAS, nExtFlags );
200 
201     pDocShell->PostDataChanged();
202     if (pViewShell)
203         pViewShell->CellContentChanged();
204 
205     ShowTable( aRange );
206 }
207 
208 
209 //----------------------------------------------------------------------------
210 
211 void __EXPORT ScUndoDeleteContents::Undo()
212 {
213     BeginUndo();
214     DoChange( sal_True );
215     EndUndo();
216 
217     // #i97876# Spreadsheet data changes are not notified
218     ScModelObj* pModelObj = ScModelObj::getImplementation( pDocShell->GetModel() );
219     if ( pModelObj && pModelObj->HasChangesListeners() )
220     {
221         ScRangeList aChangeRanges;
222         aChangeRanges.Append( aRange );
223         pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
224     }
225 }
226 
227 
228 //----------------------------------------------------------------------------
229 
230 void __EXPORT ScUndoDeleteContents::Redo()
231 {
232     BeginRedo();
233     DoChange( sal_False );
234     EndRedo();
235 
236     // #i97876# Spreadsheet data changes are not notified
237     ScModelObj* pModelObj = ScModelObj::getImplementation( pDocShell->GetModel() );
238     if ( pModelObj && pModelObj->HasChangesListeners() )
239     {
240         ScRangeList aChangeRanges;
241         aChangeRanges.Append( aRange );
242         pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
243     }
244 }
245 
246 
247 //----------------------------------------------------------------------------
248 
249 void __EXPORT ScUndoDeleteContents::Repeat(SfxRepeatTarget& rTarget)
250 {
251     if (rTarget.ISA(ScTabViewTarget))
252         ((ScTabViewTarget&)rTarget).GetViewShell()->DeleteContents( nFlags, sal_True );
253 }
254 
255 
256 //----------------------------------------------------------------------------
257 
258 sal_Bool __EXPORT ScUndoDeleteContents::CanRepeat(SfxRepeatTarget& rTarget) const
259 {
260     return (rTarget.ISA(ScTabViewTarget));
261 }
262 
263 
264 //============================================================================
265 //  class ScUndoFillTable
266 //
267 //  Tabellen ausfuellen
268 //  (Bearbeiten|Ausfuellen|...)
269 
270 //----------------------------------------------------------------------------
271 
272 ScUndoFillTable::ScUndoFillTable( ScDocShell* pNewDocShell,
273                 const ScMarkData& rMark,
274                 SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
275                 SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
276                 ScDocument* pNewUndoDoc, sal_Bool bNewMulti, SCTAB nSrc,
277                 sal_uInt16 nFlg, sal_uInt16 nFunc, sal_Bool bSkip, sal_Bool bLink )
278         //
279     :   ScSimpleUndo( pNewDocShell ),
280         //
281         aRange      ( nStartX, nStartY, nStartZ, nEndX, nEndY, nEndZ ),
282         aMarkData   ( rMark ),
283         pUndoDoc    ( pNewUndoDoc ),
284         nFlags      ( nFlg ),
285         nFunction   ( nFunc ),
286         nSrcTab     ( nSrc ),
287         bMulti      ( bNewMulti ),
288         bSkipEmpty  ( bSkip ),
289         bAsLink     ( bLink )
290 {
291     SetChangeTrack();
292 }
293 
294 
295 //----------------------------------------------------------------------------
296 
297 __EXPORT ScUndoFillTable::~ScUndoFillTable()
298 {
299     delete pUndoDoc;
300 }
301 
302 
303 //----------------------------------------------------------------------------
304 
305 String __EXPORT ScUndoFillTable::GetComment() const
306 {
307     return ScGlobal::GetRscString( STR_FILL_TAB );
308 }
309 
310 
311 void ScUndoFillTable::SetChangeTrack()
312 {
313     ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
314     if ( pChangeTrack )
315     {
316         SCTAB nTabCount = pDocShell->GetDocument()->GetTableCount();
317         ScRange aWorkRange(aRange);
318         nStartChangeAction = 0;
319         sal_uLong nTmpAction;
320         for ( SCTAB i = 0; i < nTabCount; i++ )
321         {
322             if (i != nSrcTab && aMarkData.GetTableSelect(i))
323             {
324                 aWorkRange.aStart.SetTab(i);
325                 aWorkRange.aEnd.SetTab(i);
326                 pChangeTrack->AppendContentRange( aWorkRange, pUndoDoc,
327                     nTmpAction, nEndChangeAction );
328                 if ( !nStartChangeAction )
329                     nStartChangeAction = nTmpAction;
330             }
331         }
332     }
333     else
334         nStartChangeAction = nEndChangeAction = 0;
335 }
336 
337 
338 //----------------------------------------------------------------------------
339 
340 void ScUndoFillTable::DoChange( const sal_Bool bUndo )
341 {
342     ScDocument* pDoc = pDocShell->GetDocument();
343 
344     SetViewMarkData( aMarkData );
345 
346     if (bUndo)  // nur Undo
347     {
348         SCTAB nTabCount = pDoc->GetTableCount();
349         ScRange aWorkRange(aRange);
350         for ( SCTAB i = 0; i < nTabCount; i++ )
351             if (i != nSrcTab && aMarkData.GetTableSelect(i))
352             {
353                 aWorkRange.aStart.SetTab(i);
354                 aWorkRange.aEnd.SetTab(i);
355                 if (bMulti)
356                     pDoc->DeleteSelectionTab( i, IDF_ALL, aMarkData );
357                 else
358                     pDoc->DeleteAreaTab( aWorkRange, IDF_ALL );
359                 pUndoDoc->CopyToDocument( aWorkRange, IDF_ALL, bMulti, pDoc, &aMarkData );
360             }
361 
362         ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
363         if ( pChangeTrack )
364             pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
365     }
366     else        // nur Redo
367     {
368         aMarkData.MarkToMulti();
369         pDoc->FillTabMarked( nSrcTab, aMarkData, nFlags, nFunction, bSkipEmpty, bAsLink );
370         aMarkData.MarkToSimple();
371         SetChangeTrack();
372     }
373 
374     pDocShell->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_GRID|PAINT_EXTRAS);
375     pDocShell->PostDataChanged();
376 
377     //  CellContentChanged kommt mit der Markierung
378 
379     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
380     if (pViewShell)
381     {
382         SCTAB nTab = pViewShell->GetViewData()->GetTabNo();
383         if ( !aMarkData.GetTableSelect(nTab) )
384             pViewShell->SetTabNo( nSrcTab );
385 
386         pViewShell->DoneBlockMode();    // gibt sonst Probleme, weil Markierung auf falscher Tabelle
387     }
388 }
389 
390 
391 //----------------------------------------------------------------------------
392 
393 void __EXPORT ScUndoFillTable::Undo()
394 {
395     BeginUndo();
396     DoChange( sal_True );
397     EndUndo();
398 }
399 
400 
401 //----------------------------------------------------------------------------
402 
403 void __EXPORT ScUndoFillTable::Redo()
404 {
405     BeginRedo();
406     DoChange( sal_False );
407     EndRedo();
408 }
409 
410 
411 //----------------------------------------------------------------------------
412 
413 void __EXPORT ScUndoFillTable::Repeat(SfxRepeatTarget& rTarget)
414 {
415     if (rTarget.ISA(ScTabViewTarget))
416         ((ScTabViewTarget&)rTarget).GetViewShell()->FillTab( nFlags, nFunction, bSkipEmpty, bAsLink );
417 }
418 
419 
420 //----------------------------------------------------------------------------
421 
422 sal_Bool __EXPORT ScUndoFillTable::CanRepeat(SfxRepeatTarget& rTarget) const
423 {
424     return (rTarget.ISA(ScTabViewTarget));
425 }
426 
427 
428 //============================================================================
429 //  class ScUndoSelectionAttr
430 //
431 //  Zellformat aendern
432 
433 //----------------------------------------------------------------------------
434 
435 ScUndoSelectionAttr::ScUndoSelectionAttr( ScDocShell* pNewDocShell,
436                 const ScMarkData& rMark,
437                 SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
438                 SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
439                 ScDocument* pNewUndoDoc, sal_Bool bNewMulti,
440                 const ScPatternAttr* pNewApply,
441                 const SvxBoxItem* pNewOuter, const SvxBoxInfoItem* pNewInner )
442         //
443     :   ScSimpleUndo( pNewDocShell ),
444         //
445         aMarkData   ( rMark ),
446         aRange      ( nStartX, nStartY, nStartZ, nEndX, nEndY, nEndZ ),
447         pUndoDoc    ( pNewUndoDoc ),
448         bMulti      ( bNewMulti )
449 {
450     ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
451     pApplyPattern = (ScPatternAttr*) &pPool->Put( *pNewApply );
452     pLineOuter = pNewOuter ? (SvxBoxItem*) &pPool->Put( *pNewOuter ) : NULL;
453     pLineInner = pNewInner ? (SvxBoxInfoItem*) &pPool->Put( *pNewInner ) : NULL;
454 }
455 
456 
457 //----------------------------------------------------------------------------
458 
459 __EXPORT ScUndoSelectionAttr::~ScUndoSelectionAttr()
460 {
461     ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
462     pPool->Remove(*pApplyPattern);
463     if (pLineOuter)
464         pPool->Remove(*pLineOuter);
465     if (pLineInner)
466         pPool->Remove(*pLineInner);
467 
468     delete pUndoDoc;
469 }
470 
471 
472 //----------------------------------------------------------------------------
473 
474 String __EXPORT ScUndoSelectionAttr::GetComment() const
475 {
476     //"Attribute" "/Linien"
477     return ScGlobal::GetRscString( pLineOuter ? STR_UNDO_SELATTRLINES : STR_UNDO_SELATTR );
478 }
479 
480 
481 //----------------------------------------------------------------------------
482 
483 void ScUndoSelectionAttr::DoChange( const sal_Bool bUndo )
484 {
485     ScDocument* pDoc = pDocShell->GetDocument();
486 
487     SetViewMarkData( aMarkData );
488 
489     ScRange aEffRange( aRange );
490     if ( pDoc->HasAttrib( aEffRange, HASATTR_MERGED ) )         // zusammengefasste Zellen?
491         pDoc->ExtendMerge( aEffRange );
492 
493     sal_uInt16 nExtFlags = 0;
494     pDocShell->UpdatePaintExt( nExtFlags, aEffRange );
495 
496     if (bUndo)  // nur bei Undo
497     {
498         ScRange aCopyRange = aRange;
499         SCTAB nTabCount = pDoc->GetTableCount();
500         aCopyRange.aStart.SetTab(0);
501         aCopyRange.aEnd.SetTab(nTabCount-1);
502         pUndoDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, bMulti, pDoc, &aMarkData );
503     }
504     else        // nur bei Redo
505     {
506         aMarkData.MarkToMulti();
507         pDoc->ApplySelectionPattern( *pApplyPattern, aMarkData );
508         aMarkData.MarkToSimple();
509 
510         if (pLineOuter)
511             pDoc->ApplySelectionFrame( aMarkData, pLineOuter, pLineInner );
512     }
513 
514     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
515     if ( !( (pViewShell) && pViewShell->AdjustBlockHeight() ) )
516 /*A*/   pDocShell->PostPaint( aEffRange, PAINT_GRID | PAINT_EXTRAS, nExtFlags );
517 
518     ShowTable( aRange );
519 }
520 
521 
522 //----------------------------------------------------------------------------
523 
524 void __EXPORT ScUndoSelectionAttr::Undo()
525 {
526     BeginUndo();
527     DoChange( sal_True );
528     EndUndo();
529 }
530 
531 
532 //----------------------------------------------------------------------------
533 
534 void __EXPORT ScUndoSelectionAttr::Redo()
535 {
536     BeginRedo();
537     DoChange( sal_False );
538     EndRedo();
539 }
540 
541 
542 //----------------------------------------------------------------------------
543 
544 void __EXPORT ScUndoSelectionAttr::Repeat(SfxRepeatTarget& rTarget)
545 {
546     if (rTarget.ISA(ScTabViewTarget))
547     {
548         ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
549         if (pLineOuter)
550             rViewShell.ApplyPatternLines( *pApplyPattern, pLineOuter, pLineInner, sal_True );
551         else
552             rViewShell.ApplySelectionPattern( *pApplyPattern, sal_True );
553     }
554 }
555 
556 
557 //----------------------------------------------------------------------------
558 
559 sal_Bool __EXPORT ScUndoSelectionAttr::CanRepeat(SfxRepeatTarget& rTarget) const
560 {
561     return (rTarget.ISA(ScTabViewTarget));
562 }
563 
564 
565 //============================================================================
566 //  class ScUndoAutoFill
567 //
568 //  Auto-Fill (nur einfache Bloecke)
569 
570 //----------------------------------------------------------------------------
571 
572 ScUndoAutoFill::ScUndoAutoFill( ScDocShell* pNewDocShell,
573                 const ScRange& rRange, const ScRange& rSourceArea,
574                 ScDocument* pNewUndoDoc, const ScMarkData& rMark,
575                 FillDir eNewFillDir, FillCmd eNewFillCmd, FillDateCmd eNewFillDateCmd,
576                 double fNewStartValue, double fNewStepValue, double fNewMaxValue,
577                 sal_uInt16 nMaxShIndex )
578         //
579     :   ScBlockUndo( pNewDocShell, rRange, SC_UNDO_AUTOHEIGHT ),
580         //
581         aSource         ( rSourceArea ),
582         aMarkData       ( rMark ),
583         pUndoDoc        ( pNewUndoDoc ),
584         eFillDir        ( eNewFillDir ),
585         eFillCmd        ( eNewFillCmd ),
586         eFillDateCmd    ( eNewFillDateCmd ),
587         fStartValue     ( fNewStartValue ),
588         fStepValue      ( fNewStepValue ),
589         fMaxValue       ( fNewMaxValue ),
590         nMaxSharedIndex ( nMaxShIndex)
591 {
592     SetChangeTrack();
593 }
594 
595 
596 //----------------------------------------------------------------------------
597 
598 __EXPORT ScUndoAutoFill::~ScUndoAutoFill()
599 {
600     pDocShell->GetDocument()->EraseNonUsedSharedNames(nMaxSharedIndex);
601     delete pUndoDoc;
602 }
603 
604 
605 //----------------------------------------------------------------------------
606 
607 String __EXPORT ScUndoAutoFill::GetComment() const
608 {
609     return ScGlobal::GetRscString( STR_UNDO_AUTOFILL ); //"Ausfuellen"
610 }
611 
612 
613 void ScUndoAutoFill::SetChangeTrack()
614 {
615     ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
616     if ( pChangeTrack )
617         pChangeTrack->AppendContentRange( aBlockRange, pUndoDoc,
618             nStartChangeAction, nEndChangeAction );
619     else
620         nStartChangeAction = nEndChangeAction = 0;
621 }
622 
623 
624 //----------------------------------------------------------------------------
625 
626 void __EXPORT ScUndoAutoFill::Undo()
627 {
628     BeginUndo();
629 
630     ScDocument* pDoc = pDocShell->GetDocument();
631 
632     SCTAB nTabCount = pDoc->GetTableCount();
633     for (SCTAB nTab=0; nTab<nTabCount; nTab++)
634     {
635         if (aMarkData.GetTableSelect(nTab))
636         {
637             ScRange aWorkRange = aBlockRange;
638             aWorkRange.aStart.SetTab(nTab);
639             aWorkRange.aEnd.SetTab(nTab);
640 
641             sal_uInt16 nExtFlags = 0;
642             pDocShell->UpdatePaintExt( nExtFlags, aWorkRange );
643             pDoc->DeleteAreaTab( aWorkRange, IDF_AUTOFILL );
644             pUndoDoc->CopyToDocument( aWorkRange, IDF_AUTOFILL, sal_False, pDoc );
645 
646             pDoc->ExtendMerge( aWorkRange, sal_True );
647             pDocShell->PostPaint( aWorkRange, PAINT_GRID, nExtFlags );
648         }
649     }
650     pDocShell->PostDataChanged();
651     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
652     if (pViewShell)
653         pViewShell->CellContentChanged();
654 
655 // Shared-Names loeschen
656 // Falls Undo ins Dokument gespeichert
657 // => automatisches Loeschen am Ende
658 // umarbeiten!!
659 
660     String aName = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("___SC_"));
661     aName += String::CreateFromInt32(nMaxSharedIndex);
662     aName += '_';
663     ScRangeName* pRangeName = pDoc->GetRangeName();
664     sal_Bool bHasFound = sal_False;
665     for (sal_uInt16 i = 0; i < pRangeName->GetCount(); i++)
666     {
667         ScRangeData* pRangeData = (*pRangeName)[i];
668         if (pRangeData)
669         {
670             String aRName;
671             pRangeData->GetName(aRName);
672             if (aRName.Search(aName) != STRING_NOTFOUND)
673             {
674                 pRangeName->AtFree(i);
675                 bHasFound = sal_True;
676             }
677         }
678     }
679     if (bHasFound)
680         pRangeName->SetSharedMaxIndex(pRangeName->GetSharedMaxIndex()-1);
681 
682     ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
683     if ( pChangeTrack )
684         pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
685 
686     EndUndo();
687 }
688 
689 
690 //----------------------------------------------------------------------------
691 
692 void __EXPORT ScUndoAutoFill::Redo()
693 {
694     BeginRedo();
695 
696 //! Tabellen selektieren
697 
698     SCCOLROW nCount = 0;
699     switch (eFillDir)
700     {
701         case FILL_TO_BOTTOM:
702             nCount = aBlockRange.aEnd.Row() - aSource.aEnd.Row();
703             break;
704         case FILL_TO_RIGHT:
705             nCount = aBlockRange.aEnd.Col() - aSource.aEnd.Col();
706             break;
707         case FILL_TO_TOP:
708             nCount = aSource.aStart.Row() - aBlockRange.aStart.Row();
709             break;
710         case FILL_TO_LEFT:
711             nCount = aSource.aStart.Col() - aBlockRange.aStart.Col();
712             break;
713     }
714 
715     ScDocument* pDoc = pDocShell->GetDocument();
716     if ( fStartValue != MAXDOUBLE )
717     {
718         SCCOL nValX = (eFillDir == FILL_TO_LEFT) ? aSource.aEnd.Col() : aSource.aStart.Col();
719         SCROW nValY = (eFillDir == FILL_TO_TOP ) ? aSource.aEnd.Row() : aSource.aStart.Row();
720         SCTAB nTab = aSource.aStart.Tab();
721         pDoc->SetValue( nValX, nValY, nTab, fStartValue );
722     }
723     pDoc->Fill( aSource.aStart.Col(), aSource.aStart.Row(),
724                 aSource.aEnd.Col(),   aSource.aEnd.Row(),
725                 aMarkData, nCount,
726                 eFillDir, eFillCmd, eFillDateCmd,
727                 fStepValue, fMaxValue );
728 
729     SetChangeTrack();
730 
731     pDocShell->PostPaint( aBlockRange, PAINT_GRID );
732     pDocShell->PostDataChanged();
733     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
734     if (pViewShell)
735         pViewShell->CellContentChanged();
736 
737     EndRedo();
738 }
739 
740 
741 //----------------------------------------------------------------------------
742 
743 void __EXPORT ScUndoAutoFill::Repeat(SfxRepeatTarget& rTarget)
744 {
745     if (rTarget.ISA(ScTabViewTarget))
746     {
747         ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
748         if (eFillCmd==FILL_SIMPLE)
749             rViewShell.FillSimple( eFillDir, sal_True );
750         else
751             rViewShell.FillSeries( eFillDir, eFillCmd, eFillDateCmd,
752                                    fStartValue, fStepValue, fMaxValue, sal_True );
753     }
754 }
755 
756 
757 //----------------------------------------------------------------------------
758 
759 sal_Bool __EXPORT ScUndoAutoFill::CanRepeat(SfxRepeatTarget& rTarget) const
760 {
761     return (rTarget.ISA(ScTabViewTarget));
762 }
763 
764 
765 //============================================================================
766 //  class ScUndoMerge
767 //
768 //  Zellen zusammenfassen / Zusammenfassung aufheben
769 
770 //----------------------------------------------------------------------------
771 
772 ScUndoMerge::ScUndoMerge( ScDocShell* pNewDocShell,
773                             SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
774                             SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
775                             bool bMergeContents, ScDocument* pUndoDoc, SdrUndoAction* pDrawUndo )
776         //
777     :   ScSimpleUndo( pNewDocShell ),
778         //
779         maRange( nStartX, nStartY, nStartZ, nEndX, nEndY, nEndZ ),
780         mbMergeContents( bMergeContents ),
781         mpUndoDoc( pUndoDoc ),
782         mpDrawUndo( pDrawUndo )
783 {
784 }
785 
786 
787 //----------------------------------------------------------------------------
788 
789 ScUndoMerge::~ScUndoMerge()
790 {
791     delete mpUndoDoc;
792     DeleteSdrUndoAction( mpDrawUndo );
793 }
794 
795 
796 //----------------------------------------------------------------------------
797 
798 String ScUndoMerge::GetComment() const
799 {
800     return ScGlobal::GetRscString( STR_UNDO_MERGE );
801 }
802 
803 
804 //----------------------------------------------------------------------------
805 
806 void ScUndoMerge::DoChange( bool bUndo ) const
807 {
808     ScDocument* pDoc = pDocShell->GetDocument();
809 
810     ScUndoUtil::MarkSimpleBlock( pDocShell, maRange );
811 
812     if (bUndo)
813         // remove merge (contents are copied back below from undo document)
814         pDoc->RemoveMerge( maRange.aStart.Col(), maRange.aStart.Row(), maRange.aStart.Tab() );
815     else
816         // repeat merge, but do not remove note captions (will be done by drawing redo below)
817 /*!*/   pDoc->DoMerge( maRange.aStart.Tab(),
818                        maRange.aStart.Col(), maRange.aStart.Row(),
819                        maRange.aEnd.Col(),   maRange.aEnd.Row(), false );
820 
821     // undo -> copy back deleted contents
822     if (bUndo && mpUndoDoc)
823     {
824         pDoc->DeleteAreaTab( maRange, IDF_CONTENTS|IDF_NOCAPTIONS );
825         mpUndoDoc->CopyToDocument( maRange, IDF_ALL|IDF_NOCAPTIONS, sal_False, pDoc );
826     }
827 
828     // redo -> merge contents again
829     else if (!bUndo && mbMergeContents)
830     {
831 /*!*/   pDoc->DoMergeContents( maRange.aStart.Tab(),
832                                maRange.aStart.Col(), maRange.aStart.Row(),
833                                maRange.aEnd.Col(),   maRange.aEnd.Row()   );
834     }
835 
836     if (bUndo)
837         DoSdrUndoAction( mpDrawUndo, pDoc );
838     else
839         RedoSdrUndoAction( mpDrawUndo );
840 
841     sal_Bool bDidPaint = sal_False;
842     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
843     if ( pViewShell )
844     {
845         pViewShell->SetTabNo( maRange.aStart.Tab() );
846         bDidPaint = pViewShell->AdjustRowHeight( maRange.aStart.Row(), maRange.aEnd.Row() );
847     }
848 
849     if (!bDidPaint)
850         ScUndoUtil::PaintMore( pDocShell, maRange );
851 
852     ShowTable( maRange );
853 }
854 
855 
856 //----------------------------------------------------------------------------
857 
858 void ScUndoMerge::Undo()
859 {
860     BeginUndo();
861     DoChange( true );
862     EndUndo();
863 }
864 
865 
866 //----------------------------------------------------------------------------
867 
868 void ScUndoMerge::Redo()
869 {
870     BeginRedo();
871     DoChange( false );
872     EndRedo();
873 }
874 
875 
876 //----------------------------------------------------------------------------
877 
878 void ScUndoMerge::Repeat(SfxRepeatTarget& rTarget)
879 {
880     if (rTarget.ISA(ScTabViewTarget))
881     {
882         ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
883         sal_Bool bCont = sal_False;
884         rViewShell.MergeCells( sal_False, bCont, sal_True );
885     }
886 }
887 
888 
889 //----------------------------------------------------------------------------
890 
891 sal_Bool ScUndoMerge::CanRepeat(SfxRepeatTarget& rTarget) const
892 {
893     return (rTarget.ISA(ScTabViewTarget));
894 }
895 
896 
897 //============================================================================
898 //  class ScUndoAutoFormat
899 //
900 //      Auto-Format (nur einfache Bloecke)
901 
902 //----------------------------------------------------------------------------
903 
904 ScUndoAutoFormat::ScUndoAutoFormat( ScDocShell* pNewDocShell,
905                         const ScRange& rRange, ScDocument* pNewUndoDoc,
906                         const ScMarkData& rMark, sal_Bool bNewSize, sal_uInt16 nNewFormatNo )
907         //
908     :   ScBlockUndo( pNewDocShell, rRange, bNewSize ? SC_UNDO_MANUALHEIGHT : SC_UNDO_AUTOHEIGHT ),
909         //
910         pUndoDoc    ( pNewUndoDoc ),
911         aMarkData   ( rMark ),
912         bSize       ( bNewSize ),
913         nFormatNo   ( nNewFormatNo )
914 {
915 }
916 
917 
918 //----------------------------------------------------------------------------
919 
920 __EXPORT ScUndoAutoFormat::~ScUndoAutoFormat()
921 {
922     delete pUndoDoc;
923 }
924 
925 
926 //----------------------------------------------------------------------------
927 
928 String __EXPORT ScUndoAutoFormat::GetComment() const
929 {
930     return ScGlobal::GetRscString( STR_UNDO_AUTOFORMAT );   //"Auto-Format"
931 }
932 
933 
934 //----------------------------------------------------------------------------
935 
936 void __EXPORT ScUndoAutoFormat::Undo()
937 {
938     BeginUndo();
939 
940     ScDocument* pDoc = pDocShell->GetDocument();
941 
942     // Attribute
943 //  pDoc->DeleteAreaTab( aBlockRange, IDF_ATTRIB );
944 //  pUndoDoc->CopyToDocument( aBlockRange, IDF_ATTRIB, sal_False, pDoc );
945 
946     SCTAB nTabCount = pDoc->GetTableCount();
947     pDoc->DeleteArea( aBlockRange.aStart.Col(), aBlockRange.aStart.Row(),
948                       aBlockRange.aEnd.Col(), aBlockRange.aEnd.Row(),
949                       aMarkData, IDF_ATTRIB );
950     ScRange aCopyRange = aBlockRange;
951     aCopyRange.aStart.SetTab(0);
952     aCopyRange.aEnd.SetTab(nTabCount-1);
953     pUndoDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, sal_False, pDoc, &aMarkData );
954 
955     // Zellhoehen und -breiten (IDF_NONE)
956     if (bSize)
957     {
958         SCCOL nStartX = aBlockRange.aStart.Col();
959         SCROW nStartY = aBlockRange.aStart.Row();
960         SCTAB nStartZ = aBlockRange.aStart.Tab();
961         SCCOL nEndX = aBlockRange.aEnd.Col();
962         SCROW nEndY = aBlockRange.aEnd.Row();
963         SCTAB nEndZ = aBlockRange.aEnd.Tab();
964 
965         pUndoDoc->CopyToDocument( nStartX, 0, 0, nEndX, MAXROW, nTabCount-1,
966                                     IDF_NONE, sal_False, pDoc, &aMarkData );
967         pUndoDoc->CopyToDocument( 0, nStartY, 0, MAXCOL, nEndY, nTabCount-1,
968                                     IDF_NONE, sal_False, pDoc, &aMarkData );
969         pDocShell->PostPaint( 0, 0, nStartZ, MAXCOL, MAXROW, nEndZ,
970                               PAINT_GRID | PAINT_LEFT | PAINT_TOP, SC_PF_LINES );
971     }
972     else
973         pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES );
974 
975     EndUndo();
976 }
977 
978 
979 //----------------------------------------------------------------------------
980 
981 void __EXPORT ScUndoAutoFormat::Redo()
982 {
983     BeginRedo();
984 
985     ScDocument* pDoc = pDocShell->GetDocument();
986 
987     SCCOL nStartX = aBlockRange.aStart.Col();
988     SCROW nStartY = aBlockRange.aStart.Row();
989     SCTAB nStartZ = aBlockRange.aStart.Tab();
990     SCCOL nEndX = aBlockRange.aEnd.Col();
991     SCROW nEndY = aBlockRange.aEnd.Row();
992     SCTAB nEndZ = aBlockRange.aEnd.Tab();
993 
994     pDoc->AutoFormat( nStartX, nStartY, nEndX, nEndY, nFormatNo, aMarkData );
995 
996     if (bSize)
997     {
998         VirtualDevice aVirtDev;
999         Fraction aZoomX(1,1);
1000         Fraction aZoomY = aZoomX;
1001         double nPPTX,nPPTY;
1002         ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1003         if (pViewShell)
1004         {
1005             ScViewData* pData = pViewShell->GetViewData();
1006             nPPTX = pData->GetPPTX();
1007             nPPTY = pData->GetPPTY();
1008             aZoomX = pData->GetZoomX();
1009             aZoomY = pData->GetZoomY();
1010         }
1011         else
1012         {
1013             //  Zoom auf 100 lassen
1014             nPPTX = ScGlobal::nScreenPPTX;
1015             nPPTY = ScGlobal::nScreenPPTY;
1016         }
1017 
1018         sal_Bool bFormula = sal_False;  //! merken
1019 
1020         for (SCTAB nTab=nStartZ; nTab<=nEndZ; nTab++)
1021         {
1022             ScMarkData aDestMark;
1023             aDestMark.SelectOneTable( nTab );
1024             aDestMark.SetMarkArea( ScRange( nStartX, nStartY, nTab, nEndX, nEndY, nTab ) );
1025             aDestMark.MarkToMulti();
1026 
1027             // wie SC_SIZE_VISOPT
1028             SCROW nLastRow = -1;
1029             for (SCROW nRow=nStartY; nRow<=nEndY; nRow++)
1030             {
1031                 sal_uInt8 nOld = pDoc->GetRowFlags(nRow,nTab);
1032                 bool bHidden = pDoc->RowHidden(nRow, nTab, nLastRow);
1033                 if ( !bHidden && ( nOld & CR_MANUALSIZE ) )
1034                     pDoc->SetRowFlags( nRow, nTab, nOld & ~CR_MANUALSIZE );
1035             }
1036             pDoc->SetOptimalHeight( nStartY, nEndY, nTab, 0, &aVirtDev,
1037                                         nPPTX, nPPTY, aZoomX, aZoomY, sal_False );
1038 
1039             SCCOL nLastCol = -1;
1040             for (SCCOL nCol=nStartX; nCol<=nEndX; nCol++)
1041                 if (!pDoc->ColHidden(nCol, nTab, nLastCol))
1042                 {
1043                     sal_uInt16 nThisSize = STD_EXTRA_WIDTH + pDoc->GetOptimalColWidth( nCol, nTab,
1044                                                 &aVirtDev, nPPTX, nPPTY, aZoomX, aZoomY, bFormula,
1045                                                 &aDestMark );
1046                     pDoc->SetColWidth( nCol, nTab, nThisSize );
1047                     pDoc->ShowCol( nCol, nTab, sal_True );
1048                 }
1049         }
1050 
1051         pDocShell->PostPaint( 0,      0,      nStartZ,
1052                               MAXCOL, MAXROW, nEndZ,
1053                               PAINT_GRID | PAINT_LEFT | PAINT_TOP, SC_PF_LINES);
1054     }
1055     else
1056         pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES );
1057 
1058     EndRedo();
1059 }
1060 
1061 
1062 //----------------------------------------------------------------------------
1063 
1064 void __EXPORT ScUndoAutoFormat::Repeat(SfxRepeatTarget& rTarget)
1065 {
1066     if (rTarget.ISA(ScTabViewTarget))
1067         ((ScTabViewTarget&)rTarget).GetViewShell()->AutoFormat( nFormatNo, sal_True );
1068 }
1069 
1070 
1071 //----------------------------------------------------------------------------
1072 
1073 sal_Bool __EXPORT ScUndoAutoFormat::CanRepeat(SfxRepeatTarget& rTarget) const
1074 {
1075     return (rTarget.ISA(ScTabViewTarget));
1076 }
1077 
1078 
1079 //============================================================================
1080 //  class ScUndoReplace
1081 //
1082 //      Ersetzen
1083 
1084 //----------------------------------------------------------------------------
1085 
1086 ScUndoReplace::ScUndoReplace( ScDocShell* pNewDocShell, const ScMarkData& rMark,
1087                                     SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
1088                                     const String& rNewUndoStr, ScDocument* pNewUndoDoc,
1089                                     const SvxSearchItem* pItem )
1090         //
1091     :   ScSimpleUndo( pNewDocShell ),
1092         //
1093         aCursorPos  ( nCurX, nCurY, nCurZ ),
1094         aMarkData   ( rMark ),
1095         aUndoStr    ( rNewUndoStr ),
1096         pUndoDoc    ( pNewUndoDoc )
1097 {
1098     pSearchItem = new SvxSearchItem( *pItem );
1099     SetChangeTrack();
1100 }
1101 
1102 
1103 //----------------------------------------------------------------------------
1104 
1105 __EXPORT ScUndoReplace::~ScUndoReplace()
1106 {
1107     delete pUndoDoc;
1108     delete pSearchItem;
1109 }
1110 
1111 
1112 //----------------------------------------------------------------------------
1113 
1114 void ScUndoReplace::SetChangeTrack()
1115 {
1116     ScDocument* pDoc = pDocShell->GetDocument();
1117     ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
1118     if ( pChangeTrack )
1119     {
1120         if ( pUndoDoc )
1121         {   //! im UndoDoc stehen nur die geaenderten Zellen,
1122             // deswegen per Iterator moeglich
1123             pChangeTrack->AppendContentsIfInRefDoc( pUndoDoc,
1124                 nStartChangeAction, nEndChangeAction );
1125         }
1126         else
1127         {
1128             nStartChangeAction = pChangeTrack->GetActionMax() + 1;
1129             ScChangeActionContent* pContent = new ScChangeActionContent(
1130                 ScRange( aCursorPos) );
1131             pContent->SetOldValue( aUndoStr, pDoc );
1132             pContent->SetNewValue( pDoc->GetCell( aCursorPos ), pDoc );
1133             pChangeTrack->Append( pContent );
1134             nEndChangeAction = pChangeTrack->GetActionMax();
1135         }
1136     }
1137     else
1138         nStartChangeAction = nEndChangeAction = 0;
1139 }
1140 
1141 //----------------------------------------------------------------------------
1142 
1143 String __EXPORT ScUndoReplace::GetComment() const
1144 {
1145     return ScGlobal::GetRscString( STR_UNDO_REPLACE );  // "Ersetzen"
1146 }
1147 
1148 
1149 //----------------------------------------------------------------------------
1150 
1151 void __EXPORT ScUndoReplace::Undo()
1152 {
1153     BeginUndo();
1154 
1155     ScDocument* pDoc = pDocShell->GetDocument();
1156     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1157 
1158     ShowTable( aCursorPos.Tab() );
1159 
1160     if (pUndoDoc)       // nur bei ReplaceAll !!
1161     {
1162         DBG_ASSERT(pSearchItem->GetCommand() == SVX_SEARCHCMD_REPLACE_ALL,
1163                    "ScUndoReplace:: Falscher Modus");
1164 
1165         SetViewMarkData( aMarkData );
1166 
1167 //! markierte Tabellen
1168 //! Bereich merken ?
1169 
1170         //  Undo-Dokument hat keine Zeilen-/Spalten-Infos, also mit bColRowFlags = FALSE
1171         //  kopieren, um Outline-Gruppen nicht kaputtzumachen.
1172 
1173         sal_uInt16 nUndoFlags = (pSearchItem->GetPattern()) ? IDF_ATTRIB : IDF_CONTENTS;
1174         pUndoDoc->CopyToDocument( 0,      0,      0,
1175                                   MAXCOL, MAXROW, MAXTAB,
1176                                   nUndoFlags, sal_False, pDoc, NULL, sal_False );   // ohne Row-Flags
1177         pDocShell->PostPaintGridAll();
1178     }
1179     else if (pSearchItem->GetPattern() &&
1180              pSearchItem->GetCommand() == SVX_SEARCHCMD_REPLACE)
1181     {
1182         String aTempStr = pSearchItem->GetSearchString();       // vertauschen
1183         pSearchItem->SetSearchString(pSearchItem->GetReplaceString());
1184         pSearchItem->SetReplaceString(aTempStr);
1185         pDoc->ReplaceStyle( *pSearchItem,
1186                             aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(),
1187                             aMarkData, sal_True);
1188         pSearchItem->SetReplaceString(pSearchItem->GetSearchString());
1189         pSearchItem->SetSearchString(aTempStr);
1190         if (pViewShell)
1191             pViewShell->MoveCursorAbs( aCursorPos.Col(), aCursorPos.Row(),
1192                                        SC_FOLLOW_JUMP, sal_False, sal_False );
1193         pDocShell->PostPaintGridAll();
1194     }
1195     else if (pSearchItem->GetCellType() == SVX_SEARCHIN_NOTE)
1196     {
1197         ScPostIt* pNote = pDoc->GetNote( aCursorPos );
1198         DBG_ASSERT( pNote, "ScUndoReplace::Undo - cell does not contain a note" );
1199         if (pNote)
1200             pNote->SetText( aCursorPos, aUndoStr );
1201         if (pViewShell)
1202             pViewShell->MoveCursorAbs( aCursorPos.Col(), aCursorPos.Row(),
1203                                        SC_FOLLOW_JUMP, sal_False, sal_False );
1204     }
1205     else
1206     {
1207         // #78889# aUndoStr may contain line breaks
1208         if ( aUndoStr.Search('\n') != STRING_NOTFOUND )
1209             pDoc->PutCell( aCursorPos, new ScEditCell( aUndoStr, pDoc ) );
1210         else
1211             pDoc->SetString( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(), aUndoStr );
1212         if (pViewShell)
1213             pViewShell->MoveCursorAbs( aCursorPos.Col(), aCursorPos.Row(),
1214                                        SC_FOLLOW_JUMP, sal_False, sal_False );
1215         pDocShell->PostPaintGridAll();
1216     }
1217 
1218     ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
1219     if ( pChangeTrack )
1220         pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
1221 
1222     EndUndo();
1223 }
1224 
1225 
1226 //----------------------------------------------------------------------------
1227 
1228 void __EXPORT ScUndoReplace::Redo()
1229 {
1230     BeginRedo();
1231 
1232     ScDocument* pDoc = pDocShell->GetDocument();
1233     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1234 
1235     if (pViewShell)
1236         pViewShell->MoveCursorAbs( aCursorPos.Col(), aCursorPos.Row(),
1237                                    SC_FOLLOW_JUMP, sal_False, sal_False );
1238     if (pUndoDoc)
1239     {
1240         if (pViewShell)
1241         {
1242             SetViewMarkData( aMarkData );
1243 
1244             pViewShell->SearchAndReplace( pSearchItem, sal_False, sal_True );
1245         }
1246     }
1247     else if (pSearchItem->GetPattern() &&
1248              pSearchItem->GetCommand() == SVX_SEARCHCMD_REPLACE)
1249     {
1250         pDoc->ReplaceStyle( *pSearchItem,
1251                             aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(),
1252                             aMarkData, sal_True);
1253         pDocShell->PostPaintGridAll();
1254     }
1255     else
1256         if (pViewShell)
1257             pViewShell->SearchAndReplace( pSearchItem, sal_False, sal_True );
1258 
1259     SetChangeTrack();
1260 
1261     EndRedo();
1262 }
1263 
1264 
1265 //----------------------------------------------------------------------------
1266 
1267 void __EXPORT ScUndoReplace::Repeat(SfxRepeatTarget& rTarget)
1268 {
1269     if (rTarget.ISA(ScTabViewTarget))
1270         ((ScTabViewTarget&)rTarget).GetViewShell()->SearchAndReplace( pSearchItem, sal_True, sal_False );
1271 }
1272 
1273 
1274 //----------------------------------------------------------------------------
1275 
1276 sal_Bool __EXPORT ScUndoReplace::CanRepeat(SfxRepeatTarget& rTarget) const
1277 {
1278     return (rTarget.ISA(ScTabViewTarget));
1279 }
1280 
1281 
1282 //============================================================================
1283 //  class ScUndoTabOp
1284 //
1285 //  Mehrfachoperation (nur einfache Bloecke)
1286 
1287 //----------------------------------------------------------------------------
1288 
1289 ScUndoTabOp::ScUndoTabOp( ScDocShell* pNewDocShell,
1290                 SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
1291                 SCCOL nEndX, SCROW nEndY, SCTAB nEndZ, ScDocument* pNewUndoDoc,
1292                 const ScRefAddress& rFormulaCell,
1293                 const ScRefAddress& rFormulaEnd,
1294                 const ScRefAddress& rRowCell,
1295                 const ScRefAddress& rColCell,
1296                 sal_uInt8 nMd )
1297         //
1298     :   ScSimpleUndo( pNewDocShell ),
1299         //
1300         aRange          ( nStartX, nStartY, nStartZ, nEndX, nEndY, nEndZ ),
1301         pUndoDoc        ( pNewUndoDoc ),
1302         theFormulaCell  ( rFormulaCell ),
1303         theFormulaEnd   ( rFormulaEnd ),
1304         theRowCell      ( rRowCell ),
1305         theColCell      ( rColCell ),
1306         nMode           ( nMd )
1307 {
1308 }
1309 
1310 
1311 //----------------------------------------------------------------------------
1312 
1313 __EXPORT ScUndoTabOp::~ScUndoTabOp()
1314 {
1315     delete pUndoDoc;
1316 }
1317 
1318 
1319 //----------------------------------------------------------------------------
1320 
1321 String __EXPORT ScUndoTabOp::GetComment() const
1322 {
1323     return ScGlobal::GetRscString( STR_UNDO_TABOP );    // "Mehrfachoperation"
1324 }
1325 
1326 
1327 //----------------------------------------------------------------------------
1328 
1329 void __EXPORT ScUndoTabOp::Undo()
1330 {
1331     BeginUndo();
1332 
1333     ScUndoUtil::MarkSimpleBlock( pDocShell, aRange );
1334 
1335     sal_uInt16 nExtFlags = 0;
1336     pDocShell->UpdatePaintExt( nExtFlags, aRange );
1337 
1338     ScDocument* pDoc = pDocShell->GetDocument();
1339     pDoc->DeleteAreaTab( aRange,IDF_ALL & ~IDF_NOTE );
1340     pUndoDoc->CopyToDocument( aRange, IDF_ALL & ~IDF_NOTE, sal_False, pDoc );
1341     pDocShell->PostPaint( aRange, PAINT_GRID, nExtFlags );
1342     pDocShell->PostDataChanged();
1343     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1344     if (pViewShell)
1345         pViewShell->CellContentChanged();
1346 
1347     EndUndo();
1348 }
1349 
1350 
1351 //----------------------------------------------------------------------------
1352 
1353 void __EXPORT ScUndoTabOp::Redo()
1354 {
1355     BeginRedo();
1356 
1357     ScUndoUtil::MarkSimpleBlock( pDocShell, aRange );
1358 
1359     ScTabOpParam aParam( theFormulaCell, theFormulaEnd,
1360                          theRowCell,     theColCell,
1361                          nMode );
1362 
1363     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1364     if (pViewShell)
1365         pViewShell->TabOp( aParam, sal_False);
1366 
1367     EndRedo();
1368 }
1369 
1370 
1371 //----------------------------------------------------------------------------
1372 
1373 void __EXPORT ScUndoTabOp::Repeat(SfxRepeatTarget& /* rTarget */)
1374 {
1375 }
1376 
1377 
1378 //----------------------------------------------------------------------------
1379 
1380 sal_Bool __EXPORT ScUndoTabOp::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1381 {
1382     return sal_False;
1383 }
1384 
1385 
1386 //============================================================================
1387 //  class ScUndoConversion
1388 //
1389 //  Spelling
1390 
1391 //----------------------------------------------------------------------------
1392 
1393 ScUndoConversion::ScUndoConversion(
1394         ScDocShell* pNewDocShell, const ScMarkData& rMark,
1395         SCCOL nCurX, SCROW nCurY, SCTAB nCurZ, ScDocument* pNewUndoDoc,
1396         SCCOL nNewX, SCROW nNewY, SCTAB nNewZ, ScDocument* pNewRedoDoc,
1397         const ScConversionParam& rConvParam ) :
1398     ScSimpleUndo( pNewDocShell ),
1399     aMarkData( rMark ),
1400     aCursorPos( nCurX, nCurY, nCurZ ),
1401     pUndoDoc( pNewUndoDoc ),
1402     aNewCursorPos( nNewX, nNewY, nNewZ ),
1403     pRedoDoc( pNewRedoDoc ),
1404     maConvParam( rConvParam )
1405 {
1406     SetChangeTrack();
1407 }
1408 
1409 
1410 //----------------------------------------------------------------------------
1411 
1412 __EXPORT ScUndoConversion::~ScUndoConversion()
1413 {
1414     delete pUndoDoc;
1415     delete pRedoDoc;
1416 }
1417 
1418 
1419 //----------------------------------------------------------------------------
1420 
1421 void ScUndoConversion::SetChangeTrack()
1422 {
1423     ScDocument* pDoc = pDocShell->GetDocument();
1424     ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
1425     if ( pChangeTrack )
1426     {
1427         if ( pUndoDoc )
1428             pChangeTrack->AppendContentsIfInRefDoc( pUndoDoc,
1429                 nStartChangeAction, nEndChangeAction );
1430         else
1431         {
1432             DBG_ERROR( "ScUndoConversion::SetChangeTrack: kein UndoDoc" );
1433             nStartChangeAction = nEndChangeAction = 0;
1434         }
1435     }
1436     else
1437         nStartChangeAction = nEndChangeAction = 0;
1438 }
1439 
1440 //----------------------------------------------------------------------------
1441 
1442 String ScUndoConversion::GetComment() const
1443 {
1444     String aText;
1445     switch( maConvParam.GetType() )
1446     {
1447         case SC_CONVERSION_SPELLCHECK:      aText = ScGlobal::GetRscString( STR_UNDO_SPELLING );    break;
1448         case SC_CONVERSION_HANGULHANJA:     aText = ScGlobal::GetRscString( STR_UNDO_HANGULHANJA ); break;
1449         case SC_CONVERSION_CHINESE_TRANSL:  aText = ScGlobal::GetRscString( STR_UNDO_CHINESE_TRANSLATION ); break;
1450         default: DBG_ERRORFILE( "ScUndoConversion::GetComment - unknown conversion type" );
1451     }
1452     return aText;
1453 }
1454 
1455 
1456 //----------------------------------------------------------------------------
1457 
1458 void ScUndoConversion::DoChange( ScDocument* pRefDoc, const ScAddress& rCursorPos )
1459 {
1460     if (pRefDoc)
1461     {
1462         ScDocument* pDoc = pDocShell->GetDocument();
1463         ShowTable( rCursorPos.Tab() );
1464 
1465         SetViewMarkData( aMarkData );
1466 
1467         SCTAB nTabCount = pDoc->GetTableCount();
1468         //  Undo/Redo-doc has only selected tables
1469 
1470         sal_Bool bMulti = aMarkData.IsMultiMarked();
1471         pRefDoc->CopyToDocument( 0,      0,      0,
1472                                  MAXCOL, MAXROW, nTabCount-1,
1473                                  IDF_CONTENTS, bMulti, pDoc, &aMarkData );
1474         pDocShell->PostPaintGridAll();
1475     }
1476     else
1477     {
1478         DBG_ERROR("Kein Un-/RedoDoc bei Un-/RedoSpelling");
1479     }
1480 }
1481 
1482 
1483 //----------------------------------------------------------------------------
1484 
1485 void ScUndoConversion::Undo()
1486 {
1487     BeginUndo();
1488     DoChange( pUndoDoc, aCursorPos );
1489     ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
1490     if ( pChangeTrack )
1491         pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
1492     EndUndo();
1493 }
1494 
1495 
1496 //----------------------------------------------------------------------------
1497 
1498 void ScUndoConversion::Redo()
1499 {
1500     BeginRedo();
1501     DoChange( pRedoDoc, aNewCursorPos );
1502     SetChangeTrack();
1503     EndRedo();
1504 }
1505 
1506 
1507 //----------------------------------------------------------------------------
1508 
1509 void ScUndoConversion::Repeat( SfxRepeatTarget& rTarget )
1510 {
1511     if( rTarget.ISA( ScTabViewTarget ) )
1512         ((ScTabViewTarget&)rTarget).GetViewShell()->DoSheetConversion( maConvParam, sal_True );
1513 }
1514 
1515 
1516 //----------------------------------------------------------------------------
1517 
1518 sal_Bool ScUndoConversion::CanRepeat(SfxRepeatTarget& rTarget) const
1519 {
1520     return rTarget.ISA( ScTabViewTarget );
1521 }
1522 
1523 
1524 //============================================================================
1525 //  class ScUndoRefConversion
1526 //
1527 //  cell reference conversion
1528 
1529 //----------------------------------------------------------------------------
1530 
1531 ScUndoRefConversion::ScUndoRefConversion( ScDocShell* pNewDocShell,
1532                                          const ScRange& aMarkRange, const ScMarkData& rMark,
1533                                          ScDocument* pNewUndoDoc, ScDocument* pNewRedoDoc, sal_Bool bNewMulti, sal_uInt16 nNewFlag) :
1534 ScSimpleUndo( pNewDocShell ),
1535 aMarkData   ( rMark ),
1536 pUndoDoc    ( pNewUndoDoc ),
1537 pRedoDoc    ( pNewRedoDoc ),
1538 aRange      ( aMarkRange ),
1539 bMulti      ( bNewMulti ),
1540 nFlags      ( nNewFlag )
1541 {
1542     SetChangeTrack();
1543 }
1544 
1545 __EXPORT ScUndoRefConversion::~ScUndoRefConversion()
1546 {
1547     delete pUndoDoc;
1548     delete pRedoDoc;
1549 }
1550 
1551 String __EXPORT ScUndoRefConversion::GetComment() const
1552 {
1553     return ScGlobal::GetRscString( STR_UNDO_ENTERDATA ); // "Eingabe"
1554 }
1555 
1556 void ScUndoRefConversion::SetChangeTrack()
1557 {
1558     ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
1559     if ( pChangeTrack && (nFlags & IDF_FORMULA) )
1560         pChangeTrack->AppendContentsIfInRefDoc( pUndoDoc,
1561             nStartChangeAction, nEndChangeAction );
1562     else
1563         nStartChangeAction = nEndChangeAction = 0;
1564 }
1565 
1566 void ScUndoRefConversion::DoChange( ScDocument* pRefDoc)
1567 {
1568     ScDocument* pDoc = pDocShell->GetDocument();
1569 
1570     ShowTable(aRange);
1571 
1572     SetViewMarkData( aMarkData );
1573 
1574     ScRange aCopyRange = aRange;
1575     SCTAB nTabCount = pDoc->GetTableCount();
1576     aCopyRange.aStart.SetTab(0);
1577     aCopyRange.aEnd.SetTab(nTabCount-1);
1578     pRefDoc->CopyToDocument( aCopyRange, nFlags, bMulti, pDoc, &aMarkData );
1579     pDocShell->PostPaint( aRange, PAINT_GRID);
1580     pDocShell->PostDataChanged();
1581     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1582     if (pViewShell)
1583         pViewShell->CellContentChanged();
1584 }
1585 void __EXPORT ScUndoRefConversion::Undo()
1586 {
1587     BeginUndo();
1588     if (pUndoDoc)
1589         DoChange(pUndoDoc);
1590     ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
1591     if ( pChangeTrack )
1592         pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
1593     EndUndo();
1594 }
1595 
1596 void __EXPORT ScUndoRefConversion::Redo()
1597 {
1598     BeginRedo();
1599     if (pRedoDoc)
1600         DoChange(pRedoDoc);
1601     SetChangeTrack();
1602     EndRedo();
1603 }
1604 
1605 void __EXPORT ScUndoRefConversion::Repeat(SfxRepeatTarget& rTarget)
1606 {
1607     if (rTarget.ISA(ScTabViewTarget))
1608         ((ScTabViewTarget&)rTarget).GetViewShell()->DoRefConversion();
1609 }
1610 
1611 sal_Bool __EXPORT ScUndoRefConversion::CanRepeat(SfxRepeatTarget& rTarget) const
1612 {
1613     return (rTarget.ISA(ScTabViewTarget));
1614 }
1615 //============================================================================
1616 //  class ScUndoRefreshLink
1617 //
1618 //  Link aktualisieren / aendern
1619 
1620 //----------------------------------------------------------------------------
1621 
1622 ScUndoRefreshLink::ScUndoRefreshLink( ScDocShell* pNewDocShell,
1623                                     ScDocument* pNewUndoDoc )
1624         //
1625     :   ScSimpleUndo( pNewDocShell ),
1626         //
1627         pUndoDoc( pNewUndoDoc ),
1628         pRedoDoc( NULL )
1629 {
1630 }
1631 
1632 
1633 //----------------------------------------------------------------------------
1634 
1635 __EXPORT ScUndoRefreshLink::~ScUndoRefreshLink()
1636 {
1637     delete pUndoDoc;
1638     delete pRedoDoc;
1639 }
1640 
1641 
1642 //----------------------------------------------------------------------------
1643 
1644 String __EXPORT ScUndoRefreshLink::GetComment() const
1645 {
1646     return ScGlobal::GetRscString( STR_UNDO_UPDATELINK );
1647 }
1648 
1649 
1650 //----------------------------------------------------------------------------
1651 
1652 void __EXPORT ScUndoRefreshLink::Undo()
1653 {
1654     BeginUndo();
1655 
1656     sal_Bool bMakeRedo = !pRedoDoc;
1657     if (bMakeRedo)
1658         pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
1659 
1660     sal_Bool bFirst = sal_True;
1661     ScDocument* pDoc = pDocShell->GetDocument();
1662     SCTAB nCount = pDoc->GetTableCount();
1663     for (SCTAB nTab=0; nTab<nCount; nTab++)
1664         if (pUndoDoc->HasTable(nTab))
1665         {
1666             ScRange aRange(0,0,nTab,MAXCOL,MAXROW,nTab);
1667             if (bMakeRedo)
1668             {
1669                 if (bFirst)
1670                     pRedoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True );
1671                 else
1672                     pRedoDoc->AddUndoTab( nTab, nTab, sal_True, sal_True );
1673                 bFirst = sal_False;
1674                 pDoc->CopyToDocument(aRange, IDF_ALL, sal_False, pRedoDoc);
1675 //              pRedoDoc->TransferDrawPage( pDoc, nTab, nTab );
1676                 pRedoDoc->SetLink( nTab,
1677                                    pDoc->GetLinkMode(nTab),
1678                                    pDoc->GetLinkDoc(nTab),
1679                                    pDoc->GetLinkFlt(nTab),
1680                                    pDoc->GetLinkOpt(nTab),
1681                                    pDoc->GetLinkTab(nTab),
1682                                    pDoc->GetLinkRefreshDelay(nTab) );
1683             }
1684 
1685             pDoc->DeleteAreaTab( aRange,IDF_ALL );
1686             pUndoDoc->CopyToDocument( aRange, IDF_ALL, sal_False, pDoc );
1687 //          pDoc->TransferDrawPage( pUndoDoc, nTab, nTab );
1688             pDoc->SetLink( nTab, pUndoDoc->GetLinkMode(nTab), pUndoDoc->GetLinkDoc(nTab),
1689                                  pUndoDoc->GetLinkFlt(nTab),  pUndoDoc->GetLinkOpt(nTab),
1690                                  pUndoDoc->GetLinkTab(nTab),
1691                                  pUndoDoc->GetLinkRefreshDelay(nTab) );
1692         }
1693 
1694     pDocShell->PostPaintGridAll();
1695 
1696     EndUndo();
1697 }
1698 
1699 
1700 //----------------------------------------------------------------------------
1701 
1702 void __EXPORT ScUndoRefreshLink::Redo()
1703 {
1704     DBG_ASSERT(pRedoDoc, "Kein RedoDoc bei ScUndoRefreshLink::Redo");
1705 
1706     BeginUndo();
1707 
1708     ScDocument* pDoc = pDocShell->GetDocument();
1709     SCTAB nCount = pDoc->GetTableCount();
1710     for (SCTAB nTab=0; nTab<nCount; nTab++)
1711         if (pRedoDoc->HasTable(nTab))
1712         {
1713             ScRange aRange(0,0,nTab,MAXCOL,MAXROW,nTab);
1714 
1715             pDoc->DeleteAreaTab( aRange, IDF_ALL );
1716             pRedoDoc->CopyToDocument( aRange, IDF_ALL, sal_False, pDoc );
1717 //          pDoc->TransferDrawPage( pRedoDoc, nTab, nTab );
1718             pDoc->SetLink( nTab,
1719                            pRedoDoc->GetLinkMode(nTab),
1720                            pRedoDoc->GetLinkDoc(nTab),
1721                            pRedoDoc->GetLinkFlt(nTab),
1722                            pRedoDoc->GetLinkOpt(nTab),
1723                            pRedoDoc->GetLinkTab(nTab),
1724                            pRedoDoc->GetLinkRefreshDelay(nTab) );
1725         }
1726 
1727     pDocShell->PostPaintGridAll();
1728 
1729     EndUndo();
1730 }
1731 
1732 
1733 //----------------------------------------------------------------------------
1734 
1735 void __EXPORT ScUndoRefreshLink::Repeat(SfxRepeatTarget& /* rTarget */)
1736 {
1737     //  gippsnich
1738 }
1739 
1740 
1741 //----------------------------------------------------------------------------
1742 
1743 sal_Bool __EXPORT ScUndoRefreshLink::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1744 {
1745     return sal_False;
1746 }
1747 
1748 
1749 //----------------------------------------------------------------------------
1750 
1751 ScAreaLink* lcl_FindAreaLink( sfx2::LinkManager* pLinkManager, const String& rDoc,
1752                             const String& rFlt, const String& rOpt,
1753                             const String& rSrc, const ScRange& rDest )
1754 {
1755     const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
1756     sal_uInt16 nCount = pLinkManager->GetLinks().Count();
1757     for (sal_uInt16 i=0; i<nCount; i++)
1758     {
1759         ::sfx2::SvBaseLink* pBase = *rLinks[i];
1760         if (pBase->ISA(ScAreaLink))
1761             if ( ((ScAreaLink*)pBase)->IsEqual( rDoc, rFlt, rOpt, rSrc, rDest ) )
1762                 return (ScAreaLink*)pBase;
1763     }
1764 
1765     DBG_ERROR("ScAreaLink nicht gefunden");
1766     return NULL;
1767 }
1768 
1769 
1770 //============================================================================
1771 //  class ScUndoInsertAreaLink
1772 //
1773 //  Bereichs-Verknuepfung einfuegen
1774 
1775 //----------------------------------------------------------------------------
1776 
1777 ScUndoInsertAreaLink::ScUndoInsertAreaLink( ScDocShell* pShell,
1778                             const String& rDoc,
1779                             const String& rFlt, const String& rOpt,
1780                             const String& rArea, const ScRange& rDestRange,
1781                             sal_uLong nRefresh )
1782         //
1783     :   ScSimpleUndo    ( pShell ),
1784         //
1785         aDocName        ( rDoc ),
1786         aFltName        ( rFlt ),
1787         aOptions        ( rOpt ),
1788         aAreaName       ( rArea ),
1789         aRange          ( rDestRange ),
1790         nRefreshDelay   ( nRefresh )
1791 {
1792 }
1793 
1794 
1795 //----------------------------------------------------------------------------
1796 
1797 __EXPORT ScUndoInsertAreaLink::~ScUndoInsertAreaLink()
1798 {
1799 }
1800 
1801 
1802 //----------------------------------------------------------------------------
1803 
1804 String __EXPORT ScUndoInsertAreaLink::GetComment() const
1805 {
1806     return ScGlobal::GetRscString( STR_UNDO_INSERTAREALINK );
1807 }
1808 
1809 
1810 //----------------------------------------------------------------------------
1811 
1812 void __EXPORT ScUndoInsertAreaLink::Undo()
1813 {
1814     ScDocument* pDoc = pDocShell->GetDocument();
1815     sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
1816 
1817     ScAreaLink* pLink = lcl_FindAreaLink( pLinkManager, aDocName, aFltName, aOptions,
1818                                             aAreaName, aRange );
1819     if (pLink)
1820         pLinkManager->Remove( pLink );
1821 
1822     SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );     // Navigator
1823 }
1824 
1825 
1826 //----------------------------------------------------------------------------
1827 
1828 void __EXPORT ScUndoInsertAreaLink::Redo()
1829 {
1830     ScDocument* pDoc = pDocShell->GetDocument();
1831     sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
1832 
1833     ScAreaLink* pLink = new ScAreaLink( pDocShell, aDocName, aFltName, aOptions,
1834                                             aAreaName, aRange.aStart, nRefreshDelay );
1835     pLink->SetInCreate( sal_True );
1836     pLink->SetDestArea( aRange );
1837     pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aDocName, &aFltName, &aAreaName );
1838     pLink->Update();
1839     pLink->SetInCreate( sal_False );
1840 
1841     SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );     // Navigator
1842 }
1843 
1844 
1845 //----------------------------------------------------------------------------
1846 
1847 void __EXPORT ScUndoInsertAreaLink::Repeat(SfxRepeatTarget& /* rTarget */)
1848 {
1849     //! ....
1850 }
1851 
1852 
1853 //----------------------------------------------------------------------------
1854 
1855 sal_Bool __EXPORT ScUndoInsertAreaLink::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1856 {
1857     return sal_False;
1858 }
1859 
1860 
1861 //============================================================================
1862 //  class ScUndoRemoveAreaLink
1863 //
1864 //  Bereichs-Verknuepfung loeschen
1865 
1866 //----------------------------------------------------------------------------
1867 
1868 ScUndoRemoveAreaLink::ScUndoRemoveAreaLink( ScDocShell* pShell,
1869                             const String& rDoc, const String& rFlt, const String& rOpt,
1870                             const String& rArea, const ScRange& rDestRange,
1871                             sal_uLong nRefresh )
1872         //
1873     :   ScSimpleUndo    ( pShell ),
1874         //
1875         aDocName        ( rDoc ),
1876         aFltName        ( rFlt ),
1877         aOptions        ( rOpt ),
1878         aAreaName       ( rArea ),
1879         aRange          ( rDestRange ),
1880         nRefreshDelay   ( nRefresh )
1881 {
1882 }
1883 
1884 
1885 //----------------------------------------------------------------------------
1886 
1887 __EXPORT ScUndoRemoveAreaLink::~ScUndoRemoveAreaLink()
1888 {
1889 }
1890 
1891 
1892 //----------------------------------------------------------------------------
1893 
1894 String __EXPORT ScUndoRemoveAreaLink::GetComment() const
1895 {
1896     return ScGlobal::GetRscString( STR_UNDO_REMOVELINK );   //! eigener Text ??
1897 }
1898 
1899 
1900 //----------------------------------------------------------------------------
1901 
1902 void __EXPORT ScUndoRemoveAreaLink::Undo()
1903 {
1904     ScDocument* pDoc = pDocShell->GetDocument();
1905     sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
1906 
1907     ScAreaLink* pLink = new ScAreaLink( pDocShell, aDocName, aFltName, aOptions,
1908                                         aAreaName, aRange.aStart, nRefreshDelay );
1909     pLink->SetInCreate( sal_True );
1910     pLink->SetDestArea( aRange );
1911     pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aDocName, &aFltName, &aAreaName );
1912     pLink->Update();
1913     pLink->SetInCreate( sal_False );
1914 
1915     SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );     // Navigator
1916 }
1917 
1918 
1919 //----------------------------------------------------------------------------
1920 
1921 void __EXPORT ScUndoRemoveAreaLink::Redo()
1922 {
1923     ScDocument* pDoc = pDocShell->GetDocument();
1924     sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
1925 
1926     ScAreaLink* pLink = lcl_FindAreaLink( pLinkManager, aDocName, aFltName, aOptions,
1927                                             aAreaName, aRange );
1928     if (pLink)
1929         pLinkManager->Remove( pLink );
1930 
1931     SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );     // Navigator
1932 }
1933 
1934 
1935 //----------------------------------------------------------------------------
1936 
1937 void __EXPORT ScUndoRemoveAreaLink::Repeat(SfxRepeatTarget& /* rTarget */)
1938 {
1939     //  gippsnich
1940 }
1941 
1942 
1943 //----------------------------------------------------------------------------
1944 
1945 sal_Bool __EXPORT ScUndoRemoveAreaLink::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1946 {
1947     return sal_False;
1948 }
1949 
1950 
1951 //============================================================================
1952 //  class ScUndoUpdateAreaLink
1953 //
1954 //  Bereichs-Verknuepfung aktualisieren
1955 
1956 //----------------------------------------------------------------------------
1957 
1958 ScUndoUpdateAreaLink::ScUndoUpdateAreaLink( ScDocShell* pShell,
1959                             const String& rOldD, const String& rOldF, const String& rOldO,
1960                             const String& rOldA, const ScRange& rOldR, sal_uLong nOldRD,
1961                             const String& rNewD, const String& rNewF, const String& rNewO,
1962                             const String& rNewA, const ScRange& rNewR, sal_uLong nNewRD,
1963                             ScDocument* pUndo, ScDocument* pRedo, sal_Bool bDoInsert )
1964         //
1965     :   ScSimpleUndo( pShell ),
1966         //
1967         aOldDoc     ( rOldD ),
1968         aOldFlt     ( rOldF ),
1969         aOldOpt     ( rOldO ),
1970         aOldArea    ( rOldA ),
1971         aOldRange   ( rOldR ),
1972         aNewDoc     ( rNewD ),
1973         aNewFlt     ( rNewF ),
1974         aNewOpt     ( rNewO ),
1975         aNewArea    ( rNewA ),
1976         aNewRange   ( rNewR ),
1977         pUndoDoc    ( pUndo ),
1978         pRedoDoc    ( pRedo ),
1979         nOldRefresh ( nOldRD ),
1980         nNewRefresh ( nNewRD ),
1981         bWithInsert ( bDoInsert )
1982 {
1983     DBG_ASSERT( aOldRange.aStart == aNewRange.aStart, "AreaLink verschoben ?" );
1984 }
1985 
1986 
1987 //----------------------------------------------------------------------------
1988 
1989 __EXPORT ScUndoUpdateAreaLink::~ScUndoUpdateAreaLink()
1990 {
1991     delete pUndoDoc;
1992     delete pRedoDoc;
1993 }
1994 
1995 
1996 //----------------------------------------------------------------------------
1997 
1998 String __EXPORT ScUndoUpdateAreaLink::GetComment() const
1999 {
2000     return ScGlobal::GetRscString( STR_UNDO_UPDATELINK );   //! eigener Text ??
2001 }
2002 
2003 
2004 //----------------------------------------------------------------------------
2005 
2006 void ScUndoUpdateAreaLink::DoChange( const sal_Bool bUndo ) const
2007 {
2008     ScDocument* pDoc = pDocShell->GetDocument();
2009 
2010     SCCOL nEndX = Max( aOldRange.aEnd.Col(), aNewRange.aEnd.Col() );
2011     SCROW nEndY = Max( aOldRange.aEnd.Row(), aNewRange.aEnd.Row() );
2012     SCTAB nEndZ = Max( aOldRange.aEnd.Tab(), aNewRange.aEnd.Tab() );    //?
2013 
2014     if ( bUndo )
2015     {
2016         if ( bWithInsert )
2017         {
2018             pDoc->FitBlock( aNewRange, aOldRange );
2019             pDoc->DeleteAreaTab( aOldRange, IDF_ALL & ~IDF_NOTE );
2020             pUndoDoc->UndoToDocument( aOldRange, IDF_ALL & ~IDF_NOTE, sal_False, pDoc );
2021         }
2022         else
2023         {
2024             ScRange aCopyRange( aOldRange.aStart, ScAddress(nEndX,nEndY,nEndZ) );
2025             pDoc->DeleteAreaTab( aCopyRange, IDF_ALL & ~IDF_NOTE );
2026             pUndoDoc->CopyToDocument( aCopyRange, IDF_ALL & ~IDF_NOTE, sal_False, pDoc );
2027         }
2028     }
2029     else
2030     {
2031         if ( bWithInsert )
2032         {
2033             pDoc->FitBlock( aOldRange, aNewRange );
2034             pDoc->DeleteAreaTab( aNewRange, IDF_ALL & ~IDF_NOTE );
2035             pRedoDoc->CopyToDocument( aNewRange, IDF_ALL & ~IDF_NOTE, sal_False, pDoc );
2036         }
2037         else
2038         {
2039             ScRange aCopyRange( aOldRange.aStart, ScAddress(nEndX,nEndY,nEndZ) );
2040             pDoc->DeleteAreaTab( aCopyRange, IDF_ALL & ~IDF_NOTE );
2041             pRedoDoc->CopyToDocument( aCopyRange, IDF_ALL & ~IDF_NOTE, sal_False, pDoc );
2042         }
2043     }
2044 
2045     ScRange aWorkRange( aNewRange.aStart, ScAddress( nEndX, nEndY, nEndZ ) );
2046     pDoc->ExtendMerge( aWorkRange, sal_True );
2047 
2048     //  Paint
2049 
2050     if ( aNewRange.aEnd.Col() != aOldRange.aEnd.Col() )
2051         aWorkRange.aEnd.SetCol(MAXCOL);
2052     if ( aNewRange.aEnd.Row() != aOldRange.aEnd.Row() )
2053         aWorkRange.aEnd.SetRow(MAXROW);
2054 
2055     if ( !pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), aWorkRange.aStart.Tab() ) )
2056         pDocShell->PostPaint( aWorkRange, PAINT_GRID );
2057 
2058     pDocShell->PostDataChanged();
2059     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
2060     if (pViewShell)
2061         pViewShell->CellContentChanged();
2062 }
2063 
2064 
2065 //----------------------------------------------------------------------------
2066 
2067 void __EXPORT ScUndoUpdateAreaLink::Undo()
2068 {
2069     ScDocument* pDoc = pDocShell->GetDocument();
2070     sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
2071     ScAreaLink* pLink = lcl_FindAreaLink( pLinkManager, aNewDoc, aNewFlt, aNewOpt,
2072                                             aNewArea, aNewRange );
2073     if (pLink)
2074     {
2075         pLink->SetSource( aOldDoc, aOldFlt, aOldOpt, aOldArea );        // alte Werte im Link
2076         pLink->SetDestArea( aOldRange );
2077         pLink->SetRefreshDelay( nOldRefresh );
2078     }
2079 
2080     DoChange(sal_True);
2081 }
2082 
2083 
2084 //----------------------------------------------------------------------------
2085 
2086 void __EXPORT ScUndoUpdateAreaLink::Redo()
2087 {
2088     ScDocument* pDoc = pDocShell->GetDocument();
2089     sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
2090     ScAreaLink* pLink = lcl_FindAreaLink( pLinkManager, aOldDoc, aOldFlt, aOldOpt,
2091                                             aOldArea, aOldRange );
2092     if (pLink)
2093     {
2094         pLink->SetSource( aNewDoc, aNewFlt, aNewOpt, aNewArea );        // neue Werte im Link
2095         pLink->SetDestArea( aNewRange );
2096         pLink->SetRefreshDelay( nNewRefresh );
2097     }
2098 
2099     DoChange(sal_False);
2100 }
2101 
2102 
2103 //----------------------------------------------------------------------------
2104 
2105 void __EXPORT ScUndoUpdateAreaLink::Repeat(SfxRepeatTarget& /* rTarget */)
2106 {
2107     //  gippsnich
2108 }
2109 
2110 
2111 //----------------------------------------------------------------------------
2112 
2113 sal_Bool __EXPORT ScUndoUpdateAreaLink::CanRepeat(SfxRepeatTarget& /* rTarget */) const
2114 {
2115     return sal_False;
2116 }
2117 
2118 
2119 
2120 
2121