LCOV - code coverage report
Current view: top level - sc/source/ui/docshell - docfunc.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1904 3099 61.4 %
Date: 2014-11-03 Functions: 65 90 72.2 %
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             : 
      22             : #include <sfx2/app.hxx>
      23             : #include <editeng/editobj.hxx>
      24             : #include <sfx2/linkmgr.hxx>
      25             : #include <sfx2/bindings.hxx>
      26             : #include <vcl/msgbox.hxx>
      27             : #include <vcl/virdev.hxx>
      28             : #include <vcl/waitobj.hxx>
      29             : #include <svl/PasswordHelper.hxx>
      30             : 
      31             : #include <com/sun/star/container/XNameContainer.hpp>
      32             : #include <com/sun/star/script/ModuleType.hpp>
      33             : #include <com/sun/star/script/XLibraryContainer.hpp>
      34             : #include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
      35             : 
      36             : #include "docfunc.hxx"
      37             : 
      38             : #include "sc.hrc"
      39             : 
      40             : #include "arealink.hxx"
      41             : #include "attrib.hxx"
      42             : #include "dociter.hxx"
      43             : #include "autoform.hxx"
      44             : #include "formulacell.hxx"
      45             : #include "cellmergeoption.hxx"
      46             : #include "detdata.hxx"
      47             : #include "detfunc.hxx"
      48             : #include "docpool.hxx"
      49             : #include "docsh.hxx"
      50             : #include "drwlayer.hxx"
      51             : #include "editutil.hxx"
      52             : #include "globstr.hrc"
      53             : #include "globalnames.hxx"
      54             : #include "olinetab.hxx"
      55             : #include "patattr.hxx"
      56             : #include "rangenam.hxx"
      57             : #include "rangeutl.hxx"
      58             : #include "refundo.hxx"
      59             : #include "scresid.hxx"
      60             : #include "stlpool.hxx"
      61             : #include "stlsheet.hxx"
      62             : #include "tablink.hxx"
      63             : #include "tabvwsh.hxx"
      64             : #include "uiitems.hxx"
      65             : #include "undoblk.hxx"
      66             : #include "undocell.hxx"
      67             : #include "undodraw.hxx"
      68             : #include "undotab.hxx"
      69             : #include "waitoff.hxx"
      70             : #include "sizedev.hxx"
      71             : #include "scmod.hxx"
      72             : #include "inputhdl.hxx"
      73             : #include "inputwin.hxx"
      74             : #include "editable.hxx"
      75             : #include "compiler.hxx"
      76             : #include "scui_def.hxx"
      77             : #include "tabprotection.hxx"
      78             : #include "clipparam.hxx"
      79             : #include "externalrefmgr.hxx"
      80             : #include "undorangename.hxx"
      81             : #include "progress.hxx"
      82             : #include "dpobject.hxx"
      83             : #include "stringutil.hxx"
      84             : #include "cellvalue.hxx"
      85             : #include "tokenarray.hxx"
      86             : #include <rowheightcontext.hxx>
      87             : #include <cellvalues.hxx>
      88             : #include <undoconvert.hxx>
      89             : #include <docfuncutil.hxx>
      90             : 
      91             : #include <memory>
      92             : #include <utility>
      93             : #include <basic/basmgr.hxx>
      94             : #include <boost/scoped_array.hpp>
      95             : #include <boost/scoped_ptr.hpp>
      96             : #include <set>
      97             : #include <vector>
      98             : 
      99             : using namespace com::sun::star;
     100             : using ::com::sun::star::uno::Sequence;
     101             : using ::std::vector;
     102             : 
     103             : // STATIC DATA -----------------------------------------------------------
     104             : 
     105         196 : IMPL_LINK( ScDocFunc, NotifyDrawUndo, SdrUndoAction*, pUndoAction )
     106             : {
     107             :     // #i101118# if drawing layer collects the undo actions, add it there
     108          98 :     ScDrawLayer* pDrawLayer = rDocShell.GetDocument().GetDrawLayer();
     109          98 :     if( pDrawLayer && pDrawLayer->IsRecording() )
     110           0 :         pDrawLayer->AddCalcUndo( pUndoAction );
     111             :     else
     112          98 :         rDocShell.GetUndoManager()->AddUndoAction( new ScUndoDraw( pUndoAction, &rDocShell ) );
     113          98 :     rDocShell.SetDrawModified();
     114             : 
     115             :     // the affected sheet isn't known, so all stream positions are invalidated
     116          98 :     ScDocument& rDoc = rDocShell.GetDocument();
     117          98 :     SCTAB nTabCount = rDoc.GetTableCount();
     118         352 :     for (SCTAB nTab=0; nTab<nTabCount; nTab++)
     119         254 :         if (rDoc.IsStreamValid(nTab))
     120           0 :             rDoc.SetStreamValid(nTab, false);
     121             : 
     122          98 :     return 0;
     123             : }
     124             : 
     125             : //  Zeile ueber dem Range painten (fuer Linien nach AdjustRowHeight)
     126             : 
     127          28 : static void lcl_PaintAbove( ScDocShell& rDocShell, const ScRange& rRange )
     128             : {
     129          28 :     SCROW nRow = rRange.aStart.Row();
     130          28 :     if ( nRow > 0 )
     131             :     {
     132           8 :         SCTAB nTab = rRange.aStart.Tab();   //! alle?
     133           8 :         --nRow;
     134           8 :         rDocShell.PostPaint( ScRange(0,nRow,nTab, MAXCOL,nRow,nTab), PAINT_GRID );
     135             :     }
     136          28 : }
     137             : 
     138        5842 : bool ScDocFunc::AdjustRowHeight( const ScRange& rRange, bool bPaint )
     139             : {
     140        5842 :     ScDocument& rDoc = rDocShell.GetDocument();
     141        5842 :     if ( rDoc.IsImportingXML() )
     142             :     {
     143             :         //  for XML import, all row heights are updated together after importing
     144        4406 :         return false;
     145             :     }
     146        1436 :     if ( !rDoc.IsAdjustHeightEnabled() )
     147             :     {
     148           0 :         return false;
     149             :     }
     150             : 
     151        1436 :     SCTAB nTab      = rRange.aStart.Tab();
     152        1436 :     SCROW nStartRow = rRange.aStart.Row();
     153        1436 :     SCROW nEndRow   = rRange.aEnd.Row();
     154             : 
     155        1436 :     ScSizeDeviceProvider aProv( &rDocShell );
     156        1436 :     Fraction aOne(1,1);
     157             : 
     158        2872 :     sc::RowHeightContext aCxt(aProv.GetPPTX(), aProv.GetPPTY(), aOne, aOne, aProv.GetDevice());
     159        1436 :     bool bChanged = rDoc.SetOptimalHeight(aCxt, nStartRow, nEndRow, nTab);
     160             : 
     161        1436 :     if ( bPaint && bChanged )
     162             :         rDocShell.PostPaint(ScRange(0, nStartRow, nTab, MAXCOL, MAXROW, nTab),
     163         144 :                             PAINT_GRID | PAINT_LEFT);
     164             : 
     165        2872 :     return bChanged;
     166             : }
     167             : 
     168           2 : bool ScDocFunc::DetectiveAddPred(const ScAddress& rPos)
     169             : {
     170           2 :     ScDocShellModificator aModificator( rDocShell );
     171             : 
     172           2 :     rDocShell.MakeDrawLayer();
     173           2 :     ScDocument& rDoc = rDocShell.GetDocument();
     174           2 :     bool bUndo (rDoc.IsUndoEnabled());
     175           2 :     ScDrawLayer* pModel = rDoc.GetDrawLayer();
     176           2 :     SCCOL nCol = rPos.Col();
     177           2 :     SCROW nRow = rPos.Row();
     178           2 :     SCTAB nTab = rPos.Tab();
     179             : 
     180           2 :     if (bUndo)
     181           2 :         pModel->BeginCalcUndo(false);
     182           2 :     bool bDone = ScDetectiveFunc( &rDoc,nTab ).ShowPred( nCol, nRow );
     183           2 :     SdrUndoGroup* pUndo = NULL;
     184           2 :     if (bUndo)
     185           2 :         pUndo = pModel->GetCalcUndo();
     186           2 :     if (bDone)
     187             :     {
     188           2 :         ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_ADDPRED );
     189           2 :         rDoc.AddDetectiveOperation( aOperation );
     190           2 :         if (bUndo)
     191             :         {
     192           2 :             rDocShell.GetUndoManager()->AddUndoAction(
     193           2 :                         new ScUndoDetective( &rDocShell, pUndo, &aOperation ) );
     194             :         }
     195           2 :         aModificator.SetDocumentModified();
     196           2 :         SfxBindings* pBindings = rDocShell.GetViewBindings();
     197           2 :         if (pBindings)
     198           2 :             pBindings->Invalidate( SID_DETECTIVE_REFRESH );
     199             :     }
     200             :     else
     201           0 :         delete pUndo;
     202             : 
     203           2 :     return bDone;
     204             : }
     205             : 
     206           0 : bool ScDocFunc::DetectiveDelPred(const ScAddress& rPos)
     207             : {
     208           0 :     ScDocument& rDoc = rDocShell.GetDocument();
     209             : 
     210           0 :     bool bUndo(rDoc.IsUndoEnabled());
     211           0 :     ScDrawLayer* pModel = rDoc.GetDrawLayer();
     212           0 :     if (!pModel)
     213           0 :         return false;
     214             : 
     215           0 :     ScDocShellModificator aModificator( rDocShell );
     216             : 
     217           0 :     SCCOL nCol = rPos.Col();
     218           0 :     SCROW nRow = rPos.Row();
     219           0 :     SCTAB nTab = rPos.Tab();
     220             : 
     221           0 :     if (bUndo)
     222           0 :         pModel->BeginCalcUndo(false);
     223           0 :     bool bDone = ScDetectiveFunc( &rDoc,nTab ).DeletePred( nCol, nRow );
     224           0 :     SdrUndoGroup* pUndo = NULL;
     225           0 :     if (bUndo)
     226           0 :         pUndo = pModel->GetCalcUndo();
     227           0 :     if (bDone)
     228             :     {
     229           0 :         ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_DELPRED );
     230           0 :         rDoc.AddDetectiveOperation( aOperation );
     231           0 :         if (bUndo)
     232             :         {
     233           0 :             rDocShell.GetUndoManager()->AddUndoAction(
     234           0 :                         new ScUndoDetective( &rDocShell, pUndo, &aOperation ) );
     235             :         }
     236           0 :         aModificator.SetDocumentModified();
     237           0 :         SfxBindings* pBindings = rDocShell.GetViewBindings();
     238           0 :         if (pBindings)
     239           0 :             pBindings->Invalidate( SID_DETECTIVE_REFRESH );
     240             :     }
     241             :     else
     242           0 :         delete pUndo;
     243             : 
     244           0 :     return bDone;
     245             : }
     246             : 
     247           0 : bool ScDocFunc::DetectiveAddSucc(const ScAddress& rPos)
     248             : {
     249           0 :     ScDocShellModificator aModificator( rDocShell );
     250             : 
     251           0 :     rDocShell.MakeDrawLayer();
     252           0 :     ScDocument& rDoc = rDocShell.GetDocument();
     253             : 
     254           0 :     bool bUndo(rDoc.IsUndoEnabled());
     255           0 :     ScDrawLayer* pModel = rDoc.GetDrawLayer();
     256           0 :     SCCOL nCol = rPos.Col();
     257           0 :     SCROW nRow = rPos.Row();
     258           0 :     SCTAB nTab = rPos.Tab();
     259             : 
     260           0 :     if (bUndo)
     261           0 :         pModel->BeginCalcUndo(false);
     262           0 :     bool bDone = ScDetectiveFunc( &rDoc,nTab ).ShowSucc( nCol, nRow );
     263           0 :     SdrUndoGroup* pUndo = NULL;
     264           0 :     if (bUndo)
     265           0 :         pUndo = pModel->GetCalcUndo();
     266           0 :     if (bDone)
     267             :     {
     268           0 :         ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_ADDSUCC );
     269           0 :         rDoc.AddDetectiveOperation( aOperation );
     270           0 :         if (bUndo)
     271             :         {
     272           0 :             rDocShell.GetUndoManager()->AddUndoAction(
     273           0 :                         new ScUndoDetective( &rDocShell, pUndo, &aOperation ) );
     274             :         }
     275           0 :         aModificator.SetDocumentModified();
     276           0 :         SfxBindings* pBindings = rDocShell.GetViewBindings();
     277           0 :         if (pBindings)
     278           0 :             pBindings->Invalidate( SID_DETECTIVE_REFRESH );
     279             :     }
     280             :     else
     281           0 :         delete pUndo;
     282             : 
     283           0 :     return bDone;
     284             : }
     285             : 
     286           0 : bool ScDocFunc::DetectiveDelSucc(const ScAddress& rPos)
     287             : {
     288           0 :     ScDocument& rDoc = rDocShell.GetDocument();
     289             : 
     290           0 :     bool bUndo (rDoc.IsUndoEnabled());
     291           0 :     ScDrawLayer* pModel = rDoc.GetDrawLayer();
     292           0 :     if (!pModel)
     293           0 :         return false;
     294             : 
     295           0 :     ScDocShellModificator aModificator( rDocShell );
     296             : 
     297           0 :     SCCOL nCol = rPos.Col();
     298           0 :     SCROW nRow = rPos.Row();
     299           0 :     SCTAB nTab = rPos.Tab();
     300             : 
     301           0 :     if (bUndo)
     302           0 :         pModel->BeginCalcUndo(false);
     303           0 :     bool bDone = ScDetectiveFunc( &rDoc,nTab ).DeleteSucc( nCol, nRow );
     304           0 :     SdrUndoGroup* pUndo = NULL;
     305           0 :     if (bUndo)
     306           0 :         pUndo = pModel->GetCalcUndo();
     307           0 :     if (bDone)
     308             :     {
     309           0 :         ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_DELSUCC );
     310           0 :         rDoc.AddDetectiveOperation( aOperation );
     311           0 :         if (bUndo)
     312             :         {
     313           0 :             rDocShell.GetUndoManager()->AddUndoAction(
     314           0 :                         new ScUndoDetective( &rDocShell, pUndo, &aOperation ) );
     315             :         }
     316           0 :         aModificator.SetDocumentModified();
     317           0 :         SfxBindings* pBindings = rDocShell.GetViewBindings();
     318           0 :         if (pBindings)
     319           0 :             pBindings->Invalidate( SID_DETECTIVE_REFRESH );
     320             :     }
     321             :     else
     322           0 :         delete pUndo;
     323             : 
     324           0 :     return bDone;
     325             : }
     326             : 
     327           0 : bool ScDocFunc::DetectiveAddError(const ScAddress& rPos)
     328             : {
     329           0 :     ScDocShellModificator aModificator( rDocShell );
     330             : 
     331           0 :     rDocShell.MakeDrawLayer();
     332           0 :     ScDocument& rDoc = rDocShell.GetDocument();
     333             : 
     334           0 :     bool bUndo (rDoc.IsUndoEnabled());
     335           0 :     ScDrawLayer* pModel = rDoc.GetDrawLayer();
     336           0 :     SCCOL nCol = rPos.Col();
     337           0 :     SCROW nRow = rPos.Row();
     338           0 :     SCTAB nTab = rPos.Tab();
     339             : 
     340           0 :     if (bUndo)
     341           0 :         pModel->BeginCalcUndo(false);
     342           0 :     bool bDone = ScDetectiveFunc( &rDoc,nTab ).ShowError( nCol, nRow );
     343           0 :     SdrUndoGroup* pUndo = NULL;
     344           0 :     if (bUndo)
     345           0 :         pUndo = pModel->GetCalcUndo();
     346           0 :     if (bDone)
     347             :     {
     348           0 :         ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_ADDERROR );
     349           0 :         rDoc.AddDetectiveOperation( aOperation );
     350           0 :         if (bUndo)
     351             :         {
     352           0 :             rDocShell.GetUndoManager()->AddUndoAction(
     353           0 :                         new ScUndoDetective( &rDocShell, pUndo, &aOperation ) );
     354             :         }
     355           0 :         aModificator.SetDocumentModified();
     356           0 :         SfxBindings* pBindings = rDocShell.GetViewBindings();
     357           0 :         if (pBindings)
     358           0 :             pBindings->Invalidate( SID_DETECTIVE_REFRESH );
     359             :     }
     360             :     else
     361           0 :         delete pUndo;
     362             : 
     363           0 :     return bDone;
     364             : }
     365             : 
     366           0 : bool ScDocFunc::DetectiveMarkInvalid(SCTAB nTab)
     367             : {
     368           0 :     ScDocShellModificator aModificator( rDocShell );
     369             : 
     370           0 :     rDocShell.MakeDrawLayer();
     371           0 :     ScDocument& rDoc = rDocShell.GetDocument();
     372             : 
     373           0 :     bool bUndo (rDoc.IsUndoEnabled());
     374           0 :     ScDrawLayer* pModel = rDoc.GetDrawLayer();
     375             : 
     376           0 :     vcl::Window* pWaitWin = rDocShell.GetActiveDialogParent();
     377           0 :     if (pWaitWin)
     378           0 :         pWaitWin->EnterWait();
     379           0 :     if (bUndo)
     380           0 :         pModel->BeginCalcUndo(false);
     381             :     bool bOverflow;
     382           0 :     bool bDone = ScDetectiveFunc( &rDoc,nTab ).MarkInvalid( bOverflow );
     383           0 :     SdrUndoGroup* pUndo = NULL;
     384           0 :     if (bUndo)
     385           0 :         pUndo = pModel->GetCalcUndo();
     386           0 :     if (pWaitWin)
     387           0 :         pWaitWin->LeaveWait();
     388           0 :     if (bDone)
     389             :     {
     390           0 :         if (pUndo && bUndo)
     391             :         {
     392           0 :             pUndo->SetComment( ScGlobal::GetRscString( STR_UNDO_DETINVALID ) );
     393           0 :             rDocShell.GetUndoManager()->AddUndoAction( pUndo );
     394             :         }
     395           0 :         aModificator.SetDocumentModified();
     396           0 :         if ( bOverflow )
     397             :         {
     398             :             InfoBox( NULL,
     399           0 :                     ScGlobal::GetRscString( STR_DETINVALID_OVERFLOW ) ).Execute();
     400             :         }
     401             :     }
     402             :     else
     403           0 :         delete pUndo;
     404             : 
     405           0 :     return bDone;
     406             : }
     407             : 
     408           0 : bool ScDocFunc::DetectiveDelAll(SCTAB nTab)
     409             : {
     410           0 :     ScDocument& rDoc = rDocShell.GetDocument();
     411             : 
     412           0 :     bool bUndo (rDoc.IsUndoEnabled());
     413           0 :     ScDrawLayer* pModel = rDoc.GetDrawLayer();
     414           0 :     if (!pModel)
     415           0 :         return false;
     416             : 
     417           0 :     ScDocShellModificator aModificator( rDocShell );
     418             : 
     419           0 :     if (bUndo)
     420           0 :         pModel->BeginCalcUndo(false);
     421           0 :     bool bDone = ScDetectiveFunc( &rDoc,nTab ).DeleteAll( SC_DET_DETECTIVE );
     422           0 :     SdrUndoGroup* pUndo = NULL;
     423           0 :     if (bUndo)
     424           0 :         pUndo = pModel->GetCalcUndo();
     425           0 :     if (bDone)
     426             :     {
     427           0 :         ScDetOpList* pOldList = rDoc.GetDetOpList();
     428           0 :         ScDetOpList* pUndoList = NULL;
     429           0 :         if (bUndo)
     430           0 :             pUndoList = pOldList ? new ScDetOpList(*pOldList) : NULL;
     431             : 
     432           0 :         rDoc.ClearDetectiveOperations();
     433             : 
     434           0 :         if (bUndo)
     435             :         {
     436           0 :             rDocShell.GetUndoManager()->AddUndoAction(
     437           0 :                         new ScUndoDetective( &rDocShell, pUndo, NULL, pUndoList ) );
     438             :         }
     439           0 :         aModificator.SetDocumentModified();
     440           0 :         SfxBindings* pBindings = rDocShell.GetViewBindings();
     441           0 :         if (pBindings)
     442           0 :             pBindings->Invalidate( SID_DETECTIVE_REFRESH );
     443             :     }
     444             :     else
     445           0 :         delete pUndo;
     446             : 
     447           0 :     return bDone;
     448             : }
     449             : 
     450         354 : bool ScDocFunc::DetectiveRefresh( bool bAutomatic )
     451             : {
     452         354 :     bool bDone = false;
     453         354 :     ScDocument& rDoc = rDocShell.GetDocument();
     454             : 
     455         354 :     bool bUndo (rDoc.IsUndoEnabled());
     456         354 :     ScDetOpList* pList = rDoc.GetDetOpList();
     457         354 :     if ( pList && pList->Count() )
     458             :     {
     459          26 :         rDocShell.MakeDrawLayer();
     460          26 :         ScDrawLayer* pModel = rDoc.GetDrawLayer();
     461          26 :         if (bUndo)
     462          26 :             pModel->BeginCalcUndo(false);
     463             : 
     464             :         //  Loeschen auf allen Tabellen
     465             : 
     466          26 :         SCTAB nTabCount = rDoc.GetTableCount();
     467          78 :         for (SCTAB nTab=0; nTab<nTabCount; nTab++)
     468          52 :             ScDetectiveFunc( &rDoc,nTab ).DeleteAll( SC_DET_ARROWS );    // don't remove circles
     469             : 
     470             :         //  Wiederholen
     471             : 
     472          26 :         size_t nCount = pList->Count();
     473          52 :         for (size_t i=0; i < nCount; ++i)
     474             :         {
     475          26 :             const ScDetOpData* pData = pList->GetObject(i);
     476          26 :             if (pData)
     477             :             {
     478          26 :                 ScAddress aPos = pData->GetPos();
     479          26 :                 ScDetectiveFunc aFunc( &rDoc, aPos.Tab() );
     480          26 :                 SCCOL nCol = aPos.Col();
     481          26 :                 SCROW nRow = aPos.Row();
     482          26 :                 switch (pData->GetOperation())
     483             :                 {
     484             :                     case SCDETOP_ADDSUCC:
     485           0 :                         aFunc.ShowSucc( nCol, nRow );
     486           0 :                         break;
     487             :                     case SCDETOP_DELSUCC:
     488           0 :                         aFunc.DeleteSucc( nCol, nRow );
     489           0 :                         break;
     490             :                     case SCDETOP_ADDPRED:
     491          26 :                         aFunc.ShowPred( nCol, nRow );
     492          26 :                         break;
     493             :                     case SCDETOP_DELPRED:
     494           0 :                         aFunc.DeletePred( nCol, nRow );
     495           0 :                         break;
     496             :                     case SCDETOP_ADDERROR:
     497           0 :                         aFunc.ShowError( nCol, nRow );
     498           0 :                         break;
     499             :                     default:
     500             :                         OSL_FAIL("falsche Op bei DetectiveRefresh");
     501             :                 }
     502             :             }
     503             :         }
     504             : 
     505          26 :         if (bUndo)
     506             :         {
     507          26 :             SdrUndoGroup* pUndo = pModel->GetCalcUndo();
     508          26 :             if (pUndo)
     509             :             {
     510          26 :                 pUndo->SetComment( ScGlobal::GetRscString( STR_UNDO_DETREFRESH ) );
     511             :                 //  wenn automatisch, an letzte Aktion anhaengen
     512          26 :                 rDocShell.GetUndoManager()->AddUndoAction(
     513          26 :                                                 new ScUndoDraw( pUndo, &rDocShell ),
     514          52 :                                                 bAutomatic );
     515             :             }
     516             :         }
     517          26 :         rDocShell.SetDrawModified();
     518          26 :         bDone = true;
     519             :     }
     520         354 :     return bDone;
     521             : }
     522             : 
     523           6 : static void lcl_collectAllPredOrSuccRanges(
     524             :     const ScRangeList& rSrcRanges, vector<ScTokenRef>& rRefTokens, ScDocShell& rDocShell,
     525             :     bool bPred)
     526             : {
     527           6 :     ScDocument& rDoc = rDocShell.GetDocument();
     528           6 :     vector<ScTokenRef> aRefTokens;
     529          12 :     ScRangeList aSrcRanges(rSrcRanges);
     530           6 :     if (aSrcRanges.empty())
     531           6 :         return;
     532           6 :     ScRange* p = aSrcRanges.front();
     533           6 :     ScDetectiveFunc aDetFunc(&rDoc, p->aStart.Tab());
     534          12 :     ScRangeList aDestRanges;
     535          12 :     for (size_t i = 0, n = aSrcRanges.size(); i < n; ++i)
     536             :     {
     537           6 :         p = aSrcRanges[i];
     538           6 :         if (bPred)
     539             :         {
     540             :             aDetFunc.GetAllPreds(
     541           4 :                 p->aStart.Col(), p->aStart.Row(), p->aEnd.Col(), p->aEnd.Row(), aRefTokens);
     542             :         }
     543             :         else
     544             :         {
     545             :             aDetFunc.GetAllSuccs(
     546           2 :                 p->aStart.Col(), p->aStart.Row(), p->aEnd.Col(), p->aEnd.Row(), aRefTokens);
     547             :         }
     548             :     }
     549          12 :     rRefTokens.swap(aRefTokens);
     550             : }
     551             : 
     552           4 : void ScDocFunc::DetectiveCollectAllPreds(const ScRangeList& rSrcRanges, vector<ScTokenRef>& rRefTokens)
     553             : {
     554           4 :     lcl_collectAllPredOrSuccRanges(rSrcRanges, rRefTokens, rDocShell, true);
     555           4 : }
     556             : 
     557           2 : void ScDocFunc::DetectiveCollectAllSuccs(const ScRangeList& rSrcRanges, vector<ScTokenRef>& rRefTokens)
     558             : {
     559           2 :     lcl_collectAllPredOrSuccRanges(rSrcRanges, rRefTokens, rDocShell, false);
     560           2 : }
     561             : 
     562         164 : bool ScDocFunc::DeleteContents(
     563             :     const ScMarkData& rMark, InsertDeleteFlags nFlags, bool bRecord, bool bApi )
     564             : {
     565         164 :     ScDocShellModificator aModificator( rDocShell );
     566             : 
     567         164 :     if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
     568             :     {
     569             :         OSL_FAIL("ScDocFunc::DeleteContents ohne Markierung");
     570           0 :         return false;
     571             :     }
     572             : 
     573         164 :     ScDocument& rDoc = rDocShell.GetDocument();
     574             : 
     575         164 :     if (bRecord && !rDoc.IsUndoEnabled())
     576           8 :         bRecord = false;
     577             : 
     578         164 :     ScEditableTester aTester( &rDoc, rMark );
     579         164 :     if (!aTester.IsEditable())
     580             :     {
     581           0 :         if (!bApi)
     582           0 :             rDocShell.ErrorMessage(aTester.GetMessageId());
     583           0 :         return false;
     584             :     }
     585             : 
     586         164 :     ScRange aMarkRange;
     587             : 
     588         328 :     ScMarkData aMultiMark = rMark;
     589         164 :     aMultiMark.SetMarking(false);       // fuer MarkToMulti
     590             : 
     591         164 :     ScDocument* pUndoDoc = NULL;
     592         164 :     bool bMulti = aMultiMark.IsMultiMarked();
     593         164 :     aMultiMark.MarkToMulti();
     594         164 :     aMultiMark.GetMultiMarkArea( aMarkRange );
     595         164 :     ScRange aExtendedRange(aMarkRange);
     596         164 :     if ( rDoc.ExtendMerge( aExtendedRange, true ) )
     597           0 :         bMulti = false;
     598             : 
     599             :     // no objects on protected tabs
     600         164 :     bool bObjects = (nFlags & IDF_OBJECTS) && !sc::DocFuncUtil::hasProtectedTab(rDoc, rMark);
     601             : 
     602         164 :     sal_uInt16 nExtFlags = 0;       // extra flags are needed only if attributes are deleted
     603         164 :     if ( nFlags & IDF_ATTRIB )
     604         126 :         rDocShell.UpdatePaintExt( nExtFlags, aMarkRange );
     605             : 
     606             :     //  Reihenfolge:
     607             :     //  1) BeginDrawUndo
     608             :     //  2) Objekte loeschen (DrawUndo wird gefuellt)
     609             :     //  3) Inhalte fuer Undo kopieren und Undo-Aktion anlegen
     610             :     //  4) Inhalte loeschen
     611             : 
     612         164 :     bool bDrawUndo = bObjects || (nFlags & IDF_NOTE);
     613         164 :     if (bRecord && bDrawUndo)
     614          10 :         rDoc.BeginDrawUndo();
     615             : 
     616         164 :     if (bObjects)
     617             :     {
     618           4 :         if (bMulti)
     619           2 :             rDoc.DeleteObjectsInSelection( aMultiMark );
     620             :         else
     621           2 :             rDoc.DeleteObjectsInArea( aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
     622           2 :                                        aMarkRange.aEnd.Col(),   aMarkRange.aEnd.Row(),
     623           6 :                                        aMultiMark );
     624             :     }
     625             : 
     626             :     // To keep track of all non-empty cells within the deleted area.
     627         328 :     boost::shared_ptr<ScSimpleUndo::DataSpansType> pDataSpans;
     628             : 
     629         164 :     if ( bRecord )
     630             :     {
     631         154 :         pUndoDoc = sc::DocFuncUtil::createDeleteContentsUndoDoc(rDoc, aMultiMark, aMarkRange, nFlags, bMulti);
     632         154 :         pDataSpans.reset(sc::DocFuncUtil::getNonEmptyCellSpans(rDoc, aMultiMark, aMarkRange));
     633             :     }
     634             : 
     635         164 :     rDoc.DeleteSelection( nFlags, aMultiMark );
     636             : 
     637             :     // add undo action after drawing undo is complete (objects and note captions)
     638         164 :     if( bRecord )
     639             :     {
     640             :         sc::DocFuncUtil::addDeleteContentsUndo(
     641         154 :             rDocShell.GetUndoManager(), &rDocShell, aMultiMark, aExtendedRange,
     642         308 :             pUndoDoc, nFlags, pDataSpans, bMulti, bDrawUndo);
     643             :     }
     644             : 
     645         164 :     if (!AdjustRowHeight( aExtendedRange ))
     646          98 :         rDocShell.PostPaint( aExtendedRange, PAINT_GRID, nExtFlags );
     647          66 :     else if (nExtFlags & SC_PF_LINES)
     648           0 :         lcl_PaintAbove( rDocShell, aExtendedRange );    // fuer Linien ueber dem Bereich
     649             : 
     650         164 :     aModificator.SetDocumentModified();
     651             : 
     652         328 :     return true;
     653             : }
     654             : 
     655           0 : bool ScDocFunc::DeleteCell(
     656             :     const ScAddress& rPos, const ScMarkData& rMark, InsertDeleteFlags nFlags, bool bRecord, bool bApi )
     657             : {
     658           0 :     ScDocShellModificator aModificator(rDocShell);
     659             : 
     660           0 :     ScDocument& rDoc = rDocShell.GetDocument();
     661             : 
     662           0 :     if (bRecord && !rDoc.IsUndoEnabled())
     663           0 :         bRecord = false;
     664             : 
     665           0 :     ScEditableTester aTester(&rDoc, rPos.Col(), rPos.Row(), rPos.Col(), rPos.Row(), rMark);
     666           0 :     if (!aTester.IsEditable())
     667             :     {
     668           0 :         if (!bApi)
     669           0 :             rDocShell.ErrorMessage(aTester.GetMessageId());
     670           0 :         return false;
     671             :     }
     672             : 
     673             :     // no objects on protected tabs
     674           0 :     bool bObjects = (nFlags & IDF_OBJECTS) && !sc::DocFuncUtil::hasProtectedTab(rDoc, rMark);
     675             : 
     676           0 :     sal_uInt16 nExtFlags = 0;       // extra flags are needed only if attributes are deleted
     677           0 :     if (nFlags & IDF_ATTRIB)
     678           0 :         rDocShell.UpdatePaintExt(nExtFlags, rPos);
     679             : 
     680             :     //  order op opeeration:
     681             :     //  1) BeginDrawUndo
     682             :     //  2) delete objects (DrawUndo is filled)
     683             :     //  3) copy contents for undo
     684             :     //  4) delete contents
     685             :     //  5) add undo-action
     686             : 
     687           0 :     bool bDrawUndo = bObjects || (nFlags & IDF_NOTE);     // needed for shown notes
     688           0 :     if (bDrawUndo && bRecord)
     689           0 :         rDoc.BeginDrawUndo();
     690             : 
     691           0 :     if (bObjects)
     692           0 :         rDoc.DeleteObjectsInArea(rPos.Col(), rPos.Row(), rPos.Col(), rPos.Row(), rMark);
     693             : 
     694             :     // To keep track of all non-empty cells within the deleted area.
     695           0 :     boost::shared_ptr<ScSimpleUndo::DataSpansType> pDataSpans;
     696             : 
     697           0 :     ScDocument* pUndoDoc = NULL;
     698           0 :     if (bRecord)
     699             :     {
     700           0 :         pUndoDoc = sc::DocFuncUtil::createDeleteContentsUndoDoc(rDoc, rMark, rPos, nFlags, false);
     701           0 :         pDataSpans.reset(sc::DocFuncUtil::getNonEmptyCellSpans(rDoc, rMark, rPos));
     702             :     }
     703             : 
     704           0 :     rDoc.DeleteArea(rPos.Col(), rPos.Row(), rPos.Col(), rPos.Row(), rMark, nFlags);
     705             : 
     706           0 :     if (bRecord)
     707             :     {
     708             :         sc::DocFuncUtil::addDeleteContentsUndo(
     709           0 :             rDocShell.GetUndoManager(), &rDocShell, rMark, rPos, pUndoDoc,
     710           0 :             nFlags, pDataSpans, false, bDrawUndo);
     711             :     }
     712             : 
     713           0 :     if (!AdjustRowHeight(rPos))
     714             :         rDocShell.PostPaint(
     715           0 :             rPos.Col(), rPos.Row(), rPos.Tab(), rPos.Col(), rPos.Row(), rPos.Tab(),
     716           0 :             PAINT_GRID, nExtFlags);
     717             : 
     718           0 :     aModificator.SetDocumentModified();
     719             : 
     720           0 :     return true;
     721             : }
     722             : 
     723           2 : bool ScDocFunc::TransliterateText( const ScMarkData& rMark, sal_Int32 nType,
     724             :                                     bool bRecord, bool bApi )
     725             : {
     726           2 :     ScDocShellModificator aModificator( rDocShell );
     727             : 
     728           2 :     ScDocument& rDoc = rDocShell.GetDocument();
     729           2 :     if (bRecord && !rDoc.IsUndoEnabled())
     730           0 :         bRecord = false;
     731             : 
     732           2 :     ScEditableTester aTester( &rDoc, rMark );
     733           2 :     if (!aTester.IsEditable())
     734             :     {
     735           0 :         if (!bApi)
     736           0 :             rDocShell.ErrorMessage(aTester.GetMessageId());
     737           0 :         return false;
     738             :     }
     739             : 
     740           2 :     ScRange aMarkRange;
     741           4 :     ScMarkData aMultiMark = rMark;
     742           2 :     aMultiMark.SetMarking(false);       // for MarkToMulti
     743           2 :     aMultiMark.MarkToMulti();
     744           2 :     aMultiMark.GetMultiMarkArea( aMarkRange );
     745             : 
     746           2 :     if (bRecord)
     747             :     {
     748           2 :         SCTAB nStartTab = aMarkRange.aStart.Tab();
     749           2 :         SCTAB nTabCount = rDoc.GetTableCount();
     750             : 
     751           2 :         ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
     752           2 :         pUndoDoc->InitUndo( &rDoc, nStartTab, nStartTab );
     753           2 :         ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
     754           4 :         for (; itr != itrEnd && *itr < nTabCount; ++itr)
     755           2 :             if (*itr != nStartTab)
     756           0 :                 pUndoDoc->AddUndoTab( *itr, *itr );
     757             : 
     758           2 :         ScRange aCopyRange = aMarkRange;
     759           2 :         aCopyRange.aStart.SetTab(0);
     760           2 :         aCopyRange.aEnd.SetTab(nTabCount-1);
     761           2 :         rDoc.CopyToDocument( aCopyRange, IDF_CONTENTS, true, pUndoDoc, &aMultiMark );
     762             : 
     763           2 :         rDocShell.GetUndoManager()->AddUndoAction(
     764           2 :             new ScUndoTransliterate( &rDocShell, aMultiMark, pUndoDoc, nType ) );
     765             :     }
     766             : 
     767           2 :     rDoc.TransliterateText( aMultiMark, nType );
     768             : 
     769           2 :     if (!AdjustRowHeight( aMarkRange ))
     770           2 :         rDocShell.PostPaint( aMarkRange, PAINT_GRID );
     771             : 
     772           2 :     aModificator.SetDocumentModified();
     773             : 
     774           4 :     return true;
     775             : }
     776             : 
     777        2330 : bool ScDocFunc::SetNormalString( bool& o_rbNumFmtSet, const ScAddress& rPos, const OUString& rText, bool bApi )
     778             : {
     779        2330 :     ScDocShellModificator aModificator( rDocShell );
     780        2330 :     ScDocument& rDoc = rDocShell.GetDocument();
     781             : 
     782        2330 :     bool bUndo(rDoc.IsUndoEnabled());
     783        2330 :     ScEditableTester aTester( &rDoc, rPos.Tab(), rPos.Col(),rPos.Row(), rPos.Col(),rPos.Row() );
     784        2330 :     if (!aTester.IsEditable())
     785             :     {
     786           0 :         if (!bApi)
     787           0 :             rDocShell.ErrorMessage(aTester.GetMessageId());
     788           0 :         return false;
     789             :     }
     790             : 
     791        2330 :     bool bEditDeleted = (rDoc.GetCellType(rPos) == CELLTYPE_EDIT);
     792        4660 :     ScUndoEnterData::ValuesType aOldValues;
     793             : 
     794        2330 :     if (bUndo)
     795             :     {
     796        2330 :         ScUndoEnterData::Value aOldValue;
     797             : 
     798        2330 :         aOldValue.mnTab = rPos.Tab();
     799        2330 :         aOldValue.maCell.assign(rDoc, rPos);
     800             : 
     801             :         const SfxPoolItem* pItem;
     802        2330 :         const ScPatternAttr* pPattern = rDoc.GetPattern( rPos.Col(),rPos.Row(),rPos.Tab() );
     803        4660 :         if ( SfxItemState::SET == pPattern->GetItemSet().GetItemState(
     804        2330 :                                 ATTR_VALUE_FORMAT,false,&pItem) )
     805             :         {
     806           2 :             aOldValue.mbHasFormat = true;
     807           2 :             aOldValue.mnFormat = static_cast<const SfxUInt32Item*>(pItem)->GetValue();
     808             :         }
     809             :         else
     810        2328 :             aOldValue.mbHasFormat = false;
     811             : 
     812        2330 :         aOldValues.push_back(aOldValue);
     813             :     }
     814             : 
     815        2330 :     o_rbNumFmtSet = rDoc.SetString( rPos.Col(), rPos.Row(), rPos.Tab(), rText );
     816             : 
     817        2330 :     if (bUndo)
     818             :     {
     819             :         //  wegen ChangeTracking darf UndoAction erst nach SetString angelegt werden
     820        2330 :         rDocShell.GetUndoManager()->AddUndoAction(
     821        2330 :             new ScUndoEnterData(&rDocShell, rPos, aOldValues, rText, NULL));
     822             :     }
     823             : 
     824        2330 :     if ( bEditDeleted || rDoc.HasAttrib( ScRange(rPos), HASATTR_NEEDHEIGHT ) )
     825          10 :         AdjustRowHeight( ScRange(rPos) );
     826             : 
     827        2330 :     rDocShell.PostPaintCell( rPos );
     828        2330 :     aModificator.SetDocumentModified();
     829             : 
     830             :     // notify input handler here the same way as in PutCell
     831        2330 :     if (bApi)
     832        2330 :         NotifyInputHandler( rPos );
     833             : 
     834        4660 :     return true;
     835             : }
     836             : 
     837        7108 : bool ScDocFunc::SetValueCell( const ScAddress& rPos, double fVal, bool bInteraction )
     838             : {
     839        7108 :     ScDocShellModificator aModificator( rDocShell );
     840        7108 :     ScDocument& rDoc = rDocShell.GetDocument();
     841        7108 :     bool bUndo = rDoc.IsUndoEnabled();
     842             : 
     843        7108 :     bool bHeight = rDoc.HasAttrib(rPos, HASATTR_NEEDHEIGHT);
     844             : 
     845       14216 :     ScCellValue aOldVal;
     846        7108 :     if (bUndo)
     847        7108 :         aOldVal.assign(rDoc, rPos);
     848             : 
     849        7108 :     rDoc.SetValue(rPos, fVal);
     850             : 
     851        7108 :     if (bUndo)
     852             :     {
     853        7108 :         svl::IUndoManager* pUndoMgr = rDocShell.GetUndoManager();
     854        7108 :         ScCellValue aNewVal;
     855        7108 :         aNewVal.assign(rDoc, rPos);
     856        7108 :         pUndoMgr->AddUndoAction(new ScUndoSetCell(&rDocShell, rPos, aOldVal, aNewVal));
     857             :     }
     858             : 
     859        7108 :     if (bHeight)
     860          10 :         AdjustRowHeight(rPos);
     861             : 
     862        7108 :     rDocShell.PostPaintCell( rPos );
     863        7108 :     aModificator.SetDocumentModified();
     864             : 
     865             :     // #103934#; notify editline and cell in edit mode
     866        7108 :     if (!bInteraction)
     867        7108 :         NotifyInputHandler( rPos );
     868             : 
     869       14216 :     return true;
     870             : }
     871             : 
     872           0 : bool ScDocFunc::SetValueCells( const ScAddress& rPos, const std::vector<double>& aVals, bool bInteraction )
     873             : {
     874             :     // Check for invalid range.
     875           0 :     SCROW nLastRow = rPos.Row() + aVals.size() - 1;
     876           0 :     if (nLastRow > MAXROW)
     877             :         // out of bound.
     878           0 :         return false;
     879             : 
     880           0 :     ScRange aRange(rPos);
     881           0 :     aRange.aEnd.SetRow(nLastRow);
     882             : 
     883           0 :     ScDocShellModificator aModificator(rDocShell);
     884           0 :     ScDocument& rDoc = rDocShell.GetDocument();
     885             : 
     886           0 :     if (rDoc.IsUndoEnabled())
     887             :     {
     888           0 :         sc::UndoSetCells* pUndoObj = new sc::UndoSetCells(&rDocShell, rPos);
     889           0 :         rDoc.TransferCellValuesTo(rPos, aVals.size(), pUndoObj->GetOldValues());
     890           0 :         pUndoObj->SetNewValues(aVals);
     891           0 :         svl::IUndoManager* pUndoMgr = rDocShell.GetUndoManager();
     892           0 :         pUndoMgr->AddUndoAction(pUndoObj);
     893             :     }
     894             : 
     895           0 :     rDoc.SetValues(rPos, aVals);
     896             : 
     897           0 :     rDocShell.PostPaint(aRange, PAINT_GRID);
     898           0 :     aModificator.SetDocumentModified();
     899             : 
     900             :     // #103934#; notify editline and cell in edit mode
     901           0 :     if (!bInteraction)
     902           0 :         NotifyInputHandler(rPos);
     903             : 
     904           0 :     return true;
     905             : }
     906             : 
     907        2396 : bool ScDocFunc::SetStringCell( const ScAddress& rPos, const OUString& rStr, bool bInteraction )
     908             : {
     909        2396 :     ScDocShellModificator aModificator( rDocShell );
     910        2396 :     ScDocument& rDoc = rDocShell.GetDocument();
     911        2396 :     bool bUndo = rDoc.IsUndoEnabled();
     912             : 
     913        2396 :     bool bHeight = rDoc.HasAttrib(rPos, HASATTR_NEEDHEIGHT);
     914             : 
     915        4792 :     ScCellValue aOldVal;
     916        2396 :     if (bUndo)
     917        2396 :         aOldVal.assign(rDoc, rPos);
     918             : 
     919        2396 :     ScSetStringParam aParam;
     920        2396 :     aParam.setTextInput();
     921        2396 :     rDoc.SetString(rPos, rStr, &aParam);
     922             : 
     923        2396 :     if (bUndo)
     924             :     {
     925        2396 :         svl::IUndoManager* pUndoMgr = rDocShell.GetUndoManager();
     926        2396 :         ScCellValue aNewVal;
     927        2396 :         aNewVal.assign(rDoc, rPos);
     928        2396 :         pUndoMgr->AddUndoAction(new ScUndoSetCell(&rDocShell, rPos, aOldVal, aNewVal));
     929             :     }
     930             : 
     931        2396 :     if (bHeight)
     932         106 :         AdjustRowHeight(rPos);
     933             : 
     934        2396 :     rDocShell.PostPaintCell( rPos );
     935        2396 :     aModificator.SetDocumentModified();
     936             : 
     937             :     // #103934#; notify editline and cell in edit mode
     938        2396 :     if (!bInteraction)
     939        2396 :         NotifyInputHandler( rPos );
     940             : 
     941        4792 :     return true;
     942             : }
     943             : 
     944         340 : bool ScDocFunc::SetEditCell( const ScAddress& rPos, const EditTextObject& rStr, bool bInteraction )
     945             : {
     946         340 :     ScDocShellModificator aModificator( rDocShell );
     947         340 :     ScDocument& rDoc = rDocShell.GetDocument();
     948         340 :     bool bUndo = rDoc.IsUndoEnabled();
     949             : 
     950         340 :     bool bHeight = rDoc.HasAttrib(rPos, HASATTR_NEEDHEIGHT);
     951             : 
     952         680 :     ScCellValue aOldVal;
     953         340 :     if (bUndo)
     954         340 :         aOldVal.assign(rDoc, rPos);
     955             : 
     956         340 :     rDoc.SetEditText(rPos, rStr.Clone());
     957             : 
     958         340 :     if (bUndo)
     959             :     {
     960         340 :         svl::IUndoManager* pUndoMgr = rDocShell.GetUndoManager();
     961         340 :         ScCellValue aNewVal;
     962         340 :         aNewVal.assign(rDoc, rPos);
     963         340 :         pUndoMgr->AddUndoAction(new ScUndoSetCell(&rDocShell, rPos, aOldVal, aNewVal));
     964             :     }
     965             : 
     966         340 :     if (bHeight)
     967           2 :         AdjustRowHeight(rPos);
     968             : 
     969         340 :     rDocShell.PostPaintCell( rPos );
     970         340 :     aModificator.SetDocumentModified();
     971             : 
     972             :     // #103934#; notify editline and cell in edit mode
     973         340 :     if (!bInteraction)
     974         340 :         NotifyInputHandler( rPos );
     975             : 
     976         680 :     return true;
     977             : }
     978             : 
     979        2304 : bool ScDocFunc::SetStringOrEditCell( const ScAddress& rPos, const OUString& rStr, bool bInteraction )
     980             : {
     981        2304 :     ScDocument& rDoc = rDocShell.GetDocument();
     982             : 
     983        2304 :     if (ScStringUtil::isMultiline(rStr))
     984             :     {
     985           6 :         ScFieldEditEngine& rEngine = rDoc.GetEditEngine();
     986           6 :         rEngine.SetText(rStr);
     987           6 :         boost::scoped_ptr<EditTextObject> pEditText(rEngine.CreateTextObject());
     988           6 :         return SetEditCell(rPos, *pEditText, bInteraction);
     989             :     }
     990             :     else
     991        2298 :         return SetStringCell(rPos, rStr, bInteraction);
     992             : }
     993             : 
     994         228 : bool ScDocFunc::SetFormulaCell( const ScAddress& rPos, ScFormulaCell* pCell, bool bInteraction )
     995             : {
     996         228 :     std::unique_ptr<ScFormulaCell> xCell(pCell);
     997             : 
     998         456 :     ScDocShellModificator aModificator( rDocShell );
     999         228 :     ScDocument& rDoc = rDocShell.GetDocument();
    1000         228 :     bool bUndo = rDoc.IsUndoEnabled();
    1001             : 
    1002         228 :     bool bHeight = rDoc.HasAttrib(rPos, HASATTR_NEEDHEIGHT);
    1003             : 
    1004         456 :     ScCellValue aOldVal;
    1005         228 :     if (bUndo)
    1006         228 :         aOldVal.assign(rDoc, rPos);
    1007             : 
    1008         228 :     pCell = rDoc.SetFormulaCell(rPos, xCell.release());
    1009             : 
    1010             :     // For performance reasons API calls may disable calculation while
    1011             :     // operating and recalculate once when done. If through user interaction
    1012             :     // and AutoCalc is disabled, calculate the formula (without its
    1013             :     // dependencies) once so the result matches the current document's content.
    1014         228 :     if (bInteraction && !rDoc.GetAutoCalc() && pCell)
    1015             :     {
    1016             :         // calculate just the cell once and set Dirty again
    1017           0 :         pCell->Interpret();
    1018           0 :         pCell->SetDirtyVar();
    1019           0 :         rDoc.PutInFormulaTree( pCell);
    1020             :     }
    1021             : 
    1022         228 :     if (bUndo)
    1023             :     {
    1024         228 :         svl::IUndoManager* pUndoMgr = rDocShell.GetUndoManager();
    1025         228 :         ScCellValue aNewVal;
    1026         228 :         aNewVal.assign(rDoc, rPos);
    1027         228 :         pUndoMgr->AddUndoAction(new ScUndoSetCell(&rDocShell, rPos, aOldVal, aNewVal));
    1028             :     }
    1029             : 
    1030         228 :     if (bHeight)
    1031           0 :         AdjustRowHeight(rPos);
    1032             : 
    1033         228 :     rDocShell.PostPaintCell( rPos );
    1034         228 :     aModificator.SetDocumentModified();
    1035             : 
    1036             :     // #103934#; notify editline and cell in edit mode
    1037         228 :     if (!bInteraction)
    1038         228 :         NotifyInputHandler( rPos );
    1039             : 
    1040         456 :     return true;
    1041             : }
    1042             : 
    1043       12402 : void ScDocFunc::NotifyInputHandler( const ScAddress& rPos )
    1044             : {
    1045       12402 :     ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
    1046       12402 :     if ( pViewSh && pViewSh->GetViewData().GetDocShell() == &rDocShell )
    1047             :     {
    1048       12348 :         ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
    1049       12348 :         if ( pInputHdl && pInputHdl->GetCursorPos() == rPos )
    1050             :         {
    1051         136 :             bool bIsEditMode(pInputHdl->IsEditMode());
    1052             : 
    1053             :             // set modified if in editmode, because so the string is not set in the InputWindow like in the cell
    1054             :             // (the cell shows the same like the InputWindow)
    1055         136 :             if (bIsEditMode)
    1056           0 :                 pInputHdl->SetModified();
    1057         136 :             pViewSh->UpdateInputHandler(false, !bIsEditMode);
    1058             :         }
    1059             :     }
    1060       12402 : }
    1061             : 
    1062         340 :         struct ScMyRememberItem
    1063             :         {
    1064             :             sal_Int32   nIndex;
    1065             :             SfxItemSet  aItemSet;
    1066             : 
    1067         340 :             ScMyRememberItem(const SfxItemSet& rItemSet, sal_Int32 nTempIndex) :
    1068         340 :                 nIndex(nTempIndex), aItemSet(rItemSet) {}
    1069             :         };
    1070             : 
    1071             :         typedef ::std::list<ScMyRememberItem*> ScMyRememberItemList;
    1072             : 
    1073         434 : bool ScDocFunc::PutData( const ScAddress& rPos, ScEditEngineDefaulter& rEngine, bool bApi )
    1074             : {
    1075             :     //  PutData ruft PutCell oder SetNormalString
    1076             : 
    1077         434 :     bool bRet = false;
    1078         434 :     ScDocument& rDoc = rDocShell.GetDocument();
    1079         434 :     ScEditAttrTester aTester( &rEngine );
    1080         434 :     bool bEditCell = aTester.NeedsObject();
    1081         434 :     if ( bEditCell )
    1082             :     {
    1083             :         // #i61702# With bLoseContent set, the content of rEngine isn't restored
    1084             :         // (used in loading XML, where after the removeActionLock call the API object's
    1085             :         // EditEngine isn't accessed again.
    1086         334 :         bool bLoseContent = rDoc.IsImportingXML();
    1087             : 
    1088         334 :         bool bUpdateMode(rEngine.GetUpdateMode());
    1089         334 :         if (bUpdateMode)
    1090         334 :             rEngine.SetUpdateMode(false);
    1091             : 
    1092         334 :         ScMyRememberItemList aRememberItems;
    1093         334 :         ScMyRememberItem* pRememberItem = NULL;
    1094             : 
    1095             :         //  All paragraph attributes must be removed before calling CreateTextObject,
    1096             :         //  not only alignment, so the object doesn't contain the cell attributes as
    1097             :         //  paragraph attributes. Before remove the attributes store they in a list to
    1098             :         //  set they back to the EditEngine.
    1099         334 :         sal_Int32 nCount = rEngine.GetParagraphCount();
    1100         674 :         for (sal_Int32 i=0; i<nCount; i++)
    1101             :         {
    1102         340 :             const SfxItemSet& rOld = rEngine.GetParaAttribs( i );
    1103         340 :             if ( rOld.Count() )
    1104             :             {
    1105         340 :                 if ( !bLoseContent )
    1106             :                 {
    1107         340 :                     pRememberItem = new ScMyRememberItem(rEngine.GetParaAttribs(i), i);
    1108         340 :                     aRememberItems.push_back(pRememberItem);
    1109             :                 }
    1110         340 :                 rEngine.SetParaAttribs( i, SfxItemSet( *rOld.GetPool(), rOld.GetRanges() ) );
    1111             :             }
    1112             :         }
    1113             : 
    1114             :         // A copy of pNewData will be stored in the cell.
    1115         668 :         boost::scoped_ptr<EditTextObject> pNewData(rEngine.CreateTextObject());
    1116         334 :         bRet = SetEditCell(rPos, *pNewData, !bApi);
    1117             : 
    1118             :         // Set the paragraph attributes back to the EditEngine.
    1119         334 :         if (!aRememberItems.empty())
    1120             :         {
    1121         334 :             ScMyRememberItemList::iterator aItr = aRememberItems.begin();
    1122        1008 :             while (aItr != aRememberItems.end())
    1123             :             {
    1124         340 :                 pRememberItem = *aItr;
    1125         340 :                 rEngine.SetParaAttribs(pRememberItem->nIndex, pRememberItem->aItemSet);
    1126         340 :                 delete pRememberItem;
    1127         340 :                 aItr = aRememberItems.erase(aItr);
    1128             :             }
    1129             :         }
    1130             : 
    1131             :         // #i61702# if the content isn't accessed, there's no need to set the UpdateMode again
    1132         334 :         if ( bUpdateMode && !bLoseContent )
    1133         668 :             rEngine.SetUpdateMode(true);
    1134             :     }
    1135             :     else
    1136             :     {
    1137         100 :         OUString aText = rEngine.GetText();
    1138         100 :         if (aText.isEmpty())
    1139             :         {
    1140           2 :             bool bNumFmtSet = false;
    1141           2 :             bRet = SetNormalString( bNumFmtSet, rPos, aText, bApi );
    1142             :         }
    1143             :         else
    1144          98 :             bRet = SetStringCell(rPos, aText, !bApi);
    1145             :     }
    1146             : 
    1147         434 :     if ( bRet && aTester.NeedsCellAttr() )
    1148             :     {
    1149         346 :         const SfxItemSet& rEditAttr = aTester.GetAttribs();
    1150         346 :         ScPatternAttr aPattern( rDoc.GetPool() );
    1151         346 :         aPattern.GetFromEditItemSet( &rEditAttr );
    1152         346 :         aPattern.DeleteUnchanged( rDoc.GetPattern( rPos.Col(), rPos.Row(), rPos.Tab() ) );
    1153         346 :         aPattern.GetItemSet().ClearItem( ATTR_HOR_JUSTIFY );    // wasn't removed above if no edit object
    1154         346 :         if ( aPattern.GetItemSet().Count() > 0 )
    1155             :         {
    1156         226 :             ScMarkData aMark;
    1157         226 :             aMark.SelectTable( rPos.Tab(), true );
    1158         226 :             aMark.SetMarkArea( ScRange( rPos ) );
    1159         226 :             ApplyAttributes( aMark, aPattern, true, bApi );
    1160         346 :         }
    1161             :     }
    1162             : 
    1163         434 :     return bRet;
    1164             : }
    1165             : 
    1166           0 : static ScTokenArray* lcl_ScDocFunc_CreateTokenArrayXML( const OUString& rText, const OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
    1167             : {
    1168           0 :     ScTokenArray* pCode = new ScTokenArray;
    1169           0 :     pCode->AddStringXML( rText );
    1170           0 :     if( (eGrammar == formula::FormulaGrammar::GRAM_EXTERNAL) && (!rFormulaNmsp.isEmpty()) )
    1171           0 :         pCode->AddStringXML( rFormulaNmsp );
    1172           0 :     return pCode;
    1173             : }
    1174             : 
    1175        4092 : bool ScDocFunc::SetCellText(
    1176             :     const ScAddress& rPos, const OUString& rText, bool bInterpret, bool bEnglish, bool bApi,
    1177             :     const formula::FormulaGrammar::Grammar eGrammar )
    1178             : {
    1179        4092 :     bool bSet = false;
    1180        4092 :     if ( bInterpret )
    1181             :     {
    1182        1736 :         if ( bEnglish )
    1183             :         {
    1184        1732 :             ScDocument& rDoc = rDocShell.GetDocument();
    1185             : 
    1186        1732 :             ::boost::scoped_ptr<ScExternalRefManager::ApiGuard> pExtRefGuard;
    1187        1732 :             if (bApi)
    1188        1732 :                 pExtRefGuard.reset(new ScExternalRefManager::ApiGuard(&rDoc));
    1189             : 
    1190             :             ScInputStringType aRes =
    1191        3464 :                 ScStringUtil::parseInputString(*rDoc.GetFormatTable(), rText, LANGUAGE_ENGLISH_US);
    1192             : 
    1193        1732 :             switch (aRes.meType)
    1194             :             {
    1195             :                 case ScInputStringType::Formula:
    1196         226 :                     bSet = SetFormulaCell(rPos, new ScFormulaCell(&rDoc, rPos, aRes.maText, eGrammar), !bApi);
    1197         226 :                 break;
    1198             :                 case ScInputStringType::Number:
    1199           0 :                     bSet = SetValueCell(rPos, aRes.mfValue, !bApi);
    1200           0 :                 break;
    1201             :                 case ScInputStringType::Text:
    1202        1502 :                     bSet = SetStringOrEditCell(rPos, aRes.maText, !bApi);
    1203        1502 :                 break;
    1204             :                 default:
    1205             :                     ;
    1206        1732 :             }
    1207             :         }
    1208             :         // sonst Null behalten -> SetString mit lokalen Formeln/Zahlformat
    1209             :     }
    1210        2356 :     else if (!rText.isEmpty())
    1211             :     {
    1212          36 :         bSet = SetStringOrEditCell(rPos, rText, !bApi);
    1213             :     }
    1214             : 
    1215        4092 :     if (!bSet)
    1216             :     {
    1217        2328 :         bool bNumFmtSet = false;
    1218        2328 :         bSet = SetNormalString( bNumFmtSet, rPos, rText, bApi );
    1219             :     }
    1220        4092 :     return bSet;
    1221             : }
    1222             : 
    1223           6 : bool ScDocFunc::ShowNote( const ScAddress& rPos, bool bShow )
    1224             : {
    1225           6 :     ScDocument& rDoc = rDocShell.GetDocument();
    1226           6 :     ScPostIt* pNote = rDoc.GetNote( rPos );
    1227           6 :     if( !pNote || (bShow == pNote->IsCaptionShown()) ) return false;
    1228             : 
    1229             :     // move the caption to internal or hidden layer and create undo action
    1230           4 :     pNote->ShowCaption( rPos, bShow );
    1231           4 :     if( rDoc.IsUndoEnabled() )
    1232           2 :         rDocShell.GetUndoManager()->AddUndoAction( new ScUndoShowHideNote( rDocShell, rPos, bShow ) );
    1233             : 
    1234           4 :     if (rDoc.IsStreamValid(rPos.Tab()))
    1235           2 :         rDoc.SetStreamValid(rPos.Tab(), false);
    1236             : 
    1237           4 :     rDocShell.SetDocumentModified();
    1238             : 
    1239           4 :     return true;
    1240             : }
    1241             : 
    1242           0 : bool ScDocFunc::SetNoteText( const ScAddress& rPos, const OUString& rText, bool bApi )
    1243             : {
    1244           0 :     ScDocShellModificator aModificator( rDocShell );
    1245             : 
    1246           0 :     ScDocument& rDoc = rDocShell.GetDocument();
    1247           0 :     ScEditableTester aTester( &rDoc, rPos.Tab(), rPos.Col(),rPos.Row(), rPos.Col(),rPos.Row() );
    1248           0 :     if (!aTester.IsEditable())
    1249             :     {
    1250           0 :         if (!bApi)
    1251           0 :             rDocShell.ErrorMessage(aTester.GetMessageId());
    1252           0 :         return false;
    1253             :     }
    1254             : 
    1255           0 :     OUString aNewText = convertLineEnd(rText, GetSystemLineEnd()); //! ist das noetig ???
    1256             : 
    1257           0 :     if( ScPostIt* pNote = (!aNewText.isEmpty()) ? rDoc.GetOrCreateNote( rPos ) : rDoc.GetNote(rPos) )
    1258           0 :         pNote->SetText( rPos, aNewText );
    1259             : 
    1260             :     //! Undo !!!
    1261             : 
    1262           0 :     if (rDoc.IsStreamValid(rPos.Tab()))
    1263           0 :         rDoc.SetStreamValid(rPos.Tab(), false);
    1264             : 
    1265           0 :     rDocShell.PostPaintCell( rPos );
    1266           0 :     aModificator.SetDocumentModified();
    1267             : 
    1268           0 :     return true;
    1269             : }
    1270             : 
    1271          30 : bool ScDocFunc::ReplaceNote( const ScAddress& rPos, const OUString& rNoteText, const OUString* pAuthor, const OUString* pDate, bool bApi )
    1272             : {
    1273          30 :     bool bDone = false;
    1274             : 
    1275          30 :     ScDocShellModificator aModificator( rDocShell );
    1276          30 :     ScDocument& rDoc = rDocShell.GetDocument();
    1277          30 :     ScEditableTester aTester( &rDoc, rPos.Tab(), rPos.Col(),rPos.Row(), rPos.Col(),rPos.Row() );
    1278          30 :     if (aTester.IsEditable())
    1279             :     {
    1280          30 :         ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
    1281          30 :         ::svl::IUndoManager* pUndoMgr = (pDrawLayer && rDoc.IsUndoEnabled()) ? rDocShell.GetUndoManager() : 0;
    1282             : 
    1283          30 :         ScNoteData aOldData;
    1284          30 :         ScPostIt* pOldNote = rDoc.ReleaseNote( rPos );
    1285          30 :         if( pOldNote )
    1286             :         {
    1287             :             // ensure existing caption object before draw undo tracking starts
    1288           0 :             pOldNote->GetOrCreateCaption( rPos );
    1289             :             // rescue note data for undo
    1290           0 :             aOldData = pOldNote->GetNoteData();
    1291             :         }
    1292             : 
    1293             :         // collect drawing undo actions for deleting/inserting caption objects
    1294          30 :         if( pUndoMgr )
    1295          26 :             pDrawLayer->BeginCalcUndo(false);
    1296             : 
    1297             :         // delete the note (creates drawing undo action for the caption object)
    1298          30 :         delete pOldNote;
    1299             : 
    1300             :         // create new note (creates drawing undo action for the new caption object)
    1301          60 :         ScNoteData aNewData;
    1302          30 :         if( ScPostIt* pNewNote = ScNoteUtil::CreateNoteFromString( rDoc, rPos, rNoteText, false, true ) )
    1303             :         {
    1304          30 :             if( pAuthor ) pNewNote->SetAuthor( *pAuthor );
    1305          30 :             if( pDate ) pNewNote->SetDate( *pDate );
    1306             :             // rescue note data for undo
    1307          30 :             aNewData = pNewNote->GetNoteData();
    1308             :         }
    1309             : 
    1310             :         // create the undo action
    1311          30 :         if( pUndoMgr && (aOldData.mpCaption || aNewData.mpCaption) )
    1312          26 :             pUndoMgr->AddUndoAction( new ScUndoReplaceNote( rDocShell, rPos, aOldData, aNewData, pDrawLayer->GetCalcUndo() ) );
    1313             : 
    1314             :         // repaint cell (to make note marker visible)
    1315          30 :         rDocShell.PostPaintCell( rPos );
    1316             : 
    1317          30 :         if (rDoc.IsStreamValid(rPos.Tab()))
    1318           6 :             rDoc.SetStreamValid(rPos.Tab(), false);
    1319             : 
    1320          30 :         aModificator.SetDocumentModified();
    1321          60 :         bDone = true;
    1322             :     }
    1323           0 :     else if (!bApi)
    1324             :     {
    1325           0 :         rDocShell.ErrorMessage(aTester.GetMessageId());
    1326             :     }
    1327             : 
    1328          30 :     return bDone;
    1329             : }
    1330             : 
    1331        3562 : bool ScDocFunc::ApplyAttributes( const ScMarkData& rMark, const ScPatternAttr& rPattern,
    1332             :                                     bool bRecord, bool bApi )
    1333             : {
    1334        3562 :     ScDocument& rDoc = rDocShell.GetDocument();
    1335        3562 :     if ( bRecord && !rDoc.IsUndoEnabled() )
    1336        2622 :         bRecord = false;
    1337             : 
    1338        3562 :     bool bImportingXML = rDoc.IsImportingXML();
    1339             :     // Cell formats can still be set if the range isn't editable only because of matrix formulas.
    1340             :     // #i62483# When loading XML, the check can be skipped altogether.
    1341             :     bool bOnlyNotBecauseOfMatrix;
    1342        8066 :     if ( !bImportingXML && !rDoc.IsSelectionEditable( rMark, &bOnlyNotBecauseOfMatrix )
    1343        3562 :             && !bOnlyNotBecauseOfMatrix )
    1344             :     {
    1345           0 :         if (!bApi)
    1346           0 :             rDocShell.ErrorMessage(STR_PROTECTIONERR);
    1347           0 :         return false;
    1348             :     }
    1349             : 
    1350        3562 :     ScDocShellModificator aModificator( rDocShell );
    1351             : 
    1352             :     //! Umrandung
    1353             : 
    1354        3562 :     ScRange aMultiRange;
    1355        3562 :     bool bMulti = rMark.IsMultiMarked();
    1356        3562 :     if ( bMulti )
    1357         342 :         rMark.GetMultiMarkArea( aMultiRange );
    1358             :     else
    1359        3220 :         rMark.GetMarkArea( aMultiRange );
    1360             : 
    1361        3562 :     if ( bRecord )
    1362             :     {
    1363         940 :         ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
    1364         940 :         pUndoDoc->InitUndo( &rDoc, aMultiRange.aStart.Tab(), aMultiRange.aEnd.Tab() );
    1365         940 :         rDoc.CopyToDocument( aMultiRange, IDF_ATTRIB, bMulti, pUndoDoc, &rMark );
    1366             : 
    1367         940 :         rDocShell.GetUndoManager()->AddUndoAction(
    1368             :             new ScUndoSelectionAttr(
    1369             :                     &rDocShell, rMark,
    1370        1880 :                     aMultiRange.aStart.Col(), aMultiRange.aStart.Row(), aMultiRange.aStart.Tab(),
    1371        1880 :                     aMultiRange.aEnd.Col(), aMultiRange.aEnd.Row(), aMultiRange.aEnd.Tab(),
    1372        4700 :                     pUndoDoc, bMulti, &rPattern ) );
    1373             :     }
    1374             : 
    1375             :     // While loading XML it is not necessary to ask HasAttrib. It needs too much time.
    1376        3562 :     sal_uInt16 nExtFlags = 0;
    1377        3562 :     if ( !bImportingXML )
    1378         942 :         rDocShell.UpdatePaintExt( nExtFlags, aMultiRange );     // content before the change
    1379        3562 :     rDoc.ApplySelectionPattern( rPattern, rMark );
    1380        3562 :     if ( !bImportingXML )
    1381         942 :         rDocShell.UpdatePaintExt( nExtFlags, aMultiRange );     // content after the change
    1382             : 
    1383        3562 :     if (!AdjustRowHeight( aMultiRange ))
    1384        3494 :         rDocShell.PostPaint( aMultiRange, PAINT_GRID, nExtFlags );
    1385          68 :     else if (nExtFlags & SC_PF_LINES)
    1386          26 :         lcl_PaintAbove( rDocShell, aMultiRange );   // fuer Linien ueber dem Bereich
    1387             : 
    1388        3562 :     aModificator.SetDocumentModified();
    1389             : 
    1390        3562 :     return true;
    1391             : }
    1392             : 
    1393        2604 : bool ScDocFunc::ApplyStyle( const ScMarkData& rMark, const OUString& rStyleName,
    1394             :                                 bool bRecord, bool bApi )
    1395             : {
    1396        2604 :     ScDocument& rDoc = rDocShell.GetDocument();
    1397        2604 :     if ( bRecord && !rDoc.IsUndoEnabled() )
    1398        2598 :         bRecord = false;
    1399             : 
    1400        2604 :     bool bImportingXML = rDoc.IsImportingXML();
    1401             :     // Cell formats can still be set if the range isn't editable only because of matrix formulas.
    1402             :     // #i62483# When loading XML, the check can be skipped altogether.
    1403             :     bool bOnlyNotBecauseOfMatrix;
    1404        5214 :     if ( !bImportingXML && !rDoc.IsSelectionEditable( rMark, &bOnlyNotBecauseOfMatrix )
    1405        2604 :             && !bOnlyNotBecauseOfMatrix )
    1406             :     {
    1407           0 :         if (!bApi)
    1408           0 :             rDocShell.ErrorMessage(STR_PROTECTIONERR);
    1409           0 :         return false;
    1410             :     }
    1411             : 
    1412        2604 :     ScStyleSheet* pStyleSheet = static_cast<ScStyleSheet*>( rDoc.GetStyleSheetPool()->Find(
    1413        2604 :                                                 rStyleName, SFX_STYLE_FAMILY_PARA ));
    1414        2604 :     if (!pStyleSheet)
    1415         818 :         return false;
    1416             : 
    1417        1786 :     ScDocShellModificator aModificator( rDocShell );
    1418             : 
    1419        1786 :     ScRange aMultiRange;
    1420        1786 :     bool bMulti = rMark.IsMultiMarked();
    1421        1786 :     if ( bMulti )
    1422         470 :         rMark.GetMultiMarkArea( aMultiRange );
    1423             :     else
    1424        1316 :         rMark.GetMarkArea( aMultiRange );
    1425             : 
    1426        1786 :     if ( bRecord )
    1427             :     {
    1428           0 :         ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
    1429           0 :         SCTAB nStartTab = aMultiRange.aStart.Tab();
    1430           0 :         SCTAB nTabCount = rDoc.GetTableCount();
    1431           0 :         pUndoDoc->InitUndo( &rDoc, nStartTab, nStartTab );
    1432           0 :         ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
    1433           0 :         for (; itr != itrEnd && *itr < nTabCount; ++itr)
    1434           0 :             if (*itr != nStartTab)
    1435           0 :                 pUndoDoc->AddUndoTab( *itr, *itr );
    1436             : 
    1437           0 :         ScRange aCopyRange = aMultiRange;
    1438           0 :         aCopyRange.aStart.SetTab(0);
    1439           0 :         aCopyRange.aEnd.SetTab(nTabCount-1);
    1440           0 :         rDoc.CopyToDocument( aCopyRange, IDF_ATTRIB, bMulti, pUndoDoc, &rMark );
    1441             : 
    1442           0 :         rDocShell.GetUndoManager()->AddUndoAction(
    1443             :             new ScUndoSelectionStyle(
    1444           0 :                     &rDocShell, rMark, aMultiRange, rStyleName, pUndoDoc ) );
    1445             : 
    1446             :     }
    1447             : 
    1448        1786 :     rDoc.ApplySelectionStyle( (ScStyleSheet&)*pStyleSheet, rMark );
    1449             : 
    1450        1786 :     if (!AdjustRowHeight( aMultiRange ))
    1451        1786 :         rDocShell.PostPaint( aMultiRange, PAINT_GRID, 0 );
    1452             : 
    1453        1786 :     aModificator.SetDocumentModified();
    1454             : 
    1455        1786 :     return true;
    1456             : }
    1457             : 
    1458             : namespace {
    1459             : 
    1460             : /**
    1461             :  * Check if this insertion attempt would end up cutting one or more pivot
    1462             :  * tables in half, which is not desirable.
    1463             :  *
    1464             :  * @return true if this insertion can be done safely without shearing any
    1465             :  *         existing pivot tables, false otherwise.
    1466             :  */
    1467          30 : bool canInsertCellsByPivot(const ScRange& rRange, const ScMarkData& rMarkData, InsCellCmd eCmd, const ScDocument* pDoc)
    1468             : {
    1469          30 :     if (!pDoc->HasPivotTable())
    1470             :         // This document has no pivot tables.
    1471          30 :         return true;
    1472             : 
    1473           0 :     const ScDPCollection* pDPs = pDoc->GetDPCollection();
    1474           0 :     ScMarkData::const_iterator itBeg = rMarkData.begin(), itEnd = rMarkData.end();
    1475             : 
    1476           0 :     ScRange aRange(rRange); // local copy
    1477           0 :     switch (eCmd)
    1478             :     {
    1479             :         case INS_INSROWS:
    1480             :         {
    1481           0 :             aRange.aStart.SetCol(0);
    1482           0 :             aRange.aEnd.SetCol(MAXCOL);
    1483             :             // Continue below.
    1484             :         }
    1485             :         case INS_CELLSDOWN:
    1486             :         {
    1487           0 :             for (ScMarkData::const_iterator it = itBeg; it != itEnd; ++it)
    1488             :             {
    1489           0 :                 if (pDPs->IntersectsTableByColumns(aRange.aStart.Col(), aRange.aEnd.Col(), aRange.aStart.Row(), *it))
    1490             :                     // This column range cuts through at least one pivot table.  Not good.
    1491           0 :                     return false;
    1492             :             }
    1493             : 
    1494             :             // Start row must be either at the top or above any pivot tables.
    1495           0 :             if (aRange.aStart.Row() < 0)
    1496             :                 // I don't know how to handle this case.
    1497           0 :                 return false;
    1498             : 
    1499           0 :             if (aRange.aStart.Row() == 0)
    1500             :                 // First row is always allowed.
    1501           0 :                 return true;
    1502             : 
    1503           0 :             ScRange aTest(aRange);
    1504           0 :             aTest.aStart.IncRow(-1); // Test one row up.
    1505           0 :             aTest.aEnd.SetRow(aTest.aStart.Row());
    1506           0 :             for (ScMarkData::const_iterator it = itBeg; it != itEnd; ++it)
    1507             :             {
    1508           0 :                 aTest.aStart.SetTab(*it);
    1509           0 :                 aTest.aEnd.SetTab(*it);
    1510           0 :                 if (pDPs->HasTable(aTest))
    1511           0 :                     return false;
    1512             :             }
    1513             :         }
    1514           0 :         break;
    1515             :         case INS_INSCOLS:
    1516             :         {
    1517           0 :             aRange.aStart.SetRow(0);
    1518           0 :             aRange.aEnd.SetRow(MAXROW);
    1519             :             // Continue below.
    1520             :         }
    1521             :         case INS_CELLSRIGHT:
    1522             :         {
    1523           0 :             for (ScMarkData::const_iterator it = itBeg; it != itEnd; ++it)
    1524             :             {
    1525           0 :                 if (pDPs->IntersectsTableByRows(aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Row(), *it))
    1526             :                     // This column range cuts through at least one pivot table.  Not good.
    1527           0 :                     return false;
    1528             :             }
    1529             : 
    1530             :             // Start row must be either at the top or above any pivot tables.
    1531           0 :             if (aRange.aStart.Col() < 0)
    1532             :                 // I don't know how to handle this case.
    1533           0 :                 return false;
    1534             : 
    1535           0 :             if (aRange.aStart.Col() == 0)
    1536             :                 // First row is always allowed.
    1537           0 :                 return true;
    1538             : 
    1539           0 :             ScRange aTest(aRange);
    1540           0 :             aTest.aStart.IncCol(-1); // Test one column to the left.
    1541           0 :             aTest.aEnd.SetCol(aTest.aStart.Col());
    1542           0 :             for (ScMarkData::const_iterator it = itBeg; it != itEnd; ++it)
    1543             :             {
    1544           0 :                 aTest.aStart.SetTab(*it);
    1545           0 :                 aTest.aEnd.SetTab(*it);
    1546           0 :                 if (pDPs->HasTable(aTest))
    1547           0 :                     return false;
    1548             :             }
    1549             :         }
    1550           0 :         break;
    1551             :         default:
    1552             :             ;
    1553             :     }
    1554           0 :     return true;
    1555             : }
    1556             : 
    1557             : /**
    1558             :  * Check if this deletion attempt would end up cutting one or more pivot
    1559             :  * tables in half, which is not desirable.
    1560             :  *
    1561             :  * @return true if this deletion can be done safely without shearing any
    1562             :  *         existing pivot tables, false otherwise.
    1563             :  */
    1564          54 : bool canDeleteCellsByPivot(const ScRange& rRange, const ScMarkData& rMarkData, DelCellCmd eCmd, const ScDocument* pDoc)
    1565             : {
    1566          54 :     if (!pDoc->HasPivotTable())
    1567             :         // This document has no pivot tables.
    1568          54 :         return true;
    1569             : 
    1570           0 :     const ScDPCollection* pDPs = pDoc->GetDPCollection();
    1571           0 :     ScMarkData::const_iterator itBeg = rMarkData.begin(), itEnd = rMarkData.end();
    1572             : 
    1573           0 :     ScRange aRange(rRange); // local copy
    1574             : 
    1575           0 :     switch (eCmd)
    1576             :     {
    1577             :         case DEL_DELROWS:
    1578             :         {
    1579           0 :             aRange.aStart.SetCol(0);
    1580           0 :             aRange.aEnd.SetCol(MAXCOL);
    1581             :             // Continue below.
    1582             :         }
    1583             :         case DEL_CELLSUP:
    1584             :         {
    1585           0 :             for (ScMarkData::const_iterator it = itBeg; it != itEnd; ++it)
    1586             :             {
    1587           0 :                 if (pDPs->IntersectsTableByColumns(aRange.aStart.Col(), aRange.aEnd.Col(), aRange.aStart.Row(), *it))
    1588             :                     // This column range cuts through at least one pivot table.  Not good.
    1589           0 :                     return false;
    1590             :             }
    1591             : 
    1592           0 :             ScRange aTest(aRange);
    1593           0 :             for (ScMarkData::const_iterator it = itBeg; it != itEnd; ++it)
    1594             :             {
    1595           0 :                 aTest.aStart.SetTab(*it);
    1596           0 :                 aTest.aEnd.SetTab(*it);
    1597           0 :                 if (pDPs->HasTable(aTest))
    1598           0 :                     return false;
    1599             :             }
    1600             :         }
    1601           0 :         break;
    1602             :         case DEL_DELCOLS:
    1603             :         {
    1604           0 :             aRange.aStart.SetRow(0);
    1605           0 :             aRange.aEnd.SetRow(MAXROW);
    1606             :             // Continue below.
    1607             :         }
    1608             :         case DEL_CELLSLEFT:
    1609             :         {
    1610           0 :             for (ScMarkData::const_iterator it = itBeg; it != itEnd; ++it)
    1611             :             {
    1612           0 :                 if (pDPs->IntersectsTableByRows(aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Row(), *it))
    1613             :                     // This column range cuts through at least one pivot table.  Not good.
    1614           0 :                     return false;
    1615             :             }
    1616             : 
    1617           0 :             ScRange aTest(aRange);
    1618           0 :             for (ScMarkData::const_iterator it = itBeg; it != itEnd; ++it)
    1619             :             {
    1620           0 :                 aTest.aStart.SetTab(*it);
    1621           0 :                 aTest.aEnd.SetTab(*it);
    1622           0 :                 if (pDPs->HasTable(aTest))
    1623           0 :                     return false;
    1624             :             }
    1625             :         }
    1626           0 :         break;
    1627             :         default:
    1628             :             ;
    1629             :     }
    1630           0 :     return true;
    1631             : }
    1632             : 
    1633             : }
    1634             : 
    1635          30 : bool ScDocFunc::InsertCells( const ScRange& rRange, const ScMarkData* pTabMark, InsCellCmd eCmd,
    1636             :                              bool bRecord, bool bApi, bool bPartOfPaste )
    1637             : {
    1638          30 :     ScDocShellModificator aModificator( rDocShell );
    1639             : 
    1640          30 :     SCCOL nStartCol = rRange.aStart.Col();
    1641          30 :     SCROW nStartRow = rRange.aStart.Row();
    1642          30 :     SCTAB nStartTab = rRange.aStart.Tab();
    1643          30 :     SCCOL nEndCol = rRange.aEnd.Col();
    1644          30 :     SCROW nEndRow = rRange.aEnd.Row();
    1645          30 :     SCTAB nEndTab = rRange.aEnd.Tab();
    1646             : 
    1647          30 :     if ( !ValidRow(nStartRow) || !ValidRow(nEndRow) )
    1648             :     {
    1649             :         OSL_FAIL("invalid row in InsertCells");
    1650           0 :         return false;
    1651             :     }
    1652             : 
    1653          30 :     ScDocument& rDoc = rDocShell.GetDocument();
    1654          30 :     SCTAB nTabCount = rDoc.GetTableCount();
    1655          30 :     SCCOL nPaintStartCol = nStartCol;
    1656          30 :     SCROW nPaintStartRow = nStartRow;
    1657          30 :     SCCOL nPaintEndCol = nEndCol;
    1658          30 :     SCROW nPaintEndRow = nEndRow;
    1659          30 :     sal_uInt16 nPaintFlags = PAINT_GRID;
    1660             :     bool bSuccess;
    1661             :     SCTAB i;
    1662             : 
    1663          30 :     ScTabViewShell* pViewSh = rDocShell.GetBestViewShell();  //preserve current cursor position
    1664          30 :     SCCOL nCursorCol = 0;
    1665          30 :     SCROW nCursorRow = 0;
    1666          30 :     if( pViewSh )
    1667             :     {
    1668          10 :         nCursorCol = pViewSh->GetViewData().GetCurX();
    1669          10 :         nCursorRow = pViewSh->GetViewData().GetCurY();
    1670             :     }
    1671             : 
    1672          30 :     if (bRecord && !rDoc.IsUndoEnabled())
    1673           0 :         bRecord = false;
    1674             : 
    1675          60 :     ScMarkData aMark;
    1676          30 :     if (pTabMark)
    1677          20 :         aMark = *pTabMark;
    1678             :     else
    1679             :     {
    1680          10 :         SCTAB nCount = 0;
    1681          10 :         for( i=0; i<nTabCount; i++ )
    1682             :         {
    1683          10 :             if( !rDoc.IsScenario(i) )
    1684             :             {
    1685          10 :                 nCount++;
    1686          10 :                 if( nCount == nEndTab+1 )
    1687             :                 {
    1688          10 :                     aMark.SelectTable( i, true );
    1689          10 :                     break;
    1690             :                 }
    1691             :             }
    1692             :         }
    1693             :     }
    1694             : 
    1695          60 :     ScMarkData aFullMark( aMark );          // including scenario sheets
    1696          30 :     ScMarkData::iterator itr = aMark.begin(), itrEnd = aMark.end();
    1697          60 :     for (; itr != itrEnd && *itr < nTabCount; ++itr)
    1698          30 :         for( SCTAB j = *itr+1; j<nTabCount && rDoc.IsScenario(j); j++ )
    1699           0 :             aFullMark.SelectTable( j, true );
    1700             : 
    1701          30 :     SCTAB nSelCount = aMark.GetSelectCount();
    1702             : 
    1703             :     //  zugehoerige Szenarien auch anpassen
    1704             :     // Test zusammengefasste
    1705             : 
    1706          30 :     SCCOL nMergeTestStartCol = nStartCol;
    1707          30 :     SCROW nMergeTestStartRow = nStartRow;
    1708          30 :     SCCOL nMergeTestEndCol = nEndCol;
    1709          30 :     SCROW nMergeTestEndRow = nEndRow;
    1710             : 
    1711          30 :     ScRange aExtendMergeRange( rRange );
    1712             : 
    1713          30 :     if( rRange.aStart == rRange.aEnd && rDoc.HasAttrib(rRange, HASATTR_MERGED) )
    1714             :     {
    1715           0 :         rDoc.ExtendMerge( aExtendMergeRange );
    1716           0 :         rDoc.ExtendOverlapped( aExtendMergeRange );
    1717           0 :         nMergeTestEndCol = aExtendMergeRange.aEnd.Col();
    1718           0 :         nMergeTestEndRow = aExtendMergeRange.aEnd.Row();
    1719           0 :         nPaintEndCol = nMergeTestEndCol;
    1720           0 :         nPaintEndRow = nMergeTestEndRow;
    1721             :     }
    1722             : 
    1723          30 :     if ( eCmd == INS_INSROWS )
    1724             :     {
    1725          18 :         nMergeTestStartCol = 0;
    1726          18 :         nMergeTestEndCol = MAXCOL;
    1727             :     }
    1728          30 :     if ( eCmd == INS_INSCOLS )
    1729             :     {
    1730          10 :         nMergeTestStartRow = 0;
    1731          10 :         nMergeTestEndRow = MAXROW;
    1732             :     }
    1733          30 :     if ( eCmd == INS_CELLSDOWN )
    1734           0 :         nMergeTestEndRow = MAXROW;
    1735          30 :     if ( eCmd == INS_CELLSRIGHT )
    1736           2 :         nMergeTestEndCol = MAXCOL;
    1737             : 
    1738          30 :     bool bNeedRefresh = false;
    1739             : 
    1740          30 :     SCCOL nEditTestEndCol = (eCmd==INS_INSCOLS) ? MAXCOL : nMergeTestEndCol;
    1741          30 :     SCROW nEditTestEndRow = (eCmd==INS_INSROWS) ? MAXROW : nMergeTestEndRow;
    1742          30 :     ScEditableTester aTester( &rDoc, nMergeTestStartCol, nMergeTestStartRow, nEditTestEndCol, nEditTestEndRow, aMark );
    1743          30 :     if (!aTester.IsEditable())
    1744             :     {
    1745           0 :         if (!bApi)
    1746           0 :             rDocShell.ErrorMessage(aTester.GetMessageId());
    1747           0 :         return false;
    1748             :     }
    1749             : 
    1750             :     // Check if this insertion is allowed with respect to pivot table.
    1751          30 :     if (!canInsertCellsByPivot(rRange, aMark, eCmd, &rDoc))
    1752             :     {
    1753           0 :         if (!bApi)
    1754           0 :             rDocShell.ErrorMessage(STR_NO_INSERT_DELETE_OVER_PIVOT_TABLE);
    1755           0 :         return false;
    1756             :     }
    1757             : 
    1758          60 :     WaitObject aWait( rDocShell.GetActiveDialogParent() );      // wichtig wegen TrackFormulas bei UpdateReference
    1759             : 
    1760          30 :     ScDocument* pRefUndoDoc = NULL;
    1761          30 :     ScRefUndoData* pUndoData = NULL;
    1762          30 :     if ( bRecord )
    1763             :     {
    1764          16 :         pRefUndoDoc = new ScDocument( SCDOCMODE_UNDO );
    1765          16 :         pRefUndoDoc->InitUndo( &rDoc, 0, nTabCount-1, false, false );
    1766             : 
    1767             :         // pRefUndoDoc is filled in InsertCol / InsertRow
    1768             : 
    1769          16 :         pUndoData = new ScRefUndoData( &rDoc );
    1770             : 
    1771          16 :         rDoc.BeginDrawUndo();
    1772             :     }
    1773             : 
    1774             :     // #i8302 : we unmerge overwhelming ranges, before insertion all the actions are put in the same ListAction
    1775             :     // the patch comes from mloiseleur and maoyg
    1776          30 :     bool bInsertMerge = false;
    1777          60 :     std::vector<ScRange> qIncreaseRange;
    1778          60 :     OUString aUndo = ScGlobal::GetRscString( STR_UNDO_INSERTCELLS );
    1779          30 :     if (bRecord)
    1780          16 :         rDocShell.GetUndoManager()->EnterListAction( aUndo, aUndo );
    1781             : 
    1782          30 :     itr = aMark.begin();
    1783          60 :     for (; itr != itrEnd && nTabCount; ++itr)
    1784             :     {
    1785          30 :         i = *itr;
    1786          30 :         if( rDoc.HasAttrib( nMergeTestStartCol, nMergeTestStartRow, i, nMergeTestEndCol, nMergeTestEndRow, i, HASATTR_MERGED | HASATTR_OVERLAPPED ) )
    1787             :         {
    1788           2 :             if (eCmd==INS_CELLSRIGHT)
    1789           0 :                 bNeedRefresh = true;
    1790             : 
    1791           2 :             SCCOL nMergeStartCol = nMergeTestStartCol;
    1792           2 :             SCROW nMergeStartRow = nMergeTestStartRow;
    1793           2 :             SCCOL nMergeEndCol   = nMergeTestEndCol;
    1794           2 :             SCROW nMergeEndRow   = nMergeTestEndRow;
    1795             : 
    1796           2 :             rDoc.ExtendMerge( nMergeStartCol, nMergeStartRow, nMergeEndCol, nMergeEndRow, i );
    1797           2 :             rDoc.ExtendOverlapped( nMergeStartCol, nMergeStartRow, nMergeEndCol, nMergeEndRow, i );
    1798             : 
    1799           2 :             if(( eCmd == INS_CELLSDOWN && ( nMergeStartCol != nMergeTestStartCol || nMergeEndCol != nMergeTestEndCol )) ||
    1800           0 :                 (eCmd == INS_CELLSRIGHT && ( nMergeStartRow != nMergeTestStartRow || nMergeEndRow != nMergeTestEndRow )) )
    1801             :             {
    1802           0 :                 if (!bApi)
    1803           0 :                     rDocShell.ErrorMessage(STR_MSSG_INSERTCELLS_0);
    1804           0 :                 rDocShell.GetUndoManager()->LeaveListAction();
    1805           0 :                 delete pUndoData;
    1806           0 :                 return false;
    1807             :             }
    1808             : 
    1809           2 :             SCCOL nTestCol = -1;
    1810           2 :             SCROW nTestRow1 = -1;
    1811           2 :             SCROW nTestRow2 = -1;
    1812             : 
    1813           2 :             ScDocAttrIterator aTestIter( &rDoc, i, nMergeTestStartCol, nMergeTestStartRow, nMergeTestEndCol, nMergeTestEndRow );
    1814           2 :             ScRange aExtendRange( nMergeTestStartCol, nMergeTestStartRow, i, nMergeTestEndCol, nMergeTestEndRow, i );
    1815           2 :             const ScPatternAttr* pPattern = NULL;
    1816           2 :             const ScMergeAttr* pMergeFlag = NULL;
    1817           2 :             const ScMergeFlagAttr* pMergeFlagAttr = NULL;
    1818        2052 :             while ( ( pPattern = aTestIter.GetNext( nTestCol, nTestRow1, nTestRow2 ) ) != NULL )
    1819             :             {
    1820        2048 :                 pMergeFlag = static_cast<const ScMergeAttr*>( &pPattern->GetItem(ATTR_MERGE) );
    1821        2048 :                 pMergeFlagAttr = static_cast<const ScMergeFlagAttr*>( &pPattern->GetItem(ATTR_MERGE_FLAG) );
    1822        2048 :                 sal_Int16 nNewFlags = pMergeFlagAttr->GetValue() & ( SC_MF_HOR | SC_MF_VER );
    1823        2048 :                 if( ( pMergeFlag && pMergeFlag->IsMerged() ) || nNewFlags == SC_MF_HOR || nNewFlags == SC_MF_VER )
    1824             :                 {
    1825           2 :                     ScRange aRange( nTestCol, nTestRow1, i );
    1826           2 :                     rDoc.ExtendOverlapped(aRange);
    1827           2 :                     rDoc.ExtendMerge(aRange, true);
    1828             : 
    1829           2 :                     if( nTestRow1 < nTestRow2 && nNewFlags == SC_MF_HOR )
    1830             :                     {
    1831           0 :                         for( SCROW nTestRow = nTestRow1; nTestRow <= nTestRow2; nTestRow++ )
    1832             :                         {
    1833           0 :                             ScRange aTestRange( nTestCol, nTestRow, i );
    1834           0 :                             rDoc.ExtendOverlapped( aTestRange );
    1835           0 :                             rDoc.ExtendMerge( aTestRange, true);
    1836           0 :                             ScRange aMergeRange( aTestRange.aStart.Col(),aTestRange.aStart.Row(), i );
    1837           0 :                             if( !aExtendRange.In( aMergeRange ) )
    1838             :                             {
    1839           0 :                                 qIncreaseRange.push_back( aTestRange );
    1840           0 :                                 bInsertMerge = true;
    1841             :                             }
    1842           0 :                         }
    1843             :                     }
    1844             :                     else
    1845             :                     {
    1846           2 :                         ScRange aMergeRange( aRange.aStart.Col(),aRange.aStart.Row(), i );
    1847           2 :                         if( !aExtendRange.In( aMergeRange ) )
    1848             :                         {
    1849           2 :                             qIncreaseRange.push_back( aRange );
    1850             :                         }
    1851           2 :                         bInsertMerge = true;
    1852             :                     }
    1853             :                 }
    1854             :             }
    1855             : 
    1856           2 :             if( bInsertMerge )
    1857             :             {
    1858           2 :                 if( eCmd == INS_INSROWS || eCmd == INS_CELLSDOWN )
    1859             :                 {
    1860           2 :                     nStartRow = aExtendMergeRange.aStart.Row();
    1861           2 :                     nEndRow = aExtendMergeRange.aEnd.Row();
    1862             : 
    1863           4 :                     if( eCmd == INS_CELLSDOWN )
    1864           0 :                         nEndCol = nMergeTestEndCol;
    1865             :                     else
    1866             :                     {
    1867           2 :                         nStartCol = 0;
    1868           2 :                         nEndCol = MAXCOL;
    1869             :                     }
    1870             :                 }
    1871           0 :                 else if( eCmd == INS_CELLSRIGHT || eCmd == INS_INSCOLS )
    1872             :                 {
    1873             : 
    1874           0 :                     nStartCol = aExtendMergeRange.aStart.Col();
    1875           0 :                     nEndCol = aExtendMergeRange.aEnd.Col();
    1876           0 :                     if( eCmd == INS_CELLSRIGHT )
    1877             :                     {
    1878           0 :                         nEndRow = nMergeTestEndRow;
    1879             :                     }
    1880             :                     else
    1881             :                     {
    1882           0 :                         nStartRow = 0;
    1883           0 :                         nEndRow = MAXROW;
    1884             :                     }
    1885             :                 }
    1886             : 
    1887           2 :                 if( !qIncreaseRange.empty() )
    1888             :                 {
    1889           4 :                     for( ::std::vector<ScRange>::const_iterator iIter( qIncreaseRange.begin()); iIter != qIncreaseRange.end(); ++iIter )
    1890             :                     {
    1891           2 :                         ScRange aRange( *iIter );
    1892           2 :                         if( rDoc.HasAttrib( aRange, HASATTR_OVERLAPPED | HASATTR_MERGED ) )
    1893             :                         {
    1894           2 :                             UnmergeCells( aRange, true );
    1895             :                         }
    1896             :                     }
    1897             :                 }
    1898             :             }
    1899             :             else
    1900             :             {
    1901           0 :                 if (!bApi)
    1902           0 :                     rDocShell.ErrorMessage(STR_MSSG_INSERTCELLS_0);
    1903           0 :                 rDocShell.GetUndoManager()->LeaveListAction();
    1904           0 :                 delete pUndoData;
    1905           0 :                 return false;
    1906           2 :             }
    1907             :         }
    1908             :     }
    1909             : 
    1910          30 :     switch (eCmd)
    1911             :     {
    1912             :         case INS_CELLSDOWN:
    1913           0 :             bSuccess = rDoc.InsertRow( nStartCol, 0, nEndCol, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, &aFullMark );
    1914           0 :             nPaintEndRow = MAXROW;
    1915           0 :             break;
    1916             :         case INS_INSROWS:
    1917          18 :             bSuccess = rDoc.InsertRow( 0, 0, MAXCOL, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, &aFullMark );
    1918          18 :             nPaintStartCol = 0;
    1919          18 :             nPaintEndCol = MAXCOL;
    1920          18 :             nPaintEndRow = MAXROW;
    1921          18 :             nPaintFlags |= PAINT_LEFT;
    1922          18 :             break;
    1923             :         case INS_CELLSRIGHT:
    1924           2 :             bSuccess = rDoc.InsertCol( nStartRow, 0, nEndRow, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &aFullMark );
    1925           2 :             nPaintEndCol = MAXCOL;
    1926           2 :             break;
    1927             :         case INS_INSCOLS:
    1928          10 :             bSuccess = rDoc.InsertCol( 0, 0, MAXROW, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &aFullMark );
    1929          10 :             nPaintStartRow = 0;
    1930          10 :             nPaintEndRow = MAXROW;
    1931          10 :             nPaintEndCol = MAXCOL;
    1932          10 :             nPaintFlags |= PAINT_TOP;
    1933          10 :             break;
    1934             :         default:
    1935             :             OSL_FAIL("Falscher Code beim Einfuegen");
    1936           0 :             bSuccess = false;
    1937           0 :             break;
    1938             :     }
    1939             : 
    1940          30 :     if ( bSuccess )
    1941             :     {
    1942          30 :         SCTAB* pTabs      = NULL;
    1943          30 :         SCTAB* pScenarios = NULL;
    1944          30 :         SCTAB  nUndoPos  = 0;
    1945             : 
    1946          30 :         if ( bRecord )
    1947             :         {
    1948          16 :             pTabs       = new SCTAB[nSelCount];
    1949          16 :             pScenarios  = new SCTAB[nSelCount];
    1950          16 :             nUndoPos    = 0;
    1951          16 :             itr = aMark.begin();
    1952          32 :             for (; itr != itrEnd && *itr < nTabCount; ++itr)
    1953             :             {
    1954          16 :                 SCTAB nCount = 0;
    1955          16 :                 for( SCTAB j=*itr+1; j<nTabCount && rDoc.IsScenario(j); j++ )
    1956           0 :                     nCount ++;
    1957             : 
    1958          16 :                 pScenarios[nUndoPos] = nCount;
    1959          16 :                 pTabs[nUndoPos] = *itr;
    1960          16 :                 nUndoPos ++;
    1961             :             }
    1962             : 
    1963          16 :             if( !bInsertMerge )
    1964             :             {
    1965          14 :                 rDocShell.GetUndoManager()->LeaveListAction();
    1966             :             }
    1967             : 
    1968          16 :             rDocShell.GetUndoManager()->AddUndoAction( new ScUndoInsertCells(
    1969             :                 &rDocShell, ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab ),
    1970          16 :                 nUndoPos, pTabs, pScenarios, eCmd, pRefUndoDoc, pUndoData, bPartOfPaste ) );
    1971             :         }
    1972             : 
    1973             :         // #i8302 : we remerge growing ranges, with the new part inserted
    1974             : 
    1975          62 :         while( !qIncreaseRange.empty() )
    1976             :         {
    1977           2 :             ScRange aRange = qIncreaseRange.back();
    1978           2 :             if( !rDoc.HasAttrib( aRange, HASATTR_OVERLAPPED | HASATTR_MERGED ) )
    1979             :             {
    1980           2 :                 switch (eCmd)
    1981             :                 {
    1982             :                     case INS_CELLSDOWN:
    1983             :                     case INS_INSROWS:
    1984           2 :                         aRange.aEnd.IncRow(static_cast<SCsCOL>(nEndRow-nStartRow+1));
    1985           2 :                         break;
    1986             :                     case INS_CELLSRIGHT:
    1987             :                     case INS_INSCOLS:
    1988           0 :                         aRange.aEnd.IncCol(static_cast<SCsCOL>(nEndCol-nStartCol+1));
    1989           0 :                         break;
    1990             :                     default:
    1991           0 :                         break;
    1992             :                 }
    1993             :                 ScCellMergeOption aMergeOption(
    1994           2 :                     aRange.aStart.Col(), aRange.aStart.Row(),
    1995           4 :                     aRange.aEnd.Col(), aRange.aEnd.Row() );
    1996           2 :                 aMergeOption.maTabs.insert(aRange.aStart.Tab());
    1997           2 :                 MergeCells(aMergeOption, false, true, true);
    1998             :             }
    1999           2 :             qIncreaseRange.pop_back();
    2000             :         }
    2001             : 
    2002          30 :         if( bInsertMerge )
    2003           2 :             rDocShell.GetUndoManager()->LeaveListAction();
    2004             : 
    2005          30 :         itr = aMark.begin();
    2006          60 :         for (; itr != itrEnd && *itr < nTabCount; ++itr)
    2007             :         {
    2008          30 :             i = *itr;
    2009          30 :             rDoc.SetDrawPageSize(i);
    2010             : 
    2011          30 :             if (bNeedRefresh)
    2012           0 :                 rDoc.ExtendMerge( nMergeTestStartCol, nMergeTestStartRow, nMergeTestEndCol, nMergeTestEndRow, i, true );
    2013             :             else
    2014          30 :                 rDoc.RefreshAutoFilter( nMergeTestStartCol, nMergeTestStartRow, nMergeTestEndCol, nMergeTestEndRow, i );
    2015             : 
    2016          30 :             if ( eCmd == INS_INSROWS || eCmd == INS_INSCOLS )
    2017          28 :                 rDoc.UpdatePageBreaks( i );
    2018             : 
    2019          30 :             sal_uInt16 nExtFlags = 0;
    2020          30 :             rDocShell.UpdatePaintExt( nExtFlags, nPaintStartCol, nPaintStartRow, i, nPaintEndCol, nPaintEndRow, i );
    2021             : 
    2022          30 :             SCTAB nScenarioCount = 0;
    2023             : 
    2024          30 :             for( SCTAB j = i+1; j<nTabCount && rDoc.IsScenario(j); j++ )
    2025           0 :                 nScenarioCount ++;
    2026             : 
    2027          66 :             bool bAdjusted = ( eCmd == INS_INSROWS ) ? AdjustRowHeight(ScRange(0, nStartRow, i, MAXCOL, nEndRow, i+nScenarioCount )) :
    2028          60 :                                                        AdjustRowHeight(ScRange(0, nPaintStartRow, i, MAXCOL, nPaintEndRow, i+nScenarioCount ));
    2029          30 :             if (bAdjusted)
    2030             :             {
    2031             :                 //  paint only what is not done by AdjustRowHeight
    2032           2 :                 if (nPaintFlags & PAINT_TOP)
    2033           0 :                     rDocShell.PostPaint( nPaintStartCol, nPaintStartRow, i, nPaintEndCol, nPaintEndRow, i+nScenarioCount, PAINT_TOP );
    2034             :             }
    2035             :             else
    2036          28 :                 rDocShell.PostPaint( nPaintStartCol, nPaintStartRow, i, nPaintEndCol, nPaintEndRow, i+nScenarioCount, nPaintFlags, nExtFlags );
    2037             :         }
    2038             :     }
    2039             :     else
    2040             :     {
    2041           0 :         if( bInsertMerge )
    2042             :         {
    2043           0 :             while( !qIncreaseRange.empty() )
    2044             :             {
    2045           0 :                 ScRange aRange = qIncreaseRange.back();
    2046             :                  ScCellMergeOption aMergeOption(
    2047           0 :                     aRange.aStart.Col(), aRange.aStart.Row(),
    2048           0 :                     aRange.aEnd.Col(), aRange.aEnd.Row() );
    2049           0 :                 MergeCells(aMergeOption, false, true, true);
    2050           0 :                 qIncreaseRange.pop_back();
    2051           0 :             }
    2052             : 
    2053           0 :             if( pViewSh )
    2054             :             {
    2055           0 :                 pViewSh->MarkRange( rRange, false );
    2056           0 :                 pViewSh->SetCursor( nCursorCol, nCursorRow );
    2057             :             }
    2058             :         }
    2059             : 
    2060           0 :         rDocShell.GetUndoManager()->LeaveListAction();
    2061           0 :         rDocShell.GetUndoManager()->RemoveLastUndoAction();
    2062             : 
    2063           0 :         delete pRefUndoDoc;
    2064           0 :         delete pUndoData;
    2065           0 :         if (!bApi)
    2066           0 :             rDocShell.ErrorMessage(STR_INSERT_FULL);        // Spalte/Zeile voll
    2067             :     }
    2068             : 
    2069          30 :     aModificator.SetDocumentModified();
    2070             : 
    2071          30 :     SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
    2072          60 :     return bSuccess;
    2073             : }
    2074             : 
    2075          54 : bool ScDocFunc::DeleteCells( const ScRange& rRange, const ScMarkData* pTabMark, DelCellCmd eCmd,
    2076             :                              bool bRecord, bool bApi )
    2077             : {
    2078          54 :     ScDocShellModificator aModificator( rDocShell );
    2079             : 
    2080          54 :     SCCOL nStartCol = rRange.aStart.Col();
    2081          54 :     SCROW nStartRow = rRange.aStart.Row();
    2082          54 :     SCTAB nStartTab = rRange.aStart.Tab();
    2083          54 :     SCCOL nEndCol = rRange.aEnd.Col();
    2084          54 :     SCROW nEndRow = rRange.aEnd.Row();
    2085          54 :     SCTAB nEndTab = rRange.aEnd.Tab();
    2086             : 
    2087          54 :     if ( !ValidRow(nStartRow) || !ValidRow(nEndRow) )
    2088             :     {
    2089             :         OSL_FAIL("invalid row in DeleteCells");
    2090           0 :         return false;
    2091             :     }
    2092             : 
    2093          54 :     ScDocument& rDoc = rDocShell.GetDocument();
    2094          54 :     SCTAB nTabCount = rDoc.GetTableCount();
    2095          54 :     SCCOL nPaintStartCol = nStartCol;
    2096          54 :     SCROW nPaintStartRow = nStartRow;
    2097          54 :     SCCOL nPaintEndCol = nEndCol;
    2098          54 :     SCROW nPaintEndRow = nEndRow;
    2099          54 :     sal_uInt16 nPaintFlags = PAINT_GRID;
    2100             : 
    2101          54 :     if (bRecord && !rDoc.IsUndoEnabled())
    2102           0 :         bRecord = false;
    2103             : 
    2104         108 :     ScMarkData aMark;
    2105          54 :     if (pTabMark)
    2106          40 :         aMark = *pTabMark;
    2107             :     else
    2108             :     {
    2109          14 :         SCTAB nCount = 0;
    2110          14 :         for(SCTAB i=0; i<nTabCount; i++ )
    2111             :         {
    2112          14 :             if( !rDoc.IsScenario(i) )
    2113             :             {
    2114          14 :                 nCount++;
    2115          14 :                 if( nCount == nEndTab+1 )
    2116             :                 {
    2117          14 :                     aMark.SelectTable(i, true);
    2118          14 :                     break;
    2119             :                 }
    2120             :             }
    2121             :         }
    2122             :     }
    2123             : 
    2124         108 :     ScMarkData aFullMark( aMark );          // including scenario sheets
    2125          54 :     ScMarkData::iterator itr = aMark.begin(), itrEnd = aMark.end();
    2126         108 :     for (; itr != itrEnd && *itr < nTabCount; ++itr)
    2127          54 :         for( SCTAB j = *itr+1; j<nTabCount && rDoc.IsScenario(j); j++ )
    2128           0 :             aFullMark.SelectTable( j, true );
    2129             : 
    2130          54 :     SCTAB nSelCount = aMark.GetSelectCount();
    2131             : 
    2132          54 :     SCCOL nUndoStartCol = nStartCol;
    2133          54 :     SCROW nUndoStartRow = nStartRow;
    2134          54 :     SCCOL nUndoEndCol = nEndCol;
    2135          54 :     SCROW nUndoEndRow = nEndRow;
    2136             : 
    2137          54 :     ScRange aExtendMergeRange( rRange );
    2138             : 
    2139          54 :     if( rRange.aStart == rRange.aEnd && rDoc.HasAttrib(rRange, HASATTR_MERGED) )
    2140             :     {
    2141           0 :         rDoc.ExtendMerge( aExtendMergeRange );
    2142           0 :         rDoc.ExtendOverlapped( aExtendMergeRange );
    2143           0 :         nUndoEndCol = aExtendMergeRange.aEnd.Col();
    2144           0 :         nUndoEndRow = aExtendMergeRange.aEnd.Row();
    2145           0 :         nPaintEndCol = nUndoEndCol;
    2146           0 :         nPaintEndRow = nUndoEndRow;
    2147             :     }
    2148             : 
    2149          54 :     if (eCmd==DEL_DELROWS)
    2150             :     {
    2151           2 :         nUndoStartCol = 0;
    2152           2 :         nUndoEndCol = MAXCOL;
    2153             :     }
    2154          54 :     if (eCmd==DEL_DELCOLS)
    2155             :     {
    2156           6 :         nUndoStartRow = 0;
    2157           6 :         nUndoEndRow = MAXROW;
    2158             :     }
    2159             :                     // Test Zellschutz
    2160             : 
    2161          54 :     SCCOL nEditTestEndX = nUndoEndCol;
    2162          54 :     if ( eCmd==DEL_DELCOLS || eCmd==DEL_CELLSLEFT )
    2163          26 :         nEditTestEndX = MAXCOL;
    2164          54 :     SCROW nEditTestEndY = nUndoEndRow;
    2165          54 :     if ( eCmd==DEL_DELROWS || eCmd==DEL_CELLSUP )
    2166          28 :         nEditTestEndY = MAXROW;
    2167          54 :     ScEditableTester aTester( &rDoc, nUndoStartCol, nUndoStartRow, nEditTestEndX, nEditTestEndY, aMark );
    2168          54 :     if (!aTester.IsEditable())
    2169             :     {
    2170           0 :         if (!bApi)
    2171           0 :             rDocShell.ErrorMessage(aTester.GetMessageId());
    2172           0 :         return false;
    2173             :     }
    2174             : 
    2175          54 :     if (!canDeleteCellsByPivot(rRange, aMark, eCmd, &rDoc))
    2176             :     {
    2177           0 :         if (!bApi)
    2178           0 :             rDocShell.ErrorMessage(STR_NO_INSERT_DELETE_OVER_PIVOT_TABLE);
    2179           0 :         return false;
    2180             :     }
    2181             :                     // Test zusammengefasste
    2182             : 
    2183          54 :     SCCOL nMergeTestEndCol = (eCmd==DEL_CELLSLEFT) ? MAXCOL : nUndoEndCol;
    2184          54 :     SCROW nMergeTestEndRow = (eCmd==DEL_CELLSUP)   ? MAXROW : nUndoEndRow;
    2185          54 :     SCCOL nExtendStartCol = nUndoStartCol;
    2186          54 :     SCROW nExtendStartRow = nUndoStartRow;
    2187          54 :     bool bNeedRefresh = false;
    2188             : 
    2189             :     //Issue 8302 want to be able to insert into the middle of merged cells
    2190             :     //the patch comes from maoyg
    2191         108 :     ::std::vector<ScRange> qDecreaseRange;
    2192          54 :     bool bDeletingMerge = false;
    2193         108 :     OUString aUndo = ScGlobal::GetRscString( STR_UNDO_DELETECELLS );
    2194          54 :     if (bRecord)
    2195          54 :         rDocShell.GetUndoManager()->EnterListAction( aUndo, aUndo );
    2196             : 
    2197          54 :     itr = aMark.begin();
    2198         108 :     for (; itr != itrEnd && *itr < nTabCount; ++itr)
    2199             :     {
    2200          54 :         SCTAB i = *itr;
    2201          54 :         if ( rDoc.HasAttrib( nUndoStartCol, nUndoStartRow, i, nMergeTestEndCol, nMergeTestEndRow, i, HASATTR_MERGED | HASATTR_OVERLAPPED ))
    2202             :         {
    2203           0 :             SCCOL nMergeStartCol = nUndoStartCol;
    2204           0 :             SCROW nMergeStartRow = nUndoStartRow;
    2205           0 :             SCCOL nMergeEndCol   = nMergeTestEndCol;
    2206           0 :             SCROW nMergeEndRow   = nMergeTestEndRow;
    2207             : 
    2208           0 :             rDoc.ExtendMerge( nMergeStartCol, nMergeStartRow, nMergeEndCol, nMergeEndRow, i );
    2209           0 :             rDoc.ExtendOverlapped( nMergeStartCol, nMergeStartRow, nMergeEndCol, nMergeEndRow, i );
    2210           0 :             if( ( eCmd == DEL_CELLSUP && ( nMergeStartCol != nUndoStartCol || nMergeEndCol != nMergeTestEndCol))||
    2211           0 :                 ( eCmd == DEL_CELLSLEFT && ( nMergeStartRow != nUndoStartRow || nMergeEndRow != nMergeTestEndRow)))
    2212             :             {
    2213           0 :                 if (!bApi)
    2214           0 :                     rDocShell.ErrorMessage(STR_MSSG_DELETECELLS_0);
    2215           0 :                 rDocShell.GetUndoManager()->LeaveListAction();
    2216           0 :                 return false;
    2217             :             }
    2218             : 
    2219           0 :             nExtendStartCol = nMergeStartCol;
    2220           0 :             nExtendStartRow = nMergeStartRow;
    2221           0 :             SCCOL nTestCol = -1;
    2222           0 :             SCROW nTestRow1 = -1;
    2223           0 :             SCROW nTestRow2 = -1;
    2224             : 
    2225           0 :             ScDocAttrIterator aTestIter( &rDoc, i, nUndoStartCol, nUndoStartRow, nMergeTestEndCol, nMergeTestEndRow );
    2226           0 :             ScRange aExtendRange( nUndoStartCol, nUndoStartRow, i, nMergeTestEndCol, nMergeTestEndRow, i );
    2227           0 :             const ScPatternAttr* pPattern = NULL;
    2228           0 :             const ScMergeAttr* pMergeFlag = NULL;
    2229           0 :             const ScMergeFlagAttr* pMergeFlagAttr = NULL;
    2230           0 :             while ( ( pPattern = aTestIter.GetNext( nTestCol, nTestRow1, nTestRow2 ) ) != NULL )
    2231             :             {
    2232           0 :                 pMergeFlag = static_cast<const ScMergeAttr*>( &pPattern->GetItem( ATTR_MERGE ) );
    2233           0 :                 pMergeFlagAttr = static_cast<const ScMergeFlagAttr*>( &pPattern->GetItem( ATTR_MERGE_FLAG ) );
    2234           0 :                 sal_Int16 nNewFlags = pMergeFlagAttr->GetValue() & ( SC_MF_HOR | SC_MF_VER );
    2235           0 :                 if( ( pMergeFlag && pMergeFlag->IsMerged() ) || nNewFlags == SC_MF_HOR || nNewFlags == SC_MF_VER )
    2236             :                 {
    2237           0 :                     ScRange aRange( nTestCol, nTestRow1, i );
    2238           0 :                     rDoc.ExtendOverlapped( aRange );
    2239           0 :                     rDoc.ExtendMerge( aRange, true );
    2240             : 
    2241           0 :                     if( nTestRow1 < nTestRow2 && nNewFlags == SC_MF_HOR )
    2242             :                     {
    2243           0 :                         for( SCROW nTestRow = nTestRow1; nTestRow <= nTestRow2; nTestRow++ )
    2244             :                         {
    2245           0 :                             ScRange aTestRange( nTestCol, nTestRow, i );
    2246           0 :                             rDoc.ExtendOverlapped( aTestRange );
    2247           0 :                             rDoc.ExtendMerge( aTestRange, true );
    2248           0 :                             ScRange aMergeRange( aTestRange.aStart.Col(),aTestRange.aStart.Row(), i );
    2249           0 :                             if( !aExtendRange.In( aMergeRange ) )
    2250             :                             {
    2251           0 :                                 qDecreaseRange.push_back( aTestRange );
    2252           0 :                                 bDeletingMerge = true;
    2253             :                             }
    2254           0 :                         }
    2255             :                     }
    2256             :                     else
    2257             :                     {
    2258           0 :                         ScRange aMergeRange( aRange.aStart.Col(),aRange.aStart.Row(), i );
    2259           0 :                         if( !aExtendRange.In( aMergeRange ) )
    2260             :                         {
    2261           0 :                             qDecreaseRange.push_back( aRange );
    2262             :                         }
    2263           0 :                         bDeletingMerge = true;
    2264             :                     }
    2265             :                 }
    2266             :             }
    2267             : 
    2268           0 :             if( bDeletingMerge )
    2269             :             {
    2270             : 
    2271           0 :                 if( eCmd == DEL_DELROWS || eCmd == DEL_CELLSUP )
    2272             :                 {
    2273           0 :                     nStartRow = aExtendMergeRange.aStart.Row();
    2274           0 :                     nEndRow = aExtendMergeRange.aEnd.Row();
    2275           0 :                     bNeedRefresh = true;
    2276             : 
    2277           0 :                     if( eCmd == DEL_CELLSUP )
    2278             :                     {
    2279           0 :                         nEndCol = aExtendMergeRange.aEnd.Col();
    2280             :                     }
    2281             :                     else
    2282             :                     {
    2283           0 :                         nStartCol = 0;
    2284           0 :                         nEndCol = MAXCOL;
    2285             :                     }
    2286             :                 }
    2287           0 :                 else if( eCmd == DEL_CELLSLEFT || eCmd == DEL_DELCOLS )
    2288             :                 {
    2289             : 
    2290           0 :                     nStartCol = aExtendMergeRange.aStart.Col();
    2291           0 :                     nEndCol = aExtendMergeRange.aEnd.Col();
    2292           0 :                     if( eCmd == DEL_CELLSLEFT )
    2293             :                     {
    2294           0 :                         nEndRow = aExtendMergeRange.aEnd.Row();
    2295           0 :                         bNeedRefresh = true;
    2296             :                     }
    2297             :                     else
    2298             :                     {
    2299           0 :                         nStartRow = 0;
    2300           0 :                         nEndRow = MAXROW;
    2301             :                     }
    2302             :                 }
    2303             : 
    2304           0 :                 if( !qDecreaseRange.empty() )
    2305             :                 {
    2306           0 :                     for( ::std::vector<ScRange>::const_iterator iIter( qDecreaseRange.begin()); iIter != qDecreaseRange.end(); ++iIter )
    2307             :                     {
    2308           0 :                         ScRange aRange( *iIter );
    2309           0 :                         if( rDoc.HasAttrib( aRange, HASATTR_OVERLAPPED | HASATTR_MERGED ) )
    2310             :                         {
    2311           0 :                             UnmergeCells( aRange, true );
    2312             :                         }
    2313             :                     }
    2314             :                 }
    2315             :             }
    2316             :             else
    2317             :             {
    2318           0 :                 if (!bApi)
    2319           0 :                     rDocShell.ErrorMessage(STR_MSSG_DELETECELLS_0);
    2320           0 :                 rDocShell.GetUndoManager()->LeaveListAction();
    2321           0 :                 return false;
    2322           0 :             }
    2323             :         }
    2324             :     }
    2325             : 
    2326             :     //      ausfuehren
    2327             : 
    2328         108 :     WaitObject aWait( rDocShell.GetActiveDialogParent() );      // wichtig wegen TrackFormulas bei UpdateReference
    2329             : 
    2330          54 :     ScDocument* pUndoDoc = NULL;
    2331          54 :     ScDocument* pRefUndoDoc = NULL;
    2332          54 :     ScRefUndoData* pUndoData = NULL;
    2333          54 :     if ( bRecord )
    2334             :     {
    2335             :         // With the fix for #101329#, UpdateRef always puts cells into pRefUndoDoc at their old position,
    2336             :         // so it's no longer necessary to copy more than the deleted range into pUndoDoc.
    2337             : 
    2338          54 :         pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
    2339          54 :         pUndoDoc->InitUndo( &rDoc, 0, nTabCount-1, (eCmd==DEL_DELCOLS), (eCmd==DEL_DELROWS) );
    2340          54 :         itr = aMark.begin();
    2341         108 :         for (; itr != itrEnd && *itr < nTabCount; ++itr)
    2342             :         {
    2343          54 :             SCTAB nScenarioCount = 0;
    2344             : 
    2345          54 :             for( SCTAB j = *itr+1; j<nTabCount && rDoc.IsScenario(j); j++ )
    2346           0 :                 nScenarioCount ++;
    2347             : 
    2348         108 :             rDoc.CopyToDocument( nUndoStartCol, nUndoStartRow, *itr, nUndoEndCol, nUndoEndRow, *itr+nScenarioCount,
    2349         162 :                 IDF_ALL | IDF_NOCAPTIONS, false, pUndoDoc );
    2350             :         }
    2351             : 
    2352          54 :         pRefUndoDoc = new ScDocument( SCDOCMODE_UNDO );
    2353          54 :         pRefUndoDoc->InitUndo( &rDoc, 0, nTabCount-1, false, false );
    2354             : 
    2355          54 :         pUndoData = new ScRefUndoData( &rDoc );
    2356             : 
    2357          54 :         rDoc.BeginDrawUndo();
    2358             :     }
    2359             : 
    2360          54 :     sal_uInt16 nExtFlags = 0;
    2361          54 :     itr = aMark.begin();
    2362         108 :     for (; itr != itrEnd && *itr < nTabCount; ++itr)
    2363             :     {
    2364          54 :         rDocShell.UpdatePaintExt( nExtFlags, nStartCol, nStartRow, *itr, nEndCol, nEndRow, *itr );
    2365             :     }
    2366             : 
    2367          54 :     bool bUndoOutline = false;
    2368          54 :     switch (eCmd)
    2369             :     {
    2370             :         case DEL_CELLSUP:
    2371          26 :             rDoc.DeleteRow( nStartCol, 0, nEndCol, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, NULL, &aFullMark );
    2372          26 :             nPaintEndRow = MAXROW;
    2373          26 :             break;
    2374             :         case DEL_DELROWS:
    2375           2 :             rDoc.DeleteRow( 0, 0, MAXCOL, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, &bUndoOutline, &aFullMark );
    2376           2 :             nPaintStartCol = 0;
    2377           2 :             nPaintEndCol = MAXCOL;
    2378           2 :             nPaintEndRow = MAXROW;
    2379           2 :             nPaintFlags |= PAINT_LEFT;
    2380           2 :             break;
    2381             :         case DEL_CELLSLEFT:
    2382          20 :             rDoc.DeleteCol( nStartRow, 0, nEndRow, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, NULL, &aFullMark );
    2383          20 :             nPaintEndCol = MAXCOL;
    2384          20 :             break;
    2385             :         case DEL_DELCOLS:
    2386           6 :             rDoc.DeleteCol( 0, 0, MAXROW, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &bUndoOutline, &aFullMark );
    2387           6 :             nPaintStartRow = 0;
    2388           6 :             nPaintEndRow = MAXROW;
    2389           6 :             nPaintEndCol = MAXCOL;
    2390           6 :             nPaintFlags |= PAINT_TOP;
    2391           6 :             break;
    2392             :         default:
    2393             :             OSL_FAIL("Falscher Code beim Loeschen");
    2394           0 :             break;
    2395             :     }
    2396             : 
    2397             :     //! Test, ob Outline in Groesse geaendert
    2398             : 
    2399          54 :     if ( bRecord )
    2400             :     {
    2401          54 :         itr = aFullMark.begin(), itrEnd = aFullMark.end();
    2402         108 :         for (; itr != itrEnd && *itr < nTabCount; ++itr)
    2403          54 :             pRefUndoDoc->DeleteAreaTab(nUndoStartCol,nUndoStartRow,nUndoEndCol,nUndoEndRow, *itr, IDF_ALL);
    2404             : 
    2405             :             //  alle Tabellen anlegen, damit Formeln kopiert werden koennen:
    2406          54 :         pUndoDoc->AddUndoTab( 0, nTabCount-1, false, false );
    2407             : 
    2408             :             //  kopieren mit bColRowFlags=false (#54194#)
    2409          54 :         pRefUndoDoc->CopyToDocument(0,0,0,MAXCOL,MAXROW,MAXTAB,IDF_FORMULA,false,pUndoDoc,NULL,false);
    2410          54 :         delete pRefUndoDoc;
    2411             : 
    2412          54 :         SCTAB* pTabs      = new SCTAB[nSelCount];
    2413          54 :         SCTAB* pScenarios = new SCTAB[nSelCount];
    2414          54 :         SCTAB   nUndoPos  = 0;
    2415             : 
    2416          54 :         itr = aMark.begin(), itrEnd = aMark.end();
    2417         108 :         for (; itr != itrEnd && *itr < nTabCount; ++itr)
    2418             :         {
    2419          54 :             SCTAB nCount = 0;
    2420          54 :             for( SCTAB j=*itr+1; j<nTabCount && rDoc.IsScenario(j); j++ )
    2421           0 :                 nCount ++;
    2422             : 
    2423          54 :             pScenarios[nUndoPos] = nCount;
    2424          54 :             pTabs[nUndoPos] = *itr;
    2425          54 :             nUndoPos ++;
    2426             :         }
    2427             : 
    2428          54 :         if( !bDeletingMerge )
    2429             :         {
    2430          54 :             rDocShell.GetUndoManager()->LeaveListAction();
    2431             :         }
    2432             : 
    2433          54 :         rDocShell.GetUndoManager()->AddUndoAction( new ScUndoDeleteCells(
    2434             :             &rDocShell, ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab ),nUndoPos, pTabs, pScenarios,
    2435          54 :             eCmd, pUndoDoc, pUndoData ) );
    2436             :     }
    2437             : 
    2438             :     // #i8302 want to be able to insert into the middle of merged cells
    2439             :     // the patch comes from maoyg
    2440             : 
    2441         108 :     while( !qDecreaseRange.empty() )
    2442             :     {
    2443           0 :         ScRange aRange = qDecreaseRange.back();
    2444             : 
    2445           0 :         long nDecreaseRowCount = 0;
    2446           0 :         long nDecreaseColCount = 0;
    2447           0 :         if( eCmd == DEL_CELLSUP || eCmd == DEL_DELROWS )
    2448             :         {
    2449           0 :             if( nStartRow >= aRange.aStart.Row() && nStartRow <= aRange.aEnd.Row() && nEndRow>= aRange.aStart.Row() && nEndRow <= aRange.aEnd.Row() )
    2450           0 :                 nDecreaseRowCount = nEndRow-nStartRow+1;
    2451           0 :             else if( nStartRow >= aRange.aStart.Row() && nStartRow <= aRange.aEnd.Row() && nEndRow >= aRange.aStart.Row() && nEndRow >= aRange.aEnd.Row() )
    2452           0 :                 nDecreaseRowCount = aRange.aEnd.Row()-nStartRow+1;
    2453           0 :             else if( nStartRow >= aRange.aStart.Row() && nStartRow >= aRange.aEnd.Row() && nEndRow>= aRange.aStart.Row() && nEndRow <= aRange.aEnd.Row() )
    2454           0 :                 nDecreaseRowCount = aRange.aEnd.Row()-nEndRow+1;
    2455             :         }
    2456           0 :         else if( eCmd == DEL_CELLSLEFT || eCmd == DEL_DELCOLS )
    2457             :         {
    2458           0 :             if( nStartCol >= aRange.aStart.Col() && nStartCol <= aRange.aEnd.Col() && nEndCol>= aRange.aStart.Col() && nEndCol <= aRange.aEnd.Col() )
    2459           0 :                 nDecreaseColCount = nEndCol-nStartCol+1;
    2460           0 :             else if( nStartCol >= aRange.aStart.Col() && nStartCol <= aRange.aEnd.Col() && nEndCol >= aRange.aStart.Col() && nEndCol >= aRange.aEnd.Col() )
    2461           0 :                 nDecreaseColCount = aRange.aEnd.Col()-nStartCol+1;
    2462           0 :             else if( nStartCol >= aRange.aStart.Col() && nStartCol >= aRange.aEnd.Col() && nEndCol>= aRange.aStart.Col() && nEndCol <= aRange.aEnd.Col() )
    2463           0 :                 nDecreaseColCount = aRange.aEnd.Col()-nEndCol+1;
    2464             :         }
    2465             : 
    2466           0 :         switch (eCmd)
    2467             :         {
    2468             :             case DEL_CELLSUP:
    2469             :             case DEL_DELROWS:
    2470           0 :                 aRange.aEnd.SetRow(static_cast<SCsCOL>( aRange.aEnd.Row()-nDecreaseRowCount));
    2471           0 :                 break;
    2472             :             case DEL_CELLSLEFT:
    2473             :             case DEL_DELCOLS:
    2474           0 :                 aRange.aEnd.SetCol(static_cast<SCsCOL>( aRange.aEnd.Col()-nDecreaseColCount));
    2475           0 :                 break;
    2476             :             default:
    2477           0 :                 break;
    2478             :         }
    2479             : 
    2480           0 :         if( !rDoc.HasAttrib( aRange, HASATTR_OVERLAPPED | HASATTR_MERGED ) )
    2481             :         {
    2482           0 :             ScCellMergeOption aMergeOption(aRange);
    2483           0 :             MergeCells( aMergeOption, false, true, true );
    2484             :         }
    2485           0 :         qDecreaseRange.pop_back();
    2486             :     }
    2487             : 
    2488          54 :     if( bDeletingMerge )
    2489           0 :         rDocShell.GetUndoManager()->LeaveListAction();
    2490             : 
    2491          54 :     if ( bNeedRefresh )
    2492             :     {
    2493             :         // #i51445# old merge flag attributes must be deleted also for single cells,
    2494             :         // not only for whole columns/rows
    2495             : 
    2496           0 :         if ( eCmd==DEL_DELCOLS || eCmd==DEL_CELLSLEFT )
    2497           0 :             nMergeTestEndCol = MAXCOL;
    2498           0 :         if ( eCmd==DEL_DELROWS || eCmd==DEL_CELLSUP )
    2499           0 :             nMergeTestEndRow = MAXROW;
    2500           0 :         ScPatternAttr aPattern( rDoc.GetPool() );
    2501           0 :         aPattern.GetItemSet().Put( ScMergeFlagAttr() );
    2502             : 
    2503           0 :         rDoc.ApplyPatternArea( nExtendStartCol, nExtendStartRow, nMergeTestEndCol, nMergeTestEndRow, aMark, aPattern );
    2504             : 
    2505           0 :         itr = aMark.begin(), itrEnd = aMark.end();
    2506           0 :         for (; itr != itrEnd && *itr < nTabCount; ++itr)
    2507             :         {
    2508           0 :             SCTAB nScenarioCount = 0;
    2509             : 
    2510           0 :             for( SCTAB j = *itr+1; j<nTabCount && rDoc.IsScenario(j); j++ )
    2511           0 :                 nScenarioCount ++;
    2512             : 
    2513           0 :             ScRange aMergedRange( nExtendStartCol, nExtendStartRow, *itr, nMergeTestEndCol, nMergeTestEndRow, *itr+nScenarioCount );
    2514           0 :             rDoc.ExtendMerge( aMergedRange, true );
    2515           0 :         }
    2516             :     }
    2517             : 
    2518          54 :     itr = aMark.begin(), itrEnd = aMark.end();
    2519         108 :     for (; itr != itrEnd && *itr < nTabCount; ++itr)
    2520             :     {
    2521          54 :         rDoc.SetDrawPageSize(*itr);
    2522             : 
    2523          54 :         if ( eCmd == DEL_DELCOLS || eCmd == DEL_DELROWS )
    2524           8 :             rDoc.UpdatePageBreaks( *itr );
    2525             : 
    2526          54 :         rDocShell.UpdatePaintExt( nExtFlags, nPaintStartCol, nPaintStartRow, *itr, nPaintEndCol, nPaintEndRow, *itr );
    2527             : 
    2528          54 :         SCTAB nScenarioCount = 0;
    2529             : 
    2530          54 :         for( SCTAB j = *itr+1; j<nTabCount && rDoc.IsScenario(j); j++ )
    2531           0 :             nScenarioCount ++;
    2532             : 
    2533             :         //  ganze Zeilen loeschen: nichts anpassen
    2534          54 :         if ( eCmd == DEL_DELROWS || !AdjustRowHeight(ScRange( 0, nPaintStartRow, *itr, MAXCOL, nPaintEndRow, *itr+nScenarioCount )) )
    2535          52 :             rDocShell.PostPaint( nPaintStartCol, nPaintStartRow, *itr, nPaintEndCol, nPaintEndRow, *itr+nScenarioCount, nPaintFlags,  nExtFlags );
    2536             :         else
    2537             :         {
    2538             :             //  paint only what is not done by AdjustRowHeight
    2539           2 :             if (nExtFlags & SC_PF_LINES)
    2540           2 :                 lcl_PaintAbove( rDocShell, ScRange( nPaintStartCol, nPaintStartRow, *itr, nPaintEndCol, nPaintEndRow, *itr+nScenarioCount) );
    2541           2 :             if (nPaintFlags & PAINT_TOP)
    2542           0 :                 rDocShell.PostPaint( nPaintStartCol, nPaintStartRow, *itr, nPaintEndCol, nPaintEndRow, *itr+nScenarioCount, PAINT_TOP );
    2543             :         }
    2544             :     }
    2545             : 
    2546          54 :     aModificator.SetDocumentModified();
    2547             : 
    2548          54 :     SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
    2549             : 
    2550         108 :     return true;
    2551             : }
    2552             : 
    2553          34 : bool ScDocFunc::MoveBlock( const ScRange& rSource, const ScAddress& rDestPos,
    2554             :                                 bool bCut, bool bRecord, bool bPaint, bool bApi )
    2555             : {
    2556          34 :     ScDocShellModificator aModificator( rDocShell );
    2557             : 
    2558          34 :     SCCOL nStartCol = rSource.aStart.Col();
    2559          34 :     SCROW nStartRow = rSource.aStart.Row();
    2560          34 :     SCTAB nStartTab = rSource.aStart.Tab();
    2561          34 :     SCCOL nEndCol = rSource.aEnd.Col();
    2562          34 :     SCROW nEndRow = rSource.aEnd.Row();
    2563          34 :     SCTAB nEndTab = rSource.aEnd.Tab();
    2564          34 :     SCCOL nDestCol = rDestPos.Col();
    2565          34 :     SCROW nDestRow = rDestPos.Row();
    2566          34 :     SCTAB nDestTab = rDestPos.Tab();
    2567             : 
    2568          34 :     if ( !ValidRow(nStartRow) || !ValidRow(nEndRow) || !ValidRow(nDestRow) )
    2569             :     {
    2570             :         OSL_FAIL("invalid row in MoveBlock");
    2571           0 :         return false;
    2572             :     }
    2573             : 
    2574             :     //  zugehoerige Szenarien auch anpassen - nur wenn innerhalb einer Tabelle verschoben wird!
    2575          34 :     bool bScenariosAdded = false;
    2576          34 :     ScDocument& rDoc = rDocShell.GetDocument();
    2577          34 :     if (bRecord && !rDoc.IsUndoEnabled())
    2578           0 :         bRecord = false;
    2579             : 
    2580          34 :     SCTAB nTabCount = rDoc.GetTableCount();
    2581          34 :     if ( nDestTab == nStartTab && !rDoc.IsScenario(nEndTab) )
    2582          56 :         while ( nEndTab+1 < nTabCount && rDoc.IsScenario(nEndTab+1) )
    2583             :         {
    2584           0 :             ++nEndTab;
    2585           0 :             bScenariosAdded = true;
    2586             :         }
    2587             : 
    2588          34 :     SCTAB nSrcTabCount = nEndTab-nStartTab+1;
    2589          34 :     SCTAB nDestEndTab = nDestTab+nSrcTabCount-1;
    2590             :     SCTAB nTab;
    2591             : 
    2592          34 :     ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
    2593             : 
    2594          68 :     ScMarkData aSourceMark;
    2595          68 :     for (nTab=nStartTab; nTab<=nEndTab; nTab++)
    2596          34 :         aSourceMark.SelectTable( nTab, true );      // Source selektieren
    2597          34 :     aSourceMark.SetMarkArea( rSource );
    2598             : 
    2599          68 :     ScDocShellRef aDragShellRef;
    2600          34 :     if ( rDoc.HasOLEObjectsInArea( rSource ) )
    2601             :     {
    2602           0 :         aDragShellRef = new ScDocShell;     // DocShell needs a Ref immediately
    2603           0 :         aDragShellRef->DoInitNew(NULL);
    2604             :     }
    2605          34 :     ScDrawLayer::SetGlobalDrawPersist(aDragShellRef);
    2606             : 
    2607          68 :     ScClipParam aClipParam(ScRange(nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nStartTab), bCut);
    2608          34 :     rDoc.CopyToClip(aClipParam, pClipDoc, &aSourceMark, false, bScenariosAdded, true);
    2609             : 
    2610          34 :     ScDrawLayer::SetGlobalDrawPersist(NULL);
    2611             : 
    2612          34 :     SCCOL nOldEndCol = nEndCol;
    2613          34 :     SCROW nOldEndRow = nEndRow;
    2614          34 :     bool bClipOver = false;
    2615          68 :     for (nTab=nStartTab; nTab<=nEndTab; nTab++)
    2616             :     {
    2617          34 :         SCCOL nTmpEndCol = nOldEndCol;
    2618          34 :         SCROW nTmpEndRow = nOldEndRow;
    2619          34 :         if (rDoc.ExtendMerge( nStartCol, nStartRow, nTmpEndCol, nTmpEndRow, nTab ))
    2620           0 :             bClipOver = true;
    2621          34 :         if ( nTmpEndCol > nEndCol ) nEndCol = nTmpEndCol;
    2622          34 :         if ( nTmpEndRow > nEndRow ) nEndRow = nTmpEndRow;
    2623             :     }
    2624             : 
    2625          34 :     SCCOL nDestEndCol = nDestCol + ( nOldEndCol-nStartCol );
    2626          34 :     SCROW nDestEndRow = nDestRow + ( nOldEndRow-nStartRow );
    2627             : 
    2628          34 :     SCCOL nUndoEndCol = nDestCol + ( nEndCol-nStartCol );       // erweitert im Zielblock
    2629          34 :     SCROW nUndoEndRow = nDestRow + ( nEndRow-nStartRow );
    2630             : 
    2631          34 :     bool bIncludeFiltered = bCut;
    2632          34 :     if ( !bIncludeFiltered )
    2633             :     {
    2634             :         //  adjust sizes to include only non-filtered rows
    2635             : 
    2636             :         SCCOL nClipX;
    2637             :         SCROW nClipY;
    2638           8 :         pClipDoc->GetClipArea( nClipX, nClipY, false );
    2639           8 :         SCROW nUndoAdd = nUndoEndRow - nDestEndRow;
    2640           8 :         nDestEndRow = nDestRow + nClipY;
    2641           8 :         nUndoEndRow = nDestEndRow + nUndoAdd;
    2642             :     }
    2643             : 
    2644          34 :     if (!ValidCol(nUndoEndCol) || !ValidRow(nUndoEndRow))
    2645             :     {
    2646           0 :         if (!bApi)
    2647           0 :             rDocShell.ErrorMessage(STR_PASTE_FULL);
    2648           0 :         delete pClipDoc;
    2649           0 :         return false;
    2650             :     }
    2651             : 
    2652             :     //  Test auf Zellschutz
    2653             : 
    2654          34 :     ScEditableTester aTester;
    2655          68 :     for (nTab=nDestTab; nTab<=nDestEndTab; nTab++)
    2656          34 :         aTester.TestBlock( &rDoc, nTab, nDestCol,nDestRow, nUndoEndCol,nUndoEndRow );
    2657          34 :     if (bCut)
    2658          52 :         for (nTab=nStartTab; nTab<=nEndTab; nTab++)
    2659          26 :             aTester.TestBlock( &rDoc, nTab, nStartCol,nStartRow, nEndCol,nEndRow );
    2660             : 
    2661          34 :     if (!aTester.IsEditable())
    2662             :     {
    2663           0 :         if (!bApi)
    2664           0 :             rDocShell.ErrorMessage(aTester.GetMessageId());
    2665           0 :         delete pClipDoc;
    2666           0 :         return false;
    2667             :     }
    2668             : 
    2669             :     //  Test auf zusammengefasste - beim Verschieben erst nach dem Loeschen
    2670             : 
    2671          34 :     if (bClipOver && !bCut)
    2672           0 :         if (rDoc.HasAttrib( nDestCol,nDestRow,nDestTab, nUndoEndCol,nUndoEndRow,nDestEndTab,
    2673           0 :                                 HASATTR_MERGED | HASATTR_OVERLAPPED ))
    2674             :         {       // "Zusammenfassen nicht verschachteln !"
    2675           0 :             if (!bApi)
    2676           0 :                 rDocShell.ErrorMessage(STR_MSSG_MOVEBLOCKTO_0);
    2677           0 :             delete pClipDoc;
    2678           0 :             return false;
    2679             :         }
    2680             : 
    2681             :     //  Are there borders in the cells? (for painting)
    2682             : 
    2683          34 :     sal_uInt16 nSourceExt = 0;
    2684          34 :     rDocShell.UpdatePaintExt( nSourceExt, nStartCol,nStartRow,nStartTab, nEndCol,nEndRow,nEndTab );
    2685          34 :     sal_uInt16 nDestExt = 0;
    2686          34 :     rDocShell.UpdatePaintExt( nDestExt, nDestCol,nDestRow,nDestTab, nDestEndCol,nDestEndRow,nDestEndTab );
    2687             : 
    2688             :     //  ausfuehren
    2689             : 
    2690          34 :     ScDocument* pUndoDoc = NULL;
    2691             : 
    2692          34 :     if (bRecord)
    2693             :     {
    2694          24 :         bool bWholeCols = ( nStartRow == 0 && nEndRow == MAXROW );
    2695          24 :         bool bWholeRows = ( nStartCol == 0 && nEndCol == MAXCOL );
    2696          24 :         InsertDeleteFlags nUndoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS;
    2697             : 
    2698          24 :         pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
    2699          24 :         pUndoDoc->InitUndo( &rDoc, nStartTab, nEndTab, bWholeCols, bWholeRows );
    2700             : 
    2701          24 :         if (bCut)
    2702             :         {
    2703             :             rDoc.CopyToDocument( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
    2704          18 :                                     nUndoFlags, false, pUndoDoc );
    2705             :         }
    2706             : 
    2707          24 :         if ( nDestTab != nStartTab )
    2708           6 :             pUndoDoc->AddUndoTab( nDestTab, nDestEndTab, bWholeCols, bWholeRows );
    2709             :         rDoc.CopyToDocument( nDestCol, nDestRow, nDestTab,
    2710             :                                     nDestEndCol, nDestEndRow, nDestEndTab,
    2711          24 :                                     nUndoFlags, false, pUndoDoc );
    2712          24 :         rDoc.BeginDrawUndo();
    2713             :     }
    2714             : 
    2715          34 :     bool bSourceHeight = false;     // Hoehen angepasst?
    2716          34 :     if (bCut)
    2717             :     {
    2718          26 :         ScMarkData aDelMark;    // only for tables
    2719          52 :         for (nTab=nStartTab; nTab<=nEndTab; nTab++)
    2720             :         {
    2721          26 :             rDoc.DeleteAreaTab( nStartCol,nStartRow, nOldEndCol,nOldEndRow, nTab, IDF_ALL );
    2722          26 :             aDelMark.SelectTable( nTab, true );
    2723             :         }
    2724          26 :         rDoc.DeleteObjectsInArea( nStartCol,nStartRow, nOldEndCol,nOldEndRow, aDelMark );
    2725             : 
    2726             :         //  Test auf zusammengefasste
    2727             : 
    2728          26 :         if (bClipOver)
    2729           0 :             if (rDoc.HasAttrib( nDestCol,nDestRow,nDestTab,
    2730             :                                     nUndoEndCol,nUndoEndRow,nDestEndTab,
    2731           0 :                                     HASATTR_MERGED | HASATTR_OVERLAPPED ))
    2732             :             {
    2733           0 :                 rDoc.CopyFromClip( rSource, aSourceMark, IDF_ALL, NULL, pClipDoc );
    2734           0 :                 for (nTab=nStartTab; nTab<=nEndTab; nTab++)
    2735             :                 {
    2736           0 :                     SCCOL nTmpEndCol = nEndCol;
    2737           0 :                     SCROW nTmpEndRow = nEndRow;
    2738           0 :                     rDoc.ExtendMerge( nStartCol, nStartRow, nTmpEndCol, nTmpEndRow, nTab, true );
    2739             :                 }
    2740             : 
    2741             :                 //  Fehlermeldung erst nach dem Wiederherstellen des Inhalts
    2742           0 :                 if (!bApi)      // "Zusammenfassen nicht verschachteln !"
    2743           0 :                     rDocShell.ErrorMessage(STR_MSSG_MOVEBLOCKTO_0);
    2744             : 
    2745           0 :                 delete pUndoDoc;
    2746           0 :                 delete pClipDoc;
    2747           0 :                 return false;
    2748             :             }
    2749             : 
    2750          26 :         bSourceHeight = AdjustRowHeight( rSource, false );
    2751             :     }
    2752             : 
    2753          34 :     ScRange aPasteDest( nDestCol, nDestRow, nDestTab, nDestEndCol, nDestEndRow, nDestEndTab );
    2754             : 
    2755          68 :     ScMarkData aDestMark;
    2756          68 :     for (nTab=nDestTab; nTab<=nDestEndTab; nTab++)
    2757          34 :         aDestMark.SelectTable( nTab, true );        // Destination selektieren
    2758          34 :     aDestMark.SetMarkArea( aPasteDest );
    2759             : 
    2760             :     /*  Do not drawing objects here. While pasting, the
    2761             :         function ScDocument::UpdateReference() is called which calls
    2762             :         ScDrawLayer::MoveCells() which may move away inserted objects to wrong
    2763             :         positions (e.g. if source and destination range overlaps).*/
    2764             :     rDoc.CopyFromClip( aPasteDest, aDestMark, IDF_ALL & ~(IDF_OBJECTS),
    2765          34 :                         NULL, pClipDoc, true, false, bIncludeFiltered );
    2766             : 
    2767             :     // skipped rows and merged cells don't mix
    2768          34 :     if ( !bIncludeFiltered && pClipDoc->HasClipFilteredRows() )
    2769           0 :         UnmergeCells( aPasteDest, false );
    2770             : 
    2771          68 :     VirtualDevice aVirtDev;
    2772             :     bool bDestHeight = AdjustRowHeight(
    2773             :                             ScRange( 0,nDestRow,nDestTab, MAXCOL,nDestEndRow,nDestEndTab ),
    2774          34 :                             false );
    2775             : 
    2776             :     /*  Paste drawing objects after adjusting formula references
    2777             :         and row heights. There are no cell notes or drawing objects, if the
    2778             :         clipdoc does not contain a drawing layer.*/
    2779          34 :     if ( pClipDoc->GetDrawLayer() )
    2780             :         rDoc.CopyFromClip( aPasteDest, aDestMark, IDF_OBJECTS,
    2781           0 :                            NULL, pClipDoc, true, false, bIncludeFiltered );
    2782             : 
    2783          34 :     if (bRecord)
    2784             :     {
    2785          24 :         rDocShell.GetUndoManager()->AddUndoAction(
    2786             :             new ScUndoDragDrop( &rDocShell, ScRange(
    2787             :                                     nStartCol, nStartRow, nStartTab,
    2788             :                                     nOldEndCol, nOldEndRow, nEndTab ),
    2789             :                                 ScAddress( nDestCol, nDestRow, nDestTab ),
    2790          24 :                                 bCut, pUndoDoc, NULL, bScenariosAdded ) );
    2791             :     }
    2792             : 
    2793          34 :     SCCOL nDestPaintEndCol = nDestEndCol;
    2794          34 :     SCROW nDestPaintEndRow = nDestEndRow;
    2795          68 :     for (nTab=nDestTab; nTab<=nDestEndTab; nTab++)
    2796             :     {
    2797          34 :         SCCOL nTmpEndCol = nDestEndCol;
    2798          34 :         SCROW nTmpEndRow = nDestEndRow;
    2799          34 :         rDoc.ExtendMerge( nDestCol, nDestRow, nTmpEndCol, nTmpEndRow, nTab, true );
    2800          34 :         if (nTmpEndCol > nDestPaintEndCol) nDestPaintEndCol = nTmpEndCol;
    2801          34 :         if (nTmpEndRow > nDestPaintEndRow) nDestPaintEndRow = nTmpEndRow;
    2802             :     }
    2803             : 
    2804          34 :     if (bCut)
    2805          52 :         for (nTab=nStartTab; nTab<=nEndTab; nTab++)
    2806          26 :             rDoc.RefreshAutoFilter( nStartCol, nStartRow, nEndCol, nEndRow, nTab );
    2807             : 
    2808          34 :     if (bPaint)
    2809             :     {
    2810             :             //  Zielbereich:
    2811             : 
    2812           6 :         SCCOL nPaintStartX = nDestCol;
    2813           6 :         SCROW nPaintStartY = nDestRow;
    2814           6 :         SCCOL nPaintEndX = nDestPaintEndCol;
    2815           6 :         SCROW nPaintEndY = nDestPaintEndRow;
    2816           6 :         sal_uInt16 nFlags = PAINT_GRID;
    2817             : 
    2818           6 :         if ( nStartRow==0 && nEndRow==MAXROW )      // Breiten mitkopiert?
    2819             :         {
    2820           0 :             nPaintEndX = MAXCOL;
    2821           0 :             nPaintStartY = 0;
    2822           0 :             nPaintEndY = MAXROW;
    2823           0 :             nFlags |= PAINT_TOP;
    2824             :         }
    2825           6 :         if ( bDestHeight || ( nStartCol == 0 && nEndCol == MAXCOL ) )
    2826             :         {
    2827           0 :             nPaintEndY = MAXROW;
    2828           0 :             nPaintStartX = 0;
    2829           0 :             nPaintEndX = MAXCOL;
    2830           0 :             nFlags |= PAINT_LEFT;
    2831             :         }
    2832           6 :         if ( bScenariosAdded )
    2833             :         {
    2834           0 :             nPaintStartX = 0;
    2835           0 :             nPaintStartY = 0;
    2836           0 :             nPaintEndX = MAXCOL;
    2837           0 :             nPaintEndY = MAXROW;
    2838             :         }
    2839             : 
    2840             :         rDocShell.PostPaint( nPaintStartX,nPaintStartY,nDestTab,
    2841           6 :                             nPaintEndX,nPaintEndY,nDestEndTab, nFlags, nSourceExt | nDestExt );
    2842             : 
    2843           6 :         if ( bCut )
    2844             :         {
    2845             :                 //  Quellbereich:
    2846             : 
    2847           2 :             nPaintStartX = nStartCol;
    2848           2 :             nPaintStartY = nStartRow;
    2849           2 :             nPaintEndX = nEndCol;
    2850           2 :             nPaintEndY = nEndRow;
    2851           2 :             nFlags = PAINT_GRID;
    2852             : 
    2853           2 :             if ( bSourceHeight )
    2854             :             {
    2855           0 :                 nPaintEndY = MAXROW;
    2856           0 :                 nPaintStartX = 0;
    2857           0 :                 nPaintEndX = MAXCOL;
    2858           0 :                 nFlags |= PAINT_LEFT;
    2859             :             }
    2860           2 :             if ( bScenariosAdded )
    2861             :             {
    2862           0 :                 nPaintStartX = 0;
    2863           0 :                 nPaintStartY = 0;
    2864           0 :                 nPaintEndX = MAXCOL;
    2865           0 :                 nPaintEndY = MAXROW;
    2866             :             }
    2867             : 
    2868             :             rDocShell.PostPaint( nPaintStartX,nPaintStartY,nStartTab,
    2869           2 :                                 nPaintEndX,nPaintEndY,nEndTab, nFlags, nSourceExt );
    2870             :         }
    2871             :     }
    2872             : 
    2873          34 :     aModificator.SetDocumentModified();
    2874             : 
    2875          34 :     SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
    2876             : 
    2877          34 :     delete pClipDoc;
    2878          68 :     return true;
    2879             : }
    2880             : 
    2881           0 : uno::Reference< uno::XInterface > GetDocModuleObject( SfxObjectShell& rDocSh, OUString& sCodeName )
    2882             : {
    2883           0 :     uno::Reference< lang::XMultiServiceFactory> xSF(rDocSh.GetModel(), uno::UNO_QUERY);
    2884           0 :     uno::Reference< container::XNameAccess > xVBACodeNamedObjectAccess;
    2885           0 :     uno::Reference< uno::XInterface > xDocModuleApiObject;
    2886           0 :     if ( xSF.is() )
    2887             :     {
    2888           0 :         xVBACodeNamedObjectAccess.set( xSF->createInstance("ooo.vba.VBAObjectModuleObjectProvider"), uno::UNO_QUERY );
    2889           0 :         xDocModuleApiObject.set( xVBACodeNamedObjectAccess->getByName( sCodeName ), uno::UNO_QUERY );
    2890             :     }
    2891           0 :     return xDocModuleApiObject;
    2892             : 
    2893             : }
    2894             : 
    2895           0 : static script::ModuleInfo lcl_InitModuleInfo( SfxObjectShell& rDocSh, OUString& sModule )
    2896             : {
    2897           0 :     script::ModuleInfo sModuleInfo;
    2898           0 :     sModuleInfo.ModuleType = script::ModuleType::DOCUMENT;
    2899           0 :     sModuleInfo.ModuleObject = GetDocModuleObject( rDocSh, sModule );
    2900           0 :     return sModuleInfo;
    2901             : }
    2902             : 
    2903           0 : void VBA_InsertModule( ScDocument& rDoc, SCTAB nTab, const OUString& sModuleName, const OUString& sSource )
    2904             : {
    2905           0 :     SfxObjectShell& rDocSh = *rDoc.GetDocumentShell();
    2906           0 :     uno::Reference< script::XLibraryContainer > xLibContainer = rDocSh.GetBasicContainer();
    2907             :     OSL_ENSURE( xLibContainer.is(), "No BasicContainer!" );
    2908             : 
    2909           0 :     uno::Reference< container::XNameContainer > xLib;
    2910           0 :     if( xLibContainer.is() )
    2911             :     {
    2912           0 :         OUString aLibName( "Standard" );
    2913           0 :         if ( rDocSh.GetBasicManager() && !rDocSh.GetBasicManager()->GetName().isEmpty() )
    2914             :         {
    2915           0 :             aLibName = rDocSh.GetBasicManager()->GetName();
    2916             :         }
    2917           0 :         uno::Any aLibAny = xLibContainer->getByName( aLibName );
    2918           0 :         aLibAny >>= xLib;
    2919             :     }
    2920           0 :     if( xLib.is() )
    2921             :     {
    2922             :         // if the Module with codename exists then find a new name
    2923           0 :         sal_Int32 nNum = 0;
    2924           0 :         OUString genModuleName;
    2925           0 :         if ( !sModuleName.isEmpty() )
    2926           0 :             genModuleName = sModuleName;
    2927             :         else
    2928             :         {
    2929           0 :              genModuleName = "Sheet1";
    2930           0 :              nNum = 1;
    2931             :         }
    2932           0 :         while( xLib->hasByName( genModuleName ) )
    2933           0 :             genModuleName = "Sheet" + OUString::number( ++nNum );
    2934             : 
    2935           0 :         uno::Any aSourceAny;
    2936           0 :         OUString sTmpSource = sSource;
    2937           0 :         if ( sTmpSource.isEmpty() )
    2938           0 :             sTmpSource = "Rem Attribute VBA_ModuleType=VBADocumentModule\nOption VBASupport 1\n";
    2939           0 :         aSourceAny <<= sTmpSource;
    2940           0 :         uno::Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY );
    2941           0 :         if ( xVBAModuleInfo.is() )
    2942             :         {
    2943           0 :             rDoc.SetCodeName( nTab, genModuleName );
    2944           0 :             script::ModuleInfo sModuleInfo = lcl_InitModuleInfo(  rDocSh, genModuleName );
    2945           0 :             xVBAModuleInfo->insertModuleInfo( genModuleName, sModuleInfo );
    2946           0 :             xLib->insertByName( genModuleName, aSourceAny );
    2947           0 :         }
    2948             : 
    2949           0 :     }
    2950           0 : }
    2951             : 
    2952           0 : void VBA_DeleteModule( ScDocShell& rDocSh, const OUString& sModuleName )
    2953             : {
    2954           0 :     uno::Reference< script::XLibraryContainer > xLibContainer = rDocSh.GetBasicContainer();
    2955             :     OSL_ENSURE( xLibContainer.is(), "No BasicContainer!" );
    2956             : 
    2957           0 :     uno::Reference< container::XNameContainer > xLib;
    2958           0 :     if( xLibContainer.is() )
    2959             :     {
    2960           0 :         OUString aLibName( "Standard" );
    2961           0 :         if ( rDocSh.GetBasicManager() && !rDocSh.GetBasicManager()->GetName().isEmpty() )
    2962             :         {
    2963           0 :             aLibName = rDocSh.GetBasicManager()->GetName();
    2964             :         }
    2965           0 :         uno::Any aLibAny = xLibContainer->getByName( aLibName );
    2966           0 :         aLibAny >>= xLib;
    2967             :     }
    2968           0 :     if( xLib.is() )
    2969             :     {
    2970           0 :         uno::Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY );
    2971           0 :         if( xLib->hasByName( sModuleName ) )
    2972           0 :             xLib->removeByName( sModuleName );
    2973           0 :         if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo(sModuleName) )
    2974           0 :             xVBAModuleInfo->removeModuleInfo( sModuleName );
    2975             : 
    2976           0 :     }
    2977           0 : }
    2978             : 
    2979         206 : bool ScDocFunc::InsertTable( SCTAB nTab, const OUString& rName, bool bRecord, bool bApi )
    2980             : {
    2981         206 :     bool bSuccess = false;
    2982         206 :     WaitObject aWait( rDocShell.GetActiveDialogParent() );
    2983             : 
    2984         412 :     ScDocShellModificator aModificator( rDocShell );
    2985             : 
    2986         206 :     ScDocument& rDoc = rDocShell.GetDocument();
    2987             : 
    2988             :     // Strange loop, also basic is loaded too early ( InsertTable )
    2989             :     // is called via the xml import for sheets in described in ODF
    2990         206 :     bool bInsertDocModule = false;
    2991             : 
    2992         206 :     if(  !rDocShell.GetDocument().IsImportingXML() )
    2993             :     {
    2994         206 :         bInsertDocModule = rDoc.IsInVBAMode();
    2995             :     }
    2996         206 :     if ( bInsertDocModule || ( bRecord && !rDoc.IsUndoEnabled() ) )
    2997         132 :         bRecord = false;
    2998             : 
    2999         206 :     if (bRecord)
    3000          74 :         rDoc.BeginDrawUndo();                          //  InsertTab erzeugt ein SdrUndoNewPage
    3001             : 
    3002         206 :     SCTAB nTabCount = rDoc.GetTableCount();
    3003         206 :     bool bAppend = ( nTab >= nTabCount );
    3004         206 :     if ( bAppend )
    3005         148 :         nTab = nTabCount;       // wichtig fuer Undo
    3006             : 
    3007         206 :     if (rDoc.InsertTab( nTab, rName ))
    3008             :     {
    3009         206 :         if (bRecord)
    3010          74 :             rDocShell.GetUndoManager()->AddUndoAction(
    3011          74 :                         new ScUndoInsertTab( &rDocShell, nTab, bAppend, rName));
    3012             :         //  Views updaten:
    3013             :         // Only insert vba modules if vba mode ( and not currently importing XML )
    3014         206 :         if( bInsertDocModule )
    3015             :         {
    3016           0 :             OUString sSource, sCodeName;
    3017           0 :             VBA_InsertModule( rDoc, nTab, sCodeName, sSource );
    3018             :         }
    3019         206 :         rDocShell.Broadcast( ScTablesHint( SC_TAB_INSERTED, nTab ) );
    3020             : 
    3021         206 :         rDocShell.PostPaintExtras();
    3022         206 :         aModificator.SetDocumentModified();
    3023         206 :         SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
    3024         206 :         bSuccess = true;
    3025             :     }
    3026           0 :     else if (!bApi)
    3027           0 :         rDocShell.ErrorMessage(STR_TABINSERT_ERROR);
    3028             : 
    3029         412 :     return bSuccess;
    3030             : }
    3031             : 
    3032          40 : bool ScDocFunc::DeleteTable( SCTAB nTab, bool bRecord, bool /* bApi */ )
    3033             : {
    3034          40 :     WaitObject aWait( rDocShell.GetActiveDialogParent() );
    3035             : 
    3036          80 :     ScDocShellModificator aModificator( rDocShell );
    3037             : 
    3038          40 :     bool bSuccess = false;
    3039          40 :     ScDocument& rDoc = rDocShell.GetDocument();
    3040          40 :     bool bVbaEnabled = rDoc.IsInVBAMode();
    3041          40 :     if (bRecord && !rDoc.IsUndoEnabled())
    3042           0 :         bRecord = false;
    3043          40 :     if ( bVbaEnabled )
    3044           0 :         bRecord = false;
    3045          40 :     bool bWasLinked = rDoc.IsLinked(nTab);
    3046          40 :     ScDocument* pUndoDoc = NULL;
    3047          40 :     ScRefUndoData* pUndoData = NULL;
    3048          40 :     if (bRecord)
    3049             :     {
    3050          40 :         pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
    3051          40 :         SCTAB nCount = rDoc.GetTableCount();
    3052             : 
    3053          40 :         pUndoDoc->InitUndo( &rDoc, nTab, nTab, true, true );     // nur nTab mit Flags
    3054          40 :         pUndoDoc->AddUndoTab( 0, nCount-1 );                    // alle Tabs fuer Referenzen
    3055             : 
    3056          40 :         rDoc.CopyToDocument(0,0,nTab, MAXCOL,MAXROW,nTab, IDF_ALL,false, pUndoDoc );
    3057          40 :         OUString aOldName;
    3058          40 :         rDoc.GetName( nTab, aOldName );
    3059          40 :         pUndoDoc->RenameTab( nTab, aOldName, false );
    3060          40 :         if (bWasLinked)
    3061           0 :             pUndoDoc->SetLink( nTab, rDoc.GetLinkMode(nTab), rDoc.GetLinkDoc(nTab),
    3062             :                                 rDoc.GetLinkFlt(nTab), rDoc.GetLinkOpt(nTab),
    3063             :                                 rDoc.GetLinkTab(nTab),
    3064           0 :                                 rDoc.GetLinkRefreshDelay(nTab) );
    3065             : 
    3066          40 :         if ( rDoc.IsScenario(nTab) )
    3067             :         {
    3068           0 :             pUndoDoc->SetScenario( nTab, true );
    3069           0 :             OUString aComment;
    3070           0 :             Color  aColor;
    3071             :             sal_uInt16 nScenFlags;
    3072           0 :             rDoc.GetScenarioData( nTab, aComment, aColor, nScenFlags );
    3073           0 :             pUndoDoc->SetScenarioData( nTab, aComment, aColor, nScenFlags );
    3074           0 :             bool bActive = rDoc.IsActiveScenario( nTab );
    3075           0 :             pUndoDoc->SetActiveScenario( nTab, bActive );
    3076             :         }
    3077          40 :         pUndoDoc->SetVisible( nTab, rDoc.IsVisible( nTab ) );
    3078          40 :         pUndoDoc->SetTabBgColor( nTab, rDoc.GetTabBgColor(nTab) );
    3079          40 :         pUndoDoc->SetSheetEvents( nTab, rDoc.GetSheetEvents( nTab ) );
    3080             : 
    3081             :         //  Drawing-Layer muss sein Undo selbst in der Hand behalten !!!
    3082          40 :         rDoc.BeginDrawUndo();                          //  DeleteTab erzeugt ein SdrUndoDelPage
    3083             : 
    3084          40 :         pUndoData = new ScRefUndoData( &rDoc );
    3085             :     }
    3086             : 
    3087          40 :     if (rDoc.DeleteTab(nTab))
    3088             :     {
    3089          40 :         if (bRecord)
    3090             :         {
    3091          40 :             vector<SCTAB> theTabs;
    3092          40 :             theTabs.push_back(nTab);
    3093          40 :             rDocShell.GetUndoManager()->AddUndoAction(
    3094          40 :                         new ScUndoDeleteTab( &rDocShell, theTabs, pUndoDoc, pUndoData ));
    3095             :         }
    3096             :         //  Views updaten:
    3097          40 :         if( bVbaEnabled )
    3098             :         {
    3099           0 :             OUString sCodeName;
    3100           0 :             if( rDoc.GetCodeName( nTab, sCodeName ) )
    3101             :             {
    3102           0 :                 VBA_DeleteModule( rDocShell, sCodeName );
    3103           0 :             }
    3104             :         }
    3105          40 :         rDocShell.Broadcast( ScTablesHint( SC_TAB_DELETED, nTab ) );
    3106             : 
    3107          40 :         if (bWasLinked)
    3108             :         {
    3109           0 :             rDocShell.UpdateLinks();                // Link-Manager updaten
    3110           0 :             SfxBindings* pBindings = rDocShell.GetViewBindings();
    3111           0 :             if (pBindings)
    3112           0 :                 pBindings->Invalidate(SID_LINKS);
    3113             :         }
    3114             : 
    3115          40 :         rDocShell.PostPaintExtras();
    3116          40 :         aModificator.SetDocumentModified();
    3117             : 
    3118          40 :         SfxApplication* pSfxApp = SfxGetpApp();                                // Navigator
    3119          40 :         pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
    3120          40 :         pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
    3121          40 :         pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
    3122             : 
    3123          40 :         bSuccess = true;
    3124             :     }
    3125             :     else
    3126             :     {
    3127           0 :         delete pUndoDoc;
    3128           0 :         delete pUndoData;
    3129             :     }
    3130          80 :     return bSuccess;
    3131             : }
    3132             : 
    3133         970 : bool ScDocFunc::SetTableVisible( SCTAB nTab, bool bVisible, bool bApi )
    3134             : {
    3135         970 :     ScDocument& rDoc = rDocShell.GetDocument();
    3136         970 :     bool bUndo(rDoc.IsUndoEnabled());
    3137         970 :     if ( rDoc.IsVisible( nTab ) == bVisible )
    3138         966 :         return true;                                // nichts zu tun - ok
    3139             : 
    3140           4 :     if ( !rDoc.IsDocEditable() )
    3141             :     {
    3142           0 :         if (!bApi)
    3143           0 :             rDocShell.ErrorMessage(STR_PROTECTIONERR);
    3144           0 :         return false;
    3145             :     }
    3146             : 
    3147           4 :     ScDocShellModificator aModificator( rDocShell );
    3148             : 
    3149           4 :     if ( !bVisible && !rDoc.IsImportingXML() )     // #i57869# allow hiding in any order for loading
    3150             :     {
    3151             :         //  nicht alle Tabellen ausblenden
    3152             : 
    3153           2 :         sal_uInt16 nVisCount = 0;
    3154           2 :         SCTAB nCount = rDoc.GetTableCount();
    3155           6 :         for (SCTAB i=0; i<nCount && nVisCount<2; i++)
    3156           4 :             if (rDoc.IsVisible(i))
    3157           4 :                 ++nVisCount;
    3158             : 
    3159           2 :         if (nVisCount <= 1)
    3160             :         {
    3161           0 :             if (!bApi)
    3162           0 :                 rDocShell.ErrorMessage(STR_PROTECTIONERR);  //! eigene Meldung?
    3163           0 :             return false;
    3164             :         }
    3165             :     }
    3166             : 
    3167           4 :     rDoc.SetVisible( nTab, bVisible );
    3168           4 :     if (bUndo)
    3169             :     {
    3170           4 :         std::vector<SCTAB> undoTabs;
    3171           4 :         undoTabs.push_back(nTab);
    3172           4 :         rDocShell.GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( &rDocShell, undoTabs, bVisible ) );
    3173             :     }
    3174             : 
    3175             :     //  Views updaten:
    3176           4 :     if (!bVisible)
    3177           2 :         rDocShell.Broadcast( ScTablesHint( SC_TAB_HIDDEN, nTab ) );
    3178             : 
    3179           4 :     SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
    3180           4 :     rDocShell.PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
    3181           4 :     aModificator.SetDocumentModified();
    3182             : 
    3183           4 :     return true;
    3184             : }
    3185             : 
    3186         500 : bool ScDocFunc::SetLayoutRTL( SCTAB nTab, bool bRTL, bool /* bApi */ )
    3187             : {
    3188         500 :     ScDocument& rDoc = rDocShell.GetDocument();
    3189         500 :     bool bUndo(rDoc.IsUndoEnabled());
    3190         500 :     if ( rDoc.IsLayoutRTL( nTab ) == bRTL )
    3191         492 :         return true;                                // nothing to do - ok
    3192             : 
    3193             :     //! protection (sheet or document?)
    3194             : 
    3195           8 :     ScDocShellModificator aModificator( rDocShell );
    3196             : 
    3197           8 :     rDoc.SetLayoutRTL( nTab, bRTL );
    3198             : 
    3199           8 :     if (bUndo)
    3200             :     {
    3201           8 :         rDocShell.GetUndoManager()->AddUndoAction( new ScUndoLayoutRTL( &rDocShell, nTab, bRTL ) );
    3202             :     }
    3203             : 
    3204           8 :     rDocShell.PostPaint( 0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_ALL );
    3205           8 :     aModificator.SetDocumentModified();
    3206             : 
    3207           8 :     SfxBindings* pBindings = rDocShell.GetViewBindings();
    3208           8 :     if (pBindings)
    3209             :     {
    3210           8 :         pBindings->Invalidate( FID_TAB_RTL );
    3211           8 :         pBindings->Invalidate( SID_ATTR_SIZE );
    3212             :     }
    3213             : 
    3214           8 :     return true;
    3215             : }
    3216             : 
    3217          30 : bool ScDocFunc::RenameTable( SCTAB nTab, const OUString& rName, bool bRecord, bool bApi )
    3218             : {
    3219          30 :     ScDocument& rDoc = rDocShell.GetDocument();
    3220          30 :     if (bRecord && !rDoc.IsUndoEnabled())
    3221          20 :         bRecord = false;
    3222          30 :     if ( !rDoc.IsDocEditable() )
    3223             :     {
    3224           0 :         if (!bApi)
    3225           0 :             rDocShell.ErrorMessage(STR_PROTECTIONERR);
    3226           0 :         return false;
    3227             :     }
    3228             : 
    3229          30 :     ScDocShellModificator aModificator( rDocShell );
    3230             : 
    3231          30 :     bool bSuccess = false;
    3232          60 :     OUString sOldName;
    3233          30 :     rDoc.GetName(nTab, sOldName);
    3234          30 :     if (rDoc.RenameTab( nTab, rName ))
    3235             :     {
    3236          28 :         if (bRecord)
    3237             :         {
    3238           4 :             rDocShell.GetUndoManager()->AddUndoAction(
    3239           4 :                             new ScUndoRenameTab( &rDocShell, nTab, sOldName, rName));
    3240             :         }
    3241          28 :         rDocShell.PostPaintExtras();
    3242          28 :         aModificator.SetDocumentModified();
    3243          28 :         SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
    3244             : 
    3245          28 :         bSuccess = true;
    3246             :     }
    3247          60 :     return bSuccess;
    3248             : }
    3249             : 
    3250          42 : bool ScDocFunc::SetTabBgColor( SCTAB nTab, const Color& rColor, bool bRecord, bool bApi )
    3251             : {
    3252             : 
    3253          42 :     ScDocument& rDoc = rDocShell.GetDocument();
    3254          42 :     if (bRecord && !rDoc.IsUndoEnabled())
    3255          38 :         bRecord = false;
    3256          42 :     if ( !rDoc.IsDocEditable() || rDoc.IsTabProtected(nTab) )
    3257             :     {
    3258           0 :         if (!bApi)
    3259           0 :             rDocShell.ErrorMessage(STR_PROTECTIONERR); //TODO Check to see what this string is...
    3260           0 :         return false;
    3261             :     }
    3262             : 
    3263          42 :     Color aOldTabBgColor;
    3264          42 :     aOldTabBgColor = rDoc.GetTabBgColor(nTab);
    3265             : 
    3266          42 :     bool bSuccess = false;
    3267          42 :     rDoc.SetTabBgColor(nTab, rColor);
    3268          42 :     if ( rDoc.GetTabBgColor(nTab) == rColor)
    3269          42 :         bSuccess = true;
    3270          42 :     if (bSuccess)
    3271             :     {
    3272          42 :         if (bRecord)
    3273             :         {
    3274           0 :             rDocShell.GetUndoManager()->AddUndoAction(
    3275           0 :                 new ScUndoTabColor( &rDocShell, nTab, aOldTabBgColor, rColor));
    3276             :         }
    3277          42 :         rDocShell.PostPaintExtras();
    3278          42 :         ScDocShellModificator aModificator( rDocShell );
    3279          42 :         aModificator.SetDocumentModified();
    3280          42 :         SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
    3281             : 
    3282          42 :         bSuccess = true;
    3283             :     }
    3284          42 :     return bSuccess;
    3285             : }
    3286             : 
    3287           0 : bool ScDocFunc::SetTabBgColor(
    3288             :     ScUndoTabColorInfo::List& rUndoTabColorList, bool bRecord, bool bApi )
    3289             : {
    3290           0 :     ScDocument& rDoc = rDocShell.GetDocument();
    3291           0 :     if (bRecord && !rDoc.IsUndoEnabled())
    3292           0 :         bRecord = false;
    3293             : 
    3294           0 :     if ( !rDoc.IsDocEditable() )
    3295             :     {
    3296           0 :         if (!bApi)
    3297           0 :             rDocShell.ErrorMessage(STR_PROTECTIONERR); //TODO Get a better String Error...
    3298           0 :         return false;
    3299             :     }
    3300             : 
    3301             :     sal_uInt16 nTab;
    3302           0 :     Color aNewTabBgColor;
    3303           0 :     bool bSuccess = true;
    3304           0 :     size_t nTabProtectCount = 0;
    3305           0 :     size_t nTabListCount = rUndoTabColorList.size();
    3306           0 :     for ( size_t i = 0; i < nTabListCount; ++i )
    3307             :     {
    3308           0 :         ScUndoTabColorInfo& rInfo = rUndoTabColorList[i];
    3309           0 :         nTab = rInfo.mnTabId;
    3310           0 :         if ( !rDoc.IsTabProtected(nTab) )
    3311             :         {
    3312           0 :             aNewTabBgColor = rInfo.maNewTabBgColor;
    3313           0 :             rInfo.maOldTabBgColor = rDoc.GetTabBgColor(nTab);
    3314           0 :             rDoc.SetTabBgColor(nTab, aNewTabBgColor);
    3315           0 :             if ( rDoc.GetTabBgColor(nTab) != aNewTabBgColor)
    3316             :             {
    3317           0 :                 bSuccess = false;
    3318           0 :                 break;
    3319             :             }
    3320             :         }
    3321             :         else
    3322             :         {
    3323           0 :             nTabProtectCount++;
    3324             :         }
    3325             :     }
    3326             : 
    3327           0 :     if ( nTabProtectCount == nTabListCount )
    3328             :     {
    3329           0 :         if (!bApi)
    3330           0 :             rDocShell.ErrorMessage(STR_PROTECTIONERR); //TODO Get a better String Error...
    3331           0 :         return false;
    3332             :     }
    3333             : 
    3334           0 :     if (bSuccess)
    3335             :     {
    3336           0 :         if (bRecord)
    3337             :         {
    3338           0 :             rDocShell.GetUndoManager()->AddUndoAction(
    3339           0 :                 new ScUndoTabColor( &rDocShell, rUndoTabColorList));
    3340             :         }
    3341           0 :         rDocShell.PostPaintExtras();
    3342           0 :         ScDocShellModificator aModificator( rDocShell );
    3343           0 :         aModificator.SetDocumentModified();
    3344             :     }
    3345           0 :     return bSuccess;
    3346             : }
    3347             : 
    3348             : //! SetWidthOrHeight - noch doppelt zu ViewFunc !!!!!!
    3349             : //! Probleme:
    3350             : //! - Optimale Hoehe fuer Edit-Zellen ist unterschiedlich zwischen Drucker und Bildschirm
    3351             : //! - Optimale Breite braucht Selektion, um evtl. nur selektierte Zellen zu beruecksichtigen
    3352             : 
    3353          16 : static sal_uInt16 lcl_GetOptimalColWidth( ScDocShell& rDocShell, SCCOL nCol, SCTAB nTab, bool bFormula )
    3354             : {
    3355          16 :     ScSizeDeviceProvider aProv(&rDocShell);
    3356          16 :     OutputDevice* pDev = aProv.GetDevice();         // has pixel MapMode
    3357          16 :     double nPPTX = aProv.GetPPTX();
    3358          16 :     double nPPTY = aProv.GetPPTY();
    3359             : 
    3360          16 :     ScDocument& rDoc = rDocShell.GetDocument();
    3361          16 :     Fraction aOne(1,1);
    3362             :     sal_uInt16 nTwips = rDoc.GetOptimalColWidth( nCol, nTab, pDev, nPPTX, nPPTY, aOne, aOne,
    3363          16 :                                                     bFormula, NULL );
    3364             : 
    3365          16 :     return nTwips;
    3366             : }
    3367             : 
    3368        4742 : bool ScDocFunc::SetWidthOrHeight(
    3369             :     bool bWidth, const std::vector<sc::ColRowSpan>& rRanges, SCTAB nTab,
    3370             :     ScSizeMode eMode, sal_uInt16 nSizeTwips, bool bRecord, bool bApi )
    3371             : {
    3372        4742 :     ScDocShellModificator aModificator( rDocShell );
    3373             : 
    3374        4742 :     if (rRanges.empty())
    3375           0 :         return true;
    3376             : 
    3377        4742 :     ScDocument& rDoc = rDocShell.GetDocument();
    3378        4742 :     if ( bRecord && !rDoc.IsUndoEnabled() )
    3379        4678 :         bRecord = false;
    3380             : 
    3381             :     // import into read-only document is possible
    3382        4742 :     if ( !rDoc.IsChangeReadOnlyEnabled() && !rDocShell.IsEditable() )
    3383             :     {
    3384           0 :         if (!bApi)
    3385           0 :             rDocShell.ErrorMessage(STR_PROTECTIONERR);      //! eigene Meldung?
    3386           0 :         return false;
    3387             :     }
    3388             : 
    3389        4742 :     bool bSuccess = false;
    3390        4742 :     SCCOLROW nStart = rRanges[0].mnStart;
    3391        4742 :     SCCOLROW nEnd = rRanges[0].mnEnd;
    3392             : 
    3393        4742 :     bool bFormula = false;
    3394             :     if ( eMode == SC_SIZE_OPTIMAL )
    3395             :     {
    3396             :         //! Option "Formeln anzeigen" - woher nehmen?
    3397             :     }
    3398             : 
    3399        4742 :     ScDocument*     pUndoDoc = NULL;
    3400        4742 :     ScOutlineTable* pUndoTab = NULL;
    3401        9484 :     std::vector<sc::ColRowSpan> aUndoRanges;
    3402             : 
    3403        4742 :     if ( bRecord )
    3404             :     {
    3405          64 :         rDoc.BeginDrawUndo();                          // Drawing Updates
    3406             : 
    3407          64 :         pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
    3408          64 :         if (bWidth)
    3409             :         {
    3410          32 :             pUndoDoc->InitUndo( &rDoc, nTab, nTab, true, false );
    3411          32 :             rDoc.CopyToDocument( static_cast<SCCOL>(nStart), 0, nTab, static_cast<SCCOL>(nEnd), MAXROW, nTab, IDF_NONE, false, pUndoDoc );
    3412             :         }
    3413             :         else
    3414             :         {
    3415          32 :             pUndoDoc->InitUndo( &rDoc, nTab, nTab, false, true );
    3416          32 :             rDoc.CopyToDocument( 0, static_cast<SCROW>(nStart), nTab, MAXCOL, static_cast<SCROW>(nEnd), nTab, IDF_NONE, false, pUndoDoc );
    3417             :         }
    3418             : 
    3419          64 :         aUndoRanges = rRanges;
    3420             : 
    3421          64 :         ScOutlineTable* pTable = rDoc.GetOutlineTable( nTab );
    3422          64 :         if (pTable)
    3423          54 :             pUndoTab = new ScOutlineTable( *pTable );
    3424             :     }
    3425             : 
    3426        4742 :     bool bShow = nSizeTwips > 0 || eMode != SC_SIZE_DIRECT;
    3427        4742 :     bool bOutline = false;
    3428             : 
    3429        9484 :     for (size_t i = 0, n = rRanges.size(); i < n; ++i)
    3430             :     {
    3431        4742 :         SCCOLROW nStartNo = rRanges[i].mnStart;
    3432        4742 :         SCCOLROW nEndNo   = rRanges[i].mnEnd;
    3433             : 
    3434        4742 :         if ( !bWidth )                      // Hoehen immer blockweise
    3435             :         {
    3436          66 :             if ( eMode==SC_SIZE_OPTIMAL || eMode==SC_SIZE_VISOPT )
    3437             :             {
    3438           4 :                 bool bAll = ( eMode==SC_SIZE_OPTIMAL );
    3439           4 :                 if (!bAll)
    3440             :                 {
    3441             :                     //  fuer alle eingeblendeten CR_MANUALSIZE loeschen,
    3442             :                     //  dann SetOptimalHeight mit bShrink = FALSE
    3443           0 :                     for (SCROW nRow=nStartNo; nRow<=nEndNo; nRow++)
    3444             :                     {
    3445           0 :                         sal_uInt8 nOld = rDoc.GetRowFlags(nRow,nTab);
    3446           0 :                         SCROW nLastRow = -1;
    3447           0 :                         bool bHidden = rDoc.RowHidden(nRow, nTab, NULL, &nLastRow);
    3448           0 :                         if ( !bHidden && ( nOld & CR_MANUALSIZE ) )
    3449           0 :                             rDoc.SetRowFlags( nRow, nTab, nOld & ~CR_MANUALSIZE );
    3450             :                     }
    3451             :                 }
    3452             : 
    3453           4 :                 ScSizeDeviceProvider aProv( &rDocShell );
    3454           4 :                 Fraction aOne(1,1);
    3455           8 :                 sc::RowHeightContext aCxt(aProv.GetPPTX(), aProv.GetPPTY(), aOne, aOne, aProv.GetDevice());
    3456           4 :                 aCxt.setForceAutoSize(bAll);
    3457           4 :                 rDoc.SetOptimalHeight(aCxt, nStartNo, nEndNo, nTab);
    3458             : 
    3459           4 :                 if (bAll)
    3460           8 :                     rDoc.ShowRows( nStartNo, nEndNo, nTab, true );
    3461             : 
    3462             :                 //  Manual-Flag wird bei bAll=sal_True schon in SetOptimalHeight gesetzt
    3463             :                 //  (an bei Extra-Height, sonst aus).
    3464             :             }
    3465          62 :             else if ( eMode==SC_SIZE_DIRECT || eMode==SC_SIZE_ORIGINAL )
    3466             :             {
    3467          52 :                 if (nSizeTwips)
    3468             :                 {
    3469           8 :                     rDoc.SetRowHeightRange( nStartNo, nEndNo, nTab, nSizeTwips );
    3470           8 :                     rDoc.SetManualHeight( nStartNo, nEndNo, nTab, true );          // height was set manually
    3471             :                 }
    3472         104 :                 if ( eMode != SC_SIZE_ORIGINAL )
    3473          44 :                     rDoc.ShowRows( nStartNo, nEndNo, nTab, nSizeTwips != 0 );
    3474             :             }
    3475          10 :             else if ( eMode==SC_SIZE_SHOW )
    3476             :             {
    3477          10 :                 rDoc.ShowRows( nStartNo, nEndNo, nTab, true );
    3478             :             }
    3479             :         }
    3480             :         else                                // Spaltenbreiten
    3481             :         {
    3482       61328 :             for (SCCOL nCol=static_cast<SCCOL>(nStartNo); nCol<=static_cast<SCCOL>(nEndNo); nCol++)
    3483             :             {
    3484       56652 :                 if ( eMode != SC_SIZE_VISOPT || !rDoc.ColHidden(nCol, nTab) )
    3485             :                 {
    3486       56652 :                     sal_uInt16 nThisSize = nSizeTwips;
    3487             : 
    3488       56652 :                     if ( eMode==SC_SIZE_OPTIMAL || eMode==SC_SIZE_VISOPT )
    3489             :                         nThisSize = nSizeTwips +
    3490          16 :                                     lcl_GetOptimalColWidth( rDocShell, nCol, nTab, bFormula );
    3491       56652 :                     if ( nThisSize )
    3492       28332 :                         rDoc.SetColWidth( nCol, nTab, nThisSize );
    3493             : 
    3494       56652 :                     if ( eMode != SC_SIZE_ORIGINAL )
    3495       28356 :                         rDoc.ShowCol( nCol, nTab, bShow );
    3496             :                 }
    3497             :             }
    3498             :         }
    3499             : 
    3500             :                             //  adjust outlines
    3501             : 
    3502        4742 :         if ( eMode != SC_SIZE_ORIGINAL )
    3503             :         {
    3504        2412 :             if (bWidth)
    3505        4708 :                 bOutline = bOutline || rDoc.UpdateOutlineCol(
    3506             :                         static_cast<SCCOL>(nStartNo),
    3507        4708 :                         static_cast<SCCOL>(nEndNo), nTab, bShow );
    3508             :             else
    3509         116 :                 bOutline = bOutline || rDoc.UpdateOutlineRow(
    3510             :                         static_cast<SCROW>(nStartNo),
    3511         116 :                         static_cast<SCROW>(nEndNo), nTab, bShow );
    3512             :         }
    3513             :     }
    3514        4742 :     rDoc.SetDrawPageSize(nTab);
    3515             : 
    3516        4742 :     if (!bOutline)
    3517        4742 :         DELETEZ(pUndoTab);
    3518             : 
    3519        4742 :     if (bRecord)
    3520             :     {
    3521          64 :         ScMarkData aMark;
    3522          64 :         aMark.SelectOneTable( nTab );
    3523          64 :         rDocShell.GetUndoManager()->AddUndoAction(
    3524             :             new ScUndoWidthOrHeight(
    3525             :                 &rDocShell, aMark, nStart, nTab, nEnd, nTab, pUndoDoc,
    3526          64 :                 aUndoRanges, pUndoTab, eMode, nSizeTwips, bWidth));
    3527             :     }
    3528             : 
    3529        4742 :     rDoc.UpdatePageBreaks( nTab );
    3530             : 
    3531        4742 :     rDocShell.PostPaint(0,0,nTab,MAXCOL,MAXROW,nTab,PAINT_ALL);
    3532        4742 :     aModificator.SetDocumentModified();
    3533             : 
    3534        9484 :     return bSuccess;
    3535             : }
    3536             : 
    3537           4 : bool ScDocFunc::InsertPageBreak( bool bColumn, const ScAddress& rPos,
    3538             :                                 bool bRecord, bool bSetModified, bool /* bApi */ )
    3539             : {
    3540           4 :     ScDocShellModificator aModificator( rDocShell );
    3541             : 
    3542           4 :     ScDocument& rDoc = rDocShell.GetDocument();
    3543           4 :     if (bRecord && !rDoc.IsUndoEnabled())
    3544           0 :         bRecord = false;
    3545           4 :     SCTAB nTab = rPos.Tab();
    3546           4 :     SfxBindings* pBindings = rDocShell.GetViewBindings();
    3547             : 
    3548           2 :     SCCOLROW nPos = bColumn ? static_cast<SCCOLROW>(rPos.Col()) :
    3549           6 :         static_cast<SCCOLROW>(rPos.Row());
    3550           4 :     if (nPos == 0)
    3551           0 :         return false;                   // erste Spalte / Zeile
    3552             : 
    3553             :     ScBreakType nBreak = bColumn ?
    3554           2 :         rDoc.HasColBreak(static_cast<SCCOL>(nPos), nTab) :
    3555           6 :         rDoc.HasRowBreak(static_cast<SCROW>(nPos), nTab);
    3556           4 :     if (nBreak & BREAK_MANUAL)
    3557           0 :         return true;
    3558             : 
    3559           4 :     if (bRecord)
    3560           4 :         rDocShell.GetUndoManager()->AddUndoAction(
    3561           4 :             new ScUndoPageBreak( &rDocShell, rPos.Col(), rPos.Row(), nTab, bColumn, true ) );
    3562             : 
    3563           4 :     if (bColumn)
    3564           2 :         rDoc.SetColBreak(static_cast<SCCOL>(nPos), nTab, false, true);
    3565             :     else
    3566           2 :         rDoc.SetRowBreak(static_cast<SCROW>(nPos), nTab, false, true);
    3567             : 
    3568           4 :     rDoc.InvalidatePageBreaks(nTab);
    3569           4 :     rDoc.UpdatePageBreaks( nTab );
    3570             : 
    3571           4 :     if (rDoc.IsStreamValid(nTab))
    3572           0 :         rDoc.SetStreamValid(nTab, false);
    3573             : 
    3574           4 :     if (bColumn)
    3575             :     {
    3576           2 :         rDocShell.PostPaint( static_cast<SCCOL>(nPos)-1, 0, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID );
    3577           2 :         if (pBindings)
    3578             :         {
    3579           2 :             pBindings->Invalidate( FID_INS_COLBRK );
    3580           2 :             pBindings->Invalidate( FID_DEL_COLBRK );
    3581             :         }
    3582             :     }
    3583             :     else
    3584             :     {
    3585           2 :         rDocShell.PostPaint( 0, static_cast<SCROW>(nPos)-1, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID );
    3586           2 :         if (pBindings)
    3587             :         {
    3588           2 :             pBindings->Invalidate( FID_INS_ROWBRK );
    3589           2 :             pBindings->Invalidate( FID_DEL_ROWBRK );
    3590             :         }
    3591             :     }
    3592           4 :     if (pBindings)
    3593           4 :         pBindings->Invalidate( FID_DEL_MANUALBREAKS );
    3594             : 
    3595           4 :     if (bSetModified)
    3596           4 :         aModificator.SetDocumentModified();
    3597             : 
    3598           4 :     return true;
    3599             : }
    3600             : 
    3601       26876 : bool ScDocFunc::RemovePageBreak( bool bColumn, const ScAddress& rPos,
    3602             :                                 bool bRecord, bool bSetModified, bool /* bApi */ )
    3603             : {
    3604       26876 :     ScDocShellModificator aModificator( rDocShell );
    3605             : 
    3606       26876 :     ScDocument& rDoc = rDocShell.GetDocument();
    3607       26876 :     if (bRecord && !rDoc.IsUndoEnabled())
    3608       26872 :         bRecord = false;
    3609       26876 :     SCTAB nTab = rPos.Tab();
    3610       26876 :     SfxBindings* pBindings = rDocShell.GetViewBindings();
    3611             : 
    3612       26874 :     SCCOLROW nPos = bColumn ? static_cast<SCCOLROW>(rPos.Col()) :
    3613       53750 :         static_cast<SCCOLROW>(rPos.Row());
    3614             : 
    3615             :     ScBreakType nBreak;
    3616       26876 :     if (bColumn)
    3617       26874 :         nBreak = rDoc.HasColBreak(static_cast<SCCOL>(nPos), nTab);
    3618             :     else
    3619           2 :         nBreak = rDoc.HasRowBreak(static_cast<SCROW>(nPos), nTab);
    3620       26876 :     if ((nBreak & BREAK_MANUAL) == 0)
    3621             :         // There is no manual break.
    3622       26872 :         return false;
    3623             : 
    3624           4 :     if (bRecord)
    3625           4 :         rDocShell.GetUndoManager()->AddUndoAction(
    3626           4 :             new ScUndoPageBreak( &rDocShell, rPos.Col(), rPos.Row(), nTab, bColumn, false ) );
    3627             : 
    3628           4 :     if (bColumn)
    3629           2 :         rDoc.RemoveColBreak(static_cast<SCCOL>(nPos), nTab, false, true);
    3630             :     else
    3631           2 :         rDoc.RemoveRowBreak(static_cast<SCROW>(nPos), nTab, false, true);
    3632             : 
    3633           4 :     rDoc.UpdatePageBreaks( nTab );
    3634             : 
    3635           4 :     if (rDoc.IsStreamValid(nTab))
    3636           0 :         rDoc.SetStreamValid(nTab, false);
    3637             : 
    3638           4 :     if (bColumn)
    3639             :     {
    3640           2 :         rDocShell.PostPaint( static_cast<SCCOL>(nPos)-1, 0, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID );
    3641           2 :         if (pBindings)
    3642             :         {
    3643           2 :             pBindings->Invalidate( FID_INS_COLBRK );
    3644           2 :             pBindings->Invalidate( FID_DEL_COLBRK );
    3645             :         }
    3646             :     }
    3647             :     else
    3648             :     {
    3649           2 :         rDocShell.PostPaint( 0, nPos-1, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID );
    3650           2 :         if (pBindings)
    3651             :         {
    3652           2 :             pBindings->Invalidate( FID_INS_ROWBRK );
    3653           2 :             pBindings->Invalidate( FID_DEL_ROWBRK );
    3654             :         }
    3655             :     }
    3656           4 :     if (pBindings)
    3657           4 :         pBindings->Invalidate( FID_DEL_MANUALBREAKS );
    3658             : 
    3659           4 :     if (bSetModified)
    3660           4 :         aModificator.SetDocumentModified();
    3661             : 
    3662           4 :     return true;
    3663             : }
    3664             : 
    3665           0 : void ScDocFunc::ProtectSheet( SCTAB nTab, const ScTableProtection& rProtect )
    3666             : {
    3667           0 :     ScDocument& rDoc = rDocShell.GetDocument();
    3668             : 
    3669           0 :     rDoc.SetTabProtection(nTab, &rProtect);
    3670           0 :     if (rDoc.IsUndoEnabled())
    3671             :     {
    3672           0 :         ScTableProtection* pProtect = rDoc.GetTabProtection(nTab);
    3673             :         OSL_ENSURE(pProtect, "ScDocFunc::Unprotect: ScTableProtection pointer is NULL!");
    3674           0 :         if (pProtect)
    3675             :         {
    3676           0 :             ::std::unique_ptr<ScTableProtection> p(new ScTableProtection(*pProtect));
    3677           0 :             p->setProtected(true); // just in case ...
    3678           0 :             rDocShell.GetUndoManager()->AddUndoAction(
    3679           0 :                 new ScUndoTabProtect(&rDocShell, nTab, std::move(p)) );
    3680             : 
    3681             :             // ownership of unique_ptr now transferred to ScUndoTabProtect.
    3682             :         }
    3683             :     }
    3684             : 
    3685           0 :     rDocShell.PostPaintGridAll();
    3686           0 :     ScDocShellModificator aModificator(rDocShell);
    3687           0 :     aModificator.SetDocumentModified();
    3688           0 : }
    3689             : 
    3690           2 : bool ScDocFunc::Protect( SCTAB nTab, const OUString& rPassword, bool /*bApi*/ )
    3691             : {
    3692           2 :     ScDocument& rDoc = rDocShell.GetDocument();
    3693           2 :     if (nTab == TABLEID_DOC)
    3694             :     {
    3695             :         // document protection
    3696           2 :         ScDocProtection aProtection;
    3697           2 :         aProtection.setProtected(true);
    3698           2 :         aProtection.setPassword(rPassword);
    3699           2 :         rDoc.SetDocProtection(&aProtection);
    3700           2 :         if (rDoc.IsUndoEnabled())
    3701             :         {
    3702           2 :             ScDocProtection* pProtect = rDoc.GetDocProtection();
    3703             :             OSL_ENSURE(pProtect, "ScDocFunc::Unprotect: ScDocProtection pointer is NULL!");
    3704           2 :             if (pProtect)
    3705             :             {
    3706           2 :                 ::std::unique_ptr<ScDocProtection> p(new ScDocProtection(*pProtect));
    3707           2 :                 p->setProtected(true); // just in case ...
    3708           2 :                 rDocShell.GetUndoManager()->AddUndoAction(
    3709           2 :                     new ScUndoDocProtect(&rDocShell, std::move(p)) );
    3710             :                 // ownership of unique_ptr is transferred to ScUndoDocProtect.
    3711             :             }
    3712           2 :         }
    3713             :     }
    3714             :     else
    3715             :     {
    3716             :         // sheet protection
    3717             : 
    3718           0 :         ScTableProtection aProtection;
    3719           0 :         aProtection.setProtected(true);
    3720           0 :         aProtection.setPassword(rPassword);
    3721           0 :         rDoc.SetTabProtection(nTab, &aProtection);
    3722           0 :         if (rDoc.IsUndoEnabled())
    3723             :         {
    3724           0 :             ScTableProtection* pProtect = rDoc.GetTabProtection(nTab);
    3725             :             OSL_ENSURE(pProtect, "ScDocFunc::Unprotect: ScTableProtection pointer is NULL!");
    3726           0 :             if (pProtect)
    3727             :             {
    3728           0 :                 ::std::unique_ptr<ScTableProtection> p(new ScTableProtection(*pProtect));
    3729           0 :                 p->setProtected(true); // just in case ...
    3730           0 :                 rDocShell.GetUndoManager()->AddUndoAction(
    3731           0 :                     new ScUndoTabProtect(&rDocShell, nTab, std::move(p)) );
    3732             :                 // ownership of unique_ptr now transferred to ScUndoTabProtect.
    3733             :             }
    3734           0 :         }
    3735             :     }
    3736             : 
    3737           2 :     rDocShell.PostPaintGridAll();
    3738           2 :     ScDocShellModificator aModificator( rDocShell );
    3739           2 :     aModificator.SetDocumentModified();
    3740             : 
    3741           2 :     return true;
    3742             : }
    3743             : 
    3744           4 : bool ScDocFunc::Unprotect( SCTAB nTab, const OUString& rPassword, bool bApi )
    3745             : {
    3746           4 :     ScDocument& rDoc = rDocShell.GetDocument();
    3747             : 
    3748           4 :     if (nTab == TABLEID_DOC)
    3749             :     {
    3750             :         // document protection
    3751             : 
    3752           4 :         ScDocProtection* pDocProtect = rDoc.GetDocProtection();
    3753           4 :         if (!pDocProtect || !pDocProtect->isProtected())
    3754             :             // already unprotected (should not happen)!
    3755           2 :             return true;
    3756             : 
    3757             :         // save the protection state before unprotect (for undo).
    3758           4 :         ::std::unique_ptr<ScDocProtection> pProtectCopy(new ScDocProtection(*pDocProtect));
    3759             : 
    3760           4 :         if (!pDocProtect->verifyPassword(rPassword))
    3761             :         {
    3762           2 :             if (!bApi)
    3763             :             {
    3764           0 :                 InfoBox aBox( rDocShell.GetActiveDialogParent(), OUString( ScResId( SCSTR_WRONGPASSWORD ) ) );
    3765           0 :                 aBox.Execute();
    3766             :             }
    3767           2 :             return false;
    3768             :         }
    3769             : 
    3770           2 :         rDoc.SetDocProtection(NULL);
    3771           2 :         if (rDoc.IsUndoEnabled())
    3772             :         {
    3773           2 :             pProtectCopy->setProtected(false);
    3774           2 :             rDocShell.GetUndoManager()->AddUndoAction(
    3775           2 :                 new ScUndoDocProtect(&rDocShell, std::move(pProtectCopy)) );
    3776             :             // ownership of unique_ptr now transferred to ScUndoDocProtect.
    3777           2 :         }
    3778             :     }
    3779             :     else
    3780             :     {
    3781             :         // sheet protection
    3782             : 
    3783           0 :         ScTableProtection* pTabProtect = rDoc.GetTabProtection(nTab);
    3784           0 :         if (!pTabProtect || !pTabProtect->isProtected())
    3785             :             // already unprotected (should not happen)!
    3786           0 :             return true;
    3787             : 
    3788             :         // save the protection state before unprotect (for undo).
    3789           0 :         ::std::unique_ptr<ScTableProtection> pProtectCopy(new ScTableProtection(*pTabProtect));
    3790           0 :         if (!pTabProtect->verifyPassword(rPassword))
    3791             :         {
    3792           0 :             if (!bApi)
    3793             :             {
    3794           0 :                 InfoBox aBox( rDocShell.GetActiveDialogParent(), OUString( ScResId( SCSTR_WRONGPASSWORD ) ) );
    3795           0 :                 aBox.Execute();
    3796             :             }
    3797           0 :             return false;
    3798             :         }
    3799             : 
    3800           0 :         rDoc.SetTabProtection(nTab, NULL);
    3801           0 :         if (rDoc.IsUndoEnabled())
    3802             :         {
    3803           0 :             pProtectCopy->setProtected(false);
    3804           0 :             rDocShell.GetUndoManager()->AddUndoAction(
    3805           0 :                 new ScUndoTabProtect(&rDocShell, nTab, std::move(pProtectCopy)) );
    3806             :             // ownership of unique_ptr now transferred to ScUndoTabProtect.
    3807           0 :         }
    3808             :     }
    3809             : 
    3810           2 :     rDocShell.PostPaintGridAll();
    3811           2 :     ScDocShellModificator aModificator( rDocShell );
    3812           2 :     aModificator.SetDocumentModified();
    3813             : 
    3814           2 :     return true;
    3815             : }
    3816             : 
    3817           0 : bool ScDocFunc::ClearItems( const ScMarkData& rMark, const sal_uInt16* pWhich, bool bApi )
    3818             : {
    3819           0 :     ScDocShellModificator aModificator( rDocShell );
    3820             : 
    3821           0 :     ScDocument& rDoc = rDocShell.GetDocument();
    3822           0 :     bool bUndo (rDoc.IsUndoEnabled());
    3823           0 :     ScEditableTester aTester( &rDoc, rMark );
    3824           0 :     if (!aTester.IsEditable())
    3825             :     {
    3826           0 :         if (!bApi)
    3827           0 :             rDocShell.ErrorMessage(aTester.GetMessageId());
    3828           0 :         return false;
    3829             :     }
    3830             : 
    3831             :     //  #i12940# ClearItems is called (from setPropertyToDefault) directly with uno object's cached
    3832             :     //  MarkData (GetMarkData), so rMark must be changed to multi selection for ClearSelectionItems
    3833             :     //  here.
    3834             : 
    3835           0 :     ScRange aMarkRange;
    3836           0 :     ScMarkData aMultiMark = rMark;
    3837           0 :     aMultiMark.SetMarking(false);       // for MarkToMulti
    3838           0 :     aMultiMark.MarkToMulti();
    3839           0 :     aMultiMark.GetMultiMarkArea( aMarkRange );
    3840             : 
    3841           0 :     if (bUndo)
    3842             :     {
    3843           0 :         SCTAB nStartTab = aMarkRange.aStart.Tab();
    3844           0 :         SCTAB nEndTab = aMarkRange.aEnd.Tab();
    3845             : 
    3846           0 :         ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
    3847           0 :         pUndoDoc->InitUndo( &rDoc, nStartTab, nEndTab );
    3848           0 :         rDoc.CopyToDocument( aMarkRange, IDF_ATTRIB, true, pUndoDoc, (ScMarkData*)&aMultiMark );
    3849             : 
    3850           0 :         rDocShell.GetUndoManager()->AddUndoAction(
    3851           0 :             new ScUndoClearItems( &rDocShell, aMultiMark, pUndoDoc, pWhich ) );
    3852             :     }
    3853             : 
    3854           0 :     rDoc.ClearSelectionItems( pWhich, aMultiMark );
    3855             : 
    3856           0 :     rDocShell.PostPaint( aMarkRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
    3857           0 :     aModificator.SetDocumentModified();
    3858             : 
    3859             :     //! Bindings-Invalidate etc.?
    3860             : 
    3861           0 :     return true;
    3862             : }
    3863             : 
    3864          12 : bool ScDocFunc::ChangeIndent( const ScMarkData& rMark, bool bIncrement, bool bApi )
    3865             : {
    3866          12 :     ScDocShellModificator aModificator( rDocShell );
    3867             : 
    3868          12 :     ScDocument& rDoc = rDocShell.GetDocument();
    3869          12 :     bool bUndo(rDoc.IsUndoEnabled());
    3870          12 :     ScEditableTester aTester( &rDoc, rMark );
    3871          12 :     if (!aTester.IsEditable())
    3872             :     {
    3873           0 :         if (!bApi)
    3874           0 :             rDocShell.ErrorMessage(aTester.GetMessageId());
    3875           0 :         return false;
    3876             :     }
    3877             : 
    3878          12 :     ScRange aMarkRange;
    3879          12 :     rMark.GetMultiMarkArea( aMarkRange );
    3880             : 
    3881          12 :     if (bUndo)
    3882             :     {
    3883          12 :         SCTAB nStartTab = aMarkRange.aStart.Tab();
    3884          12 :         SCTAB nTabCount = rDoc.GetTableCount();
    3885             : 
    3886          12 :         ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
    3887          12 :         pUndoDoc->InitUndo( &rDoc, nStartTab, nStartTab );
    3888          12 :         ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
    3889          24 :         for (; itr != itrEnd && *itr < nTabCount; ++itr)
    3890          12 :             if (*itr != nStartTab)
    3891           0 :                 pUndoDoc->AddUndoTab( *itr, *itr );
    3892             : 
    3893          12 :         ScRange aCopyRange = aMarkRange;
    3894          12 :         aCopyRange.aStart.SetTab(0);
    3895          12 :         aCopyRange.aEnd.SetTab(nTabCount-1);
    3896          12 :         rDoc.CopyToDocument( aCopyRange, IDF_ATTRIB, true, pUndoDoc, (ScMarkData*)&rMark );
    3897             : 
    3898          12 :         rDocShell.GetUndoManager()->AddUndoAction(
    3899          12 :             new ScUndoIndent( &rDocShell, rMark, pUndoDoc, bIncrement ) );
    3900             :     }
    3901             : 
    3902          12 :     rDoc.ChangeSelectionIndent( bIncrement, rMark );
    3903             : 
    3904          12 :     rDocShell.PostPaint( aMarkRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
    3905          12 :     aModificator.SetDocumentModified();
    3906             : 
    3907          12 :     SfxBindings* pBindings = rDocShell.GetViewBindings();
    3908          12 :     if (pBindings)
    3909             :     {
    3910          12 :         pBindings->Invalidate( SID_ALIGNLEFT );         // ChangeIndent setzt auf links
    3911          12 :         pBindings->Invalidate( SID_ALIGNRIGHT );
    3912          12 :         pBindings->Invalidate( SID_ALIGNBLOCK );
    3913          12 :         pBindings->Invalidate( SID_ALIGNCENTERHOR );
    3914          12 :         pBindings->Invalidate( SID_ATTR_LRSPACE );
    3915          12 :         pBindings->Invalidate( SID_ATTR_PARA_ADJUST_LEFT );
    3916          12 :         pBindings->Invalidate( SID_ATTR_PARA_ADJUST_RIGHT );
    3917          12 :         pBindings->Invalidate( SID_ATTR_PARA_ADJUST_BLOCK );
    3918          12 :         pBindings->Invalidate( SID_ATTR_PARA_ADJUST_CENTER);
    3919             :         // pseudo slots for Format menu
    3920          12 :         pBindings->Invalidate( SID_ALIGN_ANY_HDEFAULT );
    3921          12 :         pBindings->Invalidate( SID_ALIGN_ANY_LEFT );
    3922          12 :         pBindings->Invalidate( SID_ALIGN_ANY_HCENTER );
    3923          12 :         pBindings->Invalidate( SID_ALIGN_ANY_RIGHT );
    3924          12 :         pBindings->Invalidate( SID_ALIGN_ANY_JUSTIFIED );
    3925             :     }
    3926             : 
    3927          12 :     return true;
    3928             : }
    3929             : 
    3930           0 : bool ScDocFunc::AutoFormat( const ScRange& rRange, const ScMarkData* pTabMark,
    3931             :                             sal_uInt16 nFormatNo, bool bRecord, bool bApi )
    3932             : {
    3933           0 :     ScDocShellModificator aModificator( rDocShell );
    3934             : 
    3935           0 :     bool bSuccess = false;
    3936           0 :     ScDocument& rDoc = rDocShell.GetDocument();
    3937           0 :     SCCOL nStartCol = rRange.aStart.Col();
    3938           0 :     SCROW nStartRow = rRange.aStart.Row();
    3939           0 :     SCTAB nStartTab = rRange.aStart.Tab();
    3940           0 :     SCCOL nEndCol = rRange.aEnd.Col();
    3941           0 :     SCROW nEndRow = rRange.aEnd.Row();
    3942           0 :     SCTAB nEndTab = rRange.aEnd.Tab();
    3943             : 
    3944           0 :     if (bRecord && !rDoc.IsUndoEnabled())
    3945           0 :         bRecord = false;
    3946           0 :     ScMarkData aMark;
    3947           0 :     if (pTabMark)
    3948           0 :         aMark = *pTabMark;
    3949             :     else
    3950             :     {
    3951           0 :         for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
    3952           0 :             aMark.SelectTable( nTab, true );
    3953             :     }
    3954             : 
    3955           0 :     ScAutoFormat* pAutoFormat = ScGlobal::GetOrCreateAutoFormat();
    3956           0 :     ScEditableTester aTester( &rDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
    3957           0 :     if ( nFormatNo < pAutoFormat->size() && aTester.IsEditable() )
    3958             :     {
    3959           0 :         WaitObject aWait( rDocShell.GetActiveDialogParent() );
    3960             : 
    3961           0 :         bool bSize = pAutoFormat->findByIndex(nFormatNo)->GetIncludeWidthHeight();
    3962             : 
    3963           0 :         SCTAB nTabCount = rDoc.GetTableCount();
    3964           0 :         ScDocument* pUndoDoc = NULL;
    3965           0 :         if ( bRecord )
    3966             :         {
    3967           0 :             pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
    3968           0 :             pUndoDoc->InitUndo( &rDoc, nStartTab, nStartTab, bSize, bSize );
    3969           0 :             ScMarkData::iterator itr = aMark.begin(), itrEnd = aMark.end();
    3970           0 :             for (; itr != itrEnd && *itr < nTabCount; ++itr)
    3971           0 :                 if (*itr != nStartTab)
    3972           0 :                     pUndoDoc->AddUndoTab( *itr, *itr, bSize, bSize );
    3973             : 
    3974           0 :             ScRange aCopyRange = rRange;
    3975           0 :             aCopyRange.aStart.SetTab(0);
    3976           0 :             aCopyRange.aStart.SetTab(nTabCount-1);
    3977           0 :             rDoc.CopyToDocument( aCopyRange, IDF_ATTRIB, false, pUndoDoc, &aMark );
    3978           0 :             if (bSize)
    3979             :             {
    3980             :                 rDoc.CopyToDocument( nStartCol,0,0, nEndCol,MAXROW,nTabCount-1,
    3981           0 :                                                             IDF_NONE, false, pUndoDoc, &aMark );
    3982             :                 rDoc.CopyToDocument( 0,nStartRow,0, MAXCOL,nEndRow,nTabCount-1,
    3983           0 :                                                             IDF_NONE, false, pUndoDoc, &aMark );
    3984             :             }
    3985           0 :             rDoc.BeginDrawUndo();
    3986             :         }
    3987             : 
    3988           0 :         rDoc.AutoFormat( nStartCol, nStartRow, nEndCol, nEndRow, nFormatNo, aMark );
    3989             : 
    3990           0 :         if (bSize)
    3991             :         {
    3992           0 :             std::vector<sc::ColRowSpan> aCols(1, sc::ColRowSpan(nStartCol,nEndCol));
    3993           0 :             std::vector<sc::ColRowSpan> aRows(1, sc::ColRowSpan(nStartRow,nEndRow));
    3994             : 
    3995           0 :             ScMarkData::iterator itr = aMark.begin(), itrEnd = aMark.end();
    3996           0 :             for (; itr != itrEnd && *itr < nTabCount; ++itr)
    3997             :             {
    3998           0 :                 SetWidthOrHeight(true, aCols, *itr, SC_SIZE_VISOPT, STD_EXTRA_WIDTH, false, true);
    3999           0 :                 SetWidthOrHeight(false, aRows, *itr, SC_SIZE_VISOPT, 0, false, false);
    4000           0 :                 rDocShell.PostPaint( 0,0,*itr, MAXCOL,MAXROW,*itr,
    4001           0 :                                 PAINT_GRID | PAINT_LEFT | PAINT_TOP );
    4002           0 :             }
    4003             :         }
    4004             :         else
    4005             :         {
    4006           0 :             ScMarkData::iterator itr = aMark.begin(), itrEnd = aMark.end();
    4007           0 :             for (; itr != itrEnd && *itr < nTabCount; ++itr)
    4008             :             {
    4009           0 :                 bool bAdj = AdjustRowHeight( ScRange(nStartCol, nStartRow, *itr,
    4010           0 :                                                     nEndCol, nEndRow, *itr), false );
    4011           0 :                 if (bAdj)
    4012           0 :                     rDocShell.PostPaint( 0,nStartRow,*itr, MAXCOL,MAXROW,*itr,
    4013           0 :                                         PAINT_GRID | PAINT_LEFT );
    4014             :                 else
    4015           0 :                     rDocShell.PostPaint( nStartCol, nStartRow, *itr,
    4016           0 :                                         nEndCol, nEndRow, *itr, PAINT_GRID );
    4017             :             }
    4018             :         }
    4019             : 
    4020           0 :         if ( bRecord )      // Draw-Undo erst jetzt verfuegbar
    4021             :         {
    4022           0 :             rDocShell.GetUndoManager()->AddUndoAction(
    4023           0 :                 new ScUndoAutoFormat( &rDocShell, rRange, pUndoDoc, aMark, bSize, nFormatNo ) );
    4024             :         }
    4025             : 
    4026           0 :         aModificator.SetDocumentModified();
    4027             :     }
    4028           0 :     else if (!bApi)
    4029           0 :         rDocShell.ErrorMessage(aTester.GetMessageId());
    4030             : 
    4031           0 :     return bSuccess;
    4032             : }
    4033             : 
    4034           4 : bool ScDocFunc::EnterMatrix( const ScRange& rRange, const ScMarkData* pTabMark,
    4035             :         const ScTokenArray* pTokenArray, const OUString& rString, bool bApi, bool bEnglish,
    4036             :         const OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
    4037             : {
    4038           4 :     ScDocShellModificator aModificator( rDocShell );
    4039             : 
    4040           4 :     bool bSuccess = false;
    4041           4 :     ScDocument& rDoc = rDocShell.GetDocument();
    4042           4 :     SCCOL nStartCol = rRange.aStart.Col();
    4043           4 :     SCROW nStartRow = rRange.aStart.Row();
    4044           4 :     SCTAB nStartTab = rRange.aStart.Tab();
    4045           4 :     SCCOL nEndCol = rRange.aEnd.Col();
    4046           4 :     SCROW nEndRow = rRange.aEnd.Row();
    4047           4 :     SCTAB nEndTab = rRange.aEnd.Tab();
    4048             : 
    4049           4 :     bool bUndo(rDoc.IsUndoEnabled());
    4050             : 
    4051           8 :     ScMarkData aMark;
    4052           4 :     if (pTabMark)
    4053           0 :         aMark = *pTabMark;
    4054             :     else
    4055             :     {
    4056           8 :         for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
    4057           4 :             aMark.SelectTable( nTab, true );
    4058             :     }
    4059             : 
    4060           4 :     ScEditableTester aTester( &rDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
    4061           4 :     if ( aTester.IsEditable() )
    4062             :     {
    4063           4 :         WaitObject aWait( rDocShell.GetActiveDialogParent() );
    4064             : 
    4065           4 :         ScDocument* pUndoDoc = NULL;
    4066             : 
    4067           4 :         if (bUndo)
    4068             :         {
    4069             :             //! auch bei Undo selektierte Tabellen beruecksichtigen
    4070           4 :             pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
    4071           4 :             pUndoDoc->InitUndo( &rDoc, nStartTab, nEndTab );
    4072           4 :             rDoc.CopyToDocument( rRange, IDF_ALL & ~IDF_NOTE, false, pUndoDoc );
    4073             :         }
    4074             : 
    4075             :         // use TokenArray if given, string (and flags) otherwise
    4076           4 :         if ( pTokenArray )
    4077             :         {
    4078             :             rDoc.InsertMatrixFormula( nStartCol, nStartRow, nEndCol, nEndRow,
    4079           2 :                     aMark, EMPTY_OUSTRING, pTokenArray, eGrammar);
    4080             :         }
    4081           2 :         else if ( rDoc.IsImportingXML() )
    4082             :         {
    4083           0 :             ScTokenArray* pCode = lcl_ScDocFunc_CreateTokenArrayXML( rString, rFormulaNmsp, eGrammar );
    4084             :             rDoc.InsertMatrixFormula( nStartCol, nStartRow, nEndCol, nEndRow,
    4085           0 :                     aMark, EMPTY_OUSTRING, pCode, eGrammar);
    4086           0 :             delete pCode;
    4087           0 :             rDoc.IncXMLImportedFormulaCount( rString.getLength() );
    4088             :         }
    4089           2 :         else if (bEnglish)
    4090             :         {
    4091           2 :             ScCompiler aComp( &rDoc, rRange.aStart);
    4092           2 :             aComp.SetGrammar(eGrammar);
    4093           2 :             ScTokenArray* pCode = aComp.CompileString( rString );
    4094             :             rDoc.InsertMatrixFormula( nStartCol, nStartRow, nEndCol, nEndRow,
    4095           2 :                     aMark, EMPTY_OUSTRING, pCode, eGrammar);
    4096           2 :             delete pCode;
    4097             :         }
    4098             :         else
    4099             :             rDoc.InsertMatrixFormula( nStartCol, nStartRow, nEndCol, nEndRow,
    4100           0 :                     aMark, rString, NULL, eGrammar);
    4101             : 
    4102           4 :         if (bUndo)
    4103             :         {
    4104             :             //! auch bei Undo selektierte Tabellen beruecksichtigen
    4105           4 :             rDocShell.GetUndoManager()->AddUndoAction(
    4106           4 :                 new ScUndoEnterMatrix( &rDocShell, rRange, pUndoDoc, rString ) );
    4107             :         }
    4108             : 
    4109             :         //  Err522 beim Paint von DDE-Formeln werden jetzt beim Interpretieren abgefangen
    4110           4 :         rDocShell.PostPaint( nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab, PAINT_GRID );
    4111           4 :         aModificator.SetDocumentModified();
    4112             : 
    4113           4 :         bSuccess = true;
    4114             :     }
    4115           0 :     else if (!bApi)
    4116           0 :         rDocShell.ErrorMessage(aTester.GetMessageId());
    4117             : 
    4118           8 :     return bSuccess;
    4119             : }
    4120             : 
    4121           6 : bool ScDocFunc::TabOp( const ScRange& rRange, const ScMarkData* pTabMark,
    4122             :                             const ScTabOpParam& rParam, bool bRecord, bool bApi )
    4123             : {
    4124           6 :     ScDocShellModificator aModificator( rDocShell );
    4125             : 
    4126           6 :     bool bSuccess = false;
    4127           6 :     ScDocument& rDoc = rDocShell.GetDocument();
    4128           6 :     SCCOL nStartCol = rRange.aStart.Col();
    4129           6 :     SCROW nStartRow = rRange.aStart.Row();
    4130           6 :     SCTAB nStartTab = rRange.aStart.Tab();
    4131           6 :     SCCOL nEndCol = rRange.aEnd.Col();
    4132           6 :     SCROW nEndRow = rRange.aEnd.Row();
    4133           6 :     SCTAB nEndTab = rRange.aEnd.Tab();
    4134             : 
    4135           6 :     if (bRecord && !rDoc.IsUndoEnabled())
    4136           0 :         bRecord = false;
    4137             : 
    4138          12 :     ScMarkData aMark;
    4139           6 :     if (pTabMark)
    4140           0 :         aMark = *pTabMark;
    4141             :     else
    4142             :     {
    4143          12 :         for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
    4144           6 :             aMark.SelectTable( nTab, true );
    4145             :     }
    4146             : 
    4147           6 :     ScEditableTester aTester( &rDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
    4148           6 :     if ( aTester.IsEditable() )
    4149             :     {
    4150           6 :         WaitObject aWait( rDocShell.GetActiveDialogParent() );
    4151           6 :         rDoc.SetDirty( rRange );
    4152           6 :         if ( bRecord )
    4153             :         {
    4154             :             //! auch bei Undo selektierte Tabellen beruecksichtigen
    4155           6 :             ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
    4156           6 :             pUndoDoc->InitUndo( &rDoc, nStartTab, nEndTab );
    4157           6 :             rDoc.CopyToDocument( rRange, IDF_ALL & ~IDF_NOTE, false, pUndoDoc );
    4158             : 
    4159           6 :             rDocShell.GetUndoManager()->AddUndoAction(
    4160             :                     new ScUndoTabOp( &rDocShell,
    4161             :                                      nStartCol, nStartRow, nStartTab,
    4162             :                                      nEndCol, nEndRow, nEndTab, pUndoDoc,
    4163             :                                      rParam.aRefFormulaCell,
    4164             :                                      rParam.aRefFormulaEnd,
    4165             :                                      rParam.aRefRowCell,
    4166             :                                      rParam.aRefColCell,
    4167           6 :                                      rParam.meMode) );
    4168             :         }
    4169           6 :         rDoc.InsertTableOp(rParam, nStartCol, nStartRow, nEndCol, nEndRow, aMark);
    4170           6 :         rDocShell.PostPaintGridAll();
    4171           6 :         aModificator.SetDocumentModified();
    4172           6 :         bSuccess = true;
    4173             :     }
    4174           0 :     else if (!bApi)
    4175           0 :         rDocShell.ErrorMessage(aTester.GetMessageId());
    4176             : 
    4177          12 :     return bSuccess;
    4178             : }
    4179             : 
    4180          28 : inline ScDirection DirFromFillDir( FillDir eDir )
    4181             : {
    4182          28 :     if (eDir==FILL_TO_BOTTOM)
    4183          10 :         return DIR_BOTTOM;
    4184          18 :     else if (eDir==FILL_TO_RIGHT)
    4185          10 :         return DIR_RIGHT;
    4186           8 :     else if (eDir==FILL_TO_TOP)
    4187           4 :         return DIR_TOP;
    4188             :     else // if (eDir==FILL_TO_LEFT)
    4189           4 :         return DIR_LEFT;
    4190             : }
    4191             : 
    4192             : namespace {
    4193             : 
    4194             : /**
    4195             :  * Expand the fill range as necessary, to allow copying of adjacent cell(s)
    4196             :  * even when those cells are not in the original range.
    4197             :  */
    4198           0 : void adjustFillRangeForAdjacentCopy(ScRange& rRange, FillDir eDir)
    4199             : {
    4200           0 :     switch (eDir)
    4201             :     {
    4202             :         case FILL_TO_BOTTOM:
    4203             :         {
    4204           0 :             if (rRange.aStart.Row() == 0)
    4205           0 :                 return;
    4206             : 
    4207           0 :             if (rRange.aStart.Row() != rRange.aEnd.Row())
    4208           0 :                 return;
    4209             : 
    4210             :             // Include the above row.
    4211           0 :             ScAddress& s = rRange.aStart;
    4212           0 :             s.SetRow(s.Row()-1);
    4213             :         }
    4214           0 :         break;
    4215             :         case FILL_TO_TOP:
    4216             :         {
    4217           0 :             if (rRange.aStart.Row() == MAXROW)
    4218           0 :                 return;
    4219             : 
    4220           0 :             if (rRange.aStart.Row() != rRange.aEnd.Row())
    4221           0 :                 return;
    4222             : 
    4223             :             // Include the row below.
    4224           0 :             ScAddress& e = rRange.aEnd;
    4225           0 :             e.SetRow(e.Row()+1);
    4226             :         }
    4227           0 :         break;
    4228             :         case FILL_TO_LEFT:
    4229             :         {
    4230           0 :             if (rRange.aStart.Col() == MAXCOL)
    4231           0 :                 return;
    4232             : 
    4233           0 :             if (rRange.aStart.Col() != rRange.aEnd.Col())
    4234           0 :                 return;
    4235             : 
    4236             :             // Include the column to the right.
    4237           0 :             ScAddress& e = rRange.aEnd;
    4238           0 :             e.SetCol(e.Col()+1);
    4239             :         }
    4240           0 :         break;
    4241             :         case FILL_TO_RIGHT:
    4242             :         {
    4243           0 :             if (rRange.aStart.Col() == 0)
    4244           0 :                 return;
    4245             : 
    4246           0 :             if (rRange.aStart.Col() != rRange.aEnd.Col())
    4247           0 :                 return;
    4248             : 
    4249             :             // Include the column to the left.
    4250           0 :             ScAddress& s = rRange.aStart;
    4251           0 :             s.SetCol(s.Col()-1);
    4252             :         }
    4253           0 :         break;
    4254             :         default:
    4255             :             ;
    4256             :     }
    4257             : }
    4258             : 
    4259             : }
    4260             : 
    4261           0 : bool ScDocFunc::FillSimple( const ScRange& rRange, const ScMarkData* pTabMark,
    4262             :                             FillDir eDir, bool bRecord, bool bApi )
    4263             : {
    4264           0 :     ScDocShellModificator aModificator( rDocShell );
    4265           0 :     ScDocument& rDoc = rDocShell.GetDocument();
    4266             : 
    4267           0 :     bool bSuccess = false;
    4268           0 :     ScRange aRange = rRange;
    4269           0 :     adjustFillRangeForAdjacentCopy(aRange, eDir);
    4270             : 
    4271           0 :     SCCOL nStartCol = aRange.aStart.Col();
    4272           0 :     SCROW nStartRow = aRange.aStart.Row();
    4273           0 :     SCTAB nStartTab = aRange.aStart.Tab();
    4274           0 :     SCCOL nEndCol = aRange.aEnd.Col();
    4275           0 :     SCROW nEndRow = aRange.aEnd.Row();
    4276           0 :     SCTAB nEndTab = aRange.aEnd.Tab();
    4277             : 
    4278           0 :     if (bRecord && !rDoc.IsUndoEnabled())
    4279           0 :         bRecord = false;
    4280             : 
    4281           0 :     ScMarkData aMark;
    4282           0 :     if (pTabMark)
    4283           0 :         aMark = *pTabMark;
    4284             :     else
    4285             :     {
    4286           0 :         for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
    4287           0 :             aMark.SelectTable( nTab, true );
    4288             :     }
    4289             : 
    4290           0 :     ScEditableTester aTester( &rDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
    4291           0 :     if ( aTester.IsEditable() )
    4292             :     {
    4293           0 :         WaitObject aWait( rDocShell.GetActiveDialogParent() );
    4294             : 
    4295           0 :         ScRange aSourceArea = aRange;
    4296           0 :         ScRange aDestArea   = aRange;
    4297             : 
    4298           0 :         SCCOLROW nCount = 0;
    4299           0 :         switch (eDir)
    4300             :         {
    4301             :             case FILL_TO_BOTTOM:
    4302           0 :                 nCount = aSourceArea.aEnd.Row()-aSourceArea.aStart.Row();
    4303           0 :                 aSourceArea.aEnd.SetRow( aSourceArea.aStart.Row() );
    4304           0 :                 break;
    4305             :             case FILL_TO_RIGHT:
    4306           0 :                 nCount = aSourceArea.aEnd.Col()-aSourceArea.aStart.Col();
    4307           0 :                 aSourceArea.aEnd.SetCol( aSourceArea.aStart.Col() );
    4308           0 :                 break;
    4309             :             case FILL_TO_TOP:
    4310           0 :                 nCount = aSourceArea.aEnd.Row()-aSourceArea.aStart.Row();
    4311           0 :                 aSourceArea.aStart.SetRow( aSourceArea.aEnd.Row() );
    4312           0 :                 break;
    4313             :             case FILL_TO_LEFT:
    4314           0 :                 nCount = aSourceArea.aEnd.Col()-aSourceArea.aStart.Col();
    4315           0 :                 aSourceArea.aStart.SetCol( aSourceArea.aEnd.Col() );
    4316           0 :                 break;
    4317             :         }
    4318             : 
    4319           0 :         ScDocument* pUndoDoc = NULL;
    4320           0 :         if ( bRecord )
    4321             :         {
    4322           0 :             SCTAB nTabCount = rDoc.GetTableCount();
    4323           0 :             SCTAB nDestStartTab = aDestArea.aStart.Tab();
    4324             : 
    4325           0 :             pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
    4326           0 :             pUndoDoc->InitUndo( &rDoc, nDestStartTab, nDestStartTab );
    4327           0 :             ScMarkData::iterator itr = aMark.begin(), itrEnd = aMark.end();
    4328           0 :             for (; itr != itrEnd && *itr < nTabCount; ++itr)
    4329           0 :                 if (*itr != nDestStartTab)
    4330           0 :                     pUndoDoc->AddUndoTab( *itr, *itr );
    4331             : 
    4332           0 :             ScRange aCopyRange = aDestArea;
    4333           0 :             aCopyRange.aStart.SetTab(0);
    4334           0 :             aCopyRange.aEnd.SetTab(nTabCount-1);
    4335           0 :             rDoc.CopyToDocument( aCopyRange, IDF_AUTOFILL, false, pUndoDoc, &aMark );
    4336             :         }
    4337             : 
    4338             :         sal_uLong nProgCount;
    4339           0 :         if (eDir == FILL_TO_BOTTOM || eDir == FILL_TO_TOP)
    4340           0 :             nProgCount = aSourceArea.aEnd.Col() - aSourceArea.aStart.Col() + 1;
    4341             :         else
    4342           0 :             nProgCount = aSourceArea.aEnd.Row() - aSourceArea.aStart.Row() + 1;
    4343           0 :         nProgCount *= nCount;
    4344             :         ScProgress aProgress( rDoc.GetDocumentShell(),
    4345           0 :                 ScGlobal::GetRscString(STR_FILL_SERIES_PROGRESS), nProgCount );
    4346             : 
    4347           0 :         rDoc.Fill( aSourceArea.aStart.Col(), aSourceArea.aStart.Row(),
    4348           0 :                 aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), &aProgress,
    4349           0 :                 aMark, nCount, eDir, FILL_SIMPLE );
    4350           0 :         AdjustRowHeight(aRange);
    4351             : 
    4352           0 :         if ( bRecord )      // Draw-Undo erst jetzt verfuegbar
    4353             :         {
    4354           0 :             rDocShell.GetUndoManager()->AddUndoAction(
    4355             :                 new ScUndoAutoFill( &rDocShell, aDestArea, aSourceArea, pUndoDoc, aMark,
    4356           0 :                                     eDir, FILL_SIMPLE, FILL_DAY, MAXDOUBLE, 1.0, 1e307) );
    4357             :         }
    4358             : 
    4359           0 :         rDocShell.PostPaintGridAll();
    4360           0 :         aModificator.SetDocumentModified();
    4361             : 
    4362           0 :         bSuccess = true;
    4363             :     }
    4364           0 :     else if (!bApi)
    4365           0 :         rDocShell.ErrorMessage(aTester.GetMessageId());
    4366             : 
    4367           0 :     return bSuccess;
    4368             : }
    4369             : 
    4370          28 : bool ScDocFunc::FillSeries( const ScRange& rRange, const ScMarkData* pTabMark,
    4371             :                             FillDir eDir, FillCmd eCmd, FillDateCmd eDateCmd,
    4372             :                             double fStart, double fStep, double fMax,
    4373             :                             bool bRecord, bool bApi )
    4374             : {
    4375          28 :     ScDocShellModificator aModificator( rDocShell );
    4376             : 
    4377          28 :     bool bSuccess = false;
    4378          28 :     ScDocument& rDoc = rDocShell.GetDocument();
    4379          28 :     SCCOL nStartCol = rRange.aStart.Col();
    4380          28 :     SCROW nStartRow = rRange.aStart.Row();
    4381          28 :     SCTAB nStartTab = rRange.aStart.Tab();
    4382          28 :     SCCOL nEndCol = rRange.aEnd.Col();
    4383          28 :     SCROW nEndRow = rRange.aEnd.Row();
    4384          28 :     SCTAB nEndTab = rRange.aEnd.Tab();
    4385             : 
    4386          28 :     if (bRecord && !rDoc.IsUndoEnabled())
    4387           0 :         bRecord = false;
    4388             : 
    4389          56 :     ScMarkData aMark;
    4390          28 :     if (pTabMark)
    4391           2 :         aMark = *pTabMark;
    4392             :     else
    4393             :     {
    4394          52 :         for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
    4395          26 :             aMark.SelectTable( nTab, true );
    4396             :     }
    4397             : 
    4398          28 :     ScEditableTester aTester( &rDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
    4399          28 :     if ( aTester.IsEditable() )
    4400             :     {
    4401          28 :         WaitObject aWait( rDocShell.GetActiveDialogParent() );
    4402             : 
    4403          28 :         ScRange aSourceArea = rRange;
    4404          28 :         ScRange aDestArea   = rRange;
    4405             : 
    4406             :         SCSIZE nCount = rDoc.GetEmptyLinesInBlock(
    4407          56 :                 aSourceArea.aStart.Col(), aSourceArea.aStart.Row(), aSourceArea.aStart.Tab(),
    4408          56 :                 aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), aSourceArea.aEnd.Tab(),
    4409         140 :                 DirFromFillDir(eDir) );
    4410             : 
    4411             :         //  mindestens eine Zeile/Spalte als Quellbereich behalten:
    4412          18 :         SCSIZE nTotLines = ( eDir == FILL_TO_BOTTOM || eDir == FILL_TO_TOP ) ?
    4413          14 :             static_cast<SCSIZE>( aSourceArea.aEnd.Row() - aSourceArea.aStart.Row() + 1 ) :
    4414          42 :             static_cast<SCSIZE>( aSourceArea.aEnd.Col() - aSourceArea.aStart.Col() + 1 );
    4415          28 :         if ( nCount >= nTotLines )
    4416           2 :             nCount = nTotLines - 1;
    4417             : 
    4418          28 :         switch (eDir)
    4419             :         {
    4420             :             case FILL_TO_BOTTOM:
    4421          10 :                 aSourceArea.aEnd.SetRow( sal::static_int_cast<SCROW>( aSourceArea.aEnd.Row() - nCount ) );
    4422          10 :                 break;
    4423             :             case FILL_TO_RIGHT:
    4424          10 :                 aSourceArea.aEnd.SetCol( sal::static_int_cast<SCCOL>( aSourceArea.aEnd.Col() - nCount ) );
    4425          10 :                 break;
    4426             :             case FILL_TO_TOP:
    4427           4 :                 aSourceArea.aStart.SetRow( sal::static_int_cast<SCROW>( aSourceArea.aStart.Row() + nCount ) );
    4428           4 :                 break;
    4429             :             case FILL_TO_LEFT:
    4430           4 :                 aSourceArea.aStart.SetCol( sal::static_int_cast<SCCOL>( aSourceArea.aStart.Col() + nCount ) );
    4431           4 :                 break;
    4432             :         }
    4433             : 
    4434          28 :         ScDocument* pUndoDoc = NULL;
    4435          28 :         if ( bRecord )
    4436             :         {
    4437          28 :             SCTAB nTabCount = rDoc.GetTableCount();
    4438          28 :             SCTAB nDestStartTab = aDestArea.aStart.Tab();
    4439             : 
    4440          28 :             pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
    4441          28 :             pUndoDoc->InitUndo( &rDoc, nDestStartTab, nDestStartTab );
    4442          28 :             ScMarkData::iterator itr = aMark.begin(), itrEnd = aMark.end();
    4443          56 :             for (; itr != itrEnd && *itr < nTabCount; ++itr)
    4444          28 :                 if (*itr != nDestStartTab)
    4445           0 :                     pUndoDoc->AddUndoTab( *itr, *itr );
    4446             : 
    4447             :             rDoc.CopyToDocument(
    4448          28 :                 aDestArea.aStart.Col(), aDestArea.aStart.Row(), 0,
    4449          28 :                 aDestArea.aEnd.Col(), aDestArea.aEnd.Row(), nTabCount-1,
    4450          84 :                 IDF_AUTOFILL, false, pUndoDoc, &aMark );
    4451             :         }
    4452             : 
    4453          56 :         if (aDestArea.aStart.Col() <= aDestArea.aEnd.Col() &&
    4454          28 :             aDestArea.aStart.Row() <= aDestArea.aEnd.Row())
    4455             :         {
    4456          28 :             if ( fStart != MAXDOUBLE )
    4457             :             {
    4458           0 :                 SCCOL nValX = (eDir == FILL_TO_LEFT) ? aDestArea.aEnd.Col() : aDestArea.aStart.Col();
    4459           0 :                 SCROW nValY = (eDir == FILL_TO_TOP ) ? aDestArea.aEnd.Row() : aDestArea.aStart.Row();
    4460           0 :                 SCTAB nTab = aDestArea.aStart.Tab();
    4461           0 :                 rDoc.SetValue( nValX, nValY, nTab, fStart );
    4462             :             }
    4463             : 
    4464             :             sal_uLong nProgCount;
    4465          28 :             if (eDir == FILL_TO_BOTTOM || eDir == FILL_TO_TOP)
    4466          14 :                 nProgCount = aSourceArea.aEnd.Col() - aSourceArea.aStart.Col() + 1;
    4467             :             else
    4468          14 :                 nProgCount = aSourceArea.aEnd.Row() - aSourceArea.aStart.Row() + 1;
    4469          28 :             nProgCount *= nCount;
    4470             :             ScProgress aProgress( rDoc.GetDocumentShell(),
    4471          28 :                     ScGlobal::GetRscString(STR_FILL_SERIES_PROGRESS), nProgCount );
    4472             : 
    4473          28 :             rDoc.Fill( aSourceArea.aStart.Col(), aSourceArea.aStart.Row(),
    4474          28 :                         aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), &aProgress,
    4475          84 :                         aMark, nCount, eDir, eCmd, eDateCmd, fStep, fMax );
    4476          28 :             AdjustRowHeight(rRange);
    4477             : 
    4478          28 :             rDocShell.PostPaintGridAll();
    4479          28 :             aModificator.SetDocumentModified();
    4480             :         }
    4481             : 
    4482          28 :         if ( bRecord )      // Draw-Undo erst jetzt verfuegbar
    4483             :         {
    4484          28 :             rDocShell.GetUndoManager()->AddUndoAction(
    4485             :                 new ScUndoAutoFill( &rDocShell, aDestArea, aSourceArea, pUndoDoc, aMark,
    4486          28 :                                     eDir, eCmd, eDateCmd, fStart, fStep, fMax) );
    4487             :         }
    4488             : 
    4489          28 :         bSuccess = true;
    4490             :     }
    4491           0 :     else if (!bApi)
    4492           0 :         rDocShell.ErrorMessage(aTester.GetMessageId());
    4493             : 
    4494          56 :     return bSuccess;
    4495             : }
    4496             : 
    4497           4 : bool ScDocFunc::FillAuto( ScRange& rRange, const ScMarkData* pTabMark,
    4498             :                             FillDir eDir, sal_uLong nCount, bool bRecord, bool bApi )
    4499             : {
    4500           4 :     double      fStep = 1.0;
    4501           4 :     double      fMax = MAXDOUBLE;
    4502           4 :     return FillAuto( rRange, pTabMark, eDir, FILL_AUTO, FILL_DAY, nCount, fStep, fMax, bRecord, bApi );
    4503             : }
    4504             : 
    4505           4 : bool ScDocFunc::FillAuto( ScRange& rRange, const ScMarkData* pTabMark, FillDir eDir, FillCmd eCmd, FillDateCmd  eDateCmd, sal_uLong nCount, double fStep, double fMax,  bool bRecord, bool bApi )
    4506             : {
    4507           4 :     ScDocShellModificator aModificator( rDocShell );
    4508             : 
    4509           4 :     ScDocument& rDoc = rDocShell.GetDocument();
    4510           4 :     SCCOL nStartCol = rRange.aStart.Col();
    4511           4 :     SCROW nStartRow = rRange.aStart.Row();
    4512           4 :     SCTAB nStartTab = rRange.aStart.Tab();
    4513           4 :     SCCOL nEndCol = rRange.aEnd.Col();
    4514           4 :     SCROW nEndRow = rRange.aEnd.Row();
    4515           4 :     SCTAB nEndTab = rRange.aEnd.Tab();
    4516             : 
    4517           4 :     if (bRecord && !rDoc.IsUndoEnabled())
    4518           0 :         bRecord = false;
    4519             : 
    4520           8 :     ScMarkData aMark;
    4521           4 :     if (pTabMark)
    4522           0 :         aMark = *pTabMark;
    4523             :     else
    4524             :     {
    4525           8 :         for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
    4526           4 :             aMark.SelectTable( nTab, true );
    4527             :     }
    4528             : 
    4529           4 :     ScRange aSourceArea = rRange;
    4530           4 :     ScRange aDestArea   = rRange;
    4531             : 
    4532           4 :     switch (eDir)
    4533             :     {
    4534             :         case FILL_TO_BOTTOM:
    4535           2 :             aDestArea.aEnd.SetRow( sal::static_int_cast<SCROW>( aSourceArea.aEnd.Row() + nCount ) );
    4536           2 :             break;
    4537             :         case FILL_TO_TOP:
    4538           0 :             if (nCount > sal::static_int_cast<sal_uLong>( aSourceArea.aStart.Row() ))
    4539             :             {
    4540             :                 OSL_FAIL("FillAuto: Row < 0");
    4541           0 :                 nCount = aSourceArea.aStart.Row();
    4542             :             }
    4543           0 :             aDestArea.aStart.SetRow( sal::static_int_cast<SCROW>( aSourceArea.aStart.Row() - nCount ) );
    4544           0 :             break;
    4545             :         case FILL_TO_RIGHT:
    4546           2 :             aDestArea.aEnd.SetCol( sal::static_int_cast<SCCOL>( aSourceArea.aEnd.Col() + nCount ) );
    4547           2 :             break;
    4548             :         case FILL_TO_LEFT:
    4549           0 :             if (nCount > sal::static_int_cast<sal_uLong>( aSourceArea.aStart.Col() ))
    4550             :             {
    4551             :                 OSL_FAIL("FillAuto: Col < 0");
    4552           0 :                 nCount = aSourceArea.aStart.Col();
    4553             :             }
    4554           0 :             aDestArea.aStart.SetCol( sal::static_int_cast<SCCOL>( aSourceArea.aStart.Col() - nCount ) );
    4555           0 :             break;
    4556             :         default:
    4557             :             OSL_FAIL("Falsche Richtung bei FillAuto");
    4558           0 :             break;
    4559             :     }
    4560             : 
    4561             :     //      Zellschutz testen
    4562             :     //!     Quellbereich darf geschuetzt sein !!!
    4563             :     //!     aber kein Matrixfragment enthalten !!!
    4564             : 
    4565           4 :     ScEditableTester aTester( &rDoc, aDestArea );
    4566           4 :     if ( !aTester.IsEditable() )
    4567             :     {
    4568           0 :         if (!bApi)
    4569           0 :             rDocShell.ErrorMessage(aTester.GetMessageId());
    4570           0 :         return false;
    4571             :     }
    4572             : 
    4573           4 :     if ( rDoc.HasSelectedBlockMatrixFragment( nStartCol, nStartRow,
    4574           4 :             nEndCol, nEndRow, aMark ) )
    4575             :     {
    4576           0 :         if (!bApi)
    4577           0 :             rDocShell.ErrorMessage(STR_MATRIXFRAGMENTERR);
    4578           0 :         return false;
    4579             :     }
    4580             : 
    4581           4 :     WaitObject aWait( rDocShell.GetActiveDialogParent() );
    4582             : 
    4583           4 :     ScDocument* pUndoDoc = NULL;
    4584           4 :     if ( bRecord )
    4585             :     {
    4586           4 :         SCTAB nTabCount = rDoc.GetTableCount();
    4587           4 :         SCTAB nDestStartTab = aDestArea.aStart.Tab();
    4588             : 
    4589           4 :         pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
    4590           4 :         pUndoDoc->InitUndo( &rDoc, nDestStartTab, nDestStartTab );
    4591           4 :         ScMarkData::iterator itr = aMark.begin(), itrEnd = aMark.end();
    4592           8 :         for (; itr != itrEnd && nTabCount; ++itr)
    4593           4 :             if (*itr != nDestStartTab)
    4594           0 :                 pUndoDoc->AddUndoTab( *itr, *itr );
    4595             : 
    4596             :         // do not clone note captions in undo document
    4597             :         rDoc.CopyToDocument(
    4598           4 :             aDestArea.aStart.Col(), aDestArea.aStart.Row(), 0,
    4599           4 :             aDestArea.aEnd.Col(), aDestArea.aEnd.Row(), nTabCount-1,
    4600          12 :             IDF_AUTOFILL, false, pUndoDoc, &aMark );
    4601             :     }
    4602             : 
    4603             :     sal_uLong nProgCount;
    4604           4 :     if (eDir == FILL_TO_BOTTOM || eDir == FILL_TO_TOP)
    4605           2 :         nProgCount = aSourceArea.aEnd.Col() - aSourceArea.aStart.Col() + 1;
    4606             :     else
    4607           2 :         nProgCount = aSourceArea.aEnd.Row() - aSourceArea.aStart.Row() + 1;
    4608           4 :     nProgCount *= nCount;
    4609             :     ScProgress aProgress( rDoc.GetDocumentShell(),
    4610           8 :             ScGlobal::GetRscString(STR_FILL_SERIES_PROGRESS), nProgCount );
    4611             : 
    4612           4 :     rDoc.Fill( aSourceArea.aStart.Col(), aSourceArea.aStart.Row(),
    4613           4 :             aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), &aProgress,
    4614          12 :             aMark, nCount, eDir, eCmd, eDateCmd, fStep, fMax );
    4615             : 
    4616           4 :     AdjustRowHeight(aDestArea);
    4617             : 
    4618           4 :     if ( bRecord )      // Draw-Undo erst jetzt verfuegbar
    4619             :     {
    4620           4 :         rDocShell.GetUndoManager()->AddUndoAction(
    4621             :             new ScUndoAutoFill( &rDocShell, aDestArea, aSourceArea, pUndoDoc, aMark,
    4622           4 :                                 eDir, eCmd, eDateCmd, MAXDOUBLE, fStep, fMax) );
    4623             :     }
    4624             : 
    4625           4 :     rDocShell.PostPaintGridAll();
    4626           4 :     aModificator.SetDocumentModified();
    4627             : 
    4628           4 :     rRange = aDestArea;         // Zielbereich zurueckgeben (zum Markieren)
    4629          12 :     return true;
    4630             : }
    4631             : 
    4632          12 : bool ScDocFunc::MergeCells( const ScCellMergeOption& rOption, bool bContents, bool bRecord, bool bApi )
    4633             : {
    4634             :     using ::std::set;
    4635             : 
    4636          12 :     ScDocShellModificator aModificator( rDocShell );
    4637             : 
    4638          12 :     SCCOL nStartCol = rOption.mnStartCol;
    4639          12 :     SCROW nStartRow = rOption.mnStartRow;
    4640          12 :     SCCOL nEndCol = rOption.mnEndCol;
    4641          12 :     SCROW nEndRow = rOption.mnEndRow;
    4642          12 :     if ((nStartCol == nEndCol && nStartRow == nEndRow) || rOption.maTabs.empty())
    4643             :     {
    4644             :         // Nothing to do.  Bail out quick.
    4645           4 :         return true;
    4646             :     }
    4647             : 
    4648           8 :     ScDocument& rDoc = rDocShell.GetDocument();
    4649           8 :     set<SCTAB>::const_iterator itrBeg = rOption.maTabs.begin(), itrEnd = rOption.maTabs.end();
    4650           8 :     SCTAB nTab1 = *itrBeg, nTab2 = *rOption.maTabs.rbegin();
    4651             : 
    4652           8 :     if (bRecord && !rDoc.IsUndoEnabled())
    4653           0 :         bRecord = false;
    4654             : 
    4655          32 :     for (set<SCTAB>::const_iterator itr = itrBeg; itr != itrEnd; ++itr)
    4656             :     {
    4657           8 :         ScEditableTester aTester( &rDoc, *itr, nStartCol, nStartRow, nEndCol, nEndRow );
    4658           8 :         if (!aTester.IsEditable())
    4659             :         {
    4660           0 :             if (!bApi)
    4661           0 :                 rDocShell.ErrorMessage(aTester.GetMessageId());
    4662           0 :             return false;
    4663             :         }
    4664             : 
    4665          24 :         if ( rDoc.HasAttrib( nStartCol, nStartRow, *itr, nEndCol, nEndRow, *itr,
    4666          16 :                                 HASATTR_MERGED | HASATTR_OVERLAPPED ) )
    4667             :         {
    4668             :             // "Zusammenfassen nicht verschachteln !"
    4669           0 :             if (!bApi)
    4670           0 :                 rDocShell.ErrorMessage(STR_MSSG_MERGECELLS_0);
    4671           0 :             return false;
    4672             :         }
    4673             :     }
    4674             : 
    4675           8 :     ScDocument* pUndoDoc = NULL;
    4676           8 :     bool bNeedContentsUndo = false;
    4677          16 :     for (set<SCTAB>::const_iterator itr = itrBeg; itr != itrEnd; ++itr)
    4678             :     {
    4679           8 :         SCTAB nTab = *itr;
    4680           8 :         bool bNeedContents = bContents &&
    4681           0 :                 ( !rDoc.IsBlockEmpty( nTab, nStartCol,nStartRow+1, nStartCol,nEndRow, true ) ||
    4682           8 :                   !rDoc.IsBlockEmpty( nTab, nStartCol+1,nStartRow, nEndCol,nEndRow, true ) );
    4683             : 
    4684           8 :         if (bRecord)
    4685             :         {
    4686             :             // test if the range contains other notes which also implies that we need an undo document
    4687           8 :             bool bHasNotes = false;
    4688          28 :             for( ScAddress aPos( nStartCol, nStartRow, nTab ); !bHasNotes && (aPos.Col() <= nEndCol); aPos.IncCol() )
    4689          94 :                 for( aPos.SetRow( nStartRow ); !bHasNotes && (aPos.Row() <= nEndRow); aPos.IncRow() )
    4690          74 :                     bHasNotes = ((aPos.Col() != nStartCol) || (aPos.Row() != nStartRow)) && (rDoc.HasNote(aPos));
    4691             : 
    4692           8 :             if (!pUndoDoc)
    4693             :             {
    4694           8 :                 pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
    4695           8 :                 pUndoDoc->InitUndo(&rDoc, nTab1, nTab2);
    4696             :             }
    4697             :             // note captions are collected by drawing undo
    4698             :             rDoc.CopyToDocument( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab,
    4699           8 :                                   IDF_ALL|IDF_NOCAPTIONS, false, pUndoDoc );
    4700           8 :             if( bHasNotes )
    4701           0 :                 rDoc.BeginDrawUndo();
    4702             :         }
    4703             : 
    4704           8 :         if (bNeedContents)
    4705           0 :             rDoc.DoMergeContents( nTab, nStartCol,nStartRow, nEndCol,nEndRow );
    4706           8 :         rDoc.DoMerge( nTab, nStartCol,nStartRow, nEndCol,nEndRow );
    4707             : 
    4708           8 :         if (rOption.mbCenter)
    4709             :         {
    4710           0 :             rDoc.ApplyAttr( nStartCol, nStartRow, nTab, SvxHorJustifyItem( SVX_HOR_JUSTIFY_CENTER, ATTR_HOR_JUSTIFY ) );
    4711           0 :             rDoc.ApplyAttr( nStartCol, nStartRow, nTab, SvxVerJustifyItem( SVX_VER_JUSTIFY_CENTER, ATTR_VER_JUSTIFY ) );
    4712             :         }
    4713             : 
    4714           8 :         if ( !AdjustRowHeight( ScRange( 0,nStartRow,nTab, MAXCOL,nEndRow,nTab ) ) )
    4715             :             rDocShell.PostPaint( nStartCol, nStartRow, nTab,
    4716           8 :                                  nEndCol, nEndRow, nTab, PAINT_GRID );
    4717           8 :         if (bNeedContents || rOption.mbCenter)
    4718             :         {
    4719           0 :             ScRange aRange(nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab);
    4720           0 :             rDoc.SetDirty(aRange);
    4721             :         }
    4722             : 
    4723           8 :         bNeedContentsUndo |= bNeedContents;
    4724             :     }
    4725             : 
    4726           8 :     if (pUndoDoc)
    4727             :     {
    4728           8 :         SdrUndoGroup* pDrawUndo = rDoc.GetDrawLayer() ? rDoc.GetDrawLayer()->GetCalcUndo() : NULL;
    4729           8 :         rDocShell.GetUndoManager()->AddUndoAction(
    4730           8 :             new ScUndoMerge(&rDocShell, rOption, bNeedContentsUndo, pUndoDoc, pDrawUndo) );
    4731             :     }
    4732             : 
    4733           8 :     aModificator.SetDocumentModified();
    4734             : 
    4735           8 :     SfxBindings* pBindings = rDocShell.GetViewBindings();
    4736           8 :     if (pBindings)
    4737             :     {
    4738           6 :         pBindings->Invalidate( FID_MERGE_ON );
    4739           6 :         pBindings->Invalidate( FID_MERGE_OFF );
    4740           6 :         pBindings->Invalidate( FID_MERGE_TOGGLE );
    4741             :     }
    4742             : 
    4743           8 :     return true;
    4744             : }
    4745             : 
    4746           2 : bool ScDocFunc::UnmergeCells( const ScRange& rRange, bool bRecord )
    4747             : {
    4748           2 :     ScCellMergeOption aOption(rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row());
    4749           2 :     SCTAB nTab1 = rRange.aStart.Tab(), nTab2 = rRange.aEnd.Tab();
    4750           4 :     for (SCTAB i = nTab1; i <= nTab2; ++i)
    4751           2 :         aOption.maTabs.insert(i);
    4752             : 
    4753           2 :     return UnmergeCells(aOption, bRecord);
    4754             : }
    4755             : 
    4756          12 : bool ScDocFunc::UnmergeCells( const ScCellMergeOption& rOption, bool bRecord )
    4757             : {
    4758             :     using ::std::set;
    4759             : 
    4760          12 :     if (rOption.maTabs.empty())
    4761             :         // Nothing to unmerge.
    4762           0 :         return true;
    4763             : 
    4764          12 :     ScDocShellModificator aModificator( rDocShell );
    4765          12 :     ScDocument& rDoc = rDocShell.GetDocument();
    4766             : 
    4767          12 :     if (bRecord && !rDoc.IsUndoEnabled())
    4768           0 :         bRecord = false;
    4769             : 
    4770          12 :     ScDocument* pUndoDoc = NULL;
    4771          24 :     for (set<SCTAB>::const_iterator itr = rOption.maTabs.begin(), itrEnd = rOption.maTabs.end();
    4772             :           itr != itrEnd; ++itr)
    4773             :     {
    4774          12 :         SCTAB nTab = *itr;
    4775          12 :         ScRange aRange = rOption.getSingleRange(nTab);
    4776          12 :         if ( !rDoc.HasAttrib(aRange, HASATTR_MERGED) )
    4777           4 :             continue;
    4778             : 
    4779           8 :         ScRange aExtended = aRange;
    4780           8 :         rDoc.ExtendMerge(aExtended);
    4781           8 :         ScRange aRefresh = aExtended;
    4782           8 :         rDoc.ExtendOverlapped(aRefresh);
    4783             : 
    4784           8 :         if (bRecord)
    4785             :         {
    4786           8 :             if (!pUndoDoc)
    4787             :             {
    4788           8 :                 pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
    4789           8 :                 pUndoDoc->InitUndo(&rDoc, *rOption.maTabs.begin(), *rOption.maTabs.rbegin());
    4790             :             }
    4791           8 :             rDoc.CopyToDocument(aExtended, IDF_ATTRIB, false, pUndoDoc);
    4792             :         }
    4793             : 
    4794           8 :         const SfxPoolItem& rDefAttr = rDoc.GetPool()->GetDefaultItem( ATTR_MERGE );
    4795           8 :         ScPatternAttr aPattern( rDoc.GetPool() );
    4796           8 :         aPattern.GetItemSet().Put( rDefAttr );
    4797           8 :         rDoc.ApplyPatternAreaTab( aRange.aStart.Col(), aRange.aStart.Row(),
    4798           8 :                                    aRange.aEnd.Col(), aRange.aEnd.Row(), nTab,
    4799          24 :                                    aPattern );
    4800             : 
    4801           8 :         rDoc.RemoveFlagsTab( aExtended.aStart.Col(), aExtended.aStart.Row(),
    4802           8 :                               aExtended.aEnd.Col(), aExtended.aEnd.Row(), nTab,
    4803          24 :                               SC_MF_HOR | SC_MF_VER );
    4804             : 
    4805           8 :         rDoc.ExtendMerge( aRefresh, true );
    4806             : 
    4807           8 :         if ( !AdjustRowHeight( aExtended ) )
    4808           8 :             rDocShell.PostPaint( aExtended, PAINT_GRID );
    4809           8 :     }
    4810             : 
    4811          12 :     if (bRecord)
    4812             :     {
    4813          12 :         rDocShell.GetUndoManager()->AddUndoAction(
    4814          12 :             new ScUndoRemoveMerge( &rDocShell, rOption, pUndoDoc ) );
    4815             :     }
    4816          12 :     aModificator.SetDocumentModified();
    4817             : 
    4818          12 :     return true;
    4819             : }
    4820             : 
    4821           4 : bool ScDocFunc::ModifyRangeNames( const ScRangeName& rNewRanges, SCTAB nTab )
    4822             : {
    4823           4 :     return SetNewRangeNames( new ScRangeName(rNewRanges), true, nTab );
    4824             : }
    4825             : 
    4826          62 : bool ScDocFunc::SetNewRangeNames( ScRangeName* pNewRanges, bool bModifyDoc, SCTAB nTab )     // takes ownership of pNewRanges
    4827             : {
    4828          62 :     ScDocShellModificator aModificator( rDocShell );
    4829             : 
    4830             :     OSL_ENSURE( pNewRanges, "pNewRanges is 0" );
    4831          62 :     ScDocument& rDoc = rDocShell.GetDocument();
    4832          62 :     bool bUndo(rDoc.IsUndoEnabled());
    4833             : 
    4834          62 :     if (bUndo)
    4835             :     {
    4836             :         ScRangeName* pOld;
    4837          62 :         if (nTab >=0)
    4838             :         {
    4839           0 :             pOld = rDoc.GetRangeName(nTab);
    4840             :         }
    4841             :         else
    4842             :         {
    4843          62 :             pOld = rDoc.GetRangeName();
    4844             :         }
    4845          62 :         ScRangeName* pUndoRanges = new ScRangeName(*pOld);
    4846          62 :         ScRangeName* pRedoRanges = new ScRangeName(*pNewRanges);
    4847          62 :         rDocShell.GetUndoManager()->AddUndoAction(
    4848          62 :             new ScUndoRangeNames( &rDocShell, pUndoRanges, pRedoRanges, nTab ) );
    4849             :     }
    4850             : 
    4851             :     // #i55926# While loading XML, formula cells only have a single string token,
    4852             :     // so CompileNameFormula would never find any name (index) tokens, and would
    4853             :     // unnecessarily loop through all cells.
    4854          62 :     bool bCompile = ( !rDoc.IsImportingXML() && rDoc.GetNamedRangesLockCount() == 0 );
    4855             : 
    4856          62 :     if ( bCompile )
    4857          62 :         rDoc.PreprocessRangeNameUpdate();
    4858          62 :     if (nTab >= 0)
    4859           0 :         rDoc.SetRangeName( nTab, pNewRanges ); // takes ownership
    4860             :     else
    4861          62 :         rDoc.SetRangeName( pNewRanges );       // takes ownership
    4862          62 :     if ( bCompile )
    4863          62 :         rDoc.CompileHybridFormula();
    4864             : 
    4865          62 :     if (bModifyDoc)
    4866             :     {
    4867          62 :         aModificator.SetDocumentModified();
    4868          62 :         SfxGetpApp()->Broadcast( SfxSimpleHint(SC_HINT_AREAS_CHANGED) );
    4869             :     }
    4870             : 
    4871          62 :     return true;
    4872             : }
    4873             : 
    4874           2 : void ScDocFunc::ModifyAllRangeNames( const boost::ptr_map<OUString, ScRangeName>& rRangeMap )
    4875             : {
    4876           2 :     ScDocShellModificator aModificator(rDocShell);
    4877           2 :     ScDocument& rDoc = rDocShell.GetDocument();
    4878             : 
    4879           2 :     if (rDoc.IsUndoEnabled())
    4880             :     {
    4881           2 :         std::map<OUString, ScRangeName*> aOldRangeMap;
    4882           2 :         rDoc.GetRangeNameMap(aOldRangeMap);
    4883           2 :         rDocShell.GetUndoManager()->AddUndoAction(
    4884           2 :                 new ScUndoAllRangeNames(&rDocShell, aOldRangeMap, rRangeMap));
    4885             :     }
    4886             : 
    4887           2 :     rDoc.PreprocessRangeNameUpdate();
    4888           2 :     rDoc.SetAllRangeNames(rRangeMap);
    4889           2 :     rDoc.CompileHybridFormula();
    4890             : 
    4891           2 :     aModificator.SetDocumentModified();
    4892           2 :     SfxGetpApp()->Broadcast(SfxSimpleHint(SC_HINT_AREAS_CHANGED));
    4893           2 : }
    4894             : 
    4895          16 : void ScDocFunc::CreateOneName( ScRangeName& rList,
    4896             :                                 SCCOL nPosX, SCROW nPosY, SCTAB nTab,
    4897             :                                 SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
    4898             :                                 bool& rCancel, bool bApi )
    4899             : {
    4900          16 :     if (rCancel)
    4901          16 :         return;
    4902             : 
    4903          16 :     ScDocument& rDoc = rDocShell.GetDocument();
    4904          16 :     if (!rDoc.HasValueData( nPosX, nPosY, nTab ))
    4905             :     {
    4906          16 :         OUString aName = rDoc.GetString(nPosX, nPosY, nTab);
    4907          16 :         ScRangeData::MakeValidName(aName);
    4908          16 :         if (!aName.isEmpty())
    4909             :         {
    4910          12 :             OUString aContent(ScRange( nX1, nY1, nTab, nX2, nY2, nTab ).Format(SCR_ABS_3D, &rDoc));
    4911             : 
    4912          12 :             bool bInsert = false;
    4913          12 :             ScRangeData* pOld = rList.findByUpperName(ScGlobal::pCharClass->uppercase(aName));
    4914          12 :             if (pOld)
    4915             :             {
    4916           0 :                 OUString aOldStr;
    4917           0 :                 pOld->GetSymbol( aOldStr );
    4918           0 :                 if (aOldStr != aContent)
    4919             :                 {
    4920           0 :                     if (bApi)
    4921           0 :                         bInsert = true;     // per API nicht nachfragen
    4922             :                     else
    4923             :                     {
    4924           0 :                         OUString aTemplate = ScGlobal::GetRscString( STR_CREATENAME_REPLACE );
    4925             : 
    4926           0 :                         OUString aMessage = aTemplate.getToken( 0, '#' );
    4927           0 :                         aMessage += aName;
    4928           0 :                         aMessage += aTemplate.getToken( 1, '#' );
    4929             : 
    4930             :                         short nResult = QueryBox( rDocShell.GetActiveDialogParent(),
    4931             :                                                     WinBits(WB_YES_NO_CANCEL | WB_DEF_YES),
    4932           0 :                                                     aMessage ).Execute();
    4933           0 :                         if ( nResult == RET_YES )
    4934             :                         {
    4935           0 :                             rList.erase(*pOld);
    4936           0 :                             bInsert = true;
    4937             :                         }
    4938           0 :                         else if ( nResult == RET_CANCEL )
    4939           0 :                             rCancel = true;
    4940             :                     }
    4941           0 :                 }
    4942             :             }
    4943             :             else
    4944          12 :                 bInsert = true;
    4945             : 
    4946          12 :             if (bInsert)
    4947             :             {
    4948             :                 ScRangeData* pData = new ScRangeData( &rDoc, aName, aContent,
    4949          12 :                         ScAddress( nPosX, nPosY, nTab));
    4950          12 :                 if (!rList.insert(pData))
    4951             :                 {
    4952             :                     OSL_FAIL("nanu?");
    4953             :                 }
    4954          12 :             }
    4955          16 :         }
    4956             :     }
    4957             : }
    4958             : 
    4959           4 : bool ScDocFunc::CreateNames( const ScRange& rRange, sal_uInt16 nFlags, bool bApi, SCTAB aTab )
    4960             : {
    4961           4 :     if (!nFlags)
    4962           0 :         return false;       // war nix
    4963             : 
    4964           4 :     ScDocShellModificator aModificator( rDocShell );
    4965             : 
    4966           4 :     bool bDone = false;
    4967           4 :     SCCOL nStartCol = rRange.aStart.Col();
    4968           4 :     SCROW nStartRow = rRange.aStart.Row();
    4969           4 :     SCCOL nEndCol = rRange.aEnd.Col();
    4970           4 :     SCROW nEndRow = rRange.aEnd.Row();
    4971           4 :     SCTAB nTab = rRange.aStart.Tab();
    4972             :     OSL_ENSURE(rRange.aEnd.Tab() == nTab, "CreateNames: mehrere Tabellen geht nicht");
    4973             : 
    4974           4 :     bool bValid = true;
    4975           4 :     if ( nFlags & ( NAME_TOP | NAME_BOTTOM ) )
    4976           2 :         if ( nStartRow == nEndRow )
    4977           0 :             bValid = false;
    4978           4 :     if ( nFlags & ( NAME_LEFT | NAME_RIGHT ) )
    4979           2 :         if ( nStartCol == nEndCol )
    4980           0 :             bValid = false;
    4981             : 
    4982           4 :     if (bValid)
    4983             :     {
    4984           4 :         ScDocument& rDoc = rDocShell.GetDocument();
    4985             :         ScRangeName* pNames;
    4986           4 :         if (aTab >=0)
    4987           0 :             pNames = rDoc.GetRangeName(nTab);
    4988             :         else
    4989           4 :             pNames = rDoc.GetRangeName();
    4990             : 
    4991           4 :         if (!pNames)
    4992           0 :             return false;   // soll nicht sein
    4993           4 :         ScRangeName aNewRanges( *pNames );
    4994             : 
    4995           4 :         bool bTop    = ( ( nFlags & NAME_TOP ) != 0 );
    4996           4 :         bool bLeft   = ( ( nFlags & NAME_LEFT ) != 0 );
    4997           4 :         bool bBottom = ( ( nFlags & NAME_BOTTOM ) != 0 );
    4998           4 :         bool bRight  = ( ( nFlags & NAME_RIGHT ) != 0 );
    4999             : 
    5000           4 :         SCCOL nContX1 = nStartCol;
    5001           4 :         SCROW nContY1 = nStartRow;
    5002           4 :         SCCOL nContX2 = nEndCol;
    5003           4 :         SCROW nContY2 = nEndRow;
    5004             : 
    5005           4 :         if ( bTop )
    5006           2 :             ++nContY1;
    5007           4 :         if ( bLeft )
    5008           2 :             ++nContX1;
    5009           4 :         if ( bBottom )
    5010           0 :             --nContY2;
    5011           4 :         if ( bRight )
    5012           0 :             --nContX2;
    5013             : 
    5014           4 :         bool bCancel = false;
    5015             :         SCCOL i;
    5016             :         SCROW j;
    5017             : 
    5018           4 :         if ( bTop )
    5019          10 :             for (i=nContX1; i<=nContX2; i++)
    5020           8 :                 CreateOneName( aNewRanges, i,nStartRow,nTab, i,nContY1,i,nContY2, bCancel, bApi );
    5021           4 :         if ( bLeft )
    5022          10 :             for (j=nContY1; j<=nContY2; j++)
    5023           8 :                 CreateOneName( aNewRanges, nStartCol,j,nTab, nContX1,j,nContX2,j, bCancel, bApi );
    5024           4 :         if ( bBottom )
    5025           0 :             for (i=nContX1; i<=nContX2; i++)
    5026           0 :                 CreateOneName( aNewRanges, i,nEndRow,nTab, i,nContY1,i,nContY2, bCancel, bApi );
    5027           4 :         if ( bRight )
    5028           0 :             for (j=nContY1; j<=nContY2; j++)
    5029           0 :                 CreateOneName( aNewRanges, nEndCol,j,nTab, nContX1,j,nContX2,j, bCancel, bApi );
    5030             : 
    5031           4 :         if ( bTop && bLeft )
    5032           0 :             CreateOneName( aNewRanges, nStartCol,nStartRow,nTab, nContX1,nContY1,nContX2,nContY2, bCancel, bApi );
    5033           4 :         if ( bTop && bRight )
    5034           0 :             CreateOneName( aNewRanges, nEndCol,nStartRow,nTab, nContX1,nContY1,nContX2,nContY2, bCancel, bApi );
    5035           4 :         if ( bBottom && bLeft )
    5036           0 :             CreateOneName( aNewRanges, nStartCol,nEndRow,nTab, nContX1,nContY1,nContX2,nContY2, bCancel, bApi );
    5037           4 :         if ( bBottom && bRight )
    5038           0 :             CreateOneName( aNewRanges, nEndCol,nEndRow,nTab, nContX1,nContY1,nContX2,nContY2, bCancel, bApi );
    5039             : 
    5040           4 :         bDone = ModifyRangeNames( aNewRanges, aTab );
    5041             : 
    5042           4 :         aModificator.SetDocumentModified();
    5043           4 :         SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
    5044             :     }
    5045             : 
    5046           4 :     return bDone;
    5047             : }
    5048             : 
    5049          10 : bool ScDocFunc::InsertNameList( const ScAddress& rStartPos, bool bApi )
    5050             : {
    5051          10 :     ScDocShellModificator aModificator( rDocShell );
    5052             : 
    5053          10 :     bool bDone = false;
    5054          10 :     ScDocument& rDoc = rDocShell.GetDocument();
    5055          10 :     const bool bRecord = rDoc.IsUndoEnabled();
    5056          10 :     SCTAB nTab = rStartPos.Tab();
    5057          10 :     ScDocument* pUndoDoc = NULL;
    5058             : 
    5059             :     //local names have higher priority than global names
    5060          10 :     ScRangeName* pLocalList = rDoc.GetRangeName(nTab);
    5061          10 :     sal_uInt16 nValidCount = 0;
    5062          10 :     ScRangeName::iterator itrLocalBeg = pLocalList->begin(), itrLocalEnd = pLocalList->end();
    5063          10 :     for (ScRangeName::iterator itr = itrLocalBeg; itr != itrLocalEnd; ++itr)
    5064             :     {
    5065           0 :         const ScRangeData& r = *itr->second;
    5066           0 :         if (!r.HasType(RT_DATABASE))
    5067           0 :             ++nValidCount;
    5068             :     }
    5069          10 :     ScRangeName* pList = rDoc.GetRangeName();
    5070          10 :     ScRangeName::iterator itrBeg = pList->begin(), itrEnd = pList->end();
    5071          52 :     for (ScRangeName::iterator itr = itrBeg; itr != itrEnd; ++itr)
    5072             :     {
    5073          42 :         const ScRangeData& r = *itr->second;
    5074          42 :         if (!r.HasType(RT_DATABASE) && !pLocalList->findByUpperName(r.GetUpperName()))
    5075          42 :             ++nValidCount;
    5076             :     }
    5077             : 
    5078          10 :     if (nValidCount)
    5079             :     {
    5080          10 :         SCCOL nStartCol = rStartPos.Col();
    5081          10 :         SCROW nStartRow = rStartPos.Row();
    5082          10 :         SCCOL nEndCol = nStartCol + 1;
    5083          10 :         SCROW nEndRow = nStartRow + static_cast<SCROW>(nValidCount) - 1;
    5084             : 
    5085          10 :         ScEditableTester aTester( &rDoc, nTab, nStartCol,nStartRow, nEndCol,nEndRow );
    5086          10 :         if (aTester.IsEditable())
    5087             :         {
    5088          10 :             if (bRecord)
    5089             :             {
    5090          10 :                 pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
    5091          10 :                 pUndoDoc->InitUndo( &rDoc, nTab, nTab );
    5092             :                 rDoc.CopyToDocument( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab,
    5093          10 :                                         IDF_ALL, false, pUndoDoc );
    5094             : 
    5095          10 :                 rDoc.BeginDrawUndo();      // wegen Hoehenanpassung
    5096             :             }
    5097             : 
    5098          10 :             boost::scoped_array<ScRangeData*> ppSortArray(new ScRangeData* [ nValidCount ]);
    5099          10 :             sal_uInt16 j = 0;
    5100          10 :             for (ScRangeName::iterator itr = itrLocalBeg; itr != itrLocalEnd; ++itr)
    5101             :             {
    5102           0 :                 ScRangeData& r = *itr->second;
    5103           0 :                 if (!r.HasType(RT_DATABASE))
    5104           0 :                     ppSortArray[j++] = &r;
    5105             :             }
    5106          52 :             for (ScRangeName::iterator itr = itrBeg; itr != itrEnd; ++itr)
    5107             :             {
    5108          42 :                 ScRangeData& r = *itr->second;
    5109          42 :                 if (!r.HasType(RT_DATABASE) && !pLocalList->findByUpperName(itr->first))
    5110          42 :                     ppSortArray[j++] = &r;
    5111             :             }
    5112          10 :             qsort( (void*)ppSortArray.get(), nValidCount, sizeof(ScRangeData*),
    5113          20 :                 &ScRangeData_QsortNameCompare );
    5114          20 :             OUString aName;
    5115          20 :             OUStringBuffer aContent;
    5116          20 :             OUString aFormula;
    5117          10 :             SCROW nOutRow = nStartRow;
    5118          52 :             for (j=0; j<nValidCount; j++)
    5119             :             {
    5120          42 :                 ScRangeData* pData = ppSortArray[j];
    5121          42 :                 pData->GetName(aName);
    5122             :                 // relative Referenzen Excel-konform auf die linke Spalte anpassen:
    5123          42 :                 pData->UpdateSymbol(aContent, ScAddress( nStartCol, nOutRow, nTab ));
    5124          42 :                 aFormula = "=" + aContent.toString();
    5125          42 :                 ScSetStringParam aParam;
    5126          42 :                 aParam.setTextInput();
    5127          42 :                 rDoc.SetString(ScAddress(nStartCol,nOutRow,nTab), aName, &aParam);
    5128          42 :                 rDoc.SetString(ScAddress(nEndCol,nOutRow,nTab), aFormula, &aParam);
    5129          42 :                 ++nOutRow;
    5130             :             }
    5131             : 
    5132          10 :             ppSortArray.reset();
    5133             : 
    5134          10 :             if (bRecord)
    5135             :             {
    5136          10 :                 ScDocument* pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
    5137          10 :                 pRedoDoc->InitUndo( &rDoc, nTab, nTab );
    5138             :                 rDoc.CopyToDocument( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab,
    5139          10 :                                         IDF_ALL, false, pRedoDoc );
    5140             : 
    5141          10 :                 rDocShell.GetUndoManager()->AddUndoAction(
    5142             :                     new ScUndoListNames( &rDocShell,
    5143             :                                 ScRange( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab ),
    5144          10 :                                 pUndoDoc, pRedoDoc ) );
    5145             :             }
    5146             : 
    5147          10 :             if (!AdjustRowHeight(ScRange(0,nStartRow,nTab,MAXCOL,nEndRow,nTab)))
    5148          10 :                 rDocShell.PostPaint( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab, PAINT_GRID );
    5149             : 
    5150          10 :             aModificator.SetDocumentModified();
    5151          20 :             bDone = true;
    5152             :         }
    5153           0 :         else if (!bApi)
    5154           0 :             rDocShell.ErrorMessage(aTester.GetMessageId());
    5155             :     }
    5156          10 :     return bDone;
    5157             : }
    5158             : 
    5159           0 : bool ScDocFunc::ResizeMatrix( const ScRange& rOldRange, const ScAddress& rNewEnd, bool bApi )
    5160             : {
    5161           0 :     ScDocument& rDoc = rDocShell.GetDocument();
    5162           0 :     SCCOL nStartCol = rOldRange.aStart.Col();
    5163           0 :     SCROW nStartRow = rOldRange.aStart.Row();
    5164           0 :     SCTAB nTab = rOldRange.aStart.Tab();
    5165             : 
    5166           0 :     bool bUndo(rDoc.IsUndoEnabled());
    5167             : 
    5168           0 :     bool bRet = false;
    5169             : 
    5170           0 :     OUString aFormula;
    5171           0 :     rDoc.GetFormula( nStartCol, nStartRow, nTab, aFormula );
    5172           0 :     if ( aFormula.startsWith("{") && aFormula.endsWith("}") )
    5173             :     {
    5174           0 :         OUString aUndo = ScGlobal::GetRscString( STR_UNDO_RESIZEMATRIX );
    5175           0 :         if (bUndo)
    5176           0 :             rDocShell.GetUndoManager()->EnterListAction( aUndo, aUndo );
    5177             : 
    5178           0 :         aFormula = aFormula.copy(1, aFormula.getLength()-2);
    5179             : 
    5180           0 :         ScMarkData aMark;
    5181           0 :         aMark.SetMarkArea( rOldRange );
    5182           0 :         aMark.SelectTable( nTab, true );
    5183           0 :         ScRange aNewRange( rOldRange.aStart, rNewEnd );
    5184             : 
    5185           0 :         if ( DeleteContents( aMark, IDF_CONTENTS, true, bApi ) )
    5186             :         {
    5187             :             // GRAM_PODF_A1 for API compatibility.
    5188           0 :             bRet = EnterMatrix( aNewRange, &aMark, NULL, aFormula, bApi, false, EMPTY_OUSTRING, formula::FormulaGrammar::GRAM_PODF_A1 );
    5189           0 :             if (!bRet)
    5190             :             {
    5191             :                 //  versuchen, alten Zustand wiederherzustellen
    5192           0 :                 EnterMatrix( rOldRange, &aMark, NULL, aFormula, bApi, false, EMPTY_OUSTRING, formula::FormulaGrammar::GRAM_PODF_A1 );
    5193             :             }
    5194             :         }
    5195             : 
    5196           0 :         if (bUndo)
    5197           0 :             rDocShell.GetUndoManager()->LeaveListAction();
    5198             :     }
    5199             : 
    5200           0 :     return bRet;
    5201             : }
    5202             : 
    5203          32 : bool ScDocFunc::InsertAreaLink( const OUString& rFile, const OUString& rFilter,
    5204             :                                 const OUString& rOptions, const OUString& rSource,
    5205             :                                 const ScRange& rDestRange, sal_uLong nRefresh,
    5206             :                                 bool bFitBlock, bool bApi )
    5207             : {
    5208          32 :     ScDocument& rDoc = rDocShell.GetDocument();
    5209          32 :     bool bUndo (rDoc.IsUndoEnabled());
    5210             : 
    5211          32 :     sfx2::LinkManager* pLinkManager = rDoc.GetLinkManager();
    5212             : 
    5213             :     //  #i52120# if other area links exist at the same start position,
    5214             :     //  remove them first (file format specifies only one link definition
    5215             :     //  for a cell)
    5216             : 
    5217          32 :     sal_uInt16 nLinkCount = pLinkManager->GetLinks().size();
    5218          32 :     sal_uInt16 nRemoved = 0;
    5219          32 :     sal_uInt16 nLinkPos = 0;
    5220          64 :     while (nLinkPos<nLinkCount)
    5221             :     {
    5222           0 :         ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[nLinkPos];
    5223           0 :         if ( pBase->ISA(ScAreaLink) &&
    5224           0 :              static_cast<ScAreaLink*>(pBase)->GetDestArea().aStart == rDestRange.aStart )
    5225             :         {
    5226           0 :             if ( bUndo )
    5227             :             {
    5228           0 :                 if ( !nRemoved )
    5229             :                 {
    5230             :                     // group all remove and the insert action
    5231           0 :                     OUString aUndo = ScGlobal::GetRscString( STR_UNDO_INSERTAREALINK );
    5232           0 :                     rDocShell.GetUndoManager()->EnterListAction( aUndo, aUndo );
    5233             :                 }
    5234             : 
    5235           0 :                 ScAreaLink* pOldArea = static_cast<ScAreaLink*>(pBase);
    5236           0 :                 rDocShell.GetUndoManager()->AddUndoAction(
    5237             :                     new ScUndoRemoveAreaLink( &rDocShell,
    5238             :                         pOldArea->GetFile(), pOldArea->GetFilter(), pOldArea->GetOptions(),
    5239           0 :                         pOldArea->GetSource(), pOldArea->GetDestArea(), pOldArea->GetRefreshDelay() ) );
    5240             :             }
    5241           0 :             pLinkManager->Remove( pBase );
    5242           0 :             nLinkCount = pLinkManager->GetLinks().size();
    5243           0 :             ++nRemoved;
    5244             :         }
    5245             :         else
    5246           0 :             ++nLinkPos;
    5247             :     }
    5248             : 
    5249          32 :     OUString aFilterName = rFilter;
    5250          64 :     OUString aNewOptions = rOptions;
    5251          32 :     if (aFilterName.isEmpty())
    5252           6 :         ScDocumentLoader::GetFilterName( rFile, aFilterName, aNewOptions, true, !bApi );
    5253             : 
    5254             :     //  remove application prefix from filter name here, so the filter options
    5255             :     //  aren't reset when the filter name is changed in ScAreaLink::DataChanged
    5256          32 :     ScDocumentLoader::RemoveAppPrefix( aFilterName );
    5257             : 
    5258             :     ScAreaLink* pLink = new ScAreaLink( &rDocShell, rFile, aFilterName,
    5259          32 :                                         aNewOptions, rSource, rDestRange, nRefresh );
    5260          64 :     OUString aTmp = aFilterName;
    5261          32 :     pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, rFile, &aTmp, &rSource );
    5262             : 
    5263             :     //  Undo fuer den leeren Link
    5264             : 
    5265          32 :     if (bUndo)
    5266             :     {
    5267          32 :         rDocShell.GetUndoManager()->AddUndoAction( new ScUndoInsertAreaLink( &rDocShell,
    5268             :                                                     rFile, aFilterName, aNewOptions,
    5269          32 :                                                     rSource, rDestRange, nRefresh ) );
    5270          32 :         if ( nRemoved )
    5271           0 :             rDocShell.GetUndoManager()->LeaveListAction();  // undo for link update is still separate
    5272             :     }
    5273             : 
    5274             :     //  Update hat sein eigenes Undo
    5275          32 :     if (rDoc.IsExecuteLinkEnabled())
    5276             :     {
    5277          32 :         pLink->SetDoInsert(bFitBlock);  // beim ersten Update ggf. nichts einfuegen
    5278          32 :         pLink->Update();                // kein SetInCreate -> Update ausfuehren
    5279             :     }
    5280          32 :     pLink->SetDoInsert(true);       // Default = true
    5281             : 
    5282          32 :     SfxBindings* pBindings = rDocShell.GetViewBindings();
    5283          32 :     if (pBindings)
    5284          32 :         pBindings->Invalidate( SID_LINKS );
    5285             : 
    5286          32 :     SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );     // Navigator
    5287             : 
    5288          64 :     return true;
    5289             : }
    5290             : 
    5291             : namespace {
    5292             : 
    5293           0 : void RemoveCondFormatAttributes(ScDocument* pDoc, const ScConditionalFormat* pFormat, SCTAB nTab)
    5294             : {
    5295           0 :     const ScRangeList& rRangeList = pFormat->GetRange();
    5296           0 :     pDoc->RemoveCondFormatData( rRangeList, nTab, pFormat->GetKey() );
    5297           0 : }
    5298             : 
    5299          16 : void SetConditionalFormatAttributes(ScDocument* pDoc, const ScRangeList& rRanges, sal_uLong nIndex, SCTAB nTab)
    5300             : {
    5301          16 :     pDoc->AddCondFormatData( rRanges, nTab, nIndex );
    5302          16 : }
    5303             : 
    5304             : }
    5305             : 
    5306          16 : void ScDocFunc::ReplaceConditionalFormat( sal_uLong nOldFormat, ScConditionalFormat* pFormat, SCTAB nTab, const ScRangeList& rRanges )
    5307             : {
    5308          16 :     ScDocShellModificator aModificator(rDocShell);
    5309          16 :     ScDocument& rDoc = rDocShell.GetDocument();
    5310          16 :     if(rDoc.IsTabProtected(nTab))
    5311          16 :         return;
    5312             : 
    5313          16 :     bool bUndo = rDoc.IsUndoEnabled();
    5314          16 :     ScDocument* pUndoDoc = NULL;
    5315          16 :     ScRange aCombinedRange = rRanges.Combine();
    5316          16 :     ScRange aCompleteRange;
    5317          16 :     if(bUndo)
    5318             :     {
    5319          16 :         pUndoDoc = new ScDocument(SCDOCMODE_UNDO);
    5320          16 :         pUndoDoc->InitUndo( &rDoc, nTab, nTab );
    5321             : 
    5322          16 :         if(pFormat)
    5323             :         {
    5324          16 :             aCompleteRange = aCombinedRange;
    5325             :         }
    5326          16 :         if(nOldFormat)
    5327             :         {
    5328           0 :             ScConditionalFormat* pOldFormat = rDoc.GetCondFormList(nTab)->GetFormat(nOldFormat);
    5329           0 :             if(pOldFormat)
    5330           0 :                 aCompleteRange.ExtendTo(pOldFormat->GetRange().Combine());
    5331             :         }
    5332             : 
    5333          16 :         rDoc.CopyToDocument( aCompleteRange.aStart.Col(),aCompleteRange.aStart.Row(),nTab,
    5334          16 :                 aCompleteRange.aEnd.Col(),aCompleteRange.aEnd.Row(),nTab,
    5335          48 :                 IDF_ALL, false, pUndoDoc );
    5336             :     }
    5337             : 
    5338          32 :     boost::scoped_ptr<ScRange> pRepaintRange;
    5339          16 :     if(nOldFormat)
    5340             :     {
    5341           0 :         ScConditionalFormat* pOldFormat = rDoc.GetCondFormList(nTab)->GetFormat(nOldFormat);
    5342           0 :         if(pOldFormat)
    5343             :         {
    5344           0 :             pRepaintRange.reset(new ScRange( pOldFormat->GetRange().Combine() ));
    5345           0 :             RemoveCondFormatAttributes(&rDoc, pOldFormat, nTab);
    5346             :         }
    5347             : 
    5348           0 :         rDoc.DeleteConditionalFormat(nOldFormat, nTab);
    5349           0 :         rDoc.SetStreamValid(nTab, false);
    5350             :     }
    5351          16 :     if(pFormat)
    5352             :     {
    5353          16 :         if(pRepaintRange)
    5354           0 :             pRepaintRange->ExtendTo(aCombinedRange);
    5355             :         else
    5356          16 :             pRepaintRange.reset(new ScRange(aCombinedRange));
    5357             : 
    5358          16 :         sal_uLong nIndex = rDoc.AddCondFormat(pFormat, nTab);
    5359             : 
    5360          16 :         SetConditionalFormatAttributes(&rDoc, rRanges, nIndex, nTab);
    5361          16 :         rDoc.SetStreamValid(nTab, false);
    5362             :     }
    5363             : 
    5364          16 :     if(bUndo)
    5365             :     {
    5366          16 :         ScDocument* pRedoDoc = new ScDocument(SCDOCMODE_UNDO);
    5367          16 :         pRedoDoc->InitUndo( &rDoc, nTab, nTab );
    5368          16 :         rDoc.CopyToDocument( aCompleteRange.aStart.Col(),aCompleteRange.aStart.Row(),nTab,
    5369          16 :                 aCompleteRange.aEnd.Col(),aCompleteRange.aEnd.Row(),nTab,
    5370          48 :                 IDF_ALL, false, pRedoDoc );
    5371          16 :         rDocShell.GetUndoManager()->AddUndoAction(
    5372          16 :                 new ScUndoConditionalFormat(&rDocShell, pUndoDoc, pRedoDoc, aCompleteRange));
    5373             :     }
    5374             : 
    5375          16 :     if(pRepaintRange)
    5376          16 :         rDocShell.PostPaint(*pRepaintRange, PAINT_GRID);
    5377             : 
    5378          16 :     aModificator.SetDocumentModified();
    5379          32 :     SfxGetpApp()->Broadcast(SfxSimpleHint(SC_HINT_AREAS_CHANGED));
    5380             : }
    5381             : 
    5382           0 : void ScDocFunc::SetConditionalFormatList( ScConditionalFormatList* pList, SCTAB nTab )
    5383             : {
    5384           0 :     ScDocShellModificator aModificator(rDocShell);
    5385           0 :     ScDocument& rDoc = rDocShell.GetDocument();
    5386           0 :     if(rDoc.IsTabProtected(nTab))
    5387           0 :         return;
    5388             : 
    5389             :     // first remove all old entries
    5390           0 :     ScConditionalFormatList* pOldList = rDoc.GetCondFormList(nTab);
    5391           0 :     for(ScConditionalFormatList::const_iterator itr = pOldList->begin(), itrEnd = pOldList->end(); itr != itrEnd; ++itr)
    5392             :     {
    5393           0 :         RemoveCondFormatAttributes(&rDoc, &(*itr), nTab);
    5394             :     }
    5395             : 
    5396             :     // then set new entries
    5397           0 :     for(ScConditionalFormatList::iterator itr = pList->begin(); itr != pList->end(); ++itr)
    5398             :     {
    5399           0 :         sal_uLong nIndex = itr->GetKey();
    5400           0 :         const ScRangeList& rRange = itr->GetRange();
    5401           0 :         SetConditionalFormatAttributes(&rDoc, rRange, nIndex, nTab);
    5402             :     }
    5403             : 
    5404           0 :     rDoc.SetCondFormList(pList, nTab);
    5405           0 :     rDocShell.PostPaintGridAll();
    5406             : 
    5407           0 :     rDoc.SetStreamValid(nTab, false);
    5408           0 :     aModificator.SetDocumentModified();
    5409           0 :     SfxGetpApp()->Broadcast(SfxSimpleHint(SC_HINT_AREAS_CHANGED));
    5410             : }
    5411             : 
    5412           4 : void ScDocFunc::ConvertFormulaToValue( const ScRange& rRange, bool bRecord, bool bInteraction )
    5413             : {
    5414           4 :     ScDocShellModificator aModificator(rDocShell);
    5415           4 :     ScDocument& rDoc = rDocShell.GetDocument();
    5416           4 :     if (!rDoc.IsUndoEnabled())
    5417           0 :         bRecord = false;
    5418             : 
    5419           4 :     ScEditableTester aTester(&rDoc, rRange);
    5420           4 :     if (!aTester.IsEditable())
    5421             :     {
    5422           0 :         if (bInteraction)
    5423           0 :             rDocShell.ErrorMessage(aTester.GetMessageId());
    5424           4 :         return;
    5425             :     }
    5426             : 
    5427           8 :     sc::TableValues aUndoVals(rRange);
    5428           4 :     sc::TableValues* pUndoVals = bRecord ? &aUndoVals : NULL;
    5429             : 
    5430           4 :     rDoc.ConvertFormulaToValue(rRange, pUndoVals);
    5431             : 
    5432           4 :     if (bRecord && pUndoVals)
    5433             :     {
    5434           4 :         rDocShell.GetUndoManager()->AddUndoAction(
    5435           4 :             new sc::UndoFormulaToValue(&rDocShell, *pUndoVals));
    5436             :     }
    5437             : 
    5438           4 :     rDocShell.PostPaint(rRange, PAINT_GRID);
    5439           4 :     rDocShell.PostDataChanged();
    5440           4 :     rDoc.BroadcastCells(rRange, SC_HINT_DATACHANGED);
    5441           8 :     aModificator.SetDocumentModified();
    5442             : }
    5443             : 
    5444           0 : void ScDocFunc::EnterListAction( sal_uInt16 nNameResId )
    5445             : {
    5446           0 :     OUString aUndo( ScGlobal::GetRscString( nNameResId ) );
    5447           0 :     rDocShell.GetUndoManager()->EnterListAction( aUndo, aUndo );
    5448           0 : }
    5449             : 
    5450           0 : void ScDocFunc::EndListAction()
    5451             : {
    5452           0 :     rDocShell.GetUndoManager()->LeaveListAction();
    5453         228 : }
    5454             : 
    5455             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10