LCOV - code coverage report
Current view: top level - sc/source/ui/docshell - docfunc.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 1906 3093 61.6 %
Date: 2015-06-13 12:38:46 Functions: 64 88 72.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11