LCOV - code coverage report
Current view: top level - sc/source/ui/undo - undoblk.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 598 1254 47.7 %
Date: 2014-11-03 Functions: 84 249 33.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "scitems.hxx"
      21             : #include <vcl/virdev.hxx>
      22             : #include <vcl/waitobj.hxx>
      23             : #include <editeng/boxitem.hxx>
      24             : #include <editeng/justifyitem.hxx>
      25             : #include <sfx2/app.hxx>
      26             : 
      27             : #include "undoblk.hxx"
      28             : #include "undoutil.hxx"
      29             : #include "document.hxx"
      30             : #include "patattr.hxx"
      31             : #include "docsh.hxx"
      32             : #include "tabvwsh.hxx"
      33             : #include "rangenam.hxx"
      34             : #include "rangeutl.hxx"
      35             : #include "dbdata.hxx"
      36             : #include "stlpool.hxx"
      37             : #include "stlsheet.hxx"
      38             : #include "globstr.hrc"
      39             : #include "global.hxx"
      40             : #include "target.hxx"
      41             : #include "docpool.hxx"
      42             : #include "docfunc.hxx"
      43             : #include "attrib.hxx"
      44             : #include "chgtrack.hxx"
      45             : #include "transobj.hxx"
      46             : #include "refundo.hxx"
      47             : #include "undoolk.hxx"
      48             : #include "clipparam.hxx"
      49             : #include "sc.hrc"
      50             : #include <rowheightcontext.hxx>
      51             : #include <refhint.hxx>
      52             : #include <refupdatecontext.hxx>
      53             : #include <validat.hxx>
      54             : #include <gridwin.hxx>
      55             : #include <svl/listener.hxx>
      56             : 
      57             : #include <set>
      58             : #include <boost/scoped_ptr.hpp>
      59             : 
      60             : // STATIC DATA -----------------------------------------------------------
      61             : 
      62           0 : TYPEINIT1(ScUndoInsertCells,        SfxUndoAction);
      63           0 : TYPEINIT1(ScUndoDeleteCells,        SfxUndoAction);
      64           0 : TYPEINIT1(ScUndoDeleteMulti,        SfxUndoAction);
      65           0 : TYPEINIT1(ScUndoCut,                ScBlockUndo);
      66           0 : TYPEINIT1(ScUndoPaste,              SfxUndoAction);
      67           0 : TYPEINIT1(ScUndoDragDrop,           SfxUndoAction);
      68           0 : TYPEINIT1(ScUndoListNames,          SfxUndoAction);
      69           0 : TYPEINIT1(ScUndoConditionalFormat,  SfxUndoAction);
      70           0 : TYPEINIT1(ScUndoUseScenario,        SfxUndoAction);
      71           0 : TYPEINIT1(ScUndoSelectionStyle,     SfxUndoAction);
      72           0 : TYPEINIT1(ScUndoEnterMatrix,        ScBlockUndo);
      73           0 : TYPEINIT1(ScUndoIndent,             ScBlockUndo);
      74           0 : TYPEINIT1(ScUndoTransliterate,      ScBlockUndo);
      75           0 : TYPEINIT1(ScUndoClearItems,         ScBlockUndo);
      76           0 : TYPEINIT1(ScUndoRemoveBreaks,       SfxUndoAction);
      77           0 : TYPEINIT1(ScUndoRemoveMerge,        ScBlockUndo);
      78           0 : TYPEINIT1(ScUndoBorder,             ScBlockUndo);
      79             : 
      80             : // TODO:
      81             : /*A*/   // SetOptimalHeight on Document, if no View
      82             : /*B*/   // linked sheets
      83             : /*C*/   // ScArea
      84             : //?     // check later
      85             : 
      86          16 : ScUndoInsertCells::ScUndoInsertCells( ScDocShell* pNewDocShell,
      87             :                                 const ScRange& rRange, SCTAB nNewCount, SCTAB* pNewTabs, SCTAB* pNewScenarios,
      88             :                                 InsCellCmd eNewCmd, ScDocument* pUndoDocument, ScRefUndoData* pRefData,
      89             :                                 bool bNewPartOfPaste ) :
      90             :     ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFLAST ),
      91             :     aEffRange( rRange ),
      92             :     nCount( nNewCount ),
      93             :     pTabs( pNewTabs ),
      94             :     pScenarios( pNewScenarios ),
      95             :     eCmd( eNewCmd ),
      96             :     bPartOfPaste( bNewPartOfPaste ),
      97          16 :     pPasteUndo( NULL )
      98             : {
      99          16 :     if (eCmd == INS_INSROWS)            // whole row?
     100             :     {
     101           6 :         aEffRange.aStart.SetCol(0);
     102           6 :         aEffRange.aEnd.SetCol(MAXCOL);
     103             :     }
     104             : 
     105          16 :     if (eCmd == INS_INSCOLS)            // whole column?
     106             :     {
     107           8 :         aEffRange.aStart.SetRow(0);
     108           8 :         aEffRange.aEnd.SetRow(MAXROW);
     109             :     }
     110             : 
     111          16 :     SetChangeTrack();
     112          16 : }
     113             : 
     114          48 : ScUndoInsertCells::~ScUndoInsertCells()
     115             : {
     116          16 :     delete pPasteUndo;
     117          16 :     delete []pTabs;
     118          16 :     delete []pScenarios;
     119          32 : }
     120             : 
     121          22 : OUString ScUndoInsertCells::GetComment() const
     122             : {
     123          22 :     return ScGlobal::GetRscString( pPasteUndo ? STR_UNDO_PASTE : STR_UNDO_INSERTCELLS );
     124             : }
     125             : 
     126           0 : bool ScUndoInsertCells::Merge( SfxUndoAction* pNextAction )
     127             : {
     128             :     //  If a paste undo action has already been added, append (detective) action there.
     129           0 :     if ( pPasteUndo )
     130           0 :         return pPasteUndo->Merge( pNextAction );
     131             : 
     132           0 :     if ( bPartOfPaste && pNextAction->ISA( ScUndoWrapper ) )
     133             :     {
     134           0 :         ScUndoWrapper* pWrapper = static_cast<ScUndoWrapper*>(pNextAction);
     135           0 :         SfxUndoAction* pWrappedAction = pWrapper->GetWrappedUndo();
     136           0 :         if ( pWrappedAction && pWrappedAction->ISA( ScUndoPaste ) )
     137             :         {
     138             :             //  Store paste action if this is part of paste with inserting cells.
     139             :             //  A list action isn't used because Repeat wouldn't work (insert wrong cells).
     140             : 
     141           0 :             pPasteUndo = pWrappedAction;
     142           0 :             pWrapper->ForgetWrappedUndo();      // pWrapper is deleted by UndoManager
     143           0 :             return true;
     144             :         }
     145             :     }
     146             : 
     147             :     //  Call base class for detective handling
     148           0 :     return ScMoveUndo::Merge( pNextAction );
     149             : }
     150             : 
     151          18 : void ScUndoInsertCells::SetChangeTrack()
     152             : {
     153          18 :     ScChangeTrack* pChangeTrack = pDocShell->GetDocument().GetChangeTrack();
     154          18 :     if ( pChangeTrack )
     155             :     {
     156           0 :         pChangeTrack->AppendInsert( aEffRange );
     157           0 :         nEndChangeAction = pChangeTrack->GetActionMax();
     158             :     }
     159             :     else
     160          18 :         nEndChangeAction = 0;
     161          18 : }
     162             : 
     163           6 : void ScUndoInsertCells::DoChange( const bool bUndo )
     164             : {
     165           6 :     ScDocument& rDoc = pDocShell->GetDocument();
     166             :     SCTAB i;
     167             : 
     168           6 :     if ( bUndo )
     169             :     {
     170           4 :         ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
     171           4 :         if ( pChangeTrack )
     172           0 :             pChangeTrack->Undo( nEndChangeAction, nEndChangeAction );
     173             :     }
     174             :     else
     175           2 :         SetChangeTrack();
     176             : 
     177             :     // refresh of merged cells has to be after inserting/deleting
     178             : 
     179           6 :     switch (eCmd)
     180             :     {
     181             :         case INS_INSROWS:
     182             :         case INS_CELLSDOWN:
     183           8 :             for( i=0; i<nCount; i++ )
     184             :             {
     185           4 :                 if (bUndo)
     186          10 :                     rDoc.DeleteRow( aEffRange.aStart.Col(), pTabs[i], aEffRange.aEnd.Col(), pTabs[i]+pScenarios[i],
     187          12 :                     aEffRange.aStart.Row(), static_cast<SCSIZE>(aEffRange.aEnd.Row()-aEffRange.aStart.Row()+1));
     188             :                 else
     189          10 :                     rDoc.InsertRow( aEffRange.aStart.Col(), pTabs[i], aEffRange.aEnd.Col(), pTabs[i]+pScenarios[i],
     190          12 :                     aEffRange.aStart.Row(), static_cast<SCSIZE>(aEffRange.aEnd.Row()-aEffRange.aStart.Row()+1));
     191             :             }
     192           4 :             break;
     193             :         case INS_INSCOLS:
     194             :         case INS_CELLSRIGHT:
     195           4 :             for( i=0; i<nCount; i++ )
     196             :             {
     197           2 :                 if (bUndo)
     198           6 :                     rDoc.DeleteCol( aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
     199           8 :                     aEffRange.aStart.Col(), static_cast<SCSIZE>(aEffRange.aEnd.Col()-aEffRange.aStart.Col()+1));
     200             :                 else
     201           0 :                     rDoc.InsertCol( aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
     202           0 :                     aEffRange.aStart.Col(), static_cast<SCSIZE>(aEffRange.aEnd.Col()-aEffRange.aStart.Col()+1));
     203             :             }
     204           2 :             break;
     205             :         default:
     206             :         {
     207             :             // added to avoid warnings
     208             :         }
     209             :     }
     210             : 
     211           6 :     ScRange aWorkRange( aEffRange );
     212           6 :     if ( eCmd == INS_CELLSRIGHT )                   // only "shift right" requires refresh of the moved area
     213           0 :         aWorkRange.aEnd.SetCol(MAXCOL);
     214          12 :     for( i=0; i<nCount; i++ )
     215             :     {
     216          18 :         if ( rDoc.HasAttrib( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), pTabs[i],
     217          18 :             aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), pTabs[i], HASATTR_MERGED ) )
     218             :         {
     219           0 :             SCCOL nEndCol = aWorkRange.aEnd.Col();
     220           0 :             SCROW nEndRow = aWorkRange.aEnd.Row();
     221           0 :             rDoc.ExtendMerge( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), nEndCol, nEndRow, pTabs[i], true );
     222             :         }
     223             :     }
     224             : 
     225             :     // Undo for displaced attributes?
     226             : 
     227           6 :     sal_uInt16 nPaint = PAINT_GRID;
     228           6 :     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
     229           6 :     switch (eCmd)
     230             :     {
     231             :         case INS_INSROWS:
     232           4 :             nPaint |= PAINT_LEFT;
     233           4 :             aWorkRange.aEnd.SetRow(MAXROW);
     234           4 :             break;
     235             :         case INS_CELLSDOWN:
     236           0 :             for( i=0; i<nCount; i++ )
     237             :             {
     238           0 :                 aWorkRange.aEnd.SetRow(MAXROW);
     239           0 :                 if ( pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), pTabs[i] ))
     240             :                 {
     241           0 :                     aWorkRange.aStart.SetCol(0);
     242           0 :                     aWorkRange.aEnd.SetCol(MAXCOL);
     243           0 :                     nPaint |= PAINT_LEFT;
     244             :                 }
     245             :             }
     246           0 :             break;
     247             :         case INS_INSCOLS:
     248           2 :             nPaint |= PAINT_TOP;                // top bar
     249             :         case INS_CELLSRIGHT:
     250           4 :             for( i=0; i<nCount; i++ )
     251             :             {
     252           2 :                 aWorkRange.aEnd.SetCol(MAXCOL);     // to the far right
     253           2 :                 if ( pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), pTabs[i]) )
     254             :                 {                                   // AdjustDraw does not paint PAINT_TOP,
     255           0 :                     aWorkRange.aStart.SetCol(0);    // thus solved like this
     256           0 :                     aWorkRange.aEnd.SetRow(MAXROW);
     257           0 :                     nPaint |= PAINT_LEFT;
     258             :                 }
     259             :             }
     260           2 :             break;
     261             :         default:
     262             :         {
     263             :             // added to avoid warnings
     264             :         }
     265             :     }
     266             : 
     267          12 :     for( i=0; i<nCount; i++ )
     268             :     {
     269          12 :         pDocShell->PostPaint( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), pTabs[i],
     270          18 :             aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), pTabs[i]+pScenarios[i], nPaint );
     271             :     }
     272           6 :     pDocShell->PostDataChanged();
     273           6 :     if (pViewShell)
     274           0 :         pViewShell->CellContentChanged();
     275           6 : }
     276             : 
     277           4 : void ScUndoInsertCells::Undo()
     278             : {
     279           4 :     if ( pPasteUndo )
     280           0 :         pPasteUndo->Undo();     // undo paste first
     281             : 
     282           4 :     WaitObject aWait( pDocShell->GetActiveDialogParent() );     // important due to TrackFormulas in UpdateReference
     283           4 :     BeginUndo();
     284           4 :     DoChange( true );
     285           4 :     EndUndo();
     286             : 
     287           4 :     ScDocument& rDoc = pDocShell->GetDocument();
     288           8 :     for (SCTAB i = 0; i < nCount; ++i)
     289           8 :         rDoc.SetDrawPageSize(pTabs[i]);
     290           4 : }
     291             : 
     292           2 : void ScUndoInsertCells::Redo()
     293             : {
     294           2 :     WaitObject aWait( pDocShell->GetActiveDialogParent() );     // important due to TrackFormulas in UpdateReference
     295           2 :     BeginRedo();
     296           2 :     DoChange( false );
     297           2 :     EndRedo();
     298             : 
     299           2 :     if ( pPasteUndo )
     300           0 :         pPasteUndo->Redo();     // redo paste last
     301             : 
     302           2 :     ScDocument& rDoc = pDocShell->GetDocument();
     303           4 :     for (SCTAB i = 0; i < nCount; ++i)
     304           4 :         rDoc.SetDrawPageSize(pTabs[i]);
     305           2 : }
     306             : 
     307           0 : void ScUndoInsertCells::Repeat(SfxRepeatTarget& rTarget)
     308             : {
     309           0 :     if (rTarget.ISA(ScTabViewTarget))
     310             :     {
     311           0 :         if ( pPasteUndo )
     312             :         {
     313             :             //  Repeat for paste with inserting cells is handled completely
     314             :             //  by the Paste undo action
     315             : 
     316           0 :             pPasteUndo->Repeat( rTarget );
     317             :         }
     318             :         else
     319           0 :             static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->InsertCells( eCmd, true );
     320             :     }
     321           0 : }
     322             : 
     323           0 : bool ScUndoInsertCells::CanRepeat(SfxRepeatTarget& rTarget) const
     324             : {
     325           0 :     return rTarget.ISA(ScTabViewTarget);
     326             : }
     327             : 
     328          54 : ScUndoDeleteCells::ScUndoDeleteCells( ScDocShell* pNewDocShell,
     329             :                                 const ScRange& rRange, SCTAB nNewCount, SCTAB* pNewTabs, SCTAB* pNewScenarios,
     330             :                                 DelCellCmd eNewCmd, ScDocument* pUndoDocument, ScRefUndoData* pRefData ) :
     331             :     ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFLAST ),
     332             :     aEffRange( rRange ),
     333             :     nCount( nNewCount ),
     334             :     pTabs( pNewTabs ),
     335             :     pScenarios( pNewScenarios ),
     336          54 :     eCmd( eNewCmd )
     337             : {
     338          54 :     if (eCmd == DEL_DELROWS)            // whole row?
     339             :     {
     340           2 :         aEffRange.aStart.SetCol(0);
     341           2 :         aEffRange.aEnd.SetCol(MAXCOL);
     342             :     }
     343             : 
     344          54 :     if (eCmd == DEL_DELCOLS)            // whole column?
     345             :     {
     346           6 :         aEffRange.aStart.SetRow(0);
     347           6 :         aEffRange.aEnd.SetRow(MAXROW);
     348             :     }
     349             : 
     350          54 :     SetChangeTrack();
     351          54 : }
     352             : 
     353         162 : ScUndoDeleteCells::~ScUndoDeleteCells()
     354             : {
     355          54 :     delete []pTabs;
     356          54 :     delete []pScenarios;
     357         108 : }
     358             : 
     359          98 : OUString ScUndoDeleteCells::GetComment() const
     360             : {
     361          98 :     return ScGlobal::GetRscString( STR_UNDO_DELETECELLS ); // "Delete"
     362             : }
     363             : 
     364          58 : void ScUndoDeleteCells::SetChangeTrack()
     365             : {
     366          58 :     ScChangeTrack* pChangeTrack = pDocShell->GetDocument().GetChangeTrack();
     367          58 :     if ( pChangeTrack )
     368             :         pChangeTrack->AppendDeleteRange( aEffRange, pRefUndoDoc,
     369           0 :             nStartChangeAction, nEndChangeAction );
     370             :     else
     371          58 :         nStartChangeAction = nEndChangeAction = 0;
     372          58 : }
     373             : 
     374          44 : void ScUndoDeleteCells::DoChange( const bool bUndo )
     375             : {
     376          44 :     ScDocument& rDoc = pDocShell->GetDocument();
     377             :     SCTAB i;
     378             : 
     379          44 :     if ( bUndo )
     380             :     {
     381          40 :         ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
     382          40 :         if ( pChangeTrack )
     383           0 :             pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
     384             :     }
     385             :     else
     386           4 :         SetChangeTrack();
     387             : 
     388          44 :     switch (eCmd)
     389             :     {
     390             :         case DEL_DELROWS:
     391             :         case DEL_CELLSUP:
     392          48 :             for( i=0; i<nCount; i++ )
     393             :             {
     394          24 :                 if (bUndo)
     395         110 :                     rDoc.InsertRow( aEffRange.aStart.Col(), pTabs[i], aEffRange.aEnd.Col(), pTabs[i]+pScenarios[i],
     396         132 :                     aEffRange.aStart.Row(), static_cast<SCSIZE>(aEffRange.aEnd.Row()-aEffRange.aStart.Row()+1));
     397             :                 else
     398          10 :                     rDoc.DeleteRow( aEffRange.aStart.Col(), pTabs[i], aEffRange.aEnd.Col(), pTabs[i]+pScenarios[i],
     399          12 :                     aEffRange.aStart.Row(), static_cast<SCSIZE>(aEffRange.aEnd.Row()-aEffRange.aStart.Row()+1));
     400             :             }
     401          24 :             break;
     402             :         case DEL_DELCOLS:
     403             :         case DEL_CELLSLEFT:
     404          40 :             for( i=0; i<nCount; i++ )
     405             :             {
     406          20 :                 if (bUndo)
     407          54 :                     rDoc.InsertCol( aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
     408          72 :                     aEffRange.aStart.Col(), static_cast<SCSIZE>(aEffRange.aEnd.Col()-aEffRange.aStart.Col()+1));
     409             :                 else
     410           6 :                     rDoc.DeleteCol( aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
     411           8 :                     aEffRange.aStart.Col(), static_cast<SCSIZE>(aEffRange.aEnd.Col()-aEffRange.aStart.Col()+1));
     412             :             }
     413          20 :             break;
     414             :         default:
     415             :         {
     416             :             // added to avoid warnings
     417             :         }
     418             :     }
     419             : 
     420             :     // if Undo, restore references
     421          84 :     for( i=0; i<nCount && bUndo; i++ )
     422             :     {
     423         200 :         pRefUndoDoc->CopyToDocument( aEffRange.aStart.Col(), aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Col(), aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
     424         240 :             IDF_ALL | IDF_NOCAPTIONS, false, &rDoc );
     425             :     }
     426             : 
     427          44 :     ScRange aWorkRange( aEffRange );
     428          44 :     if ( eCmd == DEL_CELLSLEFT )        // only "shift left" requires refresh of the moved area
     429          20 :         aWorkRange.aEnd.SetCol(MAXCOL);
     430             : 
     431          88 :     for( i=0; i<nCount; i++ )
     432             :     {
     433         132 :         if ( rDoc.HasAttrib( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), pTabs[i],
     434         132 :             aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), pTabs[i], HASATTR_MERGED | HASATTR_OVERLAPPED ) )
     435             :         {
     436             :             // #i51445# old merge flag attributes must be deleted also for single cells,
     437             :             // not only for whole columns/rows
     438             : 
     439           0 :             if ( !bUndo )
     440             :             {
     441           0 :                 if ( eCmd==DEL_DELCOLS || eCmd==DEL_CELLSLEFT )
     442           0 :                     aWorkRange.aEnd.SetCol(MAXCOL);
     443           0 :                 if ( eCmd==DEL_DELROWS || eCmd==DEL_CELLSUP )
     444           0 :                     aWorkRange.aEnd.SetRow(MAXROW);
     445           0 :                 ScMarkData aMarkData;
     446           0 :                 aMarkData.SelectOneTable( aWorkRange.aStart.Tab() );
     447           0 :                 ScPatternAttr aPattern( rDoc.GetPool() );
     448           0 :                 aPattern.GetItemSet().Put( ScMergeFlagAttr() );
     449           0 :                 rDoc.ApplyPatternArea( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(),
     450           0 :                     aWorkRange.aEnd.Col(),   aWorkRange.aEnd.Row(),
     451           0 :                     aMarkData, aPattern );
     452             :             }
     453             : 
     454           0 :             SCCOL nEndCol = aWorkRange.aEnd.Col();
     455           0 :             SCROW nEndRow = aWorkRange.aEnd.Row();
     456           0 :             rDoc.ExtendMerge( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), nEndCol, nEndRow, pTabs[i], true );
     457             :         }
     458             :     }
     459             : 
     460             :     // Zeichnen
     461          44 :     sal_uInt16 nPaint = PAINT_GRID;
     462          44 :     switch (eCmd)
     463             :     {
     464             :         case DEL_DELROWS:
     465           0 :             nPaint |= PAINT_LEFT;
     466           0 :             aWorkRange.aEnd.SetRow(MAXROW);
     467           0 :             break;
     468             :         case DEL_CELLSUP:
     469          48 :             for( i=0; i<nCount; i++ )
     470             :             {
     471          24 :                 aWorkRange.aEnd.SetRow(MAXROW);
     472          24 :                 if ( pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), pTabs[i] ))
     473             :                 {
     474           0 :                     aWorkRange.aStart.SetCol(0);
     475           0 :                     aWorkRange.aEnd.SetCol(MAXCOL);
     476           0 :                     nPaint |= PAINT_LEFT;
     477             :                 }
     478             :             }
     479          24 :             break;
     480             :         case DEL_DELCOLS:
     481           0 :             nPaint |= PAINT_TOP;                // top bar
     482             :         case DEL_CELLSLEFT:
     483          40 :             for( i=0; i<nCount; i++ )
     484             :             {
     485          20 :                 aWorkRange.aEnd.SetCol(MAXCOL);     // to the far right
     486          20 :                 if ( pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), pTabs[i] ) )
     487             :                 {
     488           0 :                     aWorkRange.aStart.SetCol(0);
     489           0 :                     aWorkRange.aEnd.SetRow(MAXROW);
     490           0 :                     nPaint |= PAINT_LEFT;
     491             :                 }
     492             :             }
     493          20 :             break;
     494             :         default:
     495             :         {
     496             :             // added to avoid warnings
     497             :         }
     498             :     }
     499             : 
     500          88 :     for( i=0; i<nCount; i++ )
     501             :     {
     502          88 :         pDocShell->PostPaint( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), pTabs[i],
     503         132 :             aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), pTabs[i]+pScenarios[i], nPaint, SC_PF_LINES );
     504             :     }
     505             :     // Selection not until EndUndo
     506             : 
     507          44 :     pDocShell->PostDataChanged();
     508             :     //  CellContentChanged comes with the selection
     509          44 : }
     510             : 
     511          40 : void ScUndoDeleteCells::Undo()
     512             : {
     513          40 :     WaitObject aWait( pDocShell->GetActiveDialogParent() );     // important because of TrackFormulas in UpdateReference
     514          40 :     BeginUndo();
     515          40 :     DoChange( true );
     516          40 :     EndUndo();
     517          40 :     SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
     518             : 
     519             :     // Selection not until EndUndo
     520          40 :     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
     521          40 :     if (pViewShell)
     522             :     {
     523           0 :         for( SCTAB i=0; i<nCount; i++ )
     524             :         {
     525           0 :             pViewShell->MarkRange( ScRange(aEffRange.aStart.Col(), aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Col(), aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i]) );
     526             :         }
     527             :     }
     528             : 
     529          40 :     ScDocument& rDoc = pDocShell->GetDocument();
     530          80 :     for (SCTAB i = 0; i < nCount; ++i)
     531          80 :         rDoc.SetDrawPageSize(pTabs[i]);
     532          40 : }
     533             : 
     534           4 : void ScUndoDeleteCells::Redo()
     535             : {
     536           4 :     WaitObject aWait( pDocShell->GetActiveDialogParent() );     // important because of TrackFormulas in UpdateReference
     537           4 :     BeginRedo();
     538           4 :     DoChange( false);
     539           4 :     EndRedo();
     540           4 :     SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
     541             : 
     542           4 :     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
     543           4 :     if (pViewShell)
     544           0 :         pViewShell->DoneBlockMode();            // current way
     545             : 
     546           4 :     ScDocument& rDoc = pDocShell->GetDocument();
     547           8 :     for (SCTAB i = 0; i < nCount; ++i)
     548           8 :         rDoc.SetDrawPageSize(pTabs[i]);
     549           4 : }
     550             : 
     551           0 : void ScUndoDeleteCells::Repeat(SfxRepeatTarget& rTarget)
     552             : {
     553           0 :     if (rTarget.ISA(ScTabViewTarget))
     554           0 :         static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->DeleteCells( eCmd, true );
     555           0 : }
     556             : 
     557           0 : bool ScUndoDeleteCells::CanRepeat(SfxRepeatTarget& rTarget) const
     558             : {
     559           0 :     return rTarget.ISA(ScTabViewTarget);
     560             : }
     561             : 
     562             : // delete cells in multiselection
     563           0 : ScUndoDeleteMulti::ScUndoDeleteMulti(
     564             :     ScDocShell* pNewDocShell,
     565             :     bool bNewRows, bool bNeedsRefresh, SCTAB nNewTab,
     566             :     const std::vector<sc::ColRowSpan>& rSpans,
     567             :     ScDocument* pUndoDocument, ScRefUndoData* pRefData ) :
     568             :     ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFLAST ),
     569             :     mbRows(bNewRows),
     570             :     mbRefresh(bNeedsRefresh),
     571             :     nTab( nNewTab ),
     572           0 :     maSpans(rSpans)
     573             : {
     574           0 :     SetChangeTrack();
     575           0 : }
     576             : 
     577           0 : ScUndoDeleteMulti::~ScUndoDeleteMulti()
     578             : {
     579           0 : }
     580             : 
     581           0 : OUString ScUndoDeleteMulti::GetComment() const
     582             : {
     583           0 :     return ScGlobal::GetRscString( STR_UNDO_DELETECELLS );  // like DeleteCells
     584             : }
     585             : 
     586           0 : void ScUndoDeleteMulti::DoChange() const
     587             : {
     588             :     SCCOL nStartCol;
     589             :     SCROW nStartRow;
     590             :     sal_uInt16 nPaint;
     591           0 :     if (mbRows)
     592             :     {
     593           0 :         nStartCol = 0;
     594           0 :         nStartRow = static_cast<SCROW>(maSpans[0].mnStart);
     595           0 :         nPaint = PAINT_GRID | PAINT_LEFT;
     596             :     }
     597             :     else
     598             :     {
     599           0 :         nStartCol = static_cast<SCCOL>(maSpans[0].mnStart);
     600           0 :         nStartRow = 0;
     601           0 :         nPaint = PAINT_GRID | PAINT_TOP;
     602             :     }
     603             : 
     604           0 :     if (mbRefresh)
     605             :     {
     606           0 :         ScDocument& rDoc = pDocShell->GetDocument();
     607           0 :         SCCOL nEndCol = MAXCOL;
     608           0 :         SCROW nEndRow = MAXROW;
     609           0 :         rDoc.RemoveFlagsTab( nStartCol, nStartRow, nEndCol, nEndRow, nTab, SC_MF_HOR | SC_MF_VER );
     610           0 :         rDoc.ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, nTab, true );
     611             :     }
     612             : 
     613           0 :     pDocShell->PostPaint( nStartCol, nStartRow, nTab, MAXCOL, MAXROW, nTab, nPaint );
     614           0 :     pDocShell->PostDataChanged();
     615           0 :     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
     616           0 :     if (pViewShell)
     617           0 :         pViewShell->CellContentChanged();
     618             : 
     619           0 :     ShowTable( nTab );
     620           0 : }
     621             : 
     622           0 : void ScUndoDeleteMulti::SetChangeTrack()
     623             : {
     624           0 :     ScChangeTrack* pChangeTrack = pDocShell->GetDocument().GetChangeTrack();
     625           0 :     if ( pChangeTrack )
     626             :     {
     627           0 :         nStartChangeAction = pChangeTrack->GetActionMax() + 1;
     628           0 :         ScRange aRange( 0, 0, nTab, 0, 0, nTab );
     629           0 :         if (mbRows)
     630           0 :             aRange.aEnd.SetCol( MAXCOL );
     631             :         else
     632           0 :             aRange.aEnd.SetRow( MAXROW );
     633             :         // delete in reverse
     634           0 :         std::vector<sc::ColRowSpan>::const_reverse_iterator ri = maSpans.rbegin(), riEnd = maSpans.rend();
     635           0 :         for (; ri != riEnd; ++ri)
     636             :         {
     637           0 :             SCCOLROW nEnd = ri->mnEnd;
     638           0 :             SCCOLROW nStart = ri->mnStart;
     639           0 :             if (mbRows)
     640             :             {
     641           0 :                 aRange.aStart.SetRow( nStart );
     642           0 :                 aRange.aEnd.SetRow( nEnd );
     643             :             }
     644             :             else
     645             :             {
     646           0 :                 aRange.aStart.SetCol( static_cast<SCCOL>(nStart) );
     647           0 :                 aRange.aEnd.SetCol( static_cast<SCCOL>(nEnd) );
     648             :             }
     649             :             sal_uLong nDummyStart;
     650             :             pChangeTrack->AppendDeleteRange( aRange, pRefUndoDoc,
     651           0 :                 nDummyStart, nEndChangeAction );
     652             :         }
     653             :     }
     654             :     else
     655           0 :         nStartChangeAction = nEndChangeAction = 0;
     656           0 : }
     657             : 
     658           0 : void ScUndoDeleteMulti::Undo()
     659             : {
     660           0 :     WaitObject aWait( pDocShell->GetActiveDialogParent() );     // important because of TrackFormulas in UpdateReference
     661           0 :     BeginUndo();
     662             : 
     663           0 :     ScDocument& rDoc = pDocShell->GetDocument();
     664             : 
     665             :     // reverse delete -> forward insert
     666           0 :     std::vector<sc::ColRowSpan>::const_iterator it = maSpans.begin(), itEnd = maSpans.end();
     667           0 :     for (; it != itEnd; ++it)
     668             :     {
     669           0 :         SCCOLROW nStart = it->mnStart;
     670           0 :         SCCOLROW nEnd = it->mnEnd;
     671           0 :         if (mbRows)
     672           0 :             rDoc.InsertRow( 0,nTab, MAXCOL,nTab, nStart,static_cast<SCSIZE>(nEnd-nStart+1) );
     673             :         else
     674           0 :             rDoc.InsertCol( 0,nTab, MAXROW,nTab, static_cast<SCCOL>(nStart), static_cast<SCSIZE>(nEnd-nStart+1) );
     675             :     }
     676             : 
     677           0 :     it = maSpans.begin();
     678           0 :     for (; it != itEnd; ++it)
     679             :     {
     680           0 :         SCCOLROW nStart = it->mnStart;
     681           0 :         SCCOLROW nEnd = it->mnEnd;
     682           0 :         if (mbRows)
     683           0 :             pRefUndoDoc->CopyToDocument( 0,nStart,nTab, MAXCOL,nEnd,nTab, IDF_ALL,false, &rDoc );
     684             :         else
     685             :             pRefUndoDoc->CopyToDocument( static_cast<SCCOL>(nStart),0,nTab,
     686           0 :                     static_cast<SCCOL>(nEnd),MAXROW,nTab, IDF_ALL,false, &rDoc );
     687             :     }
     688             : 
     689           0 :     ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
     690           0 :     if ( pChangeTrack )
     691           0 :         pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
     692             : 
     693           0 :     DoChange();
     694             : 
     695             :     //! redrawing the selection is not possible at the moment
     696             :     //! since no data for selection exist
     697             : 
     698           0 :     EndUndo();
     699           0 :     SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
     700           0 : }
     701             : 
     702           0 : void ScUndoDeleteMulti::Redo()
     703             : {
     704           0 :     WaitObject aWait( pDocShell->GetActiveDialogParent() );     // important because of TrackFormulas in UpdateReference
     705           0 :     BeginRedo();
     706             : 
     707           0 :     ScDocument& rDoc = pDocShell->GetDocument();
     708             : 
     709             :     // reverse delete
     710           0 :     std::vector<sc::ColRowSpan>::const_reverse_iterator ri = maSpans.rbegin(), riEnd = maSpans.rend();
     711           0 :     for (; ri != riEnd; ++ri)
     712             :     {
     713           0 :         SCCOLROW nEnd = ri->mnEnd;
     714           0 :         SCCOLROW nStart = ri->mnStart;
     715           0 :         if (mbRows)
     716           0 :             rDoc.DeleteRow( 0,nTab, MAXCOL,nTab, nStart,static_cast<SCSIZE>(nEnd-nStart+1) );
     717             :         else
     718           0 :             rDoc.DeleteCol( 0,nTab, MAXROW,nTab, static_cast<SCCOL>(nStart), static_cast<SCSIZE>(nEnd-nStart+1) );
     719             :     }
     720             : 
     721           0 :     SetChangeTrack();
     722             : 
     723           0 :     DoChange();
     724             : 
     725           0 :     EndRedo();
     726           0 :     SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
     727           0 : }
     728             : 
     729           0 : void ScUndoDeleteMulti::Repeat(SfxRepeatTarget& rTarget)
     730             : {
     731             :     // if single selection
     732           0 :     if (rTarget.ISA(ScTabViewTarget))
     733           0 :         static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->DeleteCells( DEL_DELROWS, true );
     734           0 : }
     735             : 
     736           0 : bool ScUndoDeleteMulti::CanRepeat(SfxRepeatTarget& rTarget) const
     737             : {
     738           0 :     return rTarget.ISA(ScTabViewTarget);
     739             : }
     740             : 
     741           2 : ScUndoCut::ScUndoCut( ScDocShell* pNewDocShell,
     742             :                 ScRange aRange, ScAddress aOldEnd, const ScMarkData& rMark,
     743             :                 ScDocument* pNewUndoDoc ) :
     744             :     ScBlockUndo( pNewDocShell, ScRange(aRange.aStart, aOldEnd), SC_UNDO_AUTOHEIGHT ),
     745             :     aMarkData( rMark ),
     746             :     pUndoDoc( pNewUndoDoc ),
     747           2 :     aExtendedRange( aRange )
     748             : {
     749           2 :     SetChangeTrack();
     750           2 : }
     751             : 
     752           4 : ScUndoCut::~ScUndoCut()
     753             : {
     754           2 :     delete pUndoDoc;
     755           2 : }
     756             : 
     757           0 : OUString ScUndoCut::GetComment() const
     758             : {
     759           0 :     return ScGlobal::GetRscString( STR_UNDO_CUT ); // "cut"
     760             : }
     761             : 
     762           4 : void ScUndoCut::SetChangeTrack()
     763             : {
     764           4 :     ScChangeTrack* pChangeTrack = pDocShell->GetDocument().GetChangeTrack();
     765           4 :     if ( pChangeTrack )
     766             :         pChangeTrack->AppendContentRange( aBlockRange, pUndoDoc,
     767           0 :             nStartChangeAction, nEndChangeAction, SC_CACM_CUT );
     768             :     else
     769           4 :         nStartChangeAction = nEndChangeAction = 0;
     770           4 : }
     771             : 
     772           6 : void ScUndoCut::DoChange( const bool bUndo )
     773             : {
     774           6 :     ScDocument& rDoc = pDocShell->GetDocument();
     775           6 :     sal_uInt16 nExtFlags = 0;
     776             : 
     777             :     // do not undo/redo objects and note captions, they are handled via drawing undo
     778           6 :     InsertDeleteFlags nUndoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS;
     779             : 
     780           6 :     if (bUndo)  // only for Undo
     781             :     {
     782             :         //  all sheets - CopyToDocument skips those that don't exist in pUndoDoc
     783           4 :         SCTAB nTabCount = rDoc.GetTableCount();
     784           4 :         ScRange aCopyRange = aExtendedRange;
     785           4 :         aCopyRange.aStart.SetTab(0);
     786           4 :         aCopyRange.aEnd.SetTab(nTabCount-1);
     787           4 :         pUndoDoc->CopyToDocument( aCopyRange, nUndoFlags, false, &rDoc );
     788           4 :         ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
     789           4 :         if ( pChangeTrack )
     790           0 :             pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
     791             : 
     792           4 :         BroadcastChanges(aCopyRange);
     793             :     }
     794             :     else        // only for Redo
     795             :     {
     796           2 :         pDocShell->UpdatePaintExt( nExtFlags, aExtendedRange );
     797           2 :         rDoc.DeleteArea( aBlockRange.aStart.Col(), aBlockRange.aStart.Row(),
     798           4 :                           aBlockRange.aEnd.Col(), aBlockRange.aEnd.Row(), aMarkData, nUndoFlags );
     799           2 :         SetChangeTrack();
     800             :     }
     801             : 
     802           6 :     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
     803           6 :     if ( !( (pViewShell) && pViewShell->AdjustBlockHeight() ) )
     804           6 : /*A*/   pDocShell->PostPaint( aExtendedRange, PAINT_GRID, nExtFlags );
     805             : 
     806           6 :     if ( !bUndo )                               //   draw redo after updating row heights
     807           2 :         RedoSdrUndoAction( pDrawUndo );         //! include in ScBlockUndo?
     808             : 
     809           6 :     pDocShell->PostDataChanged();
     810           6 :     if (pViewShell)
     811           0 :         pViewShell->CellContentChanged();
     812           6 : }
     813             : 
     814           4 : void ScUndoCut::Undo()
     815             : {
     816           4 :     BeginUndo();
     817           4 :     DoChange( true );
     818           4 :     EndUndo();
     819           4 : }
     820             : 
     821           2 : void ScUndoCut::Redo()
     822             : {
     823           2 :     BeginRedo();
     824           2 :     ScDocument& rDoc = pDocShell->GetDocument();
     825           2 :     EnableDrawAdjust( &rDoc, false );                //! include in ScBlockUndo?
     826           2 :     DoChange( false );
     827           2 :     EnableDrawAdjust( &rDoc, true );                 //! include in ScBlockUndo?
     828           2 :     EndRedo();
     829           2 : }
     830             : 
     831           0 : void ScUndoCut::Repeat(SfxRepeatTarget& rTarget)
     832             : {
     833           0 :     if (rTarget.ISA(ScTabViewTarget))
     834           0 :         static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->CutToClip( NULL, true );
     835           0 : }
     836             : 
     837           0 : bool ScUndoCut::CanRepeat(SfxRepeatTarget& rTarget) const
     838             : {
     839           0 :     return rTarget.ISA(ScTabViewTarget);
     840             : }
     841             : 
     842          62 : ScUndoPaste::ScUndoPaste( ScDocShell* pNewDocShell, const ScRangeList& rRanges,
     843             :                 const ScMarkData& rMark,
     844             :                 ScDocument* pNewUndoDoc, ScDocument* pNewRedoDoc,
     845             :                 InsertDeleteFlags nNewFlags,
     846             :                 ScRefUndoData* pRefData,
     847             :                 bool bRedoIsFilled, const ScUndoPasteOptions* pOptions ) :
     848             :     ScMultiBlockUndo( pNewDocShell, rRanges, SC_UNDO_SIMPLE ),
     849             :     aMarkData( rMark ),
     850             :     pUndoDoc( pNewUndoDoc ),
     851             :     pRedoDoc( pNewRedoDoc ),
     852             :     nFlags( nNewFlags ),
     853             :     pRefUndoData( pRefData ),
     854             :     pRefRedoData( NULL ),
     855          62 :     bRedoFilled( bRedoIsFilled )
     856             : {
     857          62 :     if ( pRefUndoData )
     858           6 :         pRefUndoData->DeleteUnchanged( &pDocShell->GetDocument() );
     859             : 
     860          62 :     if ( pOptions )
     861          32 :         aPasteOptions = *pOptions;      // used only for Repeat
     862             : 
     863          62 :     SetChangeTrack();
     864          62 : }
     865             : 
     866         182 : ScUndoPaste::~ScUndoPaste()
     867             : {
     868          62 :     delete pUndoDoc;
     869          62 :     delete pRedoDoc;
     870          62 :     delete pRefUndoData;
     871          62 :     delete pRefRedoData;
     872         120 : }
     873             : 
     874         102 : OUString ScUndoPaste::GetComment() const
     875             : {
     876         102 :     return ScGlobal::GetRscString( STR_UNDO_PASTE ); // "paste"
     877             : }
     878             : 
     879          68 : void ScUndoPaste::SetChangeTrack()
     880             : {
     881          68 :     ScChangeTrack* pChangeTrack = pDocShell->GetDocument().GetChangeTrack();
     882          68 :     if ( pChangeTrack && (nFlags & IDF_CONTENTS) )
     883             :     {
     884           0 :         for (size_t i = 0, n = maBlockRanges.size(); i < n; ++i)
     885             :         {
     886           0 :             pChangeTrack->AppendContentRange(*maBlockRanges[i], pUndoDoc,
     887           0 :                 nStartChangeAction, nEndChangeAction, SC_CACM_PASTE );
     888             :         }
     889             :     }
     890             :     else
     891          68 :         nStartChangeAction = nEndChangeAction = 0;
     892          68 : }
     893             : 
     894          16 : void ScUndoPaste::DoChange(bool bUndo)
     895             : {
     896          16 :     ScDocument& rDoc = pDocShell->GetDocument();
     897             : 
     898             :     //  RefUndoData for redo is created before first undo
     899             :     //  (with DeleteUnchanged after the DoUndo call)
     900          16 :     bool bCreateRedoData = ( bUndo && pRefUndoData && !pRefRedoData );
     901          16 :     if ( bCreateRedoData )
     902           6 :         pRefRedoData = new ScRefUndoData( &rDoc );
     903             : 
     904          16 :     ScRefUndoData* pWorkRefData = bUndo ? pRefUndoData : pRefRedoData;
     905             : 
     906             :     // Always back-up either all or none of the content for Undo
     907          16 :     InsertDeleteFlags nUndoFlags = IDF_NONE;
     908          16 :     if (nFlags & IDF_CONTENTS)
     909          16 :         nUndoFlags |= IDF_CONTENTS;
     910          16 :     if (nFlags & IDF_ATTRIB)
     911          14 :         nUndoFlags |= IDF_ATTRIB;
     912             : 
     913             :     // do not undo/redo objects and note captions, they are handled via drawing undo
     914          16 :     (nUndoFlags &= ~IDF_OBJECTS) |= IDF_NOCAPTIONS;
     915             : 
     916          16 :     bool bPaintAll = false;
     917             : 
     918          16 :     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
     919             : 
     920          16 :     SCTAB nTabCount = rDoc.GetTableCount();
     921          16 :     if ( bUndo && !bRedoFilled )
     922             :     {
     923           6 :         if (!pRedoDoc)
     924             :         {
     925           6 :             bool bColInfo = true;
     926           6 :             bool bRowInfo = true;
     927           6 :             for (size_t i = 0, n = maBlockRanges.size(); i < n; ++i)
     928             :             {
     929           6 :                 const ScRange& r = *maBlockRanges[i];
     930           6 :                 bColInfo &= (r.aStart.Row() == 0 && r.aEnd.Row() == MAXROW);
     931           6 :                 bRowInfo &= (r.aStart.Col() == 0 && r.aEnd.Col() == MAXCOL);
     932           6 :                 if (!bColInfo && !bRowInfo)
     933           6 :                     break;
     934             :             }
     935             : 
     936           6 :             pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
     937           6 :             pRedoDoc->InitUndoSelected( &rDoc, aMarkData, bColInfo, bRowInfo );
     938             :         }
     939             :         //  read "redo" data from the document in the first undo
     940             :         //  all sheets - CopyToDocument skips those that don't exist in pRedoDoc
     941          12 :         for (size_t i = 0, n = maBlockRanges.size(); i < n; ++i)
     942             :         {
     943           6 :             ScRange aCopyRange = *maBlockRanges[i];
     944           6 :             aCopyRange.aStart.SetTab(0);
     945           6 :             aCopyRange.aEnd.SetTab(nTabCount-1);
     946           6 :             rDoc.CopyToDocument( aCopyRange, nUndoFlags, false, pRedoDoc );
     947           6 :             bRedoFilled = true;
     948             :         }
     949             :     }
     950             : 
     951          16 :     sal_uInt16 nExtFlags = 0;
     952          16 :     pDocShell->UpdatePaintExt(nExtFlags, maBlockRanges.Combine());
     953             : 
     954          16 :     rDoc.ForgetNoteCaptions(maBlockRanges);
     955          16 :     aMarkData.MarkToMulti();
     956          16 :     rDoc.DeleteSelection(nUndoFlags, aMarkData, false); // no broadcasting here
     957          32 :     for (size_t i = 0, n = maBlockRanges.size(); i < n; ++i)
     958          16 :         rDoc.BroadcastCells(*maBlockRanges[i], SC_HINT_DATACHANGED);
     959             : 
     960          16 :     aMarkData.MarkToSimple();
     961             : 
     962          16 :     SCTAB nFirstSelected = aMarkData.GetFirstSelected();
     963             : 
     964          16 :     if ( !bUndo && pRedoDoc )       // Redo: UndoToDocument before handling RefData
     965             :     {
     966          12 :         for (size_t i = 0, n = maBlockRanges.size(); i < n; ++i)
     967             :         {
     968           6 :             ScRange aRange = *maBlockRanges[i];
     969           6 :             aRange.aStart.SetTab(nFirstSelected);
     970           6 :             aRange.aEnd.SetTab(nFirstSelected);
     971           6 :             pRedoDoc->UndoToDocument(aRange, nUndoFlags, false, &rDoc);
     972           6 :             ScMarkData::iterator itr = aMarkData.begin(), itrEnd = aMarkData.end();
     973          12 :             for (; itr != itrEnd && *itr < nTabCount; ++itr)
     974             :             {
     975           6 :                 if (*itr == nFirstSelected)
     976           6 :                     continue;
     977             : 
     978           0 :                 aRange.aStart.SetTab(*itr);
     979           0 :                 aRange.aEnd.SetTab(*itr);
     980           0 :                 pRedoDoc->CopyToDocument( aRange, nUndoFlags, false, &rDoc );
     981             :             }
     982             :         }
     983             :     }
     984             : 
     985          16 :     if (pWorkRefData)
     986             :     {
     987          10 :         pWorkRefData->DoUndo( &rDoc, true );     // true = bSetChartRangeLists for SetChartListenerCollection
     988          20 :         if (!maBlockRanges.empty() &&
     989          10 :             rDoc.RefreshAutoFilter(0, 0, MAXCOL, MAXROW, maBlockRanges[0]->aStart.Tab()))
     990           0 :             bPaintAll = true;
     991             :     }
     992             : 
     993          16 :     if ( bCreateRedoData && pRefRedoData )
     994           6 :         pRefRedoData->DeleteUnchanged( &rDoc );
     995             : 
     996          16 :     if (bUndo)      // Undo: UndoToDocument after handling RefData
     997             :     {
     998          20 :         for (size_t i = 0, n = maBlockRanges.size(); i < n; ++i)
     999             :         {
    1000          10 :             ScRange aRange = *maBlockRanges[i];
    1001          10 :             ScMarkData::iterator itr = aMarkData.begin(), itrEnd = aMarkData.end();
    1002          20 :             for (; itr != itrEnd && *itr < nTabCount; ++itr)
    1003             :             {
    1004          10 :                 aRange.aStart.SetTab(*itr);
    1005          10 :                 aRange.aEnd.SetTab(*itr);
    1006          10 :                 pUndoDoc->UndoToDocument(aRange, nUndoFlags, false, &rDoc);
    1007             :             }
    1008             :         }
    1009             :     }
    1010             : 
    1011          16 :     if ( bUndo )
    1012             :     {
    1013          10 :         ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
    1014          10 :         if ( pChangeTrack )
    1015           0 :             pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
    1016             :     }
    1017             :     else
    1018           6 :         SetChangeTrack();
    1019             : 
    1020          16 :     ScRangeList aDrawRanges(maBlockRanges);
    1021          16 :     sal_uInt16 nPaint = PAINT_GRID;
    1022          32 :     for (size_t i = 0, n = aDrawRanges.size(); i < n; ++i)
    1023             :     {
    1024          16 :         ScRange& rDrawRange = *aDrawRanges[i];
    1025          16 :         rDoc.ExtendMerge(rDrawRange, true);      // only needed for single sheet (text/rtf etc.)
    1026          16 :         if (bPaintAll)
    1027             :         {
    1028           0 :             rDrawRange.aStart.SetCol(0);
    1029           0 :             rDrawRange.aStart.SetRow(0);
    1030           0 :             rDrawRange.aEnd.SetCol(MAXCOL);
    1031           0 :             rDrawRange.aEnd.SetRow(MAXROW);
    1032           0 :             nPaint |= PAINT_TOP | PAINT_LEFT;
    1033           0 :             if (pViewShell)
    1034           0 :                 pViewShell->AdjustBlockHeight(false);
    1035             :         }
    1036             :         else
    1037             :         {
    1038          16 :             if (maBlockRanges[i]->aStart.Row() == 0 && maBlockRanges[i]->aEnd.Row() == MAXROW) // whole column
    1039             :             {
    1040           0 :                 nPaint |= PAINT_TOP;
    1041           0 :                 rDrawRange.aEnd.SetCol(MAXCOL);
    1042             :             }
    1043          16 :             if (maBlockRanges[i]->aStart.Col() == 0 && maBlockRanges[i]->aEnd.Col() == MAXCOL) // whole row
    1044             :             {
    1045           0 :                 nPaint |= PAINT_LEFT;
    1046           0 :                 rDrawRange.aEnd.SetRow(MAXROW);
    1047             :             }
    1048          16 :             if (pViewShell && pViewShell->AdjustBlockHeight(false))
    1049             :             {
    1050           0 :                 rDrawRange.aStart.SetCol(0);
    1051           0 :                 rDrawRange.aStart.SetRow(0);
    1052           0 :                 rDrawRange.aEnd.SetCol(MAXCOL);
    1053           0 :                 rDrawRange.aEnd.SetRow(MAXROW);
    1054           0 :                 nPaint |= PAINT_LEFT;
    1055             :             }
    1056          16 :             pDocShell->UpdatePaintExt(nExtFlags, rDrawRange);
    1057             :         }
    1058             :     }
    1059             : 
    1060          16 :     if ( !bUndo )                               //   draw redo after updating row heights
    1061           6 :         RedoSdrUndoAction(mpDrawUndo);
    1062             : 
    1063          16 :     pDocShell->PostPaint(aDrawRanges, nPaint, nExtFlags);
    1064             : 
    1065          16 :     pDocShell->PostDataChanged();
    1066          16 :     if (pViewShell)
    1067           0 :         pViewShell->CellContentChanged();
    1068          16 : }
    1069             : 
    1070          10 : void ScUndoPaste::Undo()
    1071             : {
    1072          10 :     BeginUndo();
    1073          10 :     DoChange(true);
    1074          10 :     if (!maBlockRanges.empty())
    1075          10 :         ShowTable(*maBlockRanges.front());
    1076          10 :     EndUndo();
    1077          10 :     SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
    1078          10 : }
    1079             : 
    1080           6 : void ScUndoPaste::Redo()
    1081             : {
    1082           6 :     BeginRedo();
    1083           6 :     ScDocument& rDoc = pDocShell->GetDocument();
    1084           6 :     EnableDrawAdjust( &rDoc, false );                //! include in ScBlockUndo?
    1085           6 :     DoChange( false );
    1086           6 :     EnableDrawAdjust( &rDoc, true );                 //! include in ScBlockUndo?
    1087           6 :     EndRedo();
    1088           6 :     SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
    1089           6 : }
    1090             : 
    1091           0 : void ScUndoPaste::Repeat(SfxRepeatTarget& rTarget)
    1092             : {
    1093           0 :     if (rTarget.ISA(ScTabViewTarget))
    1094             :     {
    1095           0 :         ScTabViewShell* pViewSh = static_cast<ScTabViewTarget&>(rTarget).GetViewShell();
    1096           0 :         ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pViewSh->GetActiveWin() );
    1097           0 :         if (pOwnClip)
    1098             :         {
    1099             :             // keep a reference in case the clipboard is changed during PasteFromClip
    1100           0 :             com::sun::star::uno::Reference<com::sun::star::datatransfer::XTransferable> aOwnClipRef( pOwnClip );
    1101             :             pViewSh->PasteFromClip( nFlags, pOwnClip->GetDocument(),
    1102             :                                     aPasteOptions.nFunction, aPasteOptions.bSkipEmpty, aPasteOptions.bTranspose,
    1103             :                                     aPasteOptions.bAsLink, aPasteOptions.eMoveMode, IDF_NONE,
    1104           0 :                                     true );     // allow warning dialog
    1105             :         }
    1106             :     }
    1107           0 : }
    1108             : 
    1109          26 : bool ScUndoPaste::CanRepeat(SfxRepeatTarget& rTarget) const
    1110             : {
    1111          26 :     return rTarget.ISA(ScTabViewTarget);
    1112             : }
    1113             : 
    1114          24 : ScUndoDragDrop::ScUndoDragDrop( ScDocShell* pNewDocShell,
    1115             :                     const ScRange& rRange, ScAddress aNewDestPos, bool bNewCut,
    1116             :                     ScDocument* pUndoDocument, ScRefUndoData* pRefData, bool bScenario ) :
    1117             :     ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFFIRST ),
    1118             :     mnPaintExtFlags( 0 ),
    1119             :     aSrcRange( rRange ),
    1120             :     bCut( bNewCut ),
    1121          24 :     bKeepScenarioFlags( bScenario )
    1122             : {
    1123          24 :     ScAddress aDestEnd(aNewDestPos);
    1124          24 :     aDestEnd.IncRow(aSrcRange.aEnd.Row() - aSrcRange.aStart.Row());
    1125          24 :     aDestEnd.IncCol(aSrcRange.aEnd.Col() - aSrcRange.aStart.Col());
    1126          24 :     aDestEnd.IncTab(aSrcRange.aEnd.Tab() - aSrcRange.aStart.Tab());
    1127             : 
    1128          24 :     bool bIncludeFiltered = bCut;
    1129          24 :     if ( !bIncludeFiltered )
    1130             :     {
    1131             :         // find number of non-filtered rows
    1132           6 :         SCROW nPastedCount = pDocShell->GetDocument().CountNonFilteredRows(
    1133          12 :             aSrcRange.aStart.Row(), aSrcRange.aEnd.Row(), aSrcRange.aStart.Tab());
    1134             : 
    1135           6 :         if ( nPastedCount == 0 )
    1136           0 :             nPastedCount = 1;
    1137           6 :         aDestEnd.SetRow( aNewDestPos.Row() + nPastedCount - 1 );
    1138             :     }
    1139             : 
    1140          24 :     aDestRange.aStart = aNewDestPos;
    1141          24 :     aDestRange.aEnd = aDestEnd;
    1142             : 
    1143          24 :     SetChangeTrack();
    1144          24 : }
    1145             : 
    1146          48 : ScUndoDragDrop::~ScUndoDragDrop()
    1147             : {
    1148          48 : }
    1149             : 
    1150          42 : OUString ScUndoDragDrop::GetComment() const
    1151             : {   // "Move" : "Copy"
    1152             :     return bCut ?
    1153             :         ScGlobal::GetRscString( STR_UNDO_MOVE ) :
    1154          42 :         ScGlobal::GetRscString( STR_UNDO_COPY );
    1155             : }
    1156             : 
    1157          28 : void ScUndoDragDrop::SetChangeTrack()
    1158             : {
    1159          28 :     ScChangeTrack* pChangeTrack = pDocShell->GetDocument().GetChangeTrack();
    1160          28 :     if ( pChangeTrack )
    1161             :     {
    1162           0 :         if ( bCut )
    1163             :         {
    1164           0 :             nStartChangeAction = pChangeTrack->GetActionMax() + 1;
    1165           0 :             pChangeTrack->AppendMove( aSrcRange, aDestRange, pRefUndoDoc );
    1166           0 :             nEndChangeAction = pChangeTrack->GetActionMax();
    1167             :         }
    1168             :         else
    1169             :             pChangeTrack->AppendContentRange( aDestRange, pRefUndoDoc,
    1170           0 :                 nStartChangeAction, nEndChangeAction );
    1171             :     }
    1172             :     else
    1173          28 :         nStartChangeAction = nEndChangeAction = 0;
    1174          28 : }
    1175             : 
    1176          34 : void ScUndoDragDrop::PaintArea( ScRange aRange, sal_uInt16 nExtFlags ) const
    1177             : {
    1178          34 :     sal_uInt16 nPaint = PAINT_GRID;
    1179          34 :     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
    1180          34 :     ScDocument& rDoc = pDocShell->GetDocument();
    1181             : 
    1182          34 :     if (pViewShell)
    1183             :     {
    1184           0 :         VirtualDevice aVirtDev;
    1185           0 :         ScViewData& rViewData = pViewShell->GetViewData();
    1186             :         sc::RowHeightContext aCxt(
    1187           0 :             rViewData.GetPPTX(), rViewData.GetPPTY(), rViewData.GetZoomX(), rViewData.GetZoomY(),
    1188           0 :             &aVirtDev);
    1189             : 
    1190           0 :         if (rDoc.SetOptimalHeight(aCxt, aRange.aStart.Row(), aRange.aEnd.Row(), aRange.aStart.Tab()))
    1191             :         {
    1192           0 :             aRange.aStart.SetCol(0);
    1193           0 :             aRange.aEnd.SetCol(MAXCOL);
    1194           0 :             aRange.aEnd.SetRow(MAXROW);
    1195           0 :             nPaint |= PAINT_LEFT;
    1196           0 :         }
    1197             :     }
    1198             : 
    1199          34 :     if ( bKeepScenarioFlags )
    1200             :     {
    1201             :         //  Copy scenario -> also paint scenario boarder
    1202           0 :         aRange.aStart.SetCol(0);
    1203           0 :         aRange.aStart.SetRow(0);
    1204           0 :         aRange.aEnd.SetCol(MAXCOL);
    1205           0 :         aRange.aEnd.SetRow(MAXROW);
    1206             :     }
    1207             : 
    1208             :     //  column/row info (width/height) included if whole columns/rows were copied
    1209          34 :     if ( aSrcRange.aStart.Col() == 0 && aSrcRange.aEnd.Col() == MAXCOL )
    1210             :     {
    1211           0 :         nPaint |= PAINT_LEFT;
    1212           0 :         aRange.aEnd.SetRow(MAXROW);
    1213             :     }
    1214          34 :     if ( aSrcRange.aStart.Row() == 0 && aSrcRange.aEnd.Row() == MAXROW )
    1215             :     {
    1216           0 :         nPaint |= PAINT_TOP;
    1217           0 :         aRange.aEnd.SetCol(MAXCOL);
    1218             :     }
    1219             : 
    1220          34 :     pDocShell->PostPaint( aRange, nPaint, nExtFlags );
    1221          34 : }
    1222             : 
    1223          26 : void ScUndoDragDrop::DoUndo( ScRange aRange )
    1224             : {
    1225          26 :     ScDocument& rDoc = pDocShell->GetDocument();
    1226             : 
    1227          26 :     ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
    1228          26 :     if ( pChangeTrack )
    1229           0 :         pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
    1230             : 
    1231             :     // Database range before data, so that the Autofilter button match up in ExtendMerge
    1232             : 
    1233          26 :     ScRange aPaintRange = aRange;
    1234          26 :     rDoc.ExtendMerge( aPaintRange );           // before deleting
    1235             : 
    1236          26 :     pDocShell->UpdatePaintExt(mnPaintExtFlags, aPaintRange);
    1237             : 
    1238             :     // do not undo objects and note captions, they are handled via drawing undo
    1239          26 :     InsertDeleteFlags nUndoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS;
    1240             : 
    1241          26 :     rDoc.DeleteAreaTab( aRange, nUndoFlags );
    1242          26 :     pRefUndoDoc->CopyToDocument( aRange, nUndoFlags, false, &rDoc );
    1243          26 :     if ( rDoc.HasAttrib( aRange, HASATTR_MERGED ) )
    1244           0 :         rDoc.ExtendMerge( aRange, true );
    1245             : 
    1246          26 :     aPaintRange.aEnd.SetCol( std::max( aPaintRange.aEnd.Col(), aRange.aEnd.Col() ) );
    1247          26 :     aPaintRange.aEnd.SetRow( std::max( aPaintRange.aEnd.Row(), aRange.aEnd.Row() ) );
    1248             : 
    1249          26 :     pDocShell->UpdatePaintExt(mnPaintExtFlags, aPaintRange);
    1250          26 :     maPaintRanges.Join(aPaintRange);
    1251          26 : }
    1252             : 
    1253             : namespace {
    1254             : 
    1255          36 : class DataChangeNotifier : std::unary_function<SvtListener*, void>
    1256             : {
    1257             :     ScHint maHint;
    1258             : public:
    1259          12 :     DataChangeNotifier() : maHint(SC_HINT_DATACHANGED, ScAddress()) {}
    1260             : 
    1261           2 :     void operator() ( SvtListener* p )
    1262             :     {
    1263           2 :         p->Notify(maHint);
    1264           2 :     }
    1265             : };
    1266             : 
    1267             : }
    1268             : 
    1269          14 : void ScUndoDragDrop::Undo()
    1270             : {
    1271          14 :     mnPaintExtFlags = 0;
    1272          14 :     maPaintRanges.RemoveAll();
    1273             : 
    1274          14 :     BeginUndo();
    1275             : 
    1276          14 :     if (bCut)
    1277             :     {
    1278             :         // During undo, we move cells from aDestRange to aSrcRange.
    1279             : 
    1280          12 :         ScDocument& rDoc = pDocShell->GetDocument();
    1281             : 
    1282          12 :         SCCOL nColDelta = aSrcRange.aStart.Col() - aDestRange.aStart.Col();
    1283          12 :         SCROW nRowDelta = aSrcRange.aStart.Row() - aDestRange.aStart.Row();
    1284          12 :         SCTAB nTabDelta = aSrcRange.aStart.Tab() - aDestRange.aStart.Tab();
    1285             : 
    1286          12 :         sc::RefUpdateContext aCxt(rDoc);
    1287          12 :         aCxt.meMode = URM_MOVE;
    1288          12 :         aCxt.maRange = aSrcRange;
    1289          12 :         aCxt.mnColDelta = nColDelta;
    1290          12 :         aCxt.mnRowDelta = nRowDelta;
    1291          12 :         aCxt.mnTabDelta = nTabDelta;
    1292             : 
    1293             :         // Global range names.
    1294          12 :         ScRangeName* pName = rDoc.GetRangeName();
    1295          12 :         if (pName)
    1296          12 :             pName->UpdateReference(aCxt);
    1297             : 
    1298          12 :         SCTAB nTabCount = rDoc.GetTableCount();
    1299          26 :         for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
    1300             :         {
    1301             :             // Sheet-local range names.
    1302          14 :             pName = rDoc.GetRangeName(nTab);
    1303          14 :             if (pName)
    1304          14 :                 pName->UpdateReference(aCxt, nTab);
    1305             :         }
    1306             : 
    1307             :         // Notify all listeners of the destination range, and have them update their references.
    1308          24 :         sc::RefMovedHint aHint(aDestRange, ScAddress(nColDelta, nRowDelta, nTabDelta), aCxt);
    1309          12 :         rDoc.BroadcastRefMoved(aHint);
    1310             : 
    1311          12 :         ScValidationDataList* pValidList = rDoc.GetValidationList();
    1312          12 :         if (pValidList)
    1313             :         {
    1314             :             // Update the references of validation entries.
    1315           0 :             pValidList->UpdateReference(aCxt);
    1316             :         }
    1317             : 
    1318          12 :         DoUndo(aDestRange);
    1319          12 :         DoUndo(aSrcRange);
    1320             : 
    1321             :         // Notify all area listeners whose listened areas are partially moved, to
    1322             :         // recalculate.
    1323          24 :         std::vector<SvtListener*> aListeners;
    1324          12 :         rDoc.CollectAllAreaListeners(aListeners, aSrcRange, sc::AreaPartialOverlap);
    1325             : 
    1326             :         // Remove any duplicate listener entries.  We must ensure that we notify
    1327             :         // each unique listener only once.
    1328          12 :         std::sort(aListeners.begin(), aListeners.end());
    1329          12 :         aListeners.erase(std::unique(aListeners.begin(), aListeners.end()), aListeners.end());
    1330             : 
    1331          24 :         std::for_each(aListeners.begin(), aListeners.end(), DataChangeNotifier());
    1332             :     }
    1333             :     else
    1334           2 :         DoUndo(aDestRange);
    1335             : 
    1336          40 :     for (size_t i = 0; i < maPaintRanges.size(); ++i)
    1337             :     {
    1338          26 :         const ScRange* p = maPaintRanges[i];
    1339          26 :         PaintArea(*p, mnPaintExtFlags);
    1340             :     }
    1341             : 
    1342          14 :     EndUndo();
    1343          14 :     SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
    1344          14 : }
    1345             : 
    1346           4 : void ScUndoDragDrop::Redo()
    1347             : {
    1348           4 :     BeginRedo();
    1349             : 
    1350           4 :     ScDocument& rDoc = pDocShell->GetDocument();
    1351           4 :     boost::scoped_ptr<ScDocument> pClipDoc(new ScDocument( SCDOCMODE_CLIP ));
    1352             : 
    1353           4 :     EnableDrawAdjust( &rDoc, false );                //! include in ScBlockUndo?
    1354             : 
    1355             :     // do not undo/redo objects and note captions, they are handled via drawing undo
    1356           4 :     InsertDeleteFlags nRedoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS;
    1357             : 
    1358             :     /*  TODO: Redoing note captions is quite tricky due to the fact that a
    1359             :         helper clip document is used. While (re-)pasting the contents to the
    1360             :         destination area, the original pointers to the captions created while
    1361             :         dropping have to be restored. A simple CopyFromClip() would create new
    1362             :         caption objects that are not tracked by drawing undo, and the captions
    1363             :         restored by drawing redo would live without cell note objects pointing
    1364             :         to them. So, first, CopyToClip() and CopyFromClip() are called without
    1365             :         cloning the caption objects. This leads to cell notes pointing to the
    1366             :         wrong captions from source area that will be removed by drawing redo
    1367             :         later. Second, the pointers to the new captions have to be restored.
    1368             :         Sadly, currently these pointers are not stored anywhere but in the list
    1369             :         of drawing undo actions. */
    1370             : 
    1371             :     SCTAB nTab;
    1372           8 :     ScMarkData aSourceMark;
    1373           8 :     for (nTab=aSrcRange.aStart.Tab(); nTab<=aSrcRange.aEnd.Tab(); nTab++)
    1374           4 :         aSourceMark.SelectTable( nTab, true );
    1375             : 
    1376             :     // do not clone objects and note captions into clipdoc (see above)
    1377             :     // but at least copy notes
    1378           8 :     ScClipParam aClipParam(aSrcRange, bCut);
    1379           4 :     rDoc.CopyToClip(aClipParam, pClipDoc.get(), &aSourceMark, false, bKeepScenarioFlags, false, true);
    1380             : 
    1381           4 :     if (bCut)
    1382             :     {
    1383           4 :         ScRange aSrcPaintRange = aSrcRange;
    1384           4 :         rDoc.ExtendMerge( aSrcPaintRange );            // before deleting
    1385           4 :         sal_uInt16 nExtFlags = 0;
    1386           4 :         pDocShell->UpdatePaintExt( nExtFlags, aSrcPaintRange );
    1387           4 :         rDoc.DeleteAreaTab( aSrcRange, nRedoFlags );
    1388           4 :         PaintArea( aSrcPaintRange, nExtFlags );
    1389             :     }
    1390             : 
    1391           8 :     ScMarkData aDestMark;
    1392           8 :     for (nTab=aDestRange.aStart.Tab(); nTab<=aDestRange.aEnd.Tab(); nTab++)
    1393           4 :         aDestMark.SelectTable( nTab, true );
    1394             : 
    1395           4 :     bool bIncludeFiltered = bCut;
    1396             :     // TODO: restore old note captions instead of cloning new captions...
    1397           4 :     rDoc.CopyFromClip( aDestRange, aDestMark, IDF_ALL & ~IDF_OBJECTS, NULL, pClipDoc.get(), true, false, bIncludeFiltered );
    1398             : 
    1399           4 :     if (bCut)
    1400           8 :         for (nTab=aSrcRange.aStart.Tab(); nTab<=aSrcRange.aEnd.Tab(); nTab++)
    1401           4 :             rDoc.RefreshAutoFilter( aSrcRange.aStart.Col(), aSrcRange.aStart.Row(),
    1402           8 :                                      aSrcRange.aEnd.Col(),   aSrcRange.aEnd.Row(), nTab );
    1403             : 
    1404             :     // skipped rows and merged cells don't mix
    1405           4 :     if ( !bIncludeFiltered && pClipDoc->HasClipFilteredRows() )
    1406           0 :         pDocShell->GetDocFunc().UnmergeCells( aDestRange, false );
    1407             : 
    1408           8 :     for (nTab=aDestRange.aStart.Tab(); nTab<=aDestRange.aEnd.Tab(); nTab++)
    1409             :     {
    1410           4 :         SCCOL nEndCol = aDestRange.aEnd.Col();
    1411           4 :         SCROW nEndRow = aDestRange.aEnd.Row();
    1412           4 :         rDoc.ExtendMerge( aDestRange.aStart.Col(), aDestRange.aStart.Row(),
    1413           8 :                             nEndCol, nEndRow, nTab, true );
    1414           4 :         PaintArea( ScRange( aDestRange.aStart.Col(), aDestRange.aStart.Row(), nTab,
    1415           8 :                             nEndCol, nEndRow, nTab ), 0 );
    1416             :     }
    1417             : 
    1418           4 :     SetChangeTrack();
    1419             : 
    1420           4 :     pClipDoc.reset();
    1421           4 :     ShowTable( aDestRange.aStart.Tab() );
    1422             : 
    1423           4 :     RedoSdrUndoAction( pDrawUndo );             //! include in ScBlockUndo?
    1424           4 :     EnableDrawAdjust( &rDoc, true );             //! include in ScBlockUndo?
    1425             : 
    1426           4 :     EndRedo();
    1427           8 :     SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
    1428           4 : }
    1429             : 
    1430           0 : void ScUndoDragDrop::Repeat(SfxRepeatTarget& /* rTarget */)
    1431             : {
    1432           0 : }
    1433             : 
    1434           0 : bool ScUndoDragDrop::CanRepeat(SfxRepeatTarget& /* rTarget */) const
    1435             : {
    1436           0 :     return false;           // not possible
    1437             : }
    1438             : 
    1439             : //      Insert list containing range names
    1440             : //      (Insert|Name|Insert =>[List])
    1441          10 : ScUndoListNames::ScUndoListNames( ScDocShell* pNewDocShell, const ScRange& rRange,
    1442             :                 ScDocument* pNewUndoDoc, ScDocument* pNewRedoDoc ) :
    1443             :     ScBlockUndo( pNewDocShell, rRange, SC_UNDO_AUTOHEIGHT ),
    1444             :     pUndoDoc( pNewUndoDoc ),
    1445          10 :     pRedoDoc( pNewRedoDoc )
    1446             : {
    1447          10 : }
    1448             : 
    1449          30 : ScUndoListNames::~ScUndoListNames()
    1450             : {
    1451          10 :     delete pUndoDoc;
    1452          10 :     delete pRedoDoc;
    1453          20 : }
    1454             : 
    1455          22 : OUString ScUndoListNames::GetComment() const
    1456             : {
    1457          22 :     return ScGlobal::GetRscString( STR_UNDO_LISTNAMES );
    1458             : }
    1459             : 
    1460           0 : void ScUndoListNames::DoChange( ScDocument* pSrcDoc ) const
    1461             : {
    1462           0 :     ScDocument& rDoc = pDocShell->GetDocument();
    1463             : 
    1464           0 :     rDoc.DeleteAreaTab( aBlockRange, IDF_ALL );
    1465           0 :     pSrcDoc->CopyToDocument( aBlockRange, IDF_ALL, false, &rDoc );
    1466           0 :     pDocShell->PostPaint( aBlockRange, PAINT_GRID );
    1467           0 :     pDocShell->PostDataChanged();
    1468           0 :     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
    1469           0 :     if (pViewShell)
    1470           0 :         pViewShell->CellContentChanged();
    1471           0 : }
    1472             : 
    1473           0 : void ScUndoListNames::Undo()
    1474             : {
    1475           0 :     BeginUndo();
    1476           0 :     DoChange(pUndoDoc);
    1477           0 :     EndUndo();
    1478           0 : }
    1479             : 
    1480           0 : void ScUndoListNames::Redo()
    1481             : {
    1482           0 :     BeginRedo();
    1483           0 :     DoChange(pRedoDoc);
    1484           0 :     EndRedo();
    1485           0 : }
    1486             : 
    1487           0 : void ScUndoListNames::Repeat(SfxRepeatTarget& rTarget)
    1488             : {
    1489           0 :     if (rTarget.ISA(ScTabViewTarget))
    1490           0 :         static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->InsertNameList();
    1491           0 : }
    1492             : 
    1493           6 : bool ScUndoListNames::CanRepeat(SfxRepeatTarget& rTarget) const
    1494             : {
    1495           6 :     return rTarget.ISA(ScTabViewTarget);
    1496             : }
    1497             : 
    1498          16 : ScUndoConditionalFormat::ScUndoConditionalFormat(ScDocShell* pNewDocShell,
    1499             :         ScDocument* pUndoDoc, ScDocument* pRedoDoc, const ScRange& rRange):
    1500             :     ScSimpleUndo( pNewDocShell ),
    1501             :     mpUndoDoc(pUndoDoc),
    1502             :     mpRedoDoc(pRedoDoc),
    1503          16 :     maRange(rRange)
    1504             : {
    1505          16 : }
    1506             : 
    1507          32 : ScUndoConditionalFormat::~ScUndoConditionalFormat()
    1508             : {
    1509          32 : }
    1510             : 
    1511          24 : OUString ScUndoConditionalFormat::GetComment() const
    1512             : {
    1513          24 :     return ScGlobal::GetRscString( STR_UNDO_CONDFORMAT );
    1514             : }
    1515             : 
    1516           0 : void ScUndoConditionalFormat::Undo()
    1517             : {
    1518           0 :     DoChange(mpUndoDoc.get());
    1519           0 : }
    1520             : 
    1521           0 : void ScUndoConditionalFormat::Redo()
    1522             : {
    1523           0 :     DoChange(mpRedoDoc.get());
    1524           0 : }
    1525             : 
    1526           0 : void ScUndoConditionalFormat::DoChange(ScDocument* pSrcDoc)
    1527             : {
    1528           0 :     ScDocument& rDoc = pDocShell->GetDocument();
    1529             : 
    1530           0 :     rDoc.DeleteAreaTab( maRange, IDF_ALL );
    1531           0 :     pSrcDoc->CopyToDocument( maRange, IDF_ALL, false, &rDoc );
    1532           0 :     pDocShell->PostPaint( maRange, PAINT_GRID );
    1533           0 :     pDocShell->PostDataChanged();
    1534           0 :     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
    1535           0 :     if (pViewShell)
    1536           0 :         pViewShell->CellContentChanged();
    1537           0 : }
    1538             : 
    1539           0 : void ScUndoConditionalFormat::Repeat(SfxRepeatTarget& )
    1540             : {
    1541           0 : }
    1542             : 
    1543           8 : bool ScUndoConditionalFormat::CanRepeat(SfxRepeatTarget& ) const
    1544             : {
    1545           8 :     return false;
    1546             : }
    1547             : 
    1548           0 : ScUndoUseScenario::ScUndoUseScenario( ScDocShell* pNewDocShell,
    1549             :                         const ScMarkData& rMark,
    1550             : /*C*/                   const ScArea& rDestArea,
    1551             :                               ScDocument* pNewUndoDoc,
    1552             :                         const OUString& rNewName ) :
    1553             :     ScSimpleUndo( pNewDocShell ),
    1554             :     pUndoDoc( pNewUndoDoc ),
    1555             :     aMarkData( rMark ),
    1556           0 :     aName( rNewName )
    1557             : {
    1558           0 :     aRange.aStart.SetCol(rDestArea.nColStart);
    1559           0 :     aRange.aStart.SetRow(rDestArea.nRowStart);
    1560           0 :     aRange.aStart.SetTab(rDestArea.nTab);
    1561           0 :     aRange.aEnd.SetCol(rDestArea.nColEnd);
    1562           0 :     aRange.aEnd.SetRow(rDestArea.nRowEnd);
    1563           0 :     aRange.aEnd.SetTab(rDestArea.nTab);
    1564           0 : }
    1565             : 
    1566           0 : ScUndoUseScenario::~ScUndoUseScenario()
    1567             : {
    1568           0 :     delete pUndoDoc;
    1569           0 : }
    1570             : 
    1571           0 : OUString ScUndoUseScenario::GetComment() const
    1572             : {
    1573           0 :     return ScGlobal::GetRscString( STR_UNDO_USESCENARIO );
    1574             : }
    1575             : 
    1576           0 : void ScUndoUseScenario::Undo()
    1577             : {
    1578           0 :     BeginUndo();
    1579             : 
    1580           0 :     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
    1581           0 :     if (pViewShell)
    1582             :     {
    1583           0 :         pViewShell->DoneBlockMode();
    1584           0 :         pViewShell->InitOwnBlockMode();
    1585             :     }
    1586             : 
    1587           0 :     ScDocument& rDoc = pDocShell->GetDocument();
    1588           0 :     rDoc.DeleteSelection( IDF_ALL, aMarkData );
    1589           0 :     pUndoDoc->CopyToDocument( aRange, IDF_ALL, true, &rDoc, &aMarkData );
    1590             : 
    1591             :     // scenario table
    1592           0 :     bool bFrame = false;
    1593           0 :     SCTAB nTab = aRange.aStart.Tab();
    1594           0 :     SCTAB nEndTab = nTab;
    1595           0 :     while ( pUndoDoc->HasTable(nEndTab+1) && pUndoDoc->IsScenario(nEndTab+1) )
    1596           0 :         ++nEndTab;
    1597           0 :     for (SCTAB i = nTab+1; i<=nEndTab; i++)
    1598             :     {
    1599             :         // Flags always
    1600           0 :         OUString aComment;
    1601           0 :         Color  aColor;
    1602             :         sal_uInt16 nScenFlags;
    1603           0 :         pUndoDoc->GetScenarioData( i, aComment, aColor, nScenFlags );
    1604           0 :         rDoc.SetScenarioData( i, aComment, aColor, nScenFlags );
    1605           0 :         bool bActive = pUndoDoc->IsActiveScenario( i );
    1606           0 :         rDoc.SetActiveScenario( i, bActive );
    1607             :         //  For copy-back scenario also consider content
    1608           0 :         if ( nScenFlags & SC_SCENARIO_TWOWAY )
    1609             :         {
    1610           0 :             rDoc.DeleteAreaTab( 0,0, MAXCOL,MAXROW, i, IDF_ALL );
    1611           0 :             pUndoDoc->CopyToDocument( 0,0,i, MAXCOL,MAXROW,i, IDF_ALL,false, &rDoc );
    1612             :         }
    1613           0 :         if ( nScenFlags & SC_SCENARIO_SHOWFRAME )
    1614           0 :             bFrame = true;
    1615           0 :     }
    1616             : 
    1617             :     // if visible borders, then paint all
    1618           0 :     if (bFrame)
    1619           0 :         pDocShell->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID | PAINT_EXTRAS );
    1620             :     else
    1621           0 :         pDocShell->PostPaint( aRange, PAINT_GRID | PAINT_EXTRAS );
    1622           0 :     pDocShell->PostDataChanged();
    1623           0 :     if (pViewShell)
    1624           0 :         pViewShell->CellContentChanged();
    1625             : 
    1626           0 :     ShowTable( aRange.aStart.Tab() );
    1627             : 
    1628           0 :     EndUndo();
    1629           0 : }
    1630             : 
    1631           0 : void ScUndoUseScenario::Redo()
    1632             : {
    1633           0 :     SCTAB nTab = aRange.aStart.Tab();
    1634           0 :     BeginRedo();
    1635             : 
    1636           0 :     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
    1637           0 :     if (pViewShell)
    1638             :     {
    1639           0 :         pViewShell->SetTabNo( nTab );
    1640           0 :         pViewShell->DoneBlockMode();
    1641           0 :         pViewShell->InitOwnBlockMode();
    1642             :     }
    1643             : 
    1644           0 :     pDocShell->UseScenario( nTab, aName, false );
    1645             : 
    1646           0 :     EndRedo();
    1647           0 : }
    1648             : 
    1649           0 : void ScUndoUseScenario::Repeat(SfxRepeatTarget& rTarget)
    1650             : {
    1651           0 :     if (rTarget.ISA(ScTabViewTarget))
    1652             :     {
    1653           0 :         OUString aTemp = aName;
    1654           0 :         static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->UseScenario(aTemp);
    1655             :     }
    1656           0 : }
    1657             : 
    1658           0 : bool ScUndoUseScenario::CanRepeat(SfxRepeatTarget& rTarget) const
    1659             : {
    1660           0 :     if (rTarget.ISA(ScTabViewTarget))
    1661             :     {
    1662           0 :         ScViewData& rViewData = static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->GetViewData();
    1663           0 :         return !rViewData.GetDocument()->IsScenario( rViewData.GetTabNo() );
    1664             :     }
    1665           0 :     return false;
    1666             : }
    1667             : 
    1668           0 : ScUndoSelectionStyle::ScUndoSelectionStyle( ScDocShell* pNewDocShell,
    1669             :                                       const ScMarkData& rMark,
    1670             :                                       const ScRange& rRange,
    1671             :                                       const OUString& rName,
    1672             :                                             ScDocument* pNewUndoDoc ) :
    1673             :     ScSimpleUndo( pNewDocShell ),
    1674             :     aMarkData( rMark ),
    1675             :     pUndoDoc( pNewUndoDoc ),
    1676             :     aStyleName( rName ),
    1677           0 :     aRange( rRange )
    1678             : {
    1679           0 :     aMarkData.MarkToMulti();
    1680           0 : }
    1681             : 
    1682           0 : ScUndoSelectionStyle::~ScUndoSelectionStyle()
    1683             : {
    1684           0 :     delete pUndoDoc;
    1685           0 : }
    1686             : 
    1687           0 : OUString ScUndoSelectionStyle::GetComment() const
    1688             : {
    1689           0 :     return ScGlobal::GetRscString( STR_UNDO_APPLYCELLSTYLE );
    1690             : }
    1691             : 
    1692           0 : void ScUndoSelectionStyle::DoChange( const bool bUndo )
    1693             : {
    1694           0 :     ScDocument& rDoc = pDocShell->GetDocument();
    1695             : 
    1696           0 :     SetViewMarkData( aMarkData );
    1697             : 
    1698           0 :     ScRange aWorkRange( aRange );
    1699           0 :     if ( rDoc.HasAttrib( aWorkRange, HASATTR_MERGED ) )        // Merged cells?
    1700           0 :         rDoc.ExtendMerge( aWorkRange, true );
    1701             : 
    1702           0 :     sal_uInt16 nExtFlags = 0;
    1703           0 :     pDocShell->UpdatePaintExt( nExtFlags, aWorkRange );
    1704             : 
    1705           0 :     if (bUndo)      // if Undo then push back all old data again
    1706             :     {
    1707           0 :         SCTAB nTabCount = rDoc.GetTableCount();
    1708           0 :         ScRange aCopyRange = aWorkRange;
    1709           0 :         aCopyRange.aStart.SetTab(0);
    1710           0 :         aCopyRange.aEnd.SetTab(nTabCount-1);
    1711           0 :         pUndoDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, true, &rDoc, &aMarkData );
    1712             :     }
    1713             :     else            // if Redo, then reapply style
    1714             :     {
    1715           0 :         ScStyleSheetPool* pStlPool = rDoc.GetStyleSheetPool();
    1716             :         ScStyleSheet* pStyleSheet =
    1717           0 :             static_cast<ScStyleSheet*>( pStlPool->Find( aStyleName, SFX_STYLE_FAMILY_PARA ) );
    1718           0 :         if (!pStyleSheet)
    1719             :         {
    1720             :             OSL_FAIL("StyleSheet not found");
    1721           0 :             return;
    1722             :         }
    1723           0 :         rDoc.ApplySelectionStyle( *pStyleSheet, aMarkData );
    1724             :     }
    1725             : 
    1726           0 :     pDocShell->UpdatePaintExt( nExtFlags, aWorkRange );
    1727             : 
    1728           0 :     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
    1729           0 :     if ( !( (pViewShell) && pViewShell->AdjustBlockHeight() ) )
    1730           0 : /*A*/   pDocShell->PostPaint( aWorkRange, PAINT_GRID | PAINT_EXTRAS, nExtFlags );
    1731             : 
    1732           0 :     ShowTable( aWorkRange.aStart.Tab() );
    1733             : }
    1734             : 
    1735           0 : void ScUndoSelectionStyle::Undo()
    1736             : {
    1737           0 :     BeginUndo();
    1738           0 :     DoChange( true );
    1739           0 :     EndUndo();
    1740           0 : }
    1741             : 
    1742           0 : void ScUndoSelectionStyle::Redo()
    1743             : {
    1744           0 :     BeginRedo();
    1745           0 :     DoChange( false );
    1746           0 :     EndRedo();
    1747           0 : }
    1748             : 
    1749           0 : void ScUndoSelectionStyle::Repeat(SfxRepeatTarget& rTarget)
    1750             : {
    1751           0 :     if (rTarget.ISA(ScTabViewTarget))
    1752             :     {
    1753           0 :         ScDocument& rDoc = pDocShell->GetDocument();
    1754           0 :         ScStyleSheetPool* pStlPool = rDoc.GetStyleSheetPool();
    1755             :         ScStyleSheet* pStyleSheet = static_cast<ScStyleSheet*>( pStlPool->
    1756           0 :                                             Find( aStyleName, SFX_STYLE_FAMILY_PARA ));
    1757           0 :         if (!pStyleSheet)
    1758             :         {
    1759             :             OSL_FAIL("StyleSheet not found");
    1760           0 :             return;
    1761             :         }
    1762             : 
    1763           0 :         ScTabViewShell& rViewShell = *static_cast<ScTabViewTarget&>(rTarget).GetViewShell();
    1764           0 :         rViewShell.SetStyleSheetToMarked( pStyleSheet, true );
    1765             :     }
    1766             : }
    1767             : 
    1768           0 : bool ScUndoSelectionStyle::CanRepeat(SfxRepeatTarget& rTarget) const
    1769             : {
    1770           0 :     return rTarget.ISA(ScTabViewTarget);
    1771             : }
    1772             : 
    1773           0 : sal_uInt16 ScUndoSelectionStyle::GetId() const
    1774             : {
    1775           0 :     return STR_UNDO_APPLYCELLSTYLE;
    1776             : }
    1777             : 
    1778           4 : ScUndoEnterMatrix::ScUndoEnterMatrix( ScDocShell* pNewDocShell, const ScRange& rArea,
    1779             :                                       ScDocument* pNewUndoDoc, const OUString& rForm ) :
    1780             :     ScBlockUndo( pNewDocShell, rArea, SC_UNDO_SIMPLE ),
    1781             :     pUndoDoc( pNewUndoDoc ),
    1782           4 :     aFormula( rForm )
    1783             : {
    1784           4 :     SetChangeTrack();
    1785           4 : }
    1786             : 
    1787          12 : ScUndoEnterMatrix::~ScUndoEnterMatrix()
    1788             : {
    1789           4 :     delete pUndoDoc;
    1790           8 : }
    1791             : 
    1792           8 : OUString ScUndoEnterMatrix::GetComment() const
    1793             : {
    1794           8 :     return ScGlobal::GetRscString( STR_UNDO_ENTERMATRIX );
    1795             : }
    1796             : 
    1797           4 : void ScUndoEnterMatrix::SetChangeTrack()
    1798             : {
    1799           4 :     ScDocument& rDoc = pDocShell->GetDocument();
    1800           4 :     ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
    1801           4 :     if ( pChangeTrack )
    1802             :         pChangeTrack->AppendContentRange( aBlockRange, pUndoDoc,
    1803           0 :             nStartChangeAction, nEndChangeAction );
    1804             :     else
    1805           4 :         nStartChangeAction = nEndChangeAction = 0;
    1806           4 : }
    1807             : 
    1808           0 : void ScUndoEnterMatrix::Undo()
    1809             : {
    1810           0 :     BeginUndo();
    1811             : 
    1812           0 :     ScDocument& rDoc = pDocShell->GetDocument();
    1813             : 
    1814           0 :     rDoc.DeleteAreaTab( aBlockRange, IDF_ALL & ~IDF_NOTE );
    1815           0 :     pUndoDoc->CopyToDocument( aBlockRange, IDF_ALL & ~IDF_NOTE, false, &rDoc );
    1816           0 :     pDocShell->PostPaint( aBlockRange, PAINT_GRID );
    1817           0 :     pDocShell->PostDataChanged();
    1818           0 :     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
    1819           0 :     if (pViewShell)
    1820           0 :         pViewShell->CellContentChanged();
    1821             : 
    1822           0 :     ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
    1823           0 :     if ( pChangeTrack )
    1824           0 :         pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
    1825             : 
    1826           0 :     EndUndo();
    1827           0 : }
    1828             : 
    1829           0 : void ScUndoEnterMatrix::Redo()
    1830             : {
    1831           0 :     BeginRedo();
    1832             : 
    1833           0 :     ScDocument& rDoc = pDocShell->GetDocument();
    1834             : 
    1835           0 :     ScMarkData aDestMark;
    1836           0 :     aDestMark.SelectOneTable( aBlockRange.aStart.Tab() );
    1837           0 :     aDestMark.SetMarkArea( aBlockRange );
    1838             : 
    1839           0 :     rDoc.InsertMatrixFormula( aBlockRange.aStart.Col(), aBlockRange.aStart.Row(),
    1840           0 :                                aBlockRange.aEnd.Col(),   aBlockRange.aEnd.Row(),
    1841           0 :                                aDestMark, aFormula );
    1842             : 
    1843           0 :     SetChangeTrack();
    1844             : 
    1845           0 :     EndRedo();
    1846           0 : }
    1847             : 
    1848           0 : void ScUndoEnterMatrix::Repeat(SfxRepeatTarget& rTarget)
    1849             : {
    1850           0 :     if (rTarget.ISA(ScTabViewTarget))
    1851             :     {
    1852           0 :         OUString aTemp = aFormula;
    1853           0 :         ScDocument& rDoc = pDocShell->GetDocument();
    1854           0 :         static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->EnterMatrix(aTemp, rDoc.GetGrammar());
    1855             :     }
    1856           0 : }
    1857             : 
    1858           2 : bool ScUndoEnterMatrix::CanRepeat(SfxRepeatTarget& rTarget) const
    1859             : {
    1860           2 :     return rTarget.ISA(ScTabViewTarget);
    1861             : }
    1862             : 
    1863          14 : static ScRange lcl_GetMultiMarkRange( const ScMarkData& rMark )
    1864             : {
    1865             :     OSL_ENSURE( rMark.IsMultiMarked(), "wrong mark type" );
    1866             : 
    1867          14 :     ScRange aRange;
    1868          14 :     rMark.GetMultiMarkArea( aRange );
    1869          14 :     return aRange;
    1870             : }
    1871             : 
    1872          12 : ScUndoIndent::ScUndoIndent( ScDocShell* pNewDocShell, const ScMarkData& rMark,
    1873             :                             ScDocument* pNewUndoDoc, bool bIncrement ) :
    1874             :     ScBlockUndo( pNewDocShell, lcl_GetMultiMarkRange(rMark), SC_UNDO_AUTOHEIGHT ),
    1875             :     aMarkData( rMark ),
    1876             :     pUndoDoc( pNewUndoDoc ),
    1877          12 :     bIsIncrement( bIncrement )
    1878             : {
    1879          12 : }
    1880             : 
    1881          36 : ScUndoIndent::~ScUndoIndent()
    1882             : {
    1883          12 :     delete pUndoDoc;
    1884          24 : }
    1885             : 
    1886          20 : OUString ScUndoIndent::GetComment() const
    1887             : {
    1888          20 :     sal_uInt16 nId = bIsIncrement ? STR_UNDO_INC_INDENT : STR_UNDO_DEC_INDENT;
    1889          20 :     return ScGlobal::GetRscString( nId );
    1890             : }
    1891             : 
    1892           0 : void ScUndoIndent::Undo()
    1893             : {
    1894           0 :     BeginUndo();
    1895             : 
    1896           0 :     ScDocument& rDoc = pDocShell->GetDocument();
    1897           0 :     SCTAB nTabCount = rDoc.GetTableCount();
    1898           0 :     ScRange aCopyRange = aBlockRange;
    1899           0 :     aCopyRange.aStart.SetTab(0);
    1900           0 :     aCopyRange.aEnd.SetTab(nTabCount-1);
    1901           0 :     pUndoDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, true, &rDoc, &aMarkData );
    1902           0 :     pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
    1903             : 
    1904           0 :     EndUndo();
    1905           0 : }
    1906             : 
    1907           0 : void ScUndoIndent::Redo()
    1908             : {
    1909           0 :     BeginRedo();
    1910             : 
    1911           0 :     ScDocument& rDoc = pDocShell->GetDocument();
    1912           0 :     rDoc.ChangeSelectionIndent( bIsIncrement, aMarkData );
    1913           0 :     pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
    1914             : 
    1915           0 :     EndRedo();
    1916           0 : }
    1917             : 
    1918           0 : void ScUndoIndent::Repeat(SfxRepeatTarget& rTarget)
    1919             : {
    1920           0 :     if (rTarget.ISA(ScTabViewTarget))
    1921           0 :         static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->ChangeIndent( bIsIncrement );
    1922           0 : }
    1923             : 
    1924           4 : bool ScUndoIndent::CanRepeat(SfxRepeatTarget& rTarget) const
    1925             : {
    1926           4 :     return rTarget.ISA(ScTabViewTarget);
    1927             : }
    1928             : 
    1929           2 : ScUndoTransliterate::ScUndoTransliterate( ScDocShell* pNewDocShell, const ScMarkData& rMark,
    1930             :                             ScDocument* pNewUndoDoc, sal_Int32 nType ) :
    1931             :     ScBlockUndo( pNewDocShell, lcl_GetMultiMarkRange(rMark), SC_UNDO_AUTOHEIGHT ),
    1932             :     aMarkData( rMark ),
    1933             :     pUndoDoc( pNewUndoDoc ),
    1934           2 :     nTransliterationType( nType )
    1935             : {
    1936           2 : }
    1937             : 
    1938           6 : ScUndoTransliterate::~ScUndoTransliterate()
    1939             : {
    1940           2 :     delete pUndoDoc;
    1941           4 : }
    1942             : 
    1943           6 : OUString ScUndoTransliterate::GetComment() const
    1944             : {
    1945           6 :     return ScGlobal::GetRscString( STR_UNDO_TRANSLITERATE );
    1946             : }
    1947             : 
    1948           2 : void ScUndoTransliterate::Undo()
    1949             : {
    1950           2 :     BeginUndo();
    1951             : 
    1952           2 :     ScDocument& rDoc = pDocShell->GetDocument();
    1953           2 :     SCTAB nTabCount = rDoc.GetTableCount();
    1954           2 :     ScRange aCopyRange = aBlockRange;
    1955           2 :     aCopyRange.aStart.SetTab(0);
    1956           2 :     aCopyRange.aEnd.SetTab(nTabCount-1);
    1957           2 :     pUndoDoc->CopyToDocument( aCopyRange, IDF_CONTENTS, true, &rDoc, &aMarkData );
    1958           2 :     pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
    1959             : 
    1960           2 :     EndUndo();
    1961           2 : }
    1962             : 
    1963           2 : void ScUndoTransliterate::Redo()
    1964             : {
    1965           2 :     BeginRedo();
    1966             : 
    1967           2 :     ScDocument& rDoc = pDocShell->GetDocument();
    1968           2 :     rDoc.TransliterateText( aMarkData, nTransliterationType );
    1969           2 :     pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
    1970             : 
    1971           2 :     EndRedo();
    1972           2 : }
    1973             : 
    1974           0 : void ScUndoTransliterate::Repeat(SfxRepeatTarget& rTarget)
    1975             : {
    1976           0 :     if (rTarget.ISA(ScTabViewTarget))
    1977           0 :         static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->TransliterateText( nTransliterationType );
    1978           0 : }
    1979             : 
    1980           0 : bool ScUndoTransliterate::CanRepeat(SfxRepeatTarget& rTarget) const
    1981             : {
    1982           0 :     return rTarget.ISA(ScTabViewTarget);
    1983             : }
    1984             : 
    1985           0 : ScUndoClearItems::ScUndoClearItems( ScDocShell* pNewDocShell, const ScMarkData& rMark,
    1986             :                             ScDocument* pNewUndoDoc, const sal_uInt16* pW ) :
    1987             :     ScBlockUndo( pNewDocShell, lcl_GetMultiMarkRange(rMark), SC_UNDO_AUTOHEIGHT ),
    1988             :     aMarkData( rMark ),
    1989             :     pUndoDoc( pNewUndoDoc ),
    1990           0 :     pWhich( NULL )
    1991             : {
    1992             :     OSL_ENSURE( pW, "ScUndoClearItems: Which-Pointer ist 0" );
    1993             : 
    1994           0 :     sal_uInt16 nCount = 0;
    1995           0 :     while ( pW[nCount] )
    1996           0 :         ++nCount;
    1997           0 :     pWhich = new sal_uInt16[nCount+1];
    1998           0 :     for (sal_uInt16 i=0; i<=nCount; i++)
    1999           0 :         pWhich[i] = pW[i];
    2000           0 : }
    2001             : 
    2002           0 : ScUndoClearItems::~ScUndoClearItems()
    2003             : {
    2004           0 :     delete pUndoDoc;
    2005           0 :     delete pWhich;
    2006           0 : }
    2007             : 
    2008           0 : OUString ScUndoClearItems::GetComment() const
    2009             : {
    2010           0 :     return ScGlobal::GetRscString( STR_UNDO_DELETECONTENTS );
    2011             : }
    2012             : 
    2013           0 : void ScUndoClearItems::Undo()
    2014             : {
    2015           0 :     BeginUndo();
    2016             : 
    2017           0 :     ScDocument& rDoc = pDocShell->GetDocument();
    2018           0 :     pUndoDoc->CopyToDocument( aBlockRange, IDF_ATTRIB, true, &rDoc, &aMarkData );
    2019           0 :     pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
    2020             : 
    2021           0 :     EndUndo();
    2022           0 : }
    2023             : 
    2024           0 : void ScUndoClearItems::Redo()
    2025             : {
    2026           0 :     BeginRedo();
    2027             : 
    2028           0 :     ScDocument& rDoc = pDocShell->GetDocument();
    2029           0 :     rDoc.ClearSelectionItems( pWhich, aMarkData );
    2030           0 :     pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
    2031             : 
    2032           0 :     EndRedo();
    2033           0 : }
    2034             : 
    2035           0 : void ScUndoClearItems::Repeat(SfxRepeatTarget& rTarget)
    2036             : {
    2037           0 :     if (rTarget.ISA(ScTabViewTarget))
    2038             :     {
    2039           0 :         ScViewData& rViewData = static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->GetViewData();
    2040           0 :         rViewData.GetDocFunc().ClearItems( rViewData.GetMarkData(), pWhich, false );
    2041             :     }
    2042           0 : }
    2043             : 
    2044           0 : bool ScUndoClearItems::CanRepeat(SfxRepeatTarget& rTarget) const
    2045             : {
    2046           0 :     return rTarget.ISA(ScTabViewTarget);
    2047             : }
    2048             : 
    2049             : // remove all line breaks of a table
    2050           0 : ScUndoRemoveBreaks::ScUndoRemoveBreaks( ScDocShell* pNewDocShell,
    2051             :                                     SCTAB nNewTab, ScDocument* pNewUndoDoc ) :
    2052             :     ScSimpleUndo( pNewDocShell ),
    2053             :     nTab( nNewTab ),
    2054           0 :     pUndoDoc( pNewUndoDoc )
    2055             : {
    2056           0 : }
    2057             : 
    2058           0 : ScUndoRemoveBreaks::~ScUndoRemoveBreaks()
    2059             : {
    2060           0 :     delete pUndoDoc;
    2061           0 : }
    2062             : 
    2063           0 : OUString ScUndoRemoveBreaks::GetComment() const
    2064             : {
    2065           0 :     return ScGlobal::GetRscString( STR_UNDO_REMOVEBREAKS );
    2066             : }
    2067             : 
    2068           0 : void ScUndoRemoveBreaks::Undo()
    2069             : {
    2070           0 :     BeginUndo();
    2071             : 
    2072           0 :     ScDocument& rDoc = pDocShell->GetDocument();
    2073           0 :     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
    2074             : 
    2075           0 :     pUndoDoc->CopyToDocument( 0,0,nTab, MAXCOL,MAXROW,nTab, IDF_NONE, false, &rDoc );
    2076           0 :     if (pViewShell)
    2077           0 :         pViewShell->UpdatePageBreakData( true );
    2078           0 :     pDocShell->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
    2079             : 
    2080           0 :     EndUndo();
    2081           0 : }
    2082             : 
    2083           0 : void ScUndoRemoveBreaks::Redo()
    2084             : {
    2085           0 :     BeginRedo();
    2086             : 
    2087           0 :     ScDocument& rDoc = pDocShell->GetDocument();
    2088           0 :     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
    2089             : 
    2090           0 :     rDoc.RemoveManualBreaks(nTab);
    2091           0 :     rDoc.UpdatePageBreaks(nTab);
    2092           0 :     if (pViewShell)
    2093           0 :         pViewShell->UpdatePageBreakData( true );
    2094           0 :     pDocShell->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
    2095             : 
    2096           0 :     EndRedo();
    2097           0 : }
    2098             : 
    2099           0 : void ScUndoRemoveBreaks::Repeat(SfxRepeatTarget& rTarget)
    2100             : {
    2101           0 :     if (rTarget.ISA(ScTabViewTarget))
    2102             :     {
    2103           0 :         ScTabViewShell& rViewShell = *static_cast<ScTabViewTarget&>(rTarget).GetViewShell();
    2104           0 :         rViewShell.RemoveManualBreaks();
    2105             :     }
    2106           0 : }
    2107             : 
    2108           0 : bool ScUndoRemoveBreaks::CanRepeat(SfxRepeatTarget& rTarget) const
    2109             : {
    2110           0 :     return rTarget.ISA(ScTabViewTarget);
    2111             : }
    2112             : 
    2113          12 : ScUndoRemoveMerge::ScUndoRemoveMerge( ScDocShell* pNewDocShell,
    2114             :                                       const ScCellMergeOption& rOption, ScDocument* pNewUndoDoc ) :
    2115             :     ScBlockUndo( pNewDocShell, rOption.getFirstSingleRange(), SC_UNDO_SIMPLE ),
    2116             :     maOption(rOption),
    2117          12 :     pUndoDoc( pNewUndoDoc )
    2118             : {
    2119          12 : }
    2120             : 
    2121          36 : ScUndoRemoveMerge::~ScUndoRemoveMerge()
    2122             : {
    2123          12 :     delete pUndoDoc;
    2124          24 : }
    2125             : 
    2126          20 : OUString ScUndoRemoveMerge::GetComment() const
    2127             : {
    2128          20 :     return ScGlobal::GetRscString( STR_UNDO_REMERGE );  // "remove merge"
    2129             : }
    2130             : 
    2131           0 : void ScUndoRemoveMerge::Undo()
    2132             : {
    2133             :     using ::std::set;
    2134             : 
    2135           0 :     SetCurTab();
    2136           0 :     BeginUndo();
    2137             : 
    2138           0 :     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
    2139             : 
    2140           0 :     ScDocument& rDoc = pDocShell->GetDocument();
    2141           0 :     for (set<SCTAB>::const_iterator itr = maOption.maTabs.begin(), itrEnd = maOption.maTabs.end();
    2142             :           itr != itrEnd; ++itr)
    2143             :     {
    2144             :         OSL_ENSURE(pUndoDoc, "NULL pUndoDoc!");
    2145           0 :         if (!pUndoDoc)
    2146           0 :             continue;
    2147             :         // There is no need to extend merge area because it's already been extended.
    2148           0 :         ScRange aRange = maOption.getSingleRange(*itr);
    2149           0 :         rDoc.DeleteAreaTab(aRange, IDF_ATTRIB);
    2150           0 :         pUndoDoc->CopyToDocument(aRange, IDF_ATTRIB, false, &rDoc);
    2151             : 
    2152           0 :         bool bDidPaint = false;
    2153           0 :         if ( pViewShell )
    2154             :         {
    2155           0 :             pViewShell->SetTabNo(*itr);
    2156           0 :             bDidPaint = pViewShell->AdjustRowHeight(maOption.mnStartRow, maOption.mnEndRow);
    2157             :         }
    2158           0 :         if (!bDidPaint)
    2159           0 :             ScUndoUtil::PaintMore(pDocShell, aRange);
    2160             :     }
    2161             : 
    2162           0 :     EndUndo();
    2163           0 : }
    2164             : 
    2165           0 : void ScUndoRemoveMerge::Redo()
    2166             : {
    2167             :     using ::std::set;
    2168             : 
    2169           0 :     SetCurTab();
    2170           0 :     BeginRedo();
    2171             : 
    2172           0 :     ScDocument& rDoc = pDocShell->GetDocument();
    2173           0 :     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
    2174             : 
    2175           0 :     for (set<SCTAB>::const_iterator itr = maOption.maTabs.begin(), itrEnd = maOption.maTabs.end();
    2176             :           itr != itrEnd; ++itr)
    2177             :     {
    2178           0 :         SCTAB nTab = *itr;
    2179             :         // There is no need to extend merge area because it's already been extended.
    2180           0 :         ScRange aRange = maOption.getSingleRange(nTab);
    2181             : 
    2182           0 :         const SfxPoolItem& rDefAttr = rDoc.GetPool()->GetDefaultItem( ATTR_MERGE );
    2183           0 :         ScPatternAttr aPattern( rDoc.GetPool() );
    2184           0 :         aPattern.GetItemSet().Put( rDefAttr );
    2185             :         rDoc.ApplyPatternAreaTab( maOption.mnStartCol, maOption.mnStartRow,
    2186             :                                    maOption.mnEndCol, maOption.mnEndRow, nTab,
    2187           0 :                                    aPattern );
    2188             : 
    2189             :         rDoc.RemoveFlagsTab( maOption.mnStartCol, maOption.mnStartRow,
    2190             :                               maOption.mnEndCol, maOption.mnEndRow, nTab,
    2191           0 :                               SC_MF_HOR | SC_MF_VER );
    2192             : 
    2193           0 :         rDoc.ExtendMerge(aRange, true);
    2194             : 
    2195             :         //  Paint
    2196             : 
    2197           0 :         bool bDidPaint = false;
    2198           0 :         if ( pViewShell )
    2199             :         {
    2200           0 :             pViewShell->SetTabNo(nTab);
    2201           0 :             bDidPaint = pViewShell->AdjustRowHeight(maOption.mnStartRow, maOption.mnEndRow);
    2202             :         }
    2203           0 :         if (!bDidPaint)
    2204           0 :             ScUndoUtil::PaintMore(pDocShell, aRange);
    2205           0 :     }
    2206             : 
    2207           0 :     EndRedo();
    2208           0 : }
    2209             : 
    2210           0 : void ScUndoRemoveMerge::Repeat(SfxRepeatTarget& rTarget)
    2211             : {
    2212           0 :     if (rTarget.ISA(ScTabViewTarget))
    2213           0 :         static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->RemoveMerge();
    2214           0 : }
    2215             : 
    2216           4 : bool ScUndoRemoveMerge::CanRepeat(SfxRepeatTarget& rTarget) const
    2217             : {
    2218           4 :     return rTarget.ISA(ScTabViewTarget);
    2219             : }
    2220             : 
    2221           0 : void ScUndoRemoveMerge::SetCurTab()
    2222             : {
    2223           0 :     SCTAB nCurTab = ScDocShell::GetCurTab();
    2224           0 :     aBlockRange.aStart.SetTab(nCurTab);
    2225           0 :     aBlockRange.aEnd.SetTab(nCurTab);
    2226           0 : }
    2227             : 
    2228             : /** set only border, for ScRangeList (StarOne) */
    2229           8 : static ScRange lcl_TotalRange( const ScRangeList& rRanges )
    2230             : {
    2231           8 :     ScRange aTotal;
    2232           8 :     if ( !rRanges.empty() )
    2233             :     {
    2234           8 :         aTotal = *rRanges[ 0 ];
    2235           8 :         for ( size_t i = 1, nCount = rRanges.size(); i < nCount; ++i )
    2236             :         {
    2237           0 :             ScRange aRange = *rRanges[ i ];
    2238           0 :             if (aRange.aStart.Col() < aTotal.aStart.Col()) aTotal.aStart.SetCol(aRange.aStart.Col());
    2239           0 :             if (aRange.aStart.Row() < aTotal.aStart.Row()) aTotal.aStart.SetRow(aRange.aStart.Row());
    2240           0 :             if (aRange.aStart.Tab() < aTotal.aStart.Tab()) aTotal.aStart.SetTab(aRange.aStart.Tab());
    2241           0 :             if (aRange.aEnd.Col()   > aTotal.aEnd.Col()  ) aTotal.aEnd.SetCol(  aRange.aEnd.Col()  );
    2242           0 :             if (aRange.aEnd.Row()   > aTotal.aEnd.Row()  ) aTotal.aEnd.SetRow(  aRange.aEnd.Row()  );
    2243           0 :             if (aRange.aEnd.Tab()   > aTotal.aEnd.Tab()  ) aTotal.aEnd.SetTab(aRange.aEnd.Tab()    );
    2244             :         }
    2245             :     }
    2246           8 :     return aTotal;
    2247             : }
    2248             : 
    2249           8 : ScUndoBorder::ScUndoBorder( ScDocShell* pNewDocShell,
    2250             :                             const ScRangeList& rRangeList, ScDocument* pNewUndoDoc,
    2251             :                             const SvxBoxItem& rNewOuter, const SvxBoxInfoItem& rNewInner ) :
    2252             :     ScBlockUndo( pNewDocShell, lcl_TotalRange(rRangeList), SC_UNDO_SIMPLE ),
    2253           8 :     pUndoDoc( pNewUndoDoc )
    2254             : {
    2255           8 :     pRanges = new ScRangeList(rRangeList);
    2256           8 :     pOuter = new SvxBoxItem(rNewOuter);
    2257           8 :     pInner = new SvxBoxInfoItem(rNewInner);
    2258           8 : }
    2259             : 
    2260          24 : ScUndoBorder::~ScUndoBorder()
    2261             : {
    2262           8 :     delete pUndoDoc;
    2263           8 :     delete pRanges;
    2264           8 :     delete pOuter;
    2265           8 :     delete pInner;
    2266          16 : }
    2267             : 
    2268           8 : OUString ScUndoBorder::GetComment() const
    2269             : {
    2270           8 :     return ScGlobal::GetRscString( STR_UNDO_SELATTRLINES );     //! eigener String?
    2271             : }
    2272             : 
    2273           0 : void ScUndoBorder::Undo()
    2274             : {
    2275           0 :     BeginUndo();
    2276             : 
    2277           0 :     ScDocument& rDoc = pDocShell->GetDocument();
    2278           0 :     ScMarkData aMarkData;
    2279           0 :     aMarkData.MarkFromRangeList( *pRanges, false );
    2280           0 :     pUndoDoc->CopyToDocument( aBlockRange, IDF_ATTRIB, true, &rDoc, &aMarkData );
    2281           0 :     pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
    2282             : 
    2283           0 :     EndUndo();
    2284           0 : }
    2285             : 
    2286           0 : void ScUndoBorder::Redo()
    2287             : {
    2288           0 :     BeginRedo();
    2289             : 
    2290           0 :     ScDocument& rDoc = pDocShell->GetDocument();        // call function at docfunc
    2291           0 :     size_t nCount = pRanges->size();
    2292           0 :     for (size_t i = 0; i < nCount; ++i )
    2293             :     {
    2294           0 :         ScRange aRange = *(*pRanges)[i];
    2295           0 :         SCTAB nTab = aRange.aStart.Tab();
    2296             : 
    2297           0 :         ScMarkData aMark;
    2298           0 :         aMark.SetMarkArea( aRange );
    2299           0 :         aMark.SelectTable( nTab, true );
    2300             : 
    2301           0 :         rDoc.ApplySelectionFrame( aMark, pOuter, pInner );
    2302           0 :     }
    2303           0 :     for (size_t i = 0; i < nCount; ++i)
    2304           0 :         pDocShell->PostPaint( *(*pRanges)[i], PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
    2305             : 
    2306           0 :     EndRedo();
    2307           0 : }
    2308             : 
    2309           0 : void ScUndoBorder::Repeat(SfxRepeatTarget& /* rTarget */)
    2310             : {
    2311             :     //TODO later (when the function has moved from cellsuno to docfunc)
    2312           0 : }
    2313             : 
    2314           0 : bool ScUndoBorder::CanRepeat(SfxRepeatTarget& /* rTarget */) const
    2315             : {
    2316           0 :     return false;   // See above
    2317         228 : }
    2318             : 
    2319             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10