xref: /trunk/main/sc/source/ui/undo/undocell.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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 "scitems.hxx"
32 #include <editeng/eeitem.hxx>
33 
34 #include <editeng/editobj.hxx>
35 #include <svl/zforlist.hxx>
36 #include <sfx2/app.hxx>
37 
38 #include "undocell.hxx"
39 #include "document.hxx"
40 #include "docpool.hxx"
41 #include "patattr.hxx"
42 #include "docsh.hxx"
43 #include "tabvwsh.hxx"
44 #include "globstr.hrc"
45 #include "global.hxx"
46 #include "cell.hxx"
47 #include "target.hxx"
48 #include "undoolk.hxx"
49 #include "detdata.hxx"
50 #include "stlpool.hxx"
51 #include "printfun.hxx"
52 #include "rangenam.hxx"
53 #include "chgtrack.hxx"
54 #include "sc.hrc"
55 #include "docuno.hxx"
56 
57 // STATIC DATA -----------------------------------------------------------
58 
59 TYPEINIT1(ScUndoCursorAttr, ScSimpleUndo);
60 TYPEINIT1(ScUndoEnterData, ScSimpleUndo);
61 TYPEINIT1(ScUndoEnterValue, ScSimpleUndo);
62 TYPEINIT1(ScUndoPutCell, ScSimpleUndo);
63 TYPEINIT1(ScUndoPageBreak, ScSimpleUndo);
64 TYPEINIT1(ScUndoPrintZoom, ScSimpleUndo);
65 TYPEINIT1(ScUndoThesaurus, ScSimpleUndo);
66 TYPEINIT1(ScUndoReplaceNote, ScSimpleUndo);
67 TYPEINIT1(ScUndoShowHideNote, ScSimpleUndo);
68 TYPEINIT1(ScUndoDetective, ScSimpleUndo);
69 TYPEINIT1(ScUndoRangeNames, ScSimpleUndo);
70 
71 
72 // -----------------------------------------------------------------------
73 //
74 //      Attribute auf Cursor anwenden
75 //
76 
77 ScUndoCursorAttr::ScUndoCursorAttr( ScDocShell* pNewDocShell,
78             SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
79             const ScPatternAttr* pOldPat, const ScPatternAttr* pNewPat,
80             const ScPatternAttr* pApplyPat, sal_Bool bAutomatic ) :
81     ScSimpleUndo( pNewDocShell ),
82     nCol( nNewCol ),
83     nRow( nNewRow ),
84     nTab( nNewTab ),
85     bIsAutomatic( bAutomatic )
86 {
87     ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
88     pNewPattern = (ScPatternAttr*) &pPool->Put( *pNewPat );
89     pOldPattern = (ScPatternAttr*) &pPool->Put( *pOldPat );
90     pApplyPattern = (ScPatternAttr*) &pPool->Put( *pApplyPat );
91 }
92 
93 __EXPORT ScUndoCursorAttr::~ScUndoCursorAttr()
94 {
95     ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
96     pPool->Remove(*pNewPattern);
97     pPool->Remove(*pOldPattern);
98     pPool->Remove(*pApplyPattern);
99 }
100 
101 String __EXPORT ScUndoCursorAttr::GetComment() const
102 {
103     //! eigener Text fuer automatische Attributierung
104 
105     sal_uInt16 nId = STR_UNDO_CURSORATTR;        // "Attribute"
106     return ScGlobal::GetRscString( nId );
107 }
108 
109 void ScUndoCursorAttr::DoChange( const ScPatternAttr* pWhichPattern ) const
110 {
111     pDocShell->GetDocument()->SetPattern( nCol, nRow, nTab, *pWhichPattern, sal_True );
112 
113     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
114     if (pViewShell)
115     {
116         pViewShell->SetTabNo( nTab );
117         pViewShell->MoveCursorAbs( nCol, nRow, SC_FOLLOW_JUMP, sal_False, sal_False );
118         pViewShell->AdjustBlockHeight();
119     }
120 
121     const SfxItemSet& rApplySet = pApplyPattern->GetItemSet();
122     sal_Bool bPaintExt = ( rApplySet.GetItemState( ATTR_SHADOW, sal_True ) != SFX_ITEM_DEFAULT ||
123                        rApplySet.GetItemState( ATTR_CONDITIONAL, sal_True ) != SFX_ITEM_DEFAULT );
124     sal_Bool bPaintRows = ( rApplySet.GetItemState( ATTR_HOR_JUSTIFY, sal_True ) != SFX_ITEM_DEFAULT );
125 
126     sal_uInt16 nFlags = SC_PF_TESTMERGE;
127     if (bPaintExt)
128         nFlags |= SC_PF_LINES;
129     if (bPaintRows)
130         nFlags |= SC_PF_WHOLEROWS;
131     pDocShell->PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PAINT_GRID, nFlags );
132 }
133 
134 void __EXPORT ScUndoCursorAttr::Undo()
135 {
136     BeginUndo();
137     DoChange(pOldPattern);
138 
139     if ( bIsAutomatic )
140     {
141         //  wenn automatische Formatierung rueckgaengig gemacht wird,
142         //  soll auch nicht weiter automatisch formatiert werden:
143 
144         ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
145         if (pViewShell)
146             pViewShell->ForgetFormatArea();
147     }
148 
149     EndUndo();
150 }
151 
152 void __EXPORT ScUndoCursorAttr::Redo()
153 {
154     BeginRedo();
155     DoChange(pNewPattern);
156     EndRedo();
157 }
158 
159 void __EXPORT ScUndoCursorAttr::Repeat(SfxRepeatTarget& rTarget)
160 {
161     if (rTarget.ISA(ScTabViewTarget))
162         ((ScTabViewTarget&)rTarget).GetViewShell()->ApplySelectionPattern( *pApplyPattern );
163 }
164 
165 sal_Bool __EXPORT ScUndoCursorAttr::CanRepeat(SfxRepeatTarget& rTarget) const
166 {
167     return (rTarget.ISA(ScTabViewTarget));
168 }
169 
170 
171 // -----------------------------------------------------------------------
172 //
173 //      Daten eingeben
174 //
175 
176 ScUndoEnterData::ScUndoEnterData( ScDocShell* pNewDocShell,
177             SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
178             SCTAB nNewCount, SCTAB* pNewTabs, ScBaseCell** ppOldData,
179             sal_Bool* pHasForm, sal_uLong* pOldForm,
180             const String& rNewStr, EditTextObject* pObj ) :
181     ScSimpleUndo( pNewDocShell ),
182     aNewString( rNewStr ),
183     pTabs( pNewTabs ),
184     ppOldCells( ppOldData ),
185     pHasFormat( pHasForm ),
186     pOldFormats( pOldForm ),
187     pNewEditData( pObj ),
188     nCol( nNewCol ),
189     nRow( nNewRow ),
190     nTab( nNewTab ),
191     nCount( nNewCount )
192 {
193     SetChangeTrack();
194 }
195 
196 __EXPORT ScUndoEnterData::~ScUndoEnterData()
197 {
198     for (sal_uInt16 i=0; i<nCount; i++)
199         if (ppOldCells[i])
200             ppOldCells[i]->Delete();
201     delete[] ppOldCells;
202 
203     delete[] pHasFormat;
204     delete[] pOldFormats;
205     delete[] pTabs;
206 
207     delete pNewEditData;
208 }
209 
210 String __EXPORT ScUndoEnterData::GetComment() const
211 {
212     return ScGlobal::GetRscString( STR_UNDO_ENTERDATA ); // "Eingabe"
213 }
214 
215 void ScUndoEnterData::DoChange() const
216 {
217     //  Zeilenhoehe anpassen
218     //! nur wenn noetig (alte oder neue EditZelle, oder Attribute) ??
219     for (sal_uInt16 i=0; i<nCount; i++)
220         pDocShell->AdjustRowHeight( nRow, nRow, pTabs[i] );
221 
222     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
223     if (pViewShell)
224     {
225         pViewShell->SetTabNo( nTab );
226         pViewShell->MoveCursorAbs( nCol, nRow, SC_FOLLOW_JUMP, sal_False, sal_False );
227     }
228 
229     pDocShell->PostDataChanged();
230 }
231 
232 void ScUndoEnterData::SetChangeTrack()
233 {
234     ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
235     if ( pChangeTrack )
236     {
237         nEndChangeAction = pChangeTrack->GetActionMax() + 1;
238         ScAddress aPos( nCol, nRow, nTab );
239         for (sal_uInt16 i=0; i<nCount; i++)
240         {
241             aPos.SetTab( pTabs[i] );
242             sal_uLong nFormat = 0;
243             if ( pHasFormat && pOldFormats )
244             {
245                 if ( pHasFormat[i] )
246                     nFormat = pOldFormats[i];
247             }
248             pChangeTrack->AppendContent( aPos, ppOldCells[i], nFormat );
249         }
250         if ( nEndChangeAction > pChangeTrack->GetActionMax() )
251             nEndChangeAction = 0;       // nichts appended
252     }
253     else
254         nEndChangeAction = 0;
255 }
256 
257 void __EXPORT ScUndoEnterData::Undo()
258 {
259     BeginUndo();
260 
261     ScDocument* pDoc = pDocShell->GetDocument();
262     for (sal_uInt16 i=0; i<nCount; i++)
263     {
264         ScBaseCell* pNewCell = ppOldCells[i] ? ppOldCells[i]->CloneWithoutNote( *pDoc, SC_CLONECELL_STARTLISTENING ) : 0;
265         pDoc->PutCell( nCol, nRow, pTabs[i], pNewCell );
266 
267         if (pHasFormat && pOldFormats)
268         {
269             if ( pHasFormat[i] )
270                 pDoc->ApplyAttr( nCol, nRow, pTabs[i],
271                                     SfxUInt32Item( ATTR_VALUE_FORMAT, pOldFormats[i] ) );
272             else
273             {
274                 ScPatternAttr aPattern( *pDoc->GetPattern( nCol, nRow, pTabs[i] ) );
275                 aPattern.GetItemSet().ClearItem( ATTR_VALUE_FORMAT );
276                 pDoc->SetPattern( nCol, nRow, pTabs[i], aPattern, sal_True );
277             }
278         }
279         pDocShell->PostPaintCell( nCol, nRow, pTabs[i] );
280     }
281 
282     ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
283     if ( pChangeTrack && nEndChangeAction >= sal::static_int_cast<sal_uLong>(nCount) )
284         pChangeTrack->Undo( nEndChangeAction - nCount + 1, nEndChangeAction );
285 
286     DoChange();
287     EndUndo();
288 
289     // #i97876# Spreadsheet data changes are not notified
290     ScModelObj* pModelObj = ScModelObj::getImplementation( pDocShell->GetModel() );
291     if ( pModelObj && pModelObj->HasChangesListeners() )
292     {
293         ScRangeList aChangeRanges;
294         for ( sal_uInt16 i = 0; i < nCount; ++i )
295         {
296             aChangeRanges.Append( ScRange( nCol, nRow, pTabs[i] ) );
297         }
298         pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
299     }
300 }
301 
302 void __EXPORT ScUndoEnterData::Redo()
303 {
304     BeginRedo();
305 
306     ScDocument* pDoc = pDocShell->GetDocument();
307     for (sal_uInt16 i=0; i<nCount; i++)
308     {
309         if (pNewEditData)
310             pDoc->PutCell( nCol, nRow, pTabs[i], new ScEditCell( pNewEditData,
311                 pDoc, NULL ) );
312         else
313             pDoc->SetString( nCol, nRow, pTabs[i], aNewString );
314         pDocShell->PostPaintCell( nCol, nRow, pTabs[i] );
315     }
316 
317     SetChangeTrack();
318 
319     DoChange();
320     EndRedo();
321 
322     // #i97876# Spreadsheet data changes are not notified
323     ScModelObj* pModelObj = ScModelObj::getImplementation( pDocShell->GetModel() );
324     if ( pModelObj && pModelObj->HasChangesListeners() )
325     {
326         ScRangeList aChangeRanges;
327         for ( sal_uInt16 i = 0; i < nCount; ++i )
328         {
329             aChangeRanges.Append( ScRange( nCol, nRow, pTabs[i] ) );
330         }
331         pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
332     }
333 }
334 
335 void __EXPORT ScUndoEnterData::Repeat(SfxRepeatTarget& rTarget)
336 {
337     if (rTarget.ISA(ScTabViewTarget))
338     {
339         String aTemp = aNewString;
340         ((ScTabViewTarget&)rTarget).GetViewShell()->EnterDataAtCursor( aTemp );
341     }
342 }
343 
344 sal_Bool __EXPORT ScUndoEnterData::CanRepeat(SfxRepeatTarget& rTarget) const
345 {
346     return (rTarget.ISA(ScTabViewTarget));
347 }
348 
349 
350 // -----------------------------------------------------------------------
351 //
352 //      Wert aendern
353 //
354 
355 ScUndoEnterValue::ScUndoEnterValue( ScDocShell* pNewDocShell, const ScAddress& rNewPos,
356                                     ScBaseCell* pUndoCell, double nVal, sal_Bool bHeight ) :
357     ScSimpleUndo( pNewDocShell ),
358     aPos        ( rNewPos ),
359     pOldCell    ( pUndoCell ),
360     nValue      ( nVal ),
361     bNeedHeight ( bHeight )
362 {
363     SetChangeTrack();
364 }
365 
366 __EXPORT ScUndoEnterValue::~ScUndoEnterValue()
367 {
368     if (pOldCell)
369         pOldCell->Delete();
370 }
371 
372 String __EXPORT ScUndoEnterValue::GetComment() const
373 {
374     return ScGlobal::GetRscString( STR_UNDO_ENTERDATA ); // "Eingabe"
375 }
376 
377 void ScUndoEnterValue::SetChangeTrack()
378 {
379     ScDocument* pDoc = pDocShell->GetDocument();
380     ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
381     if ( pChangeTrack )
382     {
383         nEndChangeAction = pChangeTrack->GetActionMax() + 1;
384         pChangeTrack->AppendContent( aPos, pOldCell );
385         if ( nEndChangeAction > pChangeTrack->GetActionMax() )
386             nEndChangeAction = 0;       // nichts appended
387     }
388     else
389         nEndChangeAction = 0;
390 }
391 
392 void __EXPORT ScUndoEnterValue::Undo()
393 {
394     BeginUndo();
395 
396     ScDocument* pDoc = pDocShell->GetDocument();
397     ScBaseCell* pNewCell = pOldCell ? pOldCell->CloneWithoutNote( *pDoc, SC_CLONECELL_STARTLISTENING ) : 0;
398 
399     pDoc->PutCell( aPos, pNewCell );
400 
401     pDocShell->PostPaintCell( aPos );
402 
403     ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
404     if ( pChangeTrack )
405         pChangeTrack->Undo( nEndChangeAction, nEndChangeAction );
406 
407     EndUndo();
408 }
409 
410 void __EXPORT ScUndoEnterValue::Redo()
411 {
412     BeginRedo();
413 
414     ScDocument* pDoc = pDocShell->GetDocument();
415     pDoc->SetValue( aPos.Col(), aPos.Row(), aPos.Tab(), nValue );
416     pDocShell->PostPaintCell( aPos );
417 
418     SetChangeTrack();
419 
420     EndRedo();
421 }
422 
423 void __EXPORT ScUndoEnterValue::Repeat(SfxRepeatTarget& /* rTarget */)
424 {
425     //  gippsnich
426 }
427 
428 sal_Bool __EXPORT ScUndoEnterValue::CanRepeat(SfxRepeatTarget& /* rTarget */) const
429 {
430     return sal_False;
431 }
432 
433 
434 // -----------------------------------------------------------------------
435 //
436 //      Beliebige Zelle eingeben
437 //
438 
439 ScUndoPutCell::ScUndoPutCell( ScDocShell* pNewDocShell, const ScAddress& rNewPos,
440                             ScBaseCell* pUndoCell, ScBaseCell* pRedoCell, sal_Bool bHeight ) :
441     ScSimpleUndo( pNewDocShell ),
442     aPos        ( rNewPos ),
443     pOldCell    ( pUndoCell ),
444     pEnteredCell( pRedoCell ),
445     bNeedHeight ( bHeight )
446 {
447     SetChangeTrack();
448 }
449 
450 __EXPORT ScUndoPutCell::~ScUndoPutCell()
451 {
452     if (pOldCell)
453         pOldCell->Delete();
454     if (pEnteredCell)
455         pEnteredCell->Delete();
456 }
457 
458 String __EXPORT ScUndoPutCell::GetComment() const
459 {
460     return ScGlobal::GetRscString( STR_UNDO_ENTERDATA ); // "Eingabe"
461 }
462 
463 void ScUndoPutCell::SetChangeTrack()
464 {
465     ScDocument* pDoc = pDocShell->GetDocument();
466     ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
467     if ( pChangeTrack )
468     {
469         nEndChangeAction = pChangeTrack->GetActionMax() + 1;
470         pChangeTrack->AppendContent( aPos, pOldCell );
471         if ( nEndChangeAction > pChangeTrack->GetActionMax() )
472             nEndChangeAction = 0;       // nichts appended
473     }
474     else
475         nEndChangeAction = 0;
476 }
477 
478 void __EXPORT ScUndoPutCell::Undo()
479 {
480     BeginUndo();
481 
482     ScDocument* pDoc = pDocShell->GetDocument();
483     ScBaseCell* pNewCell = pOldCell ? pOldCell->CloneWithoutNote( *pDoc, aPos, SC_CLONECELL_STARTLISTENING ) : 0;
484 
485     pDoc->PutCell( aPos.Col(), aPos.Row(), aPos.Tab(), pNewCell );
486 
487     pDocShell->PostPaintCell( aPos );
488 
489     ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
490     if ( pChangeTrack )
491         pChangeTrack->Undo( nEndChangeAction, nEndChangeAction );
492 
493     EndUndo();
494 }
495 
496 void __EXPORT ScUndoPutCell::Redo()
497 {
498     BeginRedo();
499 
500     ScDocument* pDoc = pDocShell->GetDocument();
501     ScBaseCell* pNewCell = pEnteredCell ? pEnteredCell->CloneWithoutNote( *pDoc, aPos, SC_CLONECELL_STARTLISTENING ) : 0;
502 
503     pDoc->PutCell( aPos.Col(), aPos.Row(), aPos.Tab(), pNewCell );
504 
505     pDocShell->PostPaintCell( aPos );
506 
507     SetChangeTrack();
508 
509     EndRedo();
510 }
511 
512 void __EXPORT ScUndoPutCell::Repeat(SfxRepeatTarget& /* rTarget */)
513 {
514     //  gippsnich
515 }
516 
517 sal_Bool __EXPORT ScUndoPutCell::CanRepeat(SfxRepeatTarget& /* rTarget */) const
518 {
519     return sal_False;
520 }
521 
522 
523 // -----------------------------------------------------------------------
524 //
525 //      Seitenumbrueche
526 //
527 
528 ScUndoPageBreak::ScUndoPageBreak( ScDocShell* pNewDocShell,
529             SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
530             sal_Bool bNewColumn, sal_Bool bNewInsert ) :
531     ScSimpleUndo( pNewDocShell ),
532     nCol( nNewCol ),
533     nRow( nNewRow ),
534     nTab( nNewTab ),
535     bColumn( bNewColumn ),
536     bInsert( bNewInsert )
537 {
538 }
539 
540 __EXPORT ScUndoPageBreak::~ScUndoPageBreak()
541 {
542 }
543 
544 String __EXPORT ScUndoPageBreak::GetComment() const
545 {
546     //"Spaltenumbruch" | "Zeilenumbruch"  "einfuegen" | "loeschen"
547     return String ( bColumn ?
548         ( bInsert ?
549             ScGlobal::GetRscString( STR_UNDO_INSCOLBREAK ) :
550             ScGlobal::GetRscString( STR_UNDO_DELCOLBREAK )
551         ) :
552         ( bInsert ?
553             ScGlobal::GetRscString( STR_UNDO_INSROWBREAK ) :
554             ScGlobal::GetRscString( STR_UNDO_DELROWBREAK )
555         ) );
556 }
557 
558 void ScUndoPageBreak::DoChange( sal_Bool bInsertP ) const
559 {
560     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
561 
562     if (pViewShell)
563     {
564         pViewShell->SetTabNo( nTab );
565         pViewShell->MoveCursorAbs( nCol, nRow, SC_FOLLOW_JUMP, sal_False, sal_False );
566 
567         if (bInsertP)
568             pViewShell->InsertPageBreak(bColumn, sal_False);
569         else
570             pViewShell->DeletePageBreak(bColumn, sal_False);
571 
572         pDocShell->GetDocument()->InvalidatePageBreaks(nTab);
573     }
574 }
575 
576 void __EXPORT ScUndoPageBreak::Undo()
577 {
578     BeginUndo();
579     DoChange(!bInsert);
580     EndUndo();
581 }
582 
583 void __EXPORT ScUndoPageBreak::Redo()
584 {
585     BeginRedo();
586     DoChange(bInsert);
587     EndRedo();
588 }
589 
590 void __EXPORT ScUndoPageBreak::Repeat(SfxRepeatTarget& rTarget)
591 {
592     if (rTarget.ISA(ScTabViewTarget))
593     {
594         ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
595 
596         if (bInsert)
597             rViewShell.InsertPageBreak(bColumn, sal_True);
598         else
599             rViewShell.DeletePageBreak(bColumn, sal_True);
600     }
601 }
602 
603 sal_Bool __EXPORT ScUndoPageBreak::CanRepeat(SfxRepeatTarget& rTarget) const
604 {
605     return (rTarget.ISA(ScTabViewTarget));
606 }
607 
608 // -----------------------------------------------------------------------
609 //
610 //      Druck-Skalierung
611 //
612 
613 ScUndoPrintZoom::ScUndoPrintZoom( ScDocShell* pNewDocShell,
614             SCTAB nT, sal_uInt16 nOS, sal_uInt16 nOP, sal_uInt16 nNS, sal_uInt16 nNP ) :
615     ScSimpleUndo( pNewDocShell ),
616     nTab( nT ),
617     nOldScale( nOS ),
618     nOldPages( nOP ),
619     nNewScale( nNS ),
620     nNewPages( nNP )
621 {
622 }
623 
624 __EXPORT ScUndoPrintZoom::~ScUndoPrintZoom()
625 {
626 }
627 
628 String __EXPORT ScUndoPrintZoom::GetComment() const
629 {
630     return ScGlobal::GetRscString( STR_UNDO_PRINTSCALE );
631 }
632 
633 void ScUndoPrintZoom::DoChange( sal_Bool bUndo )
634 {
635     sal_uInt16 nScale = bUndo ? nOldScale : nNewScale;
636     sal_uInt16 nPages = bUndo ? nOldPages : nNewPages;
637 
638     ScDocument* pDoc = pDocShell->GetDocument();
639     String aStyleName = pDoc->GetPageStyle( nTab );
640     ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
641     SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStyleName, SFX_STYLE_FAMILY_PAGE );
642     DBG_ASSERT( pStyleSheet, "PageStyle not found" );
643     if ( pStyleSheet )
644     {
645         SfxItemSet& rSet = pStyleSheet->GetItemSet();
646         rSet.Put( SfxUInt16Item( ATTR_PAGE_SCALE, nScale ) );
647         rSet.Put( SfxUInt16Item( ATTR_PAGE_SCALETOPAGES, nPages ) );
648 
649         ScPrintFunc aPrintFunc( pDocShell, pDocShell->GetPrinter(), nTab );
650         aPrintFunc.UpdatePages();
651     }
652 }
653 
654 void __EXPORT ScUndoPrintZoom::Undo()
655 {
656     BeginUndo();
657     DoChange(sal_True);
658     EndUndo();
659 }
660 
661 void __EXPORT ScUndoPrintZoom::Redo()
662 {
663     BeginRedo();
664     DoChange(sal_False);
665     EndRedo();
666 }
667 
668 void __EXPORT ScUndoPrintZoom::Repeat(SfxRepeatTarget& rTarget)
669 {
670     if (rTarget.ISA(ScTabViewTarget))
671     {
672         ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
673         ScViewData* pViewData = rViewShell.GetViewData();
674         pViewData->GetDocShell()->SetPrintZoom( pViewData->GetTabNo(), nNewScale, nNewPages );
675     }
676 }
677 
678 sal_Bool __EXPORT ScUndoPrintZoom::CanRepeat(SfxRepeatTarget& rTarget) const
679 {
680     return (rTarget.ISA(ScTabViewTarget));
681 }
682 
683 
684 // -----------------------------------------------------------------------
685 //
686 //      Thesaurus
687 //
688 
689 ScUndoThesaurus::ScUndoThesaurus( ScDocShell* pNewDocShell,
690                                   SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
691                                   const String& rNewUndoStr, const EditTextObject* pUndoTObj,
692                                   const String& rNewRedoStr, const EditTextObject* pRedoTObj) :
693     ScSimpleUndo( pNewDocShell ),
694     nCol( nNewCol ),
695     nRow( nNewRow ),
696     nTab( nNewTab ),
697     aUndoStr( rNewUndoStr ),
698     aRedoStr( rNewRedoStr )
699 {
700     pUndoTObject = (pUndoTObj) ? pUndoTObj->Clone() : NULL;
701     pRedoTObject = (pRedoTObj) ? pRedoTObj->Clone() : NULL;
702 
703     ScBaseCell* pOldCell;
704     if ( pUndoTObject )
705         pOldCell = new ScEditCell( pUndoTObject, pDocShell->GetDocument(), NULL );
706     else
707         pOldCell = new ScStringCell( aUndoStr );
708     SetChangeTrack( pOldCell );
709     pOldCell->Delete();
710 }
711 
712 __EXPORT ScUndoThesaurus::~ScUndoThesaurus()
713 {
714     delete pUndoTObject;
715     delete pRedoTObject;
716 }
717 
718 String __EXPORT ScUndoThesaurus::GetComment() const
719 {
720     return ScGlobal::GetRscString( STR_UNDO_THESAURUS );    // "Thesaurus"
721 }
722 
723 void ScUndoThesaurus::SetChangeTrack( ScBaseCell* pOldCell )
724 {
725     ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
726     if ( pChangeTrack )
727     {
728         nEndChangeAction = pChangeTrack->GetActionMax() + 1;
729         pChangeTrack->AppendContent( ScAddress( nCol, nRow, nTab ), pOldCell );
730         if ( nEndChangeAction > pChangeTrack->GetActionMax() )
731             nEndChangeAction = 0;       // nichts appended
732     }
733     else
734         nEndChangeAction = 0;
735 }
736 
737 void __EXPORT ScUndoThesaurus::DoChange( sal_Bool bUndo, const String& rStr,
738             const EditTextObject* pTObj )
739 {
740     ScDocument* pDoc = pDocShell->GetDocument();
741 
742     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
743     if (pViewShell)
744     {
745         pViewShell->SetTabNo( nTab );
746         pViewShell->MoveCursorAbs( nCol, nRow, SC_FOLLOW_JUMP, sal_False, sal_False );
747     }
748 
749     if (pTObj)
750     {
751         ScBaseCell* pCell;
752         pDoc->GetCell( nCol, nRow, nTab, pCell );
753         if (pCell)
754         {
755             if (pCell->GetCellType() == CELLTYPE_EDIT )
756             {
757                 ScEditCell* pNewCell = new ScEditCell( pTObj, pDoc, NULL );
758                 pDoc->PutCell( nCol, nRow, nTab, pNewCell );
759                 if ( !bUndo )
760                     SetChangeTrack( pCell );
761             }
762             else
763             {
764                 DBG_ERROR("Nicht CELLTYPE_EDIT bei Un/RedoThesaurus");
765             }
766         }
767     }
768     else
769     {
770         ScBaseCell* pCell = NULL;
771         if ( !bUndo )
772             pDoc->GetCell( nCol, nRow, nTab, pCell );
773         pDoc->SetString( nCol, nRow, nTab, rStr );
774         if ( !bUndo )
775             SetChangeTrack( pCell );
776     }
777 
778     pDocShell->PostPaintCell( nCol, nRow, nTab );
779 }
780 
781 void __EXPORT ScUndoThesaurus::Undo()
782 {
783     BeginUndo();
784     DoChange( sal_True, aUndoStr, pUndoTObject );
785     ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
786     if ( pChangeTrack )
787         pChangeTrack->Undo( nEndChangeAction, nEndChangeAction );
788     EndUndo();
789 }
790 
791 void __EXPORT ScUndoThesaurus::Redo()
792 {
793     BeginRedo();
794     DoChange( sal_False, aRedoStr, pRedoTObject );
795     EndRedo();
796 }
797 
798 void __EXPORT ScUndoThesaurus::Repeat(SfxRepeatTarget& rTarget)
799 {
800     if (rTarget.ISA(ScTabViewTarget))
801         ((ScTabViewTarget&)rTarget).GetViewShell()->DoThesaurus( sal_True );
802 }
803 
804 sal_Bool __EXPORT ScUndoThesaurus::CanRepeat(SfxRepeatTarget& rTarget) const
805 {
806     return (rTarget.ISA(ScTabViewTarget));
807 }
808 
809 
810 // ============================================================================
811 
812 ScUndoReplaceNote::ScUndoReplaceNote( ScDocShell& rDocShell, const ScAddress& rPos,
813         const ScNoteData& rNoteData, bool bInsert, SdrUndoAction* pDrawUndo ) :
814     ScSimpleUndo( &rDocShell ),
815     maPos( rPos ),
816     mpDrawUndo( pDrawUndo )
817 {
818     DBG_ASSERT( rNoteData.mpCaption, "ScUndoReplaceNote::ScUndoReplaceNote - missing note caption" );
819     (bInsert ? maNewData : maOldData) = rNoteData;
820 }
821 
822 ScUndoReplaceNote::ScUndoReplaceNote( ScDocShell& rDocShell, const ScAddress& rPos,
823         const ScNoteData& rOldData, const ScNoteData& rNewData, SdrUndoAction* pDrawUndo ) :
824     ScSimpleUndo( &rDocShell ),
825     maPos( rPos ),
826     maOldData( rOldData ),
827     maNewData( rNewData ),
828     mpDrawUndo( pDrawUndo )
829 {
830     DBG_ASSERT( maOldData.mpCaption || maNewData.mpCaption, "ScUndoReplaceNote::ScUndoReplaceNote - missing note captions" );
831     DBG_ASSERT( !maOldData.mxInitData.get() && !maNewData.mxInitData.get(), "ScUndoReplaceNote::ScUndoReplaceNote - unexpected unitialized note" );
832 }
833 
834 ScUndoReplaceNote::~ScUndoReplaceNote()
835 {
836     DeleteSdrUndoAction( mpDrawUndo );
837 }
838 
839 void ScUndoReplaceNote::Undo()
840 {
841     BeginUndo();
842     DoSdrUndoAction( mpDrawUndo, pDocShell->GetDocument() );
843     /*  Undo insert -> remove new note.
844         Undo remove -> insert old note.
845         Undo replace -> remove new note, insert old note. */
846     DoRemoveNote( maNewData );
847     DoInsertNote( maOldData );
848     pDocShell->PostPaintCell( maPos );
849     EndUndo();
850 }
851 
852 void ScUndoReplaceNote::Redo()
853 {
854     BeginRedo();
855     RedoSdrUndoAction( mpDrawUndo );
856     /*  Redo insert -> insert new note.
857         Redo remove -> remove old note.
858         Redo replace -> remove old note, insert new note. */
859     DoRemoveNote( maOldData );
860     DoInsertNote( maNewData );
861     pDocShell->PostPaintCell( maPos );
862     EndRedo();
863 }
864 
865 void ScUndoReplaceNote::Repeat( SfxRepeatTarget& /*rTarget*/ )
866 {
867 }
868 
869 sal_Bool ScUndoReplaceNote::CanRepeat( SfxRepeatTarget& /*rTarget*/ ) const
870 {
871     return sal_False;
872 }
873 
874 String ScUndoReplaceNote::GetComment() const
875 {
876     return ScGlobal::GetRscString( maNewData.mpCaption ?
877         (maOldData.mpCaption ? STR_UNDO_EDITNOTE : STR_UNDO_INSERTNOTE) : STR_UNDO_DELETENOTE );
878 }
879 
880 void ScUndoReplaceNote::DoInsertNote( const ScNoteData& rNoteData )
881 {
882     if( rNoteData.mpCaption )
883     {
884         ScDocument& rDoc = *pDocShell->GetDocument();
885         DBG_ASSERT( !rDoc.GetNote( maPos ), "ScUndoReplaceNote::DoInsertNote - unexpected cell note" );
886         ScPostIt* pNote = new ScPostIt( rDoc, maPos, rNoteData, false );
887         rDoc.TakeNote( maPos, pNote );
888     }
889 }
890 
891 void ScUndoReplaceNote::DoRemoveNote( const ScNoteData& rNoteData )
892 {
893     if( rNoteData.mpCaption )
894     {
895         ScDocument& rDoc = *pDocShell->GetDocument();
896         DBG_ASSERT( rDoc.GetNote( maPos ), "ScUndoReplaceNote::DoRemoveNote - missing cell note" );
897         if( ScPostIt* pNote = rDoc.ReleaseNote( maPos ) )
898         {
899             /*  Forget pointer to caption object to suppress removing the
900                 caption object from the drawing layer while deleting pNote
901                 (removing the caption is done by a drawing undo action). */
902             pNote->ForgetCaption();
903             delete pNote;
904         }
905     }
906 }
907 
908 // ============================================================================
909 
910 ScUndoShowHideNote::ScUndoShowHideNote( ScDocShell& rDocShell, const ScAddress& rPos, bool bShow ) :
911     ScSimpleUndo( &rDocShell ),
912     maPos( rPos ),
913     mbShown( bShow )
914 {
915 }
916 
917 ScUndoShowHideNote::~ScUndoShowHideNote()
918 {
919 }
920 
921 void ScUndoShowHideNote::Undo()
922 {
923     BeginUndo();
924     if( ScPostIt* pNote = pDocShell->GetDocument()->GetNote( maPos ) )
925         pNote->ShowCaption( maPos, !mbShown );
926     EndUndo();
927 }
928 
929 void ScUndoShowHideNote::Redo()
930 {
931     BeginRedo();
932     if( ScPostIt* pNote = pDocShell->GetDocument()->GetNote( maPos ) )
933         pNote->ShowCaption( maPos, mbShown );
934     EndRedo();
935 }
936 
937 void ScUndoShowHideNote::Repeat( SfxRepeatTarget& /*rTarget*/ )
938 {
939 }
940 
941 sal_Bool ScUndoShowHideNote::CanRepeat( SfxRepeatTarget& /*rTarget*/ ) const
942 {
943     return sal_False;
944 }
945 
946 String ScUndoShowHideNote::GetComment() const
947 {
948     return ScGlobal::GetRscString( mbShown ? STR_UNDO_SHOWNOTE : STR_UNDO_HIDENOTE );
949 }
950 
951 // ============================================================================
952 
953 // -----------------------------------------------------------------------
954 //
955 //      Detektiv
956 //
957 
958 ScUndoDetective::ScUndoDetective( ScDocShell* pNewDocShell,
959                                     SdrUndoAction* pDraw, const ScDetOpData* pOperation,
960                                     ScDetOpList* pUndoList ) :
961     ScSimpleUndo( pNewDocShell ),
962     pOldList    ( pUndoList ),
963     nAction     ( 0 ),
964     pDrawUndo   ( pDraw )
965 {
966     bIsDelete = ( pOperation == NULL );
967     if (!bIsDelete)
968     {
969         nAction = (sal_uInt16) pOperation->GetOperation();
970         aPos = pOperation->GetPos();
971     }
972 }
973 
974 __EXPORT ScUndoDetective::~ScUndoDetective()
975 {
976     DeleteSdrUndoAction( pDrawUndo );
977     delete pOldList;
978 }
979 
980 String __EXPORT ScUndoDetective::GetComment() const
981 {
982     sal_uInt16 nId = STR_UNDO_DETDELALL;
983     if ( !bIsDelete )
984         switch ( (ScDetOpType) nAction )
985         {
986             case SCDETOP_ADDSUCC:   nId = STR_UNDO_DETADDSUCC;  break;
987             case SCDETOP_DELSUCC:   nId = STR_UNDO_DETDELSUCC;  break;
988             case SCDETOP_ADDPRED:   nId = STR_UNDO_DETADDPRED;  break;
989             case SCDETOP_DELPRED:   nId = STR_UNDO_DETDELPRED;  break;
990             case SCDETOP_ADDERROR:  nId = STR_UNDO_DETADDERROR; break;
991         }
992 
993     return ScGlobal::GetRscString( nId );
994 }
995 
996 
997 void __EXPORT ScUndoDetective::Undo()
998 {
999     BeginUndo();
1000 
1001     ScDocument* pDoc = pDocShell->GetDocument();
1002     DoSdrUndoAction(pDrawUndo, pDoc);
1003 
1004     if (bIsDelete)
1005     {
1006         if ( pOldList )
1007             pDoc->SetDetOpList( new ScDetOpList(*pOldList) );
1008     }
1009     else
1010     {
1011         //  Eintrag aus der Liste loeschen
1012 
1013         ScDetOpList* pList = pDoc->GetDetOpList();
1014         if (pList && pList->Count())
1015         {
1016             sal_uInt16 nPos = pList->Count() - 1;
1017             ScDetOpData* pData = (*pList)[nPos];
1018             if ( pData->GetOperation() == (ScDetOpType) nAction && pData->GetPos() == aPos )
1019                 pList->DeleteAndDestroy( nPos, 1 );
1020             else
1021             {
1022                 DBG_ERROR("Detektiv-Eintrag in der Liste nicht gefunden");
1023             }
1024         }
1025     }
1026 
1027     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1028     if (pViewShell)
1029         pViewShell->RecalcPPT();    //! use broadcast instead?
1030 
1031     EndUndo();
1032 }
1033 
1034 void __EXPORT ScUndoDetective::Redo()
1035 {
1036     BeginRedo();
1037 
1038     RedoSdrUndoAction(pDrawUndo);
1039 
1040     ScDocument* pDoc = pDocShell->GetDocument();
1041 
1042     if (bIsDelete)
1043         pDoc->ClearDetectiveOperations();
1044     else
1045         pDoc->AddDetectiveOperation( ScDetOpData( aPos, (ScDetOpType) nAction ) );
1046 
1047     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1048     if (pViewShell)
1049         pViewShell->RecalcPPT();    //! use broadcast instead?
1050 
1051     EndRedo();
1052 }
1053 
1054 void __EXPORT ScUndoDetective::Repeat(SfxRepeatTarget& /* rTarget */)
1055 {
1056     //  hammanich
1057 }
1058 
1059 sal_Bool __EXPORT ScUndoDetective::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1060 {
1061     return sal_False;
1062 }
1063 
1064 // -----------------------------------------------------------------------
1065 //
1066 //      Benannte Bereiche
1067 //
1068 
1069 ScUndoRangeNames::ScUndoRangeNames( ScDocShell* pNewDocShell,
1070                                     ScRangeName* pOld, ScRangeName* pNew ) :
1071     ScSimpleUndo( pNewDocShell ),
1072     pOldRanges  ( pOld ),
1073     pNewRanges  ( pNew )
1074 {
1075 }
1076 
1077 __EXPORT ScUndoRangeNames::~ScUndoRangeNames()
1078 {
1079     delete pOldRanges;
1080     delete pNewRanges;
1081 }
1082 
1083 String __EXPORT ScUndoRangeNames::GetComment() const
1084 {
1085     return ScGlobal::GetRscString( STR_UNDO_RANGENAMES );
1086 }
1087 
1088 void ScUndoRangeNames::DoChange( sal_Bool bUndo )
1089 {
1090     ScDocument* pDoc = pDocShell->GetDocument();
1091     pDoc->CompileNameFormula( sal_True );   // CreateFormulaString
1092 
1093     if ( bUndo )
1094         pDoc->SetRangeName( new ScRangeName( *pOldRanges ) );
1095     else
1096         pDoc->SetRangeName( new ScRangeName( *pNewRanges ) );
1097 
1098     pDoc->CompileNameFormula( sal_False );  // CompileFormulaString
1099 
1100     SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
1101 }
1102 
1103 void __EXPORT ScUndoRangeNames::Undo()
1104 {
1105     BeginUndo();
1106     DoChange( sal_True );
1107     EndUndo();
1108 }
1109 
1110 void __EXPORT ScUndoRangeNames::Redo()
1111 {
1112     BeginRedo();
1113     DoChange( sal_False );
1114     EndRedo();
1115 }
1116 
1117 void __EXPORT ScUndoRangeNames::Repeat(SfxRepeatTarget& /* rTarget */)
1118 {
1119     //  hammanich
1120 }
1121 
1122 sal_Bool __EXPORT ScUndoRangeNames::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1123 {
1124     return sal_False;
1125 }
1126 
1127 
1128 
1129 
1130