1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: undobase.cxx,v $
10 * $Revision: 1.9.128.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 // INCLUDE ---------------------------------------------------------------
38 #include <vcl/virdev.hxx>
40 #include "undobase.hxx"
41 #include "refundo.hxx"
43 #include "tabvwsh.hxx"
44 #include "undoolk.hxx"
45 #include "undodraw.hxx"
46 #include "dbcolect.hxx"
48 #include "queryparam.hxx"
49 #include "globstr.hrc"
51 // STATIC DATA -----------------------------------------------------------
53 TYPEINIT1(ScSimpleUndo
, SfxUndoAction
);
54 TYPEINIT1(ScBlockUndo
, ScSimpleUndo
);
55 TYPEINIT1(ScMoveUndo
, ScSimpleUndo
);
56 TYPEINIT1(ScDBFuncUndo
, ScSimpleUndo
);
57 TYPEINIT1(ScUndoWrapper
, SfxUndoAction
);
59 // -----------------------------------------------------------------------
61 ScSimpleUndo::ScSimpleUndo( ScDocShell
* pDocSh
) :
63 pDetectiveUndo( NULL
)
67 __EXPORT
ScSimpleUndo::~ScSimpleUndo()
69 delete pDetectiveUndo
;
72 BOOL __EXPORT
ScSimpleUndo::Merge( SfxUndoAction
*pNextAction
)
74 // Zu jeder Undo-Action kann eine SdrUndoGroup fuer das Aktualisieren
75 // der Detektiv-Pfeile gehoeren.
76 // DetectiveRefresh kommt immer hinterher, die SdrUndoGroup ist in
77 // eine ScUndoDraw Action verpackt.
78 // Nur beim automatischen Aktualisieren wird AddUndoAction mit
79 // bTryMerg=TRUE gerufen.
81 if ( !pDetectiveUndo
&& pNextAction
->ISA(ScUndoDraw
) )
83 // SdrUndoAction aus der ScUndoDraw Action uebernehmen,
84 // ScUndoDraw wird dann vom UndoManager geloescht
86 ScUndoDraw
* pCalcUndo
= (ScUndoDraw
*)pNextAction
;
87 pDetectiveUndo
= pCalcUndo
->GetDrawUndo();
88 pCalcUndo
->ForgetDrawUndo();
95 void ScSimpleUndo::BeginUndo()
97 pDocShell
->SetInUndo( TRUE
);
99 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
101 pViewShell
->HideAllCursors(); // z.B. wegen zusammengefassten Zellen
103 // detective updates happened last, must be undone first
105 pDetectiveUndo
->Undo();
108 void ScSimpleUndo::EndUndo()
110 pDocShell
->SetDocumentModified();
112 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
115 pViewShell
->UpdateAutoFillMark();
116 pViewShell
->UpdateInputHandler();
117 pViewShell
->ShowAllCursors();
120 pDocShell
->SetInUndo( FALSE
);
123 void ScSimpleUndo::BeginRedo()
125 pDocShell
->SetInUndo( TRUE
); //! eigenes Flag fuer Redo?
127 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
129 pViewShell
->HideAllCursors(); // z.B. wegen zusammengefassten Zellen
132 void ScSimpleUndo::EndRedo()
135 pDetectiveUndo
->Redo();
137 pDocShell
->SetDocumentModified();
139 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
142 pViewShell
->UpdateAutoFillMark();
143 pViewShell
->UpdateInputHandler();
144 pViewShell
->ShowAllCursors();
147 pDocShell
->SetInUndo( FALSE
);
150 void ScSimpleUndo::ShowTable( SCTAB nTab
) // static
152 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
154 pViewShell
->SetTabNo( nTab
);
157 void ScSimpleUndo::ShowTable( const ScRange
& rRange
) // static
159 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
162 SCTAB nStart
= rRange
.aStart
.Tab();
163 SCTAB nEnd
= rRange
.aEnd
.Tab();
164 SCTAB nTab
= pViewShell
->GetViewData()->GetTabNo();
165 if ( nTab
< nStart
|| nTab
> nEnd
) // wenn nicht im Bereich:
166 pViewShell
->SetTabNo( nStart
); // auf erste des Bereiches
171 // -----------------------------------------------------------------------
173 ScBlockUndo::ScBlockUndo( ScDocShell
* pDocSh
, const ScRange
& rRange
,
174 ScBlockUndoMode eBlockMode
) :
175 ScSimpleUndo( pDocSh
),
176 aBlockRange( rRange
),
179 pDrawUndo
= GetSdrUndoAction( pDocShell
->GetDocument() );
182 __EXPORT
ScBlockUndo::~ScBlockUndo()
184 DeleteSdrUndoAction( pDrawUndo
);
187 void ScBlockUndo::BeginUndo()
189 ScSimpleUndo::BeginUndo();
190 EnableDrawAdjust( pDocShell
->GetDocument(), FALSE
);
193 void ScBlockUndo::EndUndo()
195 if (eMode
== SC_UNDO_AUTOHEIGHT
)
198 EnableDrawAdjust( pDocShell
->GetDocument(), TRUE
);
199 DoSdrUndoAction( pDrawUndo
, pDocShell
->GetDocument() );
202 ScSimpleUndo::EndUndo();
206 void ScBlockUndo::BeginRedo()
208 ScSimpleUndo::BeginRedo();
212 void ScBlockUndo::EndRedo()
214 if (eMode
== SC_UNDO_AUTOHEIGHT
)
218 ScSimpleUndo::EndRedo();
221 BOOL
ScBlockUndo::AdjustHeight()
223 ScDocument
* pDoc
= pDocShell
->GetDocument();
225 VirtualDevice aVirtDev
;
226 Fraction
aZoomX( 1, 1 );
227 Fraction aZoomY
= aZoomX
;
229 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
232 ScViewData
* pData
= pViewShell
->GetViewData();
233 nPPTX
= pData
->GetPPTX();
234 nPPTY
= pData
->GetPPTY();
235 aZoomX
= pData
->GetZoomX();
236 aZoomY
= pData
->GetZoomY();
240 // Zoom auf 100 lassen
241 nPPTX
= ScGlobal::nScreenPPTX
;
242 nPPTY
= ScGlobal::nScreenPPTY
;
245 BOOL bRet
= pDoc
->SetOptimalHeight( aBlockRange
.aStart
.Row(), aBlockRange
.aEnd
.Row(),
246 /*!*/ aBlockRange
.aStart
.Tab(), 0, &aVirtDev
,
247 nPPTX
, nPPTY
, aZoomX
, aZoomY
, FALSE
);
250 pDocShell
->PostPaint( 0, aBlockRange
.aStart
.Row(), aBlockRange
.aStart
.Tab(),
251 MAXCOL
, MAXROW
, aBlockRange
.aEnd
.Tab(),
252 PAINT_GRID
| PAINT_LEFT
);
257 void ScBlockUndo::ShowBlock()
259 ScTabViewShell
* pViewShell
= ScTabViewShell::GetActiveViewShell();
262 ShowTable( aBlockRange
); // bei mehreren Tabs im Range ist jede davon gut
263 pViewShell
->MoveCursorAbs( aBlockRange
.aStart
.Col(), aBlockRange
.aStart
.Row(),
264 SC_FOLLOW_JUMP
, FALSE
, FALSE
);
265 SCTAB nTab
= pViewShell
->GetViewData()->GetTabNo();
266 ScRange aRange
= aBlockRange
;
267 aRange
.aStart
.SetTab( nTab
);
268 aRange
.aEnd
.SetTab( nTab
);
269 pViewShell
->MarkRange( aRange
);
271 // nicht per SetMarkArea an MarkData, wegen evtl. fehlendem Paint
276 // -----------------------------------------------------------------------
278 ScMoveUndo::ScMoveUndo( ScDocShell
* pDocSh
, ScDocument
* pRefDoc
, ScRefUndoData
* pRefData
,
279 ScMoveUndoMode eRefMode
) :
280 ScSimpleUndo( pDocSh
),
281 pRefUndoDoc( pRefDoc
),
282 pRefUndoData( pRefData
),
285 ScDocument
* pDoc
= pDocShell
->GetDocument();
287 pRefUndoData
->DeleteUnchanged(pDoc
);
288 pDrawUndo
= GetSdrUndoAction( pDoc
);
291 __EXPORT
ScMoveUndo::~ScMoveUndo()
295 DeleteSdrUndoAction( pDrawUndo
);
298 void ScMoveUndo::UndoRef()
300 ScDocument
* pDoc
= pDocShell
->GetDocument();
301 ScRange
aRange(0,0,0, MAXCOL
,MAXROW
,pRefUndoDoc
->GetTableCount()-1);
302 pRefUndoDoc
->CopyToDocument( aRange
, IDF_FORMULA
, FALSE
, pDoc
, NULL
, FALSE
);
304 pRefUndoData
->DoUndo( pDoc
, (eMode
== SC_UNDO_REFFIRST
) );
305 // #65055# HACK: ScDragDropUndo ist der einzige mit REFFIRST.
306 // Falls nicht, resultiert daraus evtl. ein zu haeufiges Anpassen
307 // der ChartRefs, nicht schoen, aber auch nicht schlecht..
310 void ScMoveUndo::BeginUndo()
312 ScSimpleUndo::BeginUndo();
314 EnableDrawAdjust( pDocShell
->GetDocument(), FALSE
);
316 if (pRefUndoDoc
&& eMode
== SC_UNDO_REFFIRST
)
320 void ScMoveUndo::EndUndo()
322 //@17.12.97 Reihenfolge der Fkt.s geaendert
323 DoSdrUndoAction( pDrawUndo
, pDocShell
->GetDocument() ); // #125875# must also be called when pointer is null
325 if (pRefUndoDoc
&& eMode
== SC_UNDO_REFLAST
)
328 EnableDrawAdjust( pDocShell
->GetDocument(), TRUE
);
330 ScSimpleUndo::EndUndo();
334 void ScMoveUndo::BeginRedo()
336 ScSimpleUndo::BeginRedo();
341 void ScMoveUndo::EndRedo()
343 ScSimpleUndo::EndRedo();
347 // -----------------------------------------------------------------------
349 ScDBFuncUndo::ScDBFuncUndo( ScDocShell
* pDocSh
, const ScRange
& rOriginal
, SdrUndoAction
* pDrawUndo
) :
350 ScSimpleUndo( pDocSh
),
351 aOriginalRange( rOriginal
),
352 mpDrawUndo( pDrawUndo
)
354 pAutoDBRange
= pDocSh
->GetOldAutoDBRange();
357 ScDBFuncUndo::~ScDBFuncUndo()
359 DeleteSdrUndoAction( mpDrawUndo
);
363 void ScDBFuncUndo::SetDrawUndoAction( SdrUndoAction
* pDrawUndo
)
365 DeleteSdrUndoAction( mpDrawUndo
);
366 mpDrawUndo
= pDrawUndo
;
369 void ScDBFuncUndo::BeginUndo()
371 ScSimpleUndo::BeginUndo();
372 DoSdrUndoAction( mpDrawUndo
, pDocShell
->GetDocument() );
375 void ScDBFuncUndo::EndUndo()
377 ScSimpleUndo::EndUndo();
382 ScDocument
* pDoc
= pDocShell
->GetDocument();
383 ScDBCollection
* pColl
= pDoc
->GetDBCollection();
384 if ( pColl
->SearchName( ScGlobal::GetRscString( STR_DB_NONAME
), nNoNameIndex
) )
386 ScDBData
* pNoNameData
= (*pColl
)[nNoNameIndex
];
393 pNoNameData
->GetArea( nRangeTab
, nRangeX1
, nRangeY1
, nRangeX2
, nRangeY2
);
394 pDocShell
->DBAreaDeleted( nRangeTab
, nRangeX1
, nRangeY1
, nRangeX2
, nRangeY2
);
396 *pNoNameData
= *pAutoDBRange
;
398 if ( pAutoDBRange
->HasAutoFilter() )
400 // restore AutoFilter buttons
401 pAutoDBRange
->GetArea( nRangeTab
, nRangeX1
, nRangeY1
, nRangeX2
, nRangeY2
);
402 pDoc
->ApplyFlagsTab( nRangeX1
, nRangeY1
, nRangeX2
, nRangeY1
, nRangeTab
, SC_MF_AUTO
);
403 pDocShell
->PostPaint( nRangeX1
, nRangeY1
, nRangeTab
, nRangeX2
, nRangeY1
, nRangeTab
, PAINT_GRID
);
409 void ScDBFuncUndo::BeginRedo()
411 RedoSdrUndoAction( mpDrawUndo
);
414 // move the database range to this function's position again (see ScDocShell::GetDBData)
417 ScDocument
* pDoc
= pDocShell
->GetDocument();
418 ScDBCollection
* pColl
= pDoc
->GetDBCollection();
419 if ( pColl
->SearchName( ScGlobal::GetRscString( STR_DB_NONAME
), nNoNameIndex
) )
421 ScDBData
* pNoNameData
= (*pColl
)[nNoNameIndex
];
428 pNoNameData
->GetArea( nRangeTab
, nRangeX1
, nRangeY1
, nRangeX2
, nRangeY2
);
429 pDocShell
->DBAreaDeleted( nRangeTab
, nRangeX1
, nRangeY1
, nRangeX2
, nRangeY2
);
431 pNoNameData
->SetSortParam( ScSortParam() );
432 pNoNameData
->SetQueryParam( ScQueryParam() );
433 pNoNameData
->SetSubTotalParam( ScSubTotalParam() );
435 pNoNameData
->SetArea( aOriginalRange
.aStart
.Tab(),
436 aOriginalRange
.aStart
.Col(), aOriginalRange
.aStart
.Row(),
437 aOriginalRange
.aEnd
.Col(), aOriginalRange
.aEnd
.Row() );
439 pNoNameData
->SetByRow( TRUE
);
440 pNoNameData
->SetAutoFilter( FALSE
);
441 // header is always set with the operation in redo
445 ScSimpleUndo::BeginRedo();
448 void ScDBFuncUndo::EndRedo()
450 ScSimpleUndo::EndRedo();
453 // -----------------------------------------------------------------------
455 ScUndoWrapper::ScUndoWrapper( SfxUndoAction
* pUndo
) :
456 pWrappedUndo( pUndo
)
460 ScUndoWrapper::~ScUndoWrapper()
465 void ScUndoWrapper::ForgetWrappedUndo()
467 pWrappedUndo
= NULL
; // don't delete in dtor - pointer must be stored outside
470 String
ScUndoWrapper::GetComment() const
473 return pWrappedUndo
->GetComment();
478 String
ScUndoWrapper::GetRepeatComment(SfxRepeatTarget
& rTarget
) const
481 return pWrappedUndo
->GetRepeatComment(rTarget
);
486 USHORT
ScUndoWrapper::GetId() const
489 return pWrappedUndo
->GetId();
494 BOOL
ScUndoWrapper::IsLinked()
497 return pWrappedUndo
->IsLinked();
502 void ScUndoWrapper::SetLinked( BOOL bIsLinked
)
505 pWrappedUndo
->SetLinked(bIsLinked
);
508 BOOL
ScUndoWrapper::Merge( SfxUndoAction
* pNextAction
)
511 return pWrappedUndo
->Merge(pNextAction
);
516 void ScUndoWrapper::Undo()
519 pWrappedUndo
->Undo();
522 void ScUndoWrapper::Redo()
525 pWrappedUndo
->Redo();
528 void ScUndoWrapper::Repeat(SfxRepeatTarget
& rTarget
)
531 pWrappedUndo
->Repeat(rTarget
);
534 BOOL
ScUndoWrapper::CanRepeat(SfxRepeatTarget
& rTarget
) const
537 return pWrappedUndo
->CanRepeat(rTarget
);