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

Generated by: LCOV version 1.10