update dev300-m58
[ooovba.git] / sc / source / ui / undo / undobase.cxx
blob8b59f801b4294a32aabc02285a4f53d3c357920a
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"
42 #include "docsh.hxx"
43 #include "tabvwsh.hxx"
44 #include "undoolk.hxx"
45 #include "undodraw.hxx"
46 #include "dbcolect.hxx"
47 #include "attrib.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 ) :
62 pDocShell( 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();
89 return TRUE;
92 return FALSE;
95 void ScSimpleUndo::BeginUndo()
97 pDocShell->SetInUndo( TRUE );
99 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
100 if (pViewShell)
101 pViewShell->HideAllCursors(); // z.B. wegen zusammengefassten Zellen
103 // detective updates happened last, must be undone first
104 if (pDetectiveUndo)
105 pDetectiveUndo->Undo();
108 void ScSimpleUndo::EndUndo()
110 pDocShell->SetDocumentModified();
112 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
113 if (pViewShell)
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();
128 if (pViewShell)
129 pViewShell->HideAllCursors(); // z.B. wegen zusammengefassten Zellen
132 void ScSimpleUndo::EndRedo()
134 if (pDetectiveUndo)
135 pDetectiveUndo->Redo();
137 pDocShell->SetDocumentModified();
139 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
140 if (pViewShell)
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();
153 if (pViewShell)
154 pViewShell->SetTabNo( nTab );
157 void ScSimpleUndo::ShowTable( const ScRange& rRange ) // static
159 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
160 if (pViewShell)
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 ),
177 eMode( eBlockMode )
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)
196 AdjustHeight();
198 EnableDrawAdjust( pDocShell->GetDocument(), TRUE );
199 DoSdrUndoAction( pDrawUndo, pDocShell->GetDocument() );
201 ShowBlock();
202 ScSimpleUndo::EndUndo();
206 void ScBlockUndo::BeginRedo()
208 ScSimpleUndo::BeginRedo();
212 void ScBlockUndo::EndRedo()
214 if (eMode == SC_UNDO_AUTOHEIGHT)
215 AdjustHeight();
217 ShowBlock();
218 ScSimpleUndo::EndRedo();
221 BOOL ScBlockUndo::AdjustHeight()
223 ScDocument* pDoc = pDocShell->GetDocument();
225 VirtualDevice aVirtDev;
226 Fraction aZoomX( 1, 1 );
227 Fraction aZoomY = aZoomX;
228 double nPPTX, nPPTY;
229 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
230 if (pViewShell)
232 ScViewData* pData = pViewShell->GetViewData();
233 nPPTX = pData->GetPPTX();
234 nPPTY = pData->GetPPTY();
235 aZoomX = pData->GetZoomX();
236 aZoomY = pData->GetZoomY();
238 else
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 );
249 if (bRet)
250 pDocShell->PostPaint( 0, aBlockRange.aStart.Row(), aBlockRange.aStart.Tab(),
251 MAXCOL, MAXROW, aBlockRange.aEnd.Tab(),
252 PAINT_GRID | PAINT_LEFT );
254 return bRet;
257 void ScBlockUndo::ShowBlock()
259 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
260 if (pViewShell)
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 ),
283 eMode( eRefMode )
285 ScDocument* pDoc = pDocShell->GetDocument();
286 if (pRefUndoData)
287 pRefUndoData->DeleteUnchanged(pDoc);
288 pDrawUndo = GetSdrUndoAction( pDoc );
291 __EXPORT ScMoveUndo::~ScMoveUndo()
293 delete pRefUndoData;
294 delete pRefUndoDoc;
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 );
303 if (pRefUndoData)
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)
317 UndoRef();
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)
326 UndoRef();
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 );
360 delete pAutoDBRange;
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();
379 if ( pAutoDBRange )
381 USHORT nNoNameIndex;
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];
388 SCCOL nRangeX1;
389 SCROW nRangeY1;
390 SCCOL nRangeX2;
391 SCROW nRangeY2;
392 SCTAB nRangeTab;
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 );
412 if ( pAutoDBRange )
414 // move the database range to this function's position again (see ScDocShell::GetDBData)
416 USHORT nNoNameIndex;
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];
423 SCCOL nRangeX1;
424 SCROW nRangeY1;
425 SCCOL nRangeX2;
426 SCROW nRangeY2;
427 SCTAB nRangeTab;
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()
462 delete pWrappedUndo;
465 void ScUndoWrapper::ForgetWrappedUndo()
467 pWrappedUndo = NULL; // don't delete in dtor - pointer must be stored outside
470 String ScUndoWrapper::GetComment() const
472 if (pWrappedUndo)
473 return pWrappedUndo->GetComment();
474 else
475 return String();
478 String ScUndoWrapper::GetRepeatComment(SfxRepeatTarget& rTarget) const
480 if (pWrappedUndo)
481 return pWrappedUndo->GetRepeatComment(rTarget);
482 else
483 return String();
486 USHORT ScUndoWrapper::GetId() const
488 if (pWrappedUndo)
489 return pWrappedUndo->GetId();
490 else
491 return 0;
494 BOOL ScUndoWrapper::IsLinked()
496 if (pWrappedUndo)
497 return pWrappedUndo->IsLinked();
498 else
499 return FALSE;
502 void ScUndoWrapper::SetLinked( BOOL bIsLinked )
504 if (pWrappedUndo)
505 pWrappedUndo->SetLinked(bIsLinked);
508 BOOL ScUndoWrapper::Merge( SfxUndoAction* pNextAction )
510 if (pWrappedUndo)
511 return pWrappedUndo->Merge(pNextAction);
512 else
513 return FALSE;
516 void ScUndoWrapper::Undo()
518 if (pWrappedUndo)
519 pWrappedUndo->Undo();
522 void ScUndoWrapper::Redo()
524 if (pWrappedUndo)
525 pWrappedUndo->Redo();
528 void ScUndoWrapper::Repeat(SfxRepeatTarget& rTarget)
530 if (pWrappedUndo)
531 pWrappedUndo->Repeat(rTarget);
534 BOOL ScUndoWrapper::CanRepeat(SfxRepeatTarget& rTarget) const
536 if (pWrappedUndo)
537 return pWrappedUndo->CanRepeat(rTarget);
538 else
539 return FALSE;