LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sc/source/core/data - document.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 2234 3174 70.4 %
Date: 2013-07-09 Functions: 269 335 80.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             : #include <editeng/eeitem.hxx>
      22             : 
      23             : #include <editeng/boxitem.hxx>
      24             : #include <editeng/frmdiritem.hxx>
      25             : #include "editeng/editobj.hxx"
      26             : #include <svx/pageitem.hxx>
      27             : #include <editeng/editeng.hxx>
      28             : #include <svx/sdrundomanager.hxx>
      29             : #include <svx/svditer.hxx>
      30             : #include <svx/svdpage.hxx>
      31             : #include <svx/svdocapt.hxx>
      32             : #include <sfx2/app.hxx>
      33             : #include <sfx2/objsh.hxx>
      34             : #include <sfx2/docfile.hxx>
      35             : #include <svl/poolcach.hxx>
      36             : #include <unotools/saveopt.hxx>
      37             : #include <svl/zforlist.hxx>
      38             : #include <unotools/charclass.hxx>
      39             : #include <unotools/transliterationwrapper.hxx>
      40             : #include <tools/tenccvt.hxx>
      41             : #include <tools/urlobj.hxx>
      42             : 
      43             : #include <com/sun/star/text/WritingMode2.hpp>
      44             : #include <com/sun/star/script/vba/XVBACompatibility.hpp>
      45             : #include <com/sun/star/sheet/TablePageBreakData.hpp>
      46             : #include <com/sun/star/lang/NotInitializedException.hpp>
      47             : 
      48             : #include "document.hxx"
      49             : #include "table.hxx"
      50             : #include "attrib.hxx"
      51             : #include "attarray.hxx"
      52             : #include "markarr.hxx"
      53             : #include "patattr.hxx"
      54             : #include "rangenam.hxx"
      55             : #include "poolhelp.hxx"
      56             : #include "docpool.hxx"
      57             : #include "stlpool.hxx"
      58             : #include "stlsheet.hxx"
      59             : #include "globstr.hrc"
      60             : #include "rechead.hxx"
      61             : #include "dbdata.hxx"
      62             : #include "pivot.hxx"
      63             : #include "chartlis.hxx"
      64             : #include "rangelst.hxx"
      65             : #include "markdata.hxx"
      66             : #include "drwlayer.hxx"
      67             : #include "conditio.hxx"
      68             : #include "colorscale.hxx"
      69             : #include "validat.hxx"
      70             : #include "prnsave.hxx"
      71             : #include "chgtrack.hxx"
      72             : #include "sc.hrc"
      73             : #include "scresid.hxx"
      74             : #include "hints.hxx"
      75             : #include "detdata.hxx"
      76             : #include "dpobject.hxx"
      77             : #include "detfunc.hxx"      // for UpdateAllComments
      78             : #include "scmod.hxx"
      79             : #include "dociter.hxx"
      80             : #include "progress.hxx"
      81             : #include "autonamecache.hxx"
      82             : #include "bcaslot.hxx"
      83             : #include "postit.hxx"
      84             : #include "externalrefmgr.hxx"
      85             : #include "tabprotection.hxx"
      86             : #include "clipparam.hxx"
      87             : #include "stlalgorithm.hxx"
      88             : #include "defaultsoptions.hxx"
      89             : #include "editutil.hxx"
      90             : #include "stringutil.hxx"
      91             : #include "formulaiter.hxx"
      92             : #include "formulacell.hxx"
      93             : #include "clipcontext.hxx"
      94             : #include "listenercontext.hxx"
      95             : #include "scopetools.hxx"
      96             : 
      97             : #include <map>
      98             : #include <limits>
      99             : #include <boost/scoped_ptr.hpp>
     100             : 
     101             : using ::editeng::SvxBorderLine;
     102             : using namespace ::com::sun::star;
     103             : 
     104             : namespace WritingMode2 = ::com::sun::star::text::WritingMode2;
     105             : using ::com::sun::star::uno::Sequence;
     106             : using ::com::sun::star::sheet::TablePageBreakData;
     107             : using ::std::set;
     108             : 
     109             : namespace {
     110             : 
     111          40 : std::pair<SCTAB,SCTAB> getMarkedTableRange(const std::vector<ScTable*>& rTables, const ScMarkData& rMark)
     112             : {
     113          40 :     SCTAB nTabStart = MAXTAB;
     114          40 :     SCTAB nTabEnd = 0;
     115          40 :     SCTAB nMax = static_cast<SCTAB>(rTables.size());
     116          40 :     ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
     117          77 :     for (; itr != itrEnd && *itr < nMax; ++itr)
     118             :     {
     119          37 :         if (!rTables[*itr])
     120           0 :             continue;
     121             : 
     122          37 :         if (*itr < nTabStart)
     123          37 :             nTabStart = *itr;
     124          37 :         nTabEnd = *itr;
     125             :     }
     126             : 
     127          40 :     return std::pair<SCTAB,SCTAB>(nTabStart,nTabEnd);
     128             : }
     129             : 
     130             : }
     131             : 
     132             : struct ScDefaultAttr
     133             : {
     134             :     const ScPatternAttr*    pAttr;
     135             :     SCROW                   nFirst;
     136             :     SCSIZE                  nCount;
     137          36 :     ScDefaultAttr(const ScPatternAttr* pPatAttr) : pAttr(pPatAttr), nFirst(0), nCount(0) {}
     138             : };
     139             : 
     140             : struct ScLessDefaultAttr
     141             : {
     142          88 :     bool operator() (const ScDefaultAttr& rValue1, const ScDefaultAttr& rValue2) const
     143             :     {
     144          88 :         return rValue1.pAttr < rValue2.pAttr;
     145             :     }
     146             : };
     147             : 
     148             : typedef std::set<ScDefaultAttr, ScLessDefaultAttr>  ScDefaultAttrSet;
     149             : 
     150         721 : void ScDocument::MakeTable( SCTAB nTab,bool _bNeedsNameCheck )
     151             : {
     152         721 :     if ( ValidTab(nTab) && ( nTab >= static_cast<SCTAB>(maTabs.size()) ||!maTabs[nTab]) )
     153             :     {
     154             :         // Get Custom prefix
     155         426 :         const ScDefaultsOptions& rOpt = SC_MOD()->GetDefaultsOptions();
     156         426 :         OUString aString = rOpt.GetInitTabPrefix();
     157             : 
     158         426 :         aString += OUString::valueOf(static_cast<sal_Int32>(nTab+1));
     159         426 :         if ( _bNeedsNameCheck )
     160         426 :             CreateValidTabName( aString );  // no doubles
     161         426 :         if (nTab < static_cast<SCTAB>(maTabs.size()))
     162             :         {
     163           0 :             maTabs[nTab] = new ScTable(this, nTab, aString);
     164             :         }
     165             :         else
     166             :         {
     167         852 :             while(nTab > static_cast<SCTAB>(maTabs.size()))
     168           0 :                 maTabs.push_back(NULL);
     169         426 :             maTabs.push_back( new ScTable(this, nTab, aString) );
     170             :         }
     171         426 :         maTabs[nTab]->SetLoadingMedium(bLoadingMedium);
     172             :     }
     173         721 : }
     174             : 
     175             : 
     176       10796 : bool ScDocument::HasTable( SCTAB nTab ) const
     177             : {
     178       10796 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()))
     179       10796 :         if (maTabs[nTab])
     180       10796 :             return true;
     181             : 
     182           0 :     return false;
     183             : }
     184             : 
     185       27335 : bool ScDocument::GetName( SCTAB nTab, OUString& rName ) const
     186             : {
     187       27335 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()))
     188       27335 :         if (maTabs[nTab])
     189             :         {
     190       27335 :             maTabs[nTab]->GetName( rName );
     191       27335 :             return true;
     192             :         }
     193           0 :     rName = OUString();
     194           0 :     return false;
     195             : }
     196             : 
     197           4 : OUString ScDocument::GetCopyTabName( SCTAB nTab ) const
     198             : {
     199           4 :     if (nTab < static_cast<SCTAB>(maTabNames.size()))
     200           3 :         return maTabNames[nTab];
     201             :     else
     202           1 :         return OUString();
     203             : }
     204             : 
     205         354 : bool ScDocument::SetCodeName( SCTAB nTab, const OUString& rName )
     206             : {
     207         354 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()))
     208             :     {
     209         354 :         if (maTabs[nTab])
     210             :         {
     211         354 :             maTabs[nTab]->SetCodeName( rName );
     212         354 :             return true;
     213             :         }
     214             :     }
     215             :     OSL_TRACE( "**** can't set code name %s", OUStringToOString( rName, RTL_TEXTENCODING_UTF8 ).getStr() );
     216           0 :     return false;
     217             : }
     218             : 
     219        3229 : bool ScDocument::GetCodeName( SCTAB nTab, OUString& rName ) const
     220             : {
     221        3229 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()))
     222        3229 :         if (maTabs[nTab])
     223             :         {
     224        3229 :             maTabs[nTab]->GetCodeName( rName );
     225        3229 :             return true;
     226             :         }
     227           0 :     rName = OUString();
     228           0 :     return false;
     229             : }
     230             : 
     231        4723 : bool ScDocument::GetTable( const OUString& rName, SCTAB& rTab ) const
     232             : {
     233        4723 :     OUString aUpperName = ScGlobal::pCharClass->uppercase(rName);
     234             : 
     235        7003 :     for (SCTAB i=0; i< static_cast<SCTAB>(maTabs.size()); i++)
     236        6978 :         if (maTabs[i])
     237             :         {
     238        6978 :             if (aUpperName.equals(maTabs[i]->GetUpperName()))
     239             :             {
     240        4698 :                 rTab = i;
     241        4698 :                 return true;
     242             :             }
     243             :         }
     244          25 :     rTab = 0;
     245          25 :     return false;
     246             : }
     247             : 
     248         371 : ScDBData* ScDocument::GetAnonymousDBData(SCTAB nTab)
     249             : {
     250         371 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
     251         371 :         return maTabs[nTab]->GetAnonymousDBData();
     252           0 :     return NULL;
     253             : }
     254             : 
     255          18 : void ScDocument::SetAnonymousDBData(SCTAB nTab, ScDBData* pDBData)
     256             : {
     257          18 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
     258          18 :         maTabs[nTab]->SetAnonymousDBData(pDBData);
     259          18 : }
     260             : 
     261             : 
     262        1568 : bool ScDocument::ValidTabName( const OUString& rName )
     263             : {
     264        1568 :     if (rName.isEmpty())
     265          23 :         return false;
     266        1545 :     sal_Int32 nLen = rName.getLength();
     267             : 
     268             : #if 1
     269             :     // Restrict sheet names to what Excel accepts.
     270             :     /* TODO: We may want to remove this restriction for full ODFF compliance.
     271             :      * Merely loading and calculating ODF documents using these characters in
     272             :      * sheet names is not affected by this, but all sheet name editing and
     273             :      * copying functionality is, maybe falling back to "Sheet4" or similar. */
     274       11300 :     for (sal_Int32 i = 0; i < nLen; ++i)
     275             :     {
     276        9755 :         const sal_Unicode c = rName[i];
     277        9755 :         switch (c)
     278             :         {
     279             :             case ':':
     280             :             case '\\':
     281             :             case '/':
     282             :             case '?':
     283             :             case '*':
     284             :             case '[':
     285             :             case ']':
     286             :                 // these characters are not allowed to match XL's convention.
     287           0 :                 return false;
     288             :             case '\'':
     289           0 :                 if (i == 0 || i == nLen - 1)
     290             :                     // single quote is not allowed at the first or last
     291             :                     // character position.
     292           0 :                     return false;
     293           0 :             break;
     294             :         }
     295             :     }
     296             : #endif
     297             : 
     298        1545 :     return true;
     299             : }
     300             : 
     301             : 
     302         733 : bool ScDocument::ValidNewTabName( const OUString& rName ) const
     303             : {
     304         733 :     bool bValid = ValidTabName(rName);
     305         733 :     TableContainer::const_iterator it = maTabs.begin();
     306        1486 :     for (; it != maTabs.end() && bValid; ++it)
     307         753 :         if ( *it )
     308             :         {
     309         753 :             OUString aOldName;
     310         753 :             (*it)->GetName(aOldName);
     311         753 :             bValid = !ScGlobal::GetpTransliteration()->isEqual( rName, aOldName );
     312             :         }
     313         733 :     return bValid;
     314             : }
     315             : 
     316             : 
     317         547 : void ScDocument::CreateValidTabName(OUString& rName) const
     318             : {
     319         547 :     if ( !ValidTabName(rName) )
     320             :     {
     321             :         // Find new one
     322             : 
     323             :         // Get Custom prefix
     324          23 :         const ScDefaultsOptions& rOpt = SC_MOD()->GetDefaultsOptions();
     325          23 :         OUString aStrTable = rOpt.GetInitTabPrefix();
     326             : 
     327          23 :         bool         bOk   = false;
     328             : 
     329             :         // First test if the prefix is valid, if so only avoid doubles
     330          23 :         bool bPrefix = ValidTabName( aStrTable );
     331             :         OSL_ENSURE(bPrefix, "Invalid Table Name");
     332             :         SCTAB nDummy;
     333             : 
     334          46 :         for ( SCTAB i = static_cast<SCTAB>(maTabs.size())+1; !bOk ; i++ )
     335             :         {
     336          23 :             OUStringBuffer aBuf;
     337          23 :             aBuf.append(aStrTable);
     338          23 :             aBuf.append(static_cast<sal_Int32>(i));
     339          23 :             rName = aBuf.makeStringAndClear();
     340          23 :             if (bPrefix)
     341          23 :                 bOk = ValidNewTabName( rName );
     342             :             else
     343           0 :                 bOk = !GetTable( rName, nDummy );
     344          46 :         }
     345             :     }
     346             :     else
     347             :     {
     348             :         // testing the supplied Name
     349             : 
     350         524 :         if ( !ValidNewTabName(rName) )
     351             :         {
     352           9 :             SCTAB i = 1;
     353           9 :             OUStringBuffer aName;
     354          18 :             do
     355             :             {
     356           9 :                 i++;
     357           9 :                 aName = rName;
     358           9 :                 aName.append('_');
     359           9 :                 aName.append(static_cast<sal_Int32>(i));
     360             :             }
     361          27 :             while (!ValidNewTabName(aName.toString()) && (i < MAXTAB+1));
     362           9 :             rName = aName.makeStringAndClear();
     363             :         }
     364             :     }
     365         547 : }
     366             : 
     367           0 : void ScDocument::CreateValidTabNames(std::vector<OUString>& aNames, SCTAB nCount) const
     368             : {
     369           0 :     aNames.clear();//ensure that the vector is empty
     370             : 
     371             :     // Get Custom prefix
     372           0 :     const ScDefaultsOptions& rOpt = SC_MOD()->GetDefaultsOptions();
     373           0 :     OUString aStrTable = rOpt.GetInitTabPrefix();
     374             : 
     375           0 :     OUStringBuffer rName;
     376           0 :     bool         bOk   = false;
     377             : 
     378             :     // First test if the prefix is valid, if so only avoid doubles
     379           0 :     bool bPrefix = ValidTabName( aStrTable );
     380             :     OSL_ENSURE(bPrefix, "Invalid Table Name");
     381             :     SCTAB nDummy;
     382           0 :     SCTAB i = static_cast<SCTAB>(maTabs.size())+1;
     383             : 
     384           0 :     for (SCTAB j = 0; j < nCount; ++j)
     385             :     {
     386           0 :         bOk = false;
     387           0 :         while(!bOk)
     388             :         {
     389           0 :             rName = aStrTable;
     390           0 :             rName.append(static_cast<sal_Int32>(i));
     391           0 :             if (bPrefix)
     392           0 :                 bOk = ValidNewTabName( rName.toString() );
     393             :             else
     394           0 :                 bOk = !GetTable( rName.toString(), nDummy );
     395           0 :             i++;
     396             :         }
     397           0 :         aNames.push_back(rName.makeStringAndClear());
     398           0 :     }
     399           0 : }
     400             : 
     401          93 : void ScDocument::AppendTabOnLoad(const OUString& rName)
     402             : {
     403          93 :     SCTAB nTabCount = static_cast<SCTAB>(maTabs.size());
     404          93 :     if (!ValidTab(nTabCount))
     405             :         // max table count reached.  No more tables.
     406          93 :         return;
     407             : 
     408          93 :     OUString aName = rName;
     409          93 :     CreateValidTabName(aName);
     410          93 :     maTabs.push_back( new ScTable(this, nTabCount, aName) );
     411             : }
     412             : 
     413          75 : void ScDocument::SetTabNameOnLoad(SCTAB nTab, const OUString& rName)
     414             : {
     415          75 :     if (!ValidTab(nTab) || static_cast<SCTAB>(maTabs.size()) <= nTab)
     416           0 :         return;
     417             : 
     418          75 :     if (!ValidTabName(rName))
     419           0 :         return;
     420             : 
     421          75 :     maTabs[nTab]->SetName(rName);
     422             : }
     423             : 
     424           4 : void ScDocument::InvalidateStreamOnSave()
     425             : {
     426           4 :     TableContainer::iterator it = maTabs.begin(), itEnd = maTabs.end();
     427           9 :     for (; it != itEnd; ++it)
     428             :     {
     429           5 :         ScTable* pTab = *it;
     430           5 :         if (pTab)
     431           5 :             pTab->SetStreamValid(false);
     432             :     }
     433           4 : }
     434             : 
     435         173 : bool ScDocument::InsertTab( SCTAB nPos, const OUString& rName,
     436             :             bool bExternalDocument )
     437             : {
     438         173 :     SCTAB   nTabCount = static_cast<SCTAB>(maTabs.size());
     439         173 :     bool    bValid = ValidTab(nTabCount);
     440         173 :     if ( !bExternalDocument )   // else test rName == "'Doc'!Tab" first
     441         173 :         bValid = (bValid && ValidNewTabName(rName));
     442         173 :     if (bValid)
     443             :     {
     444         171 :         if (nPos == SC_TAB_APPEND || nPos >= nTabCount)
     445             :         {
     446         131 :             maTabs.push_back( new ScTable(this, nTabCount, rName) );
     447         262 :             if ( bExternalDocument )
     448           0 :                 maTabs[nTabCount]->SetVisible( false );
     449             :         }
     450             :         else
     451             :         {
     452          40 :             if (ValidTab(nPos) && (nPos < nTabCount))
     453             :             {
     454          40 :                 ScRange aRange( 0,0,nPos, MAXCOL,MAXROW,MAXTAB );
     455          40 :                 xColNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,1 );
     456          40 :                 xRowNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,1 );
     457          40 :                 if (pRangeName)
     458          29 :                     pRangeName->UpdateTabRef( nPos, 1 );
     459             :                 pDBCollection->UpdateReference(
     460          40 :                                     URM_INSDEL, 0,0,nPos, MAXCOL,MAXROW,MAXTAB, 0,0,1 );
     461          40 :                 if (pDPCollection)
     462          17 :                     pDPCollection->UpdateReference( URM_INSDEL, aRange, 0,0,1 );
     463          40 :                 if (pDetOpList)
     464           0 :                     pDetOpList->UpdateReference( this, URM_INSDEL, aRange, 0,0,1 );
     465          40 :                 UpdateChartRef( URM_INSDEL, 0,0,nPos, MAXCOL,MAXROW,MAXTAB, 0,0,1 );
     466          40 :                 UpdateRefAreaLinks( URM_INSDEL, aRange, 0,0,1 );
     467          40 :                 if ( pUnoBroadcaster )
     468          40 :                     pUnoBroadcaster->Broadcast( ScUpdateRefHint( URM_INSDEL, aRange, 0,0,1 ) );
     469             : 
     470             :                 SCTAB i;
     471          40 :                 TableContainer::iterator it = maTabs.begin();
     472          91 :                 for (; it != maTabs.end(); ++it)
     473          51 :                     if ( *it )
     474          51 :                         (*it)->UpdateInsertTab(nPos);
     475          40 :                 maTabs.push_back(NULL);
     476          87 :                 for (i = nTabCount; i > nPos; i--)
     477             :                 {
     478          47 :                     maTabs[i] = maTabs[i - 1];
     479             :                 }
     480             : 
     481          40 :                 maTabs[nPos] = new ScTable(this, nPos, rName);
     482             : 
     483             :                 // UpdateBroadcastAreas must be called between UpdateInsertTab,
     484             :                 // which ends listening, and StartAllListeners, to not modify
     485             :                 // areas that are to be inserted by starting listeners.
     486          40 :                 UpdateBroadcastAreas( URM_INSDEL, aRange, 0,0,1);
     487          40 :                 it = maTabs.begin();
     488         131 :                 for (; it != maTabs.end(); ++it)
     489          91 :                     if ( *it )
     490          91 :                         (*it)->UpdateCompile();
     491          40 :                 it = maTabs.begin();
     492         131 :                 for (; it != maTabs.end(); ++it)
     493          91 :                     if ( *it )
     494          91 :                         (*it)->StartAllListeners();
     495             : 
     496          40 :                 if ( pValidationList )
     497           0 :                     pValidationList->UpdateReference( URM_INSDEL, aRange, 0,0,1 );
     498             :                 // sheet names of references are not valid until sheet is inserted
     499          40 :                 if ( pChartListenerCollection )
     500          40 :                     pChartListenerCollection->UpdateScheduledSeriesRanges();
     501             : 
     502          40 :                 bValid = true;
     503             :             }
     504             :             else
     505           0 :                 bValid = false;
     506             :         }
     507             :     }
     508             : 
     509         173 :     if (bValid)
     510         171 :         SetDirty();
     511             : 
     512         173 :     return bValid;
     513             : }
     514             : 
     515             : 
     516           1 : bool ScDocument::InsertTabs( SCTAB nPos, const std::vector<OUString>& rNames,
     517             :             bool bExternalDocument, bool bNamesValid )
     518             : {
     519           1 :     SCTAB   nNewSheets = static_cast<SCTAB>(rNames.size());
     520           1 :     SCTAB    nTabCount = static_cast<SCTAB>(maTabs.size());
     521           1 :     bool    bValid = bNamesValid || ValidTab(nTabCount+nNewSheets);
     522             : //    if ( !bExternalDocument )    // else test rName == "'Doc'!Tab" first
     523             : //        bValid = (bValid && ValidNewTabName(rNames));
     524           1 :     if (bValid)
     525             :     {
     526           1 :         if (nPos == SC_TAB_APPEND || nPos >= nTabCount)
     527             :         {
     528           0 :             for ( SCTAB i = 0; i < nNewSheets; ++i )
     529             :             {
     530           0 :                 maTabs.push_back( new ScTable(this, nTabCount + i, rNames.at(i)) );
     531           0 :                 if ( bExternalDocument )
     532           0 :                     maTabs[nTabCount+i]->SetVisible( false );
     533           0 :             }
     534             :         }
     535             :         else
     536             :         {
     537           1 :             if (ValidTab(nPos) && (nPos < nTabCount))
     538             :             {
     539           1 :                 ScRange aRange( 0,0,nPos, MAXCOL,MAXROW,MAXTAB );
     540           1 :                 xColNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,nNewSheets );
     541           1 :                 xRowNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,nNewSheets );
     542           1 :                 if (pRangeName)
     543           0 :                     pRangeName->UpdateTabRef( nPos, 1, 0, nNewSheets);
     544             :                 pDBCollection->UpdateReference(
     545           1 :                                     URM_INSDEL, 0,0,nPos, MAXCOL,MAXROW,MAXTAB, 0,0,nNewSheets );
     546           1 :                 if (pDPCollection)
     547           0 :                     pDPCollection->UpdateReference( URM_INSDEL, aRange, 0,0,nNewSheets );
     548           1 :                 if (pDetOpList)
     549           0 :                     pDetOpList->UpdateReference( this, URM_INSDEL, aRange, 0,0,nNewSheets );
     550           1 :                 UpdateChartRef( URM_INSDEL, 0,0,nPos, MAXCOL,MAXROW,MAXTAB, 0,0,nNewSheets );
     551           1 :                 UpdateRefAreaLinks( URM_INSDEL, aRange, 0,0, nNewSheets );
     552           1 :                 if ( pUnoBroadcaster )
     553           1 :                     pUnoBroadcaster->Broadcast( ScUpdateRefHint( URM_INSDEL, aRange, 0,0,nNewSheets ) );
     554             : 
     555           1 :                 TableContainer::iterator it = maTabs.begin();
     556           3 :                 for (; it != maTabs.end(); ++it)
     557           2 :                     if ( *it )
     558           2 :                         (*it)->UpdateInsertTab(nPos, nNewSheets);
     559           1 :                 it = maTabs.begin();
     560           1 :                 maTabs.insert(it+nPos,nNewSheets, NULL);
     561           3 :                 for (SCTAB i = 0; i < nNewSheets; ++i)
     562             :                 {
     563           2 :                     maTabs[nPos + i] = new ScTable(this, nPos + i, rNames.at(i));
     564             :                 }
     565             : 
     566             :                 // UpdateBroadcastAreas must be called between UpdateInsertTab,
     567             :                 // which ends listening, and StartAllListeners, to not modify
     568             :                 // areas that are to be inserted by starting listeners.
     569           1 :                 UpdateBroadcastAreas( URM_INSDEL, aRange, 0,0,nNewSheets);
     570           1 :                 it = maTabs.begin();
     571           5 :                 for (; it != maTabs.end(); ++it)
     572             :                 {
     573           4 :                     if ( *it )
     574           4 :                         (*it)->UpdateCompile();
     575             :                 }
     576           1 :                 it = maTabs.begin();
     577           5 :                 for (; it != maTabs.end(); ++it)
     578           4 :                     if ( *it )
     579           4 :                         (*it)->StartAllListeners();
     580             : 
     581           1 :                 if ( pValidationList )
     582           0 :                     pValidationList->UpdateReference( URM_INSDEL, aRange, 0,0,nNewSheets );
     583             :                 // sheet names of references are not valid until sheet is inserted
     584           1 :                 if ( pChartListenerCollection )
     585           1 :                     pChartListenerCollection->UpdateScheduledSeriesRanges();
     586             : 
     587           1 :                 bValid = true;
     588             :             }
     589             :             else
     590           0 :                 bValid = false;
     591             :         }
     592             :     }
     593             : 
     594           1 :     if (bValid)
     595           1 :         SetDirty();
     596             : 
     597           1 :     return bValid;
     598             : }
     599             : 
     600             : 
     601         124 : bool ScDocument::DeleteTab( SCTAB nTab, ScDocument* pRefUndoDoc )
     602             : {
     603         124 :     bool bValid = false;
     604         124 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()))
     605             :     {
     606         121 :         if (maTabs[nTab])
     607             :         {
     608         121 :             SCTAB nTabCount = static_cast<SCTAB>(maTabs.size());
     609         121 :             if (nTabCount > 1)
     610             :             {
     611          52 :                 bool bOldAutoCalc = GetAutoCalc();
     612          52 :                 SetAutoCalc( false );   // avoid multiple calculations
     613          52 :                 ScRange aRange( 0, 0, nTab, MAXCOL, MAXROW, nTab );
     614          52 :                 DelBroadcastAreasInRange( aRange );
     615             : 
     616             :                 // #i8180# remove database ranges etc. that are on the deleted tab
     617             :                 // (restored in undo with ScRefUndoData)
     618             : 
     619          52 :                 xColNameRanges->DeleteOnTab( nTab );
     620          52 :                 xRowNameRanges->DeleteOnTab( nTab );
     621          52 :                 pDBCollection->DeleteOnTab( nTab );
     622          52 :                 if (pDPCollection)
     623          34 :                     pDPCollection->DeleteOnTab( nTab );
     624          52 :                 if (pDetOpList)
     625           0 :                     pDetOpList->DeleteOnTab( nTab );
     626          52 :                 DeleteAreaLinksOnTab( nTab );
     627             : 
     628             :                 // normal reference update
     629             : 
     630          52 :                 aRange.aEnd.SetTab( static_cast<SCTAB>(maTabs.size())-1 );
     631          52 :                 xColNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,-1 );
     632          52 :                 xRowNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,-1 );
     633          52 :                 if (pRangeName)
     634          20 :                     pRangeName->UpdateTabRef( nTab, 2 );
     635             :                 pDBCollection->UpdateReference(
     636          52 :                                     URM_INSDEL, 0,0,nTab, MAXCOL,MAXROW,MAXTAB, 0,0,-1 );
     637          52 :                 if (pDPCollection)
     638          34 :                     pDPCollection->UpdateReference( URM_INSDEL, aRange, 0,0,-1 );
     639          52 :                 if (pDetOpList)
     640           0 :                     pDetOpList->UpdateReference( this, URM_INSDEL, aRange, 0,0,-1 );
     641          52 :                 UpdateChartRef( URM_INSDEL, 0,0,nTab, MAXCOL,MAXROW,MAXTAB, 0,0,-1 );
     642          52 :                 UpdateRefAreaLinks( URM_INSDEL, aRange, 0,0,-1 );
     643          52 :                 if ( pValidationList )
     644           0 :                     pValidationList->UpdateReference( URM_INSDEL, aRange, 0,0,-1 );
     645          52 :                 if ( pUnoBroadcaster )
     646          52 :                     pUnoBroadcaster->Broadcast( ScUpdateRefHint( URM_INSDEL, aRange, 0,0,-1 ) );
     647             : 
     648         170 :                 for (SCTAB i = 0, n = static_cast<SCTAB>(maTabs.size()); i < n; ++i)
     649         118 :                     if (maTabs[i])
     650         118 :                         maTabs[i]->UpdateDeleteTab(
     651         236 :                             nTab, false, pRefUndoDoc ? pRefUndoDoc->maTabs[i] : 0);
     652             : 
     653          52 :                 TableContainer::iterator it = maTabs.begin() + nTab;
     654          52 :                 delete *it;
     655          52 :                 maTabs.erase(it);
     656             :                 // UpdateBroadcastAreas must be called between UpdateDeleteTab,
     657             :                 // which ends listening, and StartAllListeners, to not modify
     658             :                 // areas that are to be inserted by starting listeners.
     659          52 :                 UpdateBroadcastAreas( URM_INSDEL, aRange, 0,0,-1);
     660          52 :                 it = maTabs.begin();
     661         118 :                 for (; it != maTabs.end(); ++it)
     662          66 :                     if ( *it )
     663          66 :                         (*it)->UpdateCompile();
     664             :                 // Excel-Filter deletes some Tables while loading, Listeners will
     665             :                 // only be triggered after the loading is done.
     666          52 :                 if ( !bInsertingFromOtherDoc )
     667             :                 {
     668          52 :                     it = maTabs.begin();
     669         118 :                     for (; it != maTabs.end(); ++it)
     670          66 :                         if ( *it )
     671          66 :                             (*it)->StartAllListeners();
     672          52 :                     SetDirty();
     673             :                 }
     674             :                 // sheet names of references are not valid until sheet is deleted
     675          52 :                 pChartListenerCollection->UpdateScheduledSeriesRanges();
     676             : 
     677          52 :                 SetAutoCalc( bOldAutoCalc );
     678          52 :                 bValid = true;
     679             :             }
     680             :         }
     681             :     }
     682         124 :     return bValid;
     683             : }
     684             : 
     685             : 
     686           1 : bool ScDocument::DeleteTabs( SCTAB nTab, SCTAB nSheets, ScDocument* pRefUndoDoc )
     687             : {
     688           1 :     bool bValid = false;
     689           1 :     if (ValidTab(nTab) && (nTab + nSheets) < static_cast<SCTAB>(maTabs.size()))
     690             :     {
     691           1 :         if (maTabs[nTab])
     692             :         {
     693           1 :             SCTAB nTabCount = static_cast<SCTAB>(maTabs.size());
     694           1 :             if (nTabCount > nSheets)
     695             :             {
     696           1 :                 bool bOldAutoCalc = GetAutoCalc();
     697           1 :                 SetAutoCalc( false );   // avoid multiple calculations
     698           3 :                 for (SCTAB aTab = 0; aTab < nSheets; ++aTab)
     699             :                 {
     700           2 :                     ScRange aRange( 0, 0, nTab, MAXCOL, MAXROW, nTab + aTab );
     701           2 :                     DelBroadcastAreasInRange( aRange );
     702             : 
     703             :                     // #i8180# remove database ranges etc. that are on the deleted tab
     704             :                     // (restored in undo with ScRefUndoData)
     705             : 
     706           2 :                     xColNameRanges->DeleteOnTab( nTab + aTab );
     707           2 :                     xRowNameRanges->DeleteOnTab( nTab + aTab );
     708           2 :                     pDBCollection->DeleteOnTab( nTab + aTab );
     709           2 :                     if (pDPCollection)
     710           0 :                         pDPCollection->DeleteOnTab( nTab + aTab );
     711           2 :                     if (pDetOpList)
     712           0 :                         pDetOpList->DeleteOnTab( nTab + aTab );
     713           2 :                     DeleteAreaLinksOnTab( nTab + aTab );
     714           2 :                     if (pRangeName)
     715           0 :                         pRangeName->UpdateTabRef( nTab + aTab, 2 );
     716             :                 }
     717             :                 // normal reference update
     718             : 
     719           1 :                 ScRange aRange( 0, 0, nTab, MAXCOL, MAXROW, nTabCount - 1 );
     720           1 :                 xColNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,-1*nSheets );
     721           1 :                 xRowNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,-1*nSheets );
     722             :                 pDBCollection->UpdateReference(
     723           1 :                                     URM_INSDEL, 0,0,nTab, MAXCOL,MAXROW,MAXTAB, 0,0,-1*nSheets );
     724           1 :                 if (pDPCollection)
     725           0 :                     pDPCollection->UpdateReference( URM_INSDEL, aRange, 0,0,-1*nSheets );
     726           1 :                 if (pDetOpList)
     727           0 :                     pDetOpList->UpdateReference( this, URM_INSDEL, aRange, 0,0,-1*nSheets );
     728           1 :                 UpdateChartRef( URM_INSDEL, 0,0,nTab, MAXCOL,MAXROW,MAXTAB, 0,0,-1*nSheets );
     729           1 :                 UpdateRefAreaLinks( URM_INSDEL, aRange, 0,0,-1*nSheets );
     730           1 :                 if ( pValidationList )
     731           0 :                     pValidationList->UpdateReference( URM_INSDEL, aRange, 0,0,-1*nSheets );
     732           1 :                 if ( pUnoBroadcaster )
     733           1 :                     pUnoBroadcaster->Broadcast( ScUpdateRefHint( URM_INSDEL, aRange, 0,0,-1*nSheets ) );
     734             : 
     735           5 :                 for (SCTAB i = 0, n = static_cast<SCTAB>(maTabs.size()); i < n; ++i)
     736           4 :                     if (maTabs[i])
     737           4 :                         maTabs[i]->UpdateDeleteTab(
     738           8 :                             nTab, false, pRefUndoDoc ? pRefUndoDoc->maTabs[i] : 0,nSheets);
     739             : 
     740           1 :                 TableContainer::iterator it = maTabs.begin() + nTab;
     741           1 :                 TableContainer::iterator itEnd = it + nSheets;
     742           1 :                 std::for_each(it, itEnd, ScDeleteObjectByPtr<ScTable>());
     743           1 :                 maTabs.erase(it, itEnd);
     744             :                 // UpdateBroadcastAreas must be called between UpdateDeleteTab,
     745             :                 // which ends listening, and StartAllListeners, to not modify
     746             :                 // areas that are to be inserted by starting listeners.
     747           1 :                 UpdateBroadcastAreas( URM_INSDEL, aRange, 0,0,-1*nSheets);
     748           1 :                 it = maTabs.begin();
     749           3 :                 for (; it != maTabs.end(); ++it)
     750           2 :                     if ( *it )
     751           2 :                         (*it)->UpdateCompile();
     752             :                 // Excel-Filter deletes some Tables while loading, Listeners will
     753             :                 // only be triggered after the loading is done.
     754           1 :                 if ( !bInsertingFromOtherDoc )
     755             :                 {
     756           1 :                     it = maTabs.begin();
     757           3 :                     for (; it != maTabs.end(); ++it)
     758           2 :                         if ( *it )
     759           2 :                             (*it)->StartAllListeners();
     760           1 :                     SetDirty();
     761             :                 }
     762             :                 // sheet names of references are not valid until sheet is deleted
     763           1 :                 pChartListenerCollection->UpdateScheduledSeriesRanges();
     764             : 
     765           1 :                 SetAutoCalc( bOldAutoCalc );
     766           1 :                 bValid = true;
     767             :             }
     768             :         }
     769             :     }
     770           1 :     return bValid;
     771             : }
     772             : 
     773             : 
     774         186 : bool ScDocument::RenameTab( SCTAB nTab, const OUString& rName, bool /* bUpdateRef */,
     775             :         bool bExternalDocument )
     776             : {
     777         186 :     bool bValid = false;
     778             :     SCTAB i;
     779         186 :     if (ValidTab(nTab))
     780             :     {
     781         186 :         if (maTabs[nTab])
     782             :         {
     783         186 :             if ( bExternalDocument )
     784           0 :                 bValid = true;      // composed name
     785             :             else
     786         186 :                 bValid = ValidTabName(rName);
     787         753 :             for (i=0; (i< static_cast<SCTAB>(maTabs.size())) && bValid; i++)
     788         567 :                 if (maTabs[i] && (i != nTab))
     789             :                 {
     790         382 :                     OUString aOldName;
     791         382 :                     maTabs[i]->GetName(aOldName);
     792         382 :                     bValid = !ScGlobal::GetpTransliteration()->isEqual( rName, aOldName );
     793             :                 }
     794         186 :             if (bValid)
     795             :             {
     796             :                 // #i75258# update charts before renaming, so they can get their live data objects.
     797             :                 // Once the charts are live, the sheet can be renamed without problems.
     798         185 :                 if ( pChartListenerCollection )
     799         167 :                     pChartListenerCollection->UpdateChartsContainingTab( nTab );
     800         185 :                 maTabs[nTab]->SetName(rName);
     801             : 
     802             :                 // If formulas refer to the renamed sheet, the TokenArray remains valid,
     803             :                 // but the XML stream must be re-generated.
     804         185 :                 TableContainer::iterator it = maTabs.begin();
     805         751 :                 for (; it != maTabs.end(); ++it)
     806         566 :                     if ( *it && (*it)->IsStreamValid())
     807           0 :                         (*it)->SetStreamValid( false );
     808             :             }
     809             :         }
     810             :     }
     811         186 :     return bValid;
     812             : }
     813             : 
     814             : 
     815          30 : void ScDocument::SetVisible( SCTAB nTab, bool bVisible )
     816             : {
     817          30 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB> (maTabs.size()))
     818          30 :         if (maTabs[nTab])
     819          30 :             maTabs[nTab]->SetVisible(bVisible);
     820          30 : }
     821             : 
     822             : 
     823        3213 : bool ScDocument::IsVisible( SCTAB nTab ) const
     824             : {
     825        3213 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB> (maTabs.size()))
     826        3213 :         if (maTabs[nTab])
     827        3213 :             return maTabs[nTab]->IsVisible();
     828             : 
     829           0 :     return false;
     830             : }
     831             : 
     832             : 
     833      198840 : bool ScDocument::IsStreamValid( SCTAB nTab ) const
     834             : {
     835      198840 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB> (maTabs.size()) && maTabs[nTab] )
     836      198840 :         return maTabs[nTab]->IsStreamValid();
     837             : 
     838           0 :     return false;
     839             : }
     840             : 
     841             : 
     842         180 : void ScDocument::SetStreamValid( SCTAB nTab, bool bSet, bool bIgnoreLock )
     843             : {
     844         180 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB> (maTabs.size()) && maTabs[nTab] )
     845         180 :         maTabs[nTab]->SetStreamValid( bSet, bIgnoreLock );
     846         180 : }
     847             : 
     848             : 
     849        8236 : void ScDocument::LockStreamValid( bool bLock )
     850             : {
     851        8236 :     mbStreamValidLocked = bLock;
     852        8236 : }
     853             : 
     854             : 
     855        4118 : bool ScDocument::IsPendingRowHeights( SCTAB nTab ) const
     856             : {
     857        4118 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB> (maTabs.size()) && maTabs[nTab] )
     858        4118 :         return maTabs[nTab]->IsPendingRowHeights();
     859             : 
     860           0 :     return false;
     861             : }
     862             : 
     863             : 
     864           0 : void ScDocument::SetPendingRowHeights( SCTAB nTab, bool bSet )
     865             : {
     866           0 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB> (maTabs.size()) && maTabs[nTab] )
     867           0 :         maTabs[nTab]->SetPendingRowHeights( bSet );
     868           0 : }
     869             : 
     870             : 
     871         156 : void ScDocument::SetLayoutRTL( SCTAB nTab, bool bRTL )
     872             : {
     873         156 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB> (maTabs.size()) && maTabs[nTab] )
     874             :     {
     875         156 :         if ( bImportingXML )
     876             :         {
     877             :             // #i57869# only set the LoadingRTL flag, the real setting (including mirroring)
     878             :             // is applied in SetImportingXML(false). This is so the shapes can be loaded in
     879             :             // normal LTR mode.
     880             : 
     881           0 :             maTabs[nTab]->SetLoadingRTL( bRTL );
     882         156 :             return;
     883             :         }
     884             : 
     885         156 :         maTabs[nTab]->SetLayoutRTL( bRTL );     // only sets the flag
     886         156 :         maTabs[nTab]->SetDrawPageSize();
     887             : 
     888             :         //  mirror existing objects:
     889             : 
     890         156 :         if (pDrawLayer)
     891             :         {
     892           4 :             SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
     893             :             OSL_ENSURE(pPage,"Page ?");
     894           4 :             if (pPage)
     895             :             {
     896           4 :                 SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
     897           4 :                 SdrObject* pObject = aIter.Next();
     898          10 :                 while (pObject)
     899             :                 {
     900             :                     //  objects with ScDrawObjData are re-positioned in SetPageSize,
     901             :                     //  don't mirror again
     902           2 :                     ScDrawObjData* pData = ScDrawLayer::GetObjData( pObject );
     903           2 :                     if ( !pData )
     904           2 :                         pDrawLayer->MirrorRTL( pObject );
     905             : 
     906           2 :                     pObject->SetContextWritingMode( bRTL ? WritingMode2::RL_TB : WritingMode2::LR_TB );
     907             : 
     908           2 :                     pObject = aIter.Next();
     909           4 :                 }
     910             :             }
     911             :         }
     912             :     }
     913             : }
     914             : 
     915             : 
     916       94086 : bool ScDocument::IsLayoutRTL( SCTAB nTab ) const
     917             : {
     918       94086 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB> (maTabs.size()) && maTabs[nTab] )
     919       93922 :         return maTabs[nTab]->IsLayoutRTL();
     920             : 
     921         164 :     return false;
     922             : }
     923             : 
     924             : 
     925       22227 : bool ScDocument::IsNegativePage( SCTAB nTab ) const
     926             : {
     927             :     //  Negative page area is always used for RTL layout.
     928             :     //  The separate method is used to find all RTL handling of drawing objects.
     929       22227 :     return IsLayoutRTL( nTab );
     930             : }
     931             : 
     932             : 
     933             : /* ----------------------------------------------------------------------------
     934             :     used search area:
     935             : 
     936             :     GetCellArea  - Only Data
     937             :     GetTableArea - Data / Attributes
     938             :     GetPrintArea - intended for character objects,
     939             :                     sweeps attributes all the way to bottom / right
     940             : ---------------------------------------------------------------------------- */
     941             : 
     942             : 
     943          26 : bool ScDocument::GetCellArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow ) const
     944             : {
     945          26 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB> (maTabs.size()))
     946          26 :         if (maTabs[nTab])
     947          26 :             return maTabs[nTab]->GetCellArea( rEndCol, rEndRow );
     948             : 
     949           0 :     rEndCol = 0;
     950           0 :     rEndRow = 0;
     951           0 :     return false;
     952             : }
     953             : 
     954             : 
     955        2473 : bool ScDocument::GetTableArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow ) const
     956             : {
     957        2473 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB> (maTabs.size()))
     958        2473 :         if (maTabs[nTab])
     959        2473 :             return maTabs[nTab]->GetTableArea( rEndCol, rEndRow );
     960             : 
     961           0 :     rEndCol = 0;
     962           0 :     rEndRow = 0;
     963           0 :     return false;
     964             : }
     965             : 
     966         448 : bool ScDocument::ShrinkToDataArea(SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow) const
     967             : {
     968         448 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB> (maTabs.size()) || !maTabs[nTab])
     969           0 :         return false;
     970             : 
     971             :     SCCOL nCol1, nCol2;
     972             :     SCROW nRow1, nRow2;
     973         448 :     maTabs[nTab]->GetFirstDataPos(nCol1, nRow1);
     974         448 :     maTabs[nTab]->GetLastDataPos(nCol2, nRow2);
     975             : 
     976         448 :     if (nCol1 > nCol2 || nRow1 > nRow2)
     977             :         // invalid range.
     978           1 :         return false;
     979             : 
     980             :     // Make sure the area only shrinks, and doesn't grow.
     981         447 :     if (rStartCol < nCol1)
     982          10 :         rStartCol = nCol1;
     983         447 :     if (nCol2 < rEndCol)
     984         402 :         rEndCol = nCol2;
     985         447 :     if (rStartRow < nRow1)
     986          14 :         rStartRow = nRow1;
     987         447 :     if (nRow2 < rEndRow)
     988         406 :         rEndRow = nRow2;
     989             : 
     990         447 :     if (rStartCol > rEndCol || rStartRow > rEndRow)
     991             :         // invalid range.
     992           0 :         return false;
     993             : 
     994         447 :     return true;  // success!
     995             : }
     996             : 
     997           6 : bool ScDocument::ShrinkToUsedDataArea( bool& o_bShrunk, SCTAB nTab, SCCOL& rStartCol,
     998             :         SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow, bool bColumnsOnly ) const
     999             : {
    1000           6 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB> (maTabs.size()) || !maTabs[nTab])
    1001             :     {
    1002           0 :         o_bShrunk = false;
    1003           0 :         return false;
    1004             :     }
    1005           6 :     return maTabs[nTab]->ShrinkToUsedDataArea( o_bShrunk, rStartCol, rStartRow, rEndCol, rEndRow, bColumnsOnly);
    1006             : }
    1007             : 
    1008             : // connected area
    1009             : 
    1010          35 : void ScDocument::GetDataArea( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow,
    1011             :                               SCCOL& rEndCol, SCROW& rEndRow, bool bIncludeOld, bool bOnlyDown ) const
    1012             : {
    1013          35 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB> (maTabs.size()) && maTabs[nTab])
    1014          35 :         maTabs[nTab]->GetDataArea( rStartCol, rStartRow, rEndCol, rEndRow, bIncludeOld, bOnlyDown );
    1015          35 : }
    1016             : 
    1017             : 
    1018           0 : void ScDocument::LimitChartArea( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow,
    1019             :                                     SCCOL& rEndCol, SCROW& rEndRow )
    1020             : {
    1021           0 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB> (maTabs.size()))
    1022           0 :         if (maTabs[nTab])
    1023           0 :             maTabs[nTab]->LimitChartArea( rStartCol, rStartRow, rEndCol, rEndRow );
    1024           0 : }
    1025             : 
    1026             : 
    1027           0 : void ScDocument::LimitChartIfAll( ScRangeListRef& rRangeList )
    1028             : {
    1029           0 :     ScRangeListRef aNew = new ScRangeList;
    1030           0 :     if (rRangeList.Is())
    1031             :     {
    1032           0 :         for ( size_t i = 0, nCount = rRangeList->size(); i < nCount; i++ )
    1033             :         {
    1034           0 :             ScRange aRange( *(*rRangeList)[i] );
    1035           0 :             if ( ( aRange.aStart.Col() == 0 && aRange.aEnd.Col() == MAXCOL ) ||
    1036           0 :                  ( aRange.aStart.Row() == 0 && aRange.aEnd.Row() == MAXROW ) )
    1037             :             {
    1038           0 :                 SCCOL nStartCol = aRange.aStart.Col();
    1039           0 :                 SCROW nStartRow = aRange.aStart.Row();
    1040           0 :                 SCCOL nEndCol = aRange.aEnd.Col();
    1041           0 :                 SCROW nEndRow = aRange.aEnd.Row();
    1042           0 :                 SCTAB nTab = aRange.aStart.Tab();
    1043           0 :                 if ( nTab < static_cast<SCTAB> (maTabs.size()) && maTabs[nTab])
    1044           0 :                     maTabs[nTab]->LimitChartArea(nStartCol, nStartRow, nEndCol, nEndRow);
    1045           0 :                 aRange.aStart.SetCol( nStartCol );
    1046           0 :                 aRange.aStart.SetRow( nStartRow );
    1047           0 :                 aRange.aEnd.SetCol( nEndCol );
    1048           0 :                 aRange.aEnd.SetRow( nEndRow );
    1049             :             }
    1050           0 :             aNew->Append(aRange);
    1051             :         }
    1052             :     }
    1053             :     else
    1054             :     {
    1055             :         OSL_FAIL("LimitChartIfAll: Ref==0");
    1056             :     }
    1057           0 :     rRangeList = aNew;
    1058           0 : }
    1059             : 
    1060             : 
    1061          88 : static void lcl_GetFirstTabRange( SCTAB& rTabRangeStart, SCTAB& rTabRangeEnd, const ScMarkData* pTabMark, SCTAB aMaxTab )
    1062             : {
    1063             :     // without ScMarkData, leave start/end unchanged
    1064          88 :     if ( pTabMark )
    1065             :     {
    1066          26 :         for (SCTAB nTab=0; nTab< aMaxTab; ++nTab)
    1067          26 :             if (pTabMark->GetTableSelect(nTab))
    1068             :             {
    1069             :                 // find first range of consecutive selected sheets
    1070          26 :                 rTabRangeStart = pTabMark->GetFirstSelected();
    1071          52 :                 while ( nTab+1 < aMaxTab && pTabMark->GetTableSelect(nTab+1) )
    1072           0 :                     ++nTab;
    1073          26 :                 rTabRangeEnd = nTab;
    1074         114 :                 return;
    1075             :             }
    1076             :     }
    1077             : }
    1078             : 
    1079          88 : static bool lcl_GetNextTabRange( SCTAB& rTabRangeStart, SCTAB& rTabRangeEnd, const ScMarkData* pTabMark, SCTAB aMaxTab )
    1080             : {
    1081          88 :     if ( pTabMark )
    1082             :     {
    1083             :         // find next range of consecutive selected sheets after rTabRangeEnd
    1084          50 :         for (SCTAB nTab=rTabRangeEnd+1; nTab< aMaxTab; ++nTab)
    1085          24 :             if (pTabMark->GetTableSelect(nTab))
    1086             :             {
    1087           0 :                 rTabRangeStart = nTab;
    1088           0 :                 while ( nTab+1 < aMaxTab && pTabMark->GetTableSelect(nTab+1) )
    1089           0 :                     ++nTab;
    1090           0 :                 rTabRangeEnd = nTab;
    1091           0 :                 return true;
    1092             :             }
    1093             :     }
    1094          88 :     return false;
    1095             : }
    1096             : 
    1097             : 
    1098           3 : bool ScDocument::CanInsertRow( const ScRange& rRange ) const
    1099             : {
    1100           3 :     SCCOL nStartCol = rRange.aStart.Col();
    1101           3 :     SCROW nStartRow = rRange.aStart.Row();
    1102           3 :     SCTAB nStartTab = rRange.aStart.Tab();
    1103           3 :     SCCOL nEndCol = rRange.aEnd.Col();
    1104           3 :     SCROW nEndRow = rRange.aEnd.Row();
    1105           3 :     SCTAB nEndTab = rRange.aEnd.Tab();
    1106           3 :     PutInOrder( nStartCol, nEndCol );
    1107           3 :     PutInOrder( nStartRow, nEndRow );
    1108           3 :     PutInOrder( nStartTab, nEndTab );
    1109           3 :     SCSIZE nSize = static_cast<SCSIZE>(nEndRow - nStartRow + 1);
    1110             : 
    1111           3 :     bool bTest = true;
    1112           3 :     for (SCTAB i=nStartTab; i<=nEndTab && bTest && i < static_cast<SCTAB>(maTabs.size()); i++)
    1113           0 :         if (maTabs[i])
    1114           0 :             bTest &= maTabs[i]->TestInsertRow( nStartCol, nEndCol, nStartRow, nSize );
    1115             : 
    1116           3 :     return bTest;
    1117             : }
    1118             : 
    1119             : 
    1120          14 : bool ScDocument::InsertRow( SCCOL nStartCol, SCTAB nStartTab,
    1121             :                             SCCOL nEndCol,   SCTAB nEndTab,
    1122             :                             SCROW nStartRow, SCSIZE nSize, ScDocument* pRefUndoDoc,
    1123             :                             const ScMarkData* pTabMark )
    1124             : {
    1125             :     SCTAB i;
    1126             : 
    1127          14 :     PutInOrder( nStartCol, nEndCol );
    1128          14 :     PutInOrder( nStartTab, nEndTab );
    1129          14 :     if ( pTabMark )
    1130             :     {
    1131           2 :         nStartTab = 0;
    1132           2 :         nEndTab = static_cast<SCTAB>(maTabs.size()) -1;
    1133             :     }
    1134             : 
    1135          14 :     bool bTest = true;
    1136          14 :     bool bRet = false;
    1137          14 :     bool bOldAutoCalc = GetAutoCalc();
    1138          14 :     SetAutoCalc( false );   // avoid mulitple calculations
    1139          28 :     for ( i = nStartTab; i <= nEndTab && bTest && i < static_cast<SCTAB>(maTabs.size()); i++)
    1140          14 :         if (maTabs[i] && (!pTabMark || pTabMark->GetTableSelect(i)))
    1141          14 :             bTest &= maTabs[i]->TestInsertRow(nStartCol, nEndCol, nStartRow, nSize);
    1142          14 :     if (bTest)
    1143             :     {
    1144             :         // UpdateBroadcastAreas have to be called before UpdateReference, so that entries
    1145             :         // aren't shifted that would be rebuild at UpdateReference
    1146             : 
    1147             :         // handle chunks of consecutive selected sheets together
    1148          14 :         SCTAB nTabRangeStart = nStartTab;
    1149          14 :         SCTAB nTabRangeEnd = nEndTab;
    1150          14 :         lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) );
    1151          14 :         do
    1152             :         {
    1153             :             UpdateBroadcastAreas( URM_INSDEL, ScRange(
    1154             :                 ScAddress( nStartCol, nStartRow, nTabRangeStart ),
    1155          14 :                 ScAddress( nEndCol, MAXROW, nTabRangeEnd )), 0, static_cast<SCsROW>(nSize), 0 );
    1156             :         }
    1157          14 :         while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) ) );
    1158             : 
    1159          14 :         lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) );
    1160          14 :         do
    1161             :         {
    1162             :             UpdateReference( URM_INSDEL, nStartCol, nStartRow, nTabRangeStart,
    1163             :                              nEndCol, MAXROW, nTabRangeEnd,
    1164          14 :                              0, static_cast<SCsROW>(nSize), 0, pRefUndoDoc, false );        // without drawing objects
    1165             :         }
    1166          14 :         while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) ) );
    1167             : 
    1168          28 :         for (i=nStartTab; i<=nEndTab && i < static_cast<SCTAB>(maTabs.size()); i++)
    1169          14 :             if (maTabs[i] && (!pTabMark || pTabMark->GetTableSelect(i)))
    1170          14 :                 maTabs[i]->InsertRow( nStartCol, nEndCol, nStartRow, nSize );
    1171             : 
    1172             :         //  UpdateRef for drawing layer must be after inserting,
    1173             :         //  when the new row heights are known.
    1174          28 :         for (i=nStartTab; i<=nEndTab && i < static_cast<SCTAB>(maTabs.size()); i++)
    1175          14 :             if (maTabs[i] && (!pTabMark || pTabMark->GetTableSelect(i)))
    1176          14 :                 maTabs[i]->UpdateDrawRef( URM_INSDEL,
    1177             :                             nStartCol, nStartRow, nStartTab, nEndCol, MAXROW, nEndTab,
    1178          28 :                             0, static_cast<SCsROW>(nSize), 0 );
    1179             : 
    1180          14 :         if ( pChangeTrack && pChangeTrack->IsInDeleteUndo() )
    1181             :         {   // durch Restaurierung von Referenzen auf geloeschte Bereiche ist
    1182             :             // ein neues Listening faellig, bisherige Listener wurden in
    1183             :             // FormulaCell UpdateReference abgehaengt
    1184           0 :             StartAllListeners();
    1185             :         }
    1186             :         else
    1187             :         {   // Listeners have been removed in UpdateReference
    1188          14 :             TableContainer::iterator it = maTabs.begin();
    1189          31 :             for (; it != maTabs.end(); ++it)
    1190          17 :                 if (*it)
    1191          17 :                     (*it)->StartNeededListeners();
    1192             :             // at least all cells using range names pointing relative
    1193             :             // to the moved range must recalculate
    1194          14 :             it = maTabs.begin();
    1195          31 :             for (; it != maTabs.end(); ++it)
    1196          17 :                 if (*it)
    1197          17 :                     (*it)->SetRelNameDirty();
    1198             :         }
    1199          14 :         bRet = true;
    1200             :     }
    1201          14 :     SetAutoCalc( bOldAutoCalc );
    1202          14 :     if ( bRet )
    1203          14 :         pChartListenerCollection->UpdateDirtyCharts();
    1204          14 :     return bRet;
    1205             : }
    1206             : 
    1207             : 
    1208           0 : bool ScDocument::InsertRow( const ScRange& rRange, ScDocument* pRefUndoDoc )
    1209             : {
    1210           0 :     return InsertRow( rRange.aStart.Col(), rRange.aStart.Tab(),
    1211           0 :                       rRange.aEnd.Col(),   rRange.aEnd.Tab(),
    1212           0 :                       rRange.aStart.Row(), static_cast<SCSIZE>(rRange.aEnd.Row()-rRange.aStart.Row()+1),
    1213           0 :                       pRefUndoDoc );
    1214             : }
    1215             : 
    1216             : 
    1217          14 : void ScDocument::DeleteRow( SCCOL nStartCol, SCTAB nStartTab,
    1218             :                             SCCOL nEndCol,   SCTAB nEndTab,
    1219             :                             SCROW nStartRow, SCSIZE nSize,
    1220             :                             ScDocument* pRefUndoDoc, bool* pUndoOutline,
    1221             :                             const ScMarkData* pTabMark )
    1222             : {
    1223             :     SCTAB i;
    1224             : 
    1225          14 :     PutInOrder( nStartCol, nEndCol );
    1226          14 :     PutInOrder( nStartTab, nEndTab );
    1227          14 :     if ( pTabMark )
    1228             :     {
    1229           2 :         nStartTab = 0;
    1230           2 :         nEndTab = static_cast<SCTAB>(maTabs.size())-1;
    1231             :     }
    1232             : 
    1233          14 :     bool bOldAutoCalc = GetAutoCalc();
    1234          14 :     SetAutoCalc( false );   // avoid multiple calculations
    1235             : 
    1236             :     // handle chunks of consecutive selected sheets together
    1237          14 :     SCTAB nTabRangeStart = nStartTab;
    1238          14 :     SCTAB nTabRangeEnd = nEndTab;
    1239          14 :     lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) );
    1240          14 :     do
    1241             :     {
    1242          14 :         if ( ValidRow(nStartRow+nSize) )
    1243             :         {
    1244             :             DelBroadcastAreasInRange( ScRange(
    1245             :                 ScAddress( nStartCol, nStartRow, nTabRangeStart ),
    1246          14 :                 ScAddress( nEndCol, nStartRow+nSize-1, nTabRangeEnd ) ) );
    1247             :             UpdateBroadcastAreas( URM_INSDEL, ScRange(
    1248          14 :                 ScAddress( nStartCol, nStartRow+nSize, nTabRangeStart ),
    1249          28 :                 ScAddress( nEndCol, MAXROW, nTabRangeEnd )), 0, -(static_cast<SCsROW>(nSize)), 0 );
    1250             :         }
    1251             :         else
    1252             :             DelBroadcastAreasInRange( ScRange(
    1253             :                 ScAddress( nStartCol, nStartRow, nTabRangeStart ),
    1254           0 :                 ScAddress( nEndCol, MAXROW, nTabRangeEnd ) ) );
    1255             :     }
    1256          14 :     while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) ) );
    1257             : 
    1258          14 :     if ( ValidRow(nStartRow+nSize) )
    1259             :     {
    1260          14 :         lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) );
    1261          14 :         do
    1262             :         {
    1263          14 :             UpdateReference( URM_INSDEL, nStartCol, nStartRow+nSize, nTabRangeStart,
    1264             :                              nEndCol, MAXROW, nTabRangeEnd,
    1265          28 :                              0, -(static_cast<SCsROW>(nSize)), 0, pRefUndoDoc, true, false );
    1266             :         }
    1267          14 :         while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) ) );
    1268             :     }
    1269             : 
    1270          14 :     if (pUndoOutline)
    1271           1 :         *pUndoOutline = false;
    1272             : 
    1273          31 :     for ( i = nStartTab; i <= nEndTab && i < static_cast<SCTAB>(maTabs.size()); i++)
    1274          17 :         if (maTabs[i] && (!pTabMark || pTabMark->GetTableSelect(i)))
    1275          14 :             maTabs[i]->DeleteRow( nStartCol, nEndCol, nStartRow, nSize, pUndoOutline );
    1276             : 
    1277          14 :     if ( ValidRow(nStartRow+nSize) )
    1278             :     {   // Listeners have been removed in UpdateReference
    1279          14 :         TableContainer::iterator it = maTabs.begin();
    1280          31 :         for (; it != maTabs.end(); ++it)
    1281          17 :             if (*it)
    1282          17 :                 (*it)->StartNeededListeners();
    1283             :         // at least all cells using range names pointing relative
    1284             :         // to the moved range must recalculate
    1285          14 :         it = maTabs.begin();
    1286          31 :         for (; it != maTabs.end(); ++it)
    1287          17 :             if (*it)
    1288          17 :                 (*it)->SetRelNameDirty();
    1289             :     }
    1290             : 
    1291          14 :     SetAutoCalc( bOldAutoCalc );
    1292          14 :     pChartListenerCollection->UpdateDirtyCharts();
    1293          14 : }
    1294             : 
    1295             : 
    1296           0 : void ScDocument::DeleteRow( const ScRange& rRange, ScDocument* pRefUndoDoc, bool* pUndoOutline )
    1297             : {
    1298           0 :     DeleteRow( rRange.aStart.Col(), rRange.aStart.Tab(),
    1299           0 :                rRange.aEnd.Col(),   rRange.aEnd.Tab(),
    1300           0 :                rRange.aStart.Row(), static_cast<SCSIZE>(rRange.aEnd.Row()-rRange.aStart.Row()+1),
    1301           0 :                pRefUndoDoc, pUndoOutline );
    1302           0 : }
    1303             : 
    1304             : 
    1305           3 : bool ScDocument::CanInsertCol( const ScRange& rRange ) const
    1306             : {
    1307           3 :     SCCOL nStartCol = rRange.aStart.Col();
    1308           3 :     SCROW nStartRow = rRange.aStart.Row();
    1309           3 :     SCTAB nStartTab = rRange.aStart.Tab();
    1310           3 :     SCCOL nEndCol = rRange.aEnd.Col();
    1311           3 :     SCROW nEndRow = rRange.aEnd.Row();
    1312           3 :     SCTAB nEndTab = rRange.aEnd.Tab();
    1313           3 :     PutInOrder( nStartCol, nEndCol );
    1314           3 :     PutInOrder( nStartRow, nEndRow );
    1315           3 :     PutInOrder( nStartTab, nEndTab );
    1316           3 :     SCSIZE nSize = static_cast<SCSIZE>(nEndCol - nStartCol + 1);
    1317             : 
    1318           3 :     bool bTest = true;
    1319           3 :     for (SCTAB i=nStartTab; i<=nEndTab && bTest && i < static_cast<SCTAB>(maTabs.size()); i++)
    1320           0 :         if (maTabs[i])
    1321           0 :             bTest &= maTabs[i]->TestInsertCol( nStartRow, nEndRow, nSize );
    1322             : 
    1323           3 :     return bTest;
    1324             : }
    1325             : 
    1326             : 
    1327           8 : bool ScDocument::InsertCol( SCROW nStartRow, SCTAB nStartTab,
    1328             :                             SCROW nEndRow,   SCTAB nEndTab,
    1329             :                             SCCOL nStartCol, SCSIZE nSize, ScDocument* pRefUndoDoc,
    1330             :                             const ScMarkData* pTabMark )
    1331             : {
    1332             :     SCTAB i;
    1333             : 
    1334           8 :     PutInOrder( nStartRow, nEndRow );
    1335           8 :     PutInOrder( nStartTab, nEndTab );
    1336           8 :     if ( pTabMark )
    1337             :     {
    1338           4 :         nStartTab = 0;
    1339           4 :         nEndTab = static_cast<SCTAB>(maTabs.size())-1;
    1340             :     }
    1341             : 
    1342           8 :     bool bTest = true;
    1343           8 :     bool bRet = false;
    1344           8 :     bool bOldAutoCalc = GetAutoCalc();
    1345           8 :     SetAutoCalc( false );   // avoid multiple calculations
    1346          19 :     for ( i = nStartTab; i <= nEndTab && bTest && i < static_cast<SCTAB>(maTabs.size()); i++)
    1347          11 :         if (maTabs[i] && (!pTabMark || pTabMark->GetTableSelect(i)))
    1348           8 :             bTest &= maTabs[i]->TestInsertCol( nStartRow, nEndRow, nSize );
    1349           8 :     if (bTest)
    1350             :     {
    1351             :         // handle chunks of consecutive selected sheets together
    1352           8 :         SCTAB nTabRangeStart = nStartTab;
    1353           8 :         SCTAB nTabRangeEnd = nEndTab;
    1354           8 :         lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) );
    1355           8 :         do
    1356             :         {
    1357             :             UpdateBroadcastAreas( URM_INSDEL, ScRange(
    1358             :                 ScAddress( nStartCol, nStartRow, nTabRangeStart ),
    1359           8 :                 ScAddress( MAXCOL, nEndRow, nTabRangeEnd )), static_cast<SCsCOL>(nSize), 0, 0 );
    1360             :         }
    1361           8 :         while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) ) );
    1362             : 
    1363           8 :         lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) );
    1364           8 :         do
    1365             :         {
    1366             :             UpdateReference( URM_INSDEL, nStartCol, nStartRow, nTabRangeStart,
    1367             :                              MAXCOL, nEndRow, nTabRangeEnd,
    1368           8 :                              static_cast<SCsCOL>(nSize), 0, 0, pRefUndoDoc, true, false );
    1369             :         }
    1370           8 :         while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) ) );
    1371             : 
    1372          19 :         for (i=nStartTab; i<=nEndTab && i < static_cast<SCTAB>(maTabs.size()); i++)
    1373          11 :             if (maTabs[i] && (!pTabMark || pTabMark->GetTableSelect(i)))
    1374           8 :                 maTabs[i]->InsertCol( nStartCol, nStartRow, nEndRow, nSize );
    1375             : 
    1376           8 :         if ( pChangeTrack && pChangeTrack->IsInDeleteUndo() )
    1377             :         {   // durch Restaurierung von Referenzen auf geloeschte Bereiche ist
    1378             :             // ein neues Listening faellig, bisherige Listener wurden in
    1379             :             // FormulaCell UpdateReference abgehaengt
    1380           0 :             StartAllListeners();
    1381             :         }
    1382             :         else
    1383             :         {// Listeners have been removed in UpdateReference
    1384           8 :             TableContainer::iterator it = maTabs.begin();
    1385          19 :             for (; it != maTabs.end(); ++it)
    1386          11 :                 if (*it)
    1387          11 :                     (*it)->StartNeededListeners();
    1388             :             // at least all cells using range names pointing relative
    1389             :             // to the moved range must recalculate
    1390           8 :             it = maTabs.begin();
    1391          19 :             for (; it != maTabs.end(); ++it)
    1392          11 :                 if (*it)
    1393          11 :                     (*it)->SetRelNameDirty();
    1394             :         }
    1395           8 :         bRet = true;
    1396             :     }
    1397           8 :     SetAutoCalc( bOldAutoCalc );
    1398           8 :     if ( bRet )
    1399           8 :         pChartListenerCollection->UpdateDirtyCharts();
    1400           8 :     return bRet;
    1401             : }
    1402             : 
    1403             : 
    1404           1 : bool ScDocument::InsertCol( const ScRange& rRange, ScDocument* pRefUndoDoc )
    1405             : {
    1406           1 :     return InsertCol( rRange.aStart.Row(), rRange.aStart.Tab(),
    1407           1 :                       rRange.aEnd.Row(),   rRange.aEnd.Tab(),
    1408           2 :                       rRange.aStart.Col(), static_cast<SCSIZE>(rRange.aEnd.Col()-rRange.aStart.Col()+1),
    1409           4 :                       pRefUndoDoc );
    1410             : }
    1411             : 
    1412             : 
    1413           8 : void ScDocument::DeleteCol(SCROW nStartRow, SCTAB nStartTab, SCROW nEndRow, SCTAB nEndTab,
    1414             :                                 SCCOL nStartCol, SCSIZE nSize, ScDocument* pRefUndoDoc,
    1415             :                                 bool* pUndoOutline, const ScMarkData* pTabMark )
    1416             : {
    1417             :     SCTAB i;
    1418             : 
    1419           8 :     PutInOrder( nStartRow, nEndRow );
    1420           8 :     PutInOrder( nStartTab, nEndTab );
    1421           8 :     if ( pTabMark )
    1422             :     {
    1423           5 :         nStartTab = 0;
    1424           5 :         nEndTab = static_cast<SCTAB>(maTabs.size())-1;
    1425             :     }
    1426             : 
    1427           8 :     bool bOldAutoCalc = GetAutoCalc();
    1428           8 :     SetAutoCalc( false );   // avoid multiple calculations
    1429             : 
    1430             :     // handle chunks of consecutive selected sheets together
    1431           8 :     SCTAB nTabRangeStart = nStartTab;
    1432           8 :     SCTAB nTabRangeEnd = nEndTab;
    1433           8 :     lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) );
    1434           8 :     do
    1435             :     {
    1436           8 :         if ( ValidCol(sal::static_int_cast<SCCOL>(nStartCol+nSize)) )
    1437             :         {
    1438             :             DelBroadcastAreasInRange( ScRange(
    1439             :                 ScAddress( nStartCol, nStartRow, nTabRangeStart ),
    1440           8 :                 ScAddress( sal::static_int_cast<SCCOL>(nStartCol+nSize-1), nEndRow, nTabRangeEnd ) ) );
    1441             :             UpdateBroadcastAreas( URM_INSDEL, ScRange(
    1442           8 :                 ScAddress( sal::static_int_cast<SCCOL>(nStartCol+nSize), nStartRow, nTabRangeStart ),
    1443          16 :                 ScAddress( MAXCOL, nEndRow, nTabRangeEnd )), -static_cast<SCsCOL>(nSize), 0, 0 );
    1444             :         }
    1445             :         else
    1446             :             DelBroadcastAreasInRange( ScRange(
    1447             :                 ScAddress( nStartCol, nStartRow, nTabRangeStart ),
    1448           0 :                 ScAddress( MAXCOL, nEndRow, nTabRangeEnd ) ) );
    1449             :     }
    1450           8 :     while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) ) );
    1451             : 
    1452           8 :     if ( ValidCol(sal::static_int_cast<SCCOL>(nStartCol+nSize)) )
    1453             :     {
    1454           8 :         lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) );
    1455           8 :         do
    1456             :         {
    1457           8 :             UpdateReference( URM_INSDEL, sal::static_int_cast<SCCOL>(nStartCol+nSize), nStartRow, nTabRangeStart,
    1458             :                              MAXCOL, nEndRow, nTabRangeEnd,
    1459          16 :                              -static_cast<SCsCOL>(nSize), 0, 0, pRefUndoDoc, true, false );
    1460             :         }
    1461           8 :         while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) ) );
    1462             :     }
    1463             : 
    1464           8 :     if (pUndoOutline)
    1465           3 :         *pUndoOutline = false;
    1466             : 
    1467          22 :     for ( i = nStartTab; i <= nEndTab && i < static_cast<SCTAB>(maTabs.size()); i++)
    1468          14 :         if (maTabs[i] && (!pTabMark || pTabMark->GetTableSelect(i)))
    1469           8 :             maTabs[i]->DeleteCol( nStartCol, nStartRow, nEndRow, nSize, pUndoOutline );
    1470             : 
    1471           8 :     if ( ValidCol(sal::static_int_cast<SCCOL>(nStartCol+nSize)) )
    1472             :     {// Listeners have been removed in UpdateReference
    1473           8 :         TableContainer::iterator it = maTabs.begin();
    1474          22 :         for (; it != maTabs.end(); ++it)
    1475          14 :             if (*it)
    1476          14 :                 (*it)->StartNeededListeners();
    1477             :         // at least all cells using range names pointing relative
    1478             :         // to the moved range must recalculate
    1479           8 :         it = maTabs.begin();
    1480          22 :         for (; it != maTabs.end(); ++it)
    1481          14 :             if (*it)
    1482          14 :                 (*it)->SetRelNameDirty();
    1483             :     }
    1484             : 
    1485           8 :     SetAutoCalc( bOldAutoCalc );
    1486           8 :     pChartListenerCollection->UpdateDirtyCharts();
    1487           8 : }
    1488             : 
    1489             : 
    1490           0 : void ScDocument::DeleteCol( const ScRange& rRange, ScDocument* pRefUndoDoc, bool* pUndoOutline )
    1491             : {
    1492           0 :     DeleteCol( rRange.aStart.Row(), rRange.aStart.Tab(),
    1493           0 :                rRange.aEnd.Row(),   rRange.aEnd.Tab(),
    1494           0 :                rRange.aStart.Col(), static_cast<SCSIZE>(rRange.aEnd.Col()-rRange.aStart.Col()+1),
    1495           0 :                pRefUndoDoc, pUndoOutline );
    1496           0 : }
    1497             : 
    1498             : 
    1499             : //  fuer Area-Links: Zellen einuegen/loeschen, wenn sich der Bereich veraendert
    1500             : //  (ohne Paint)
    1501             : 
    1502             : 
    1503           4 : static void lcl_GetInsDelRanges( const ScRange& rOld, const ScRange& rNew,
    1504             :                             ScRange& rColRange, bool& rInsCol, bool& rDelCol,
    1505             :                             ScRange& rRowRange, bool& rInsRow, bool& rDelRow )
    1506             : {
    1507             :     OSL_ENSURE( rOld.aStart == rNew.aStart, "FitBlock: Beginning is different" );
    1508             : 
    1509           4 :     rInsCol = rDelCol = rInsRow = rDelRow = false;
    1510             : 
    1511           4 :     SCCOL nStartX = rOld.aStart.Col();
    1512           4 :     SCROW nStartY = rOld.aStart.Row();
    1513           4 :     SCCOL nOldEndX = rOld.aEnd.Col();
    1514           4 :     SCROW nOldEndY = rOld.aEnd.Row();
    1515           4 :     SCCOL nNewEndX = rNew.aEnd.Col();
    1516           4 :     SCROW nNewEndY = rNew.aEnd.Row();
    1517           4 :     SCTAB nTab = rOld.aStart.Tab();
    1518             : 
    1519             :     //  wenn es mehr Zeilen werden, werden Spalten auf der alten Hoehe eingefuegt/geloescht
    1520           4 :     bool bGrowY = ( nNewEndY > nOldEndY );
    1521           4 :     SCROW nColEndY = bGrowY ? nOldEndY : nNewEndY;
    1522           4 :     SCCOL nRowEndX = bGrowY ? nNewEndX : nOldEndX;
    1523             : 
    1524             :     //  Spalten
    1525             : 
    1526           4 :     if ( nNewEndX > nOldEndX )          // Spalten einfuegen
    1527             :     {
    1528           3 :         rColRange = ScRange( nOldEndX+1, nStartY, nTab, nNewEndX, nColEndY, nTab );
    1529           3 :         rInsCol = true;
    1530             :     }
    1531           1 :     else if ( nNewEndX < nOldEndX )     // Spalten loeschen
    1532             :     {
    1533           0 :         rColRange = ScRange( nNewEndX+1, nStartY, nTab, nOldEndX, nColEndY, nTab );
    1534           0 :         rDelCol = true;
    1535             :     }
    1536             : 
    1537             :     //  Zeilen
    1538             : 
    1539           4 :     if ( nNewEndY > nOldEndY )          // Zeilen einfuegen
    1540             :     {
    1541           3 :         rRowRange = ScRange( nStartX, nOldEndY+1, nTab, nRowEndX, nNewEndY, nTab );
    1542           3 :         rInsRow = true;
    1543             :     }
    1544           1 :     else if ( nNewEndY < nOldEndY )     // Zeilen loeschen
    1545             :     {
    1546           0 :         rRowRange = ScRange( nStartX, nNewEndY+1, nTab, nRowEndX, nOldEndY, nTab );
    1547           0 :         rDelRow = true;
    1548             :     }
    1549           4 : }
    1550             : 
    1551             : 
    1552           6 : bool ScDocument::HasPartOfMerged( const ScRange& rRange )
    1553             : {
    1554           6 :     bool bPart = false;
    1555           6 :     SCTAB nTab = rRange.aStart.Tab();
    1556             : 
    1557           6 :     SCCOL nStartX = rRange.aStart.Col();
    1558           6 :     SCROW nStartY = rRange.aStart.Row();
    1559           6 :     SCCOL nEndX = rRange.aEnd.Col();
    1560           6 :     SCROW nEndY = rRange.aEnd.Row();
    1561             : 
    1562           6 :     if (HasAttrib( nStartX, nStartY, nTab, nEndX, nEndY, nTab,
    1563           6 :                         HASATTR_MERGED | HASATTR_OVERLAPPED ))
    1564             :     {
    1565           0 :         ExtendMerge( nStartX, nStartY, nEndX, nEndY, nTab );
    1566           0 :         ExtendOverlapped( nStartX, nStartY, nEndX, nEndY, nTab );
    1567             : 
    1568           0 :         bPart = ( nStartX != rRange.aStart.Col() || nEndX != rRange.aEnd.Col() ||
    1569           0 :                   nStartY != rRange.aStart.Row() || nEndY != rRange.aEnd.Row() );
    1570             :     }
    1571           6 :     return bPart;
    1572             : }
    1573             : 
    1574          38 : size_t ScDocument::GetFormulaHash( const ScAddress& rPos ) const
    1575             : {
    1576          38 :     SCTAB nTab = rPos.Tab();
    1577          38 :     if (!ValidTab(nTab) || static_cast<size_t>(nTab) >= maTabs.size() || !maTabs[nTab])
    1578           0 :         return 0;
    1579             : 
    1580          38 :     return maTabs[nTab]->GetFormulaHash(rPos.Col(), rPos.Row());
    1581             : }
    1582             : 
    1583           6 : ScFormulaVectorState ScDocument::GetFormulaVectorState( const ScAddress& rPos ) const
    1584             : {
    1585           6 :     SCTAB nTab = rPos.Tab();
    1586           6 :     if (!ValidTab(nTab) || static_cast<size_t>(nTab) >= maTabs.size() || !maTabs[nTab])
    1587           0 :         return FormulaVectorUnknown;
    1588             : 
    1589           6 :     return maTabs[nTab]->GetFormulaVectorState(rPos.Col(), rPos.Row());
    1590             : }
    1591             : 
    1592           0 : formula::FormulaTokenRef ScDocument::ResolveStaticReference( const ScAddress& rPos )
    1593             : {
    1594           0 :     SCTAB nTab = rPos.Tab();
    1595           0 :     if (!TableExists(nTab))
    1596           0 :         return formula::FormulaTokenRef();
    1597             : 
    1598           0 :     return maTabs[nTab]->ResolveStaticReference(rPos.Col(), rPos.Row());
    1599             : }
    1600             : 
    1601           0 : formula::FormulaTokenRef ScDocument::ResolveStaticReference( const ScRange& rRange )
    1602             : {
    1603           0 :     SCTAB nTab = rRange.aStart.Tab();
    1604           0 :     if (nTab != rRange.aEnd.Tab() || !TableExists(nTab))
    1605           0 :         return formula::FormulaTokenRef();
    1606             : 
    1607           0 :     return maTabs[nTab]->ResolveStaticReference(
    1608           0 :         rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row());
    1609             : }
    1610             : 
    1611           0 : const double* ScDocument::FetchDoubleArray(
    1612             :     sc::FormulaGroupContext& rCxt, const ScAddress& rPos, SCROW nLength )
    1613             : {
    1614           0 :     SCTAB nTab = rPos.Tab();
    1615           0 :     if (!TableExists(nTab))
    1616           0 :         return NULL;
    1617             : 
    1618           0 :     return maTabs[nTab]->FetchDoubleArray(rCxt, rPos.Col(), rPos.Row(), rPos.Row()+nLength-1);
    1619             : }
    1620             : 
    1621           4 : bool ScDocument::CanFitBlock( const ScRange& rOld, const ScRange& rNew )
    1622             : {
    1623           4 :     if ( rOld == rNew )
    1624           1 :         return true;
    1625             : 
    1626           3 :     bool bOk = true;
    1627             :     bool bInsCol,bDelCol,bInsRow,bDelRow;
    1628           3 :     ScRange aColRange,aRowRange;
    1629           3 :     lcl_GetInsDelRanges( rOld, rNew, aColRange,bInsCol,bDelCol, aRowRange,bInsRow,bDelRow );
    1630             : 
    1631           3 :     if ( bInsCol && !CanInsertCol( aColRange ) )            // Zellen am Rand ?
    1632           0 :         bOk = false;
    1633           3 :     if ( bInsRow && !CanInsertRow( aRowRange ) )            // Zellen am Rand ?
    1634           0 :         bOk = false;
    1635             : 
    1636           3 :     if ( bInsCol || bDelCol )
    1637             :     {
    1638           3 :         aColRange.aEnd.SetCol(MAXCOL);
    1639           3 :         if ( HasPartOfMerged(aColRange) )
    1640           0 :             bOk = false;
    1641             :     }
    1642           3 :     if ( bInsRow || bDelRow )
    1643             :     {
    1644           3 :         aRowRange.aEnd.SetRow(MAXROW);
    1645           3 :         if ( HasPartOfMerged(aRowRange) )
    1646           0 :             bOk = false;
    1647             :     }
    1648             : 
    1649           3 :     return bOk;
    1650             : }
    1651             : 
    1652             : 
    1653           1 : void ScDocument::FitBlock( const ScRange& rOld, const ScRange& rNew, bool bClear )
    1654             : {
    1655           1 :     if (bClear)
    1656           1 :         DeleteAreaTab( rOld, IDF_ALL );
    1657             : 
    1658             :     bool bInsCol,bDelCol,bInsRow,bDelRow;
    1659           1 :     ScRange aColRange,aRowRange;
    1660           1 :     lcl_GetInsDelRanges( rOld, rNew, aColRange,bInsCol,bDelCol, aRowRange,bInsRow,bDelRow );
    1661             : 
    1662           1 :     if ( bInsCol )
    1663           0 :         InsertCol( aColRange );         // Spalten zuerst einfuegen
    1664           1 :     if ( bInsRow )
    1665           0 :         InsertRow( aRowRange );
    1666             : 
    1667           1 :     if ( bDelRow )
    1668           0 :         DeleteRow( aRowRange );         // Zeilen zuerst loeschen
    1669           1 :     if ( bDelCol )
    1670           0 :         DeleteCol( aColRange );
    1671             : 
    1672             :     //  Referenzen um eingefuegte Zeilen erweitern
    1673             : 
    1674           1 :     if ( bInsCol || bInsRow )
    1675             :     {
    1676           0 :         ScRange aGrowSource = rOld;
    1677           0 :         aGrowSource.aEnd.SetCol(std::min( rOld.aEnd.Col(), rNew.aEnd.Col() ));
    1678           0 :         aGrowSource.aEnd.SetRow(std::min( rOld.aEnd.Row(), rNew.aEnd.Row() ));
    1679           0 :         SCCOL nGrowX = bInsCol ? ( rNew.aEnd.Col() - rOld.aEnd.Col() ) : 0;
    1680           0 :         SCROW nGrowY = bInsRow ? ( rNew.aEnd.Row() - rOld.aEnd.Row() ) : 0;
    1681           0 :         UpdateGrow( aGrowSource, nGrowX, nGrowY );
    1682             :     }
    1683           1 : }
    1684             : 
    1685             : 
    1686          91 : void ScDocument::DeleteArea(SCCOL nCol1, SCROW nRow1,
    1687             :                             SCCOL nCol2, SCROW nRow2,
    1688             :                             const ScMarkData& rMark, sal_uInt16 nDelFlag)
    1689             : {
    1690          91 :     PutInOrder( nCol1, nCol2 );
    1691          91 :     PutInOrder( nRow1, nRow2 );
    1692          91 :     bool bOldAutoCalc = GetAutoCalc();
    1693          91 :     SetAutoCalc( false );   // avoid multiple calculations
    1694         236 :     for (SCTAB i = 0; i < static_cast<SCTAB>(maTabs.size()); i++)
    1695         145 :         if (maTabs[i])
    1696         145 :             if ( rMark.GetTableSelect(i) || bIsUndo )
    1697          91 :                 maTabs[i]->DeleteArea(nCol1, nRow1, nCol2, nRow2, nDelFlag);
    1698          91 :     SetAutoCalc( bOldAutoCalc );
    1699          91 : }
    1700             : 
    1701             : 
    1702         676 : void ScDocument::DeleteAreaTab(SCCOL nCol1, SCROW nRow1,
    1703             :                                 SCCOL nCol2, SCROW nRow2,
    1704             :                                 SCTAB nTab, sal_uInt16 nDelFlag)
    1705             : {
    1706         676 :     PutInOrder( nCol1, nCol2 );
    1707         676 :     PutInOrder( nRow1, nRow2 );
    1708         676 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    1709             :     {
    1710         672 :         bool bOldAutoCalc = GetAutoCalc();
    1711         672 :         SetAutoCalc( false );   // avoid multiple calculations
    1712         672 :         maTabs[nTab]->DeleteArea(nCol1, nRow1, nCol2, nRow2, nDelFlag);
    1713         672 :         SetAutoCalc( bOldAutoCalc );
    1714             :     }
    1715         676 : }
    1716             : 
    1717             : 
    1718           4 : void ScDocument::DeleteAreaTab( const ScRange& rRange, sal_uInt16 nDelFlag )
    1719             : {
    1720           8 :     for ( SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); nTab++ )
    1721           4 :         DeleteAreaTab( rRange.aStart.Col(), rRange.aStart.Row(),
    1722           4 :                        rRange.aEnd.Col(),   rRange.aEnd.Row(),
    1723          12 :                        nTab, nDelFlag );
    1724           4 : }
    1725             : 
    1726             : 
    1727          17 : void ScDocument::InitUndoSelected( ScDocument* pSrcDoc, const ScMarkData& rTabSelection,
    1728             :                                 bool bColInfo, bool bRowInfo )
    1729             : {
    1730          17 :     if (bIsUndo)
    1731             :     {
    1732          17 :         Clear();
    1733             : 
    1734          17 :         xPoolHelper = pSrcDoc->xPoolHelper;
    1735             : 
    1736             : 
    1737          17 :         OUString aString;
    1738          35 :         for (SCTAB nTab = 0; nTab <= rTabSelection.GetLastSelected(); nTab++)
    1739          18 :             if ( rTabSelection.GetTableSelect( nTab ) )
    1740             :             {
    1741          17 :                 ScTable* pTable = new ScTable(this, nTab, aString, bColInfo, bRowInfo);
    1742          17 :                 if (nTab < static_cast<SCTAB>(maTabs.size()))
    1743           0 :                     maTabs[nTab] = pTable;
    1744             :                 else
    1745          17 :                     maTabs.push_back(pTable);
    1746             :             }
    1747             :             else
    1748             :             {
    1749           1 :                 if (nTab < static_cast<SCTAB>(maTabs.size()))
    1750           0 :                     maTabs[nTab]=NULL;
    1751             :                 else
    1752           1 :                     maTabs.push_back(NULL);
    1753          17 :             }
    1754             :     }
    1755             :     else
    1756             :     {
    1757             :         OSL_FAIL("InitUndo");
    1758             :     }
    1759          17 : }
    1760             : 
    1761             : 
    1762         824 : void ScDocument::InitUndo( ScDocument* pSrcDoc, SCTAB nTab1, SCTAB nTab2,
    1763             :                                 bool bColInfo, bool bRowInfo )
    1764             : {
    1765         824 :     if (bIsUndo)
    1766             :     {
    1767         824 :         Clear();
    1768             : 
    1769         824 :         xPoolHelper = pSrcDoc->xPoolHelper;
    1770         824 :         if (pSrcDoc->pShell->GetMedium())
    1771         824 :             maFileURL = pSrcDoc->pShell->GetMedium()->GetURLObject().GetMainURL(INetURLObject::DECODE_TO_IURI);
    1772             : 
    1773         824 :         OUString aString;
    1774         824 :         if ( nTab2 >= static_cast<SCTAB>(maTabs.size()))
    1775         824 :             maTabs.resize(nTab2 + 1, NULL);
    1776        1672 :         for (SCTAB nTab = nTab1; nTab <= nTab2; nTab++)
    1777             :         {
    1778         848 :             ScTable* pTable = new ScTable(this, nTab, aString, bColInfo, bRowInfo);
    1779         848 :             maTabs[nTab] = pTable;
    1780         824 :         }
    1781             :     }
    1782             :     else
    1783             :     {
    1784             :         OSL_FAIL("InitUndo");
    1785             :     }
    1786         824 : }
    1787             : 
    1788             : 
    1789          26 : void ScDocument::AddUndoTab( SCTAB nTab1, SCTAB nTab2, bool bColInfo, bool bRowInfo )
    1790             : {
    1791          26 :     if (bIsUndo)
    1792             :     {
    1793          26 :         OUString aString;
    1794          26 :         if (nTab2 >= static_cast<SCTAB>(maTabs.size()))
    1795             :         {
    1796          19 :             maTabs.resize(nTab2+1,NULL);
    1797             :         }
    1798          85 :         for (SCTAB nTab = nTab1; nTab <= nTab2; nTab++)
    1799          59 :             if (!maTabs[nTab])
    1800             :             {
    1801          24 :                 maTabs[nTab] = new ScTable(this, nTab, aString, bColInfo, bRowInfo);
    1802          26 :             }
    1803             : 
    1804             :     }
    1805             :     else
    1806             :     {
    1807             :         OSL_FAIL("InitUndo");
    1808             :     }
    1809          26 : }
    1810             : 
    1811             : 
    1812           0 : void ScDocument::SetCutMode( bool bVal )
    1813             : {
    1814           0 :     if (bIsClip)
    1815           0 :         GetClipParam().mbCutMode = bVal;
    1816             :     else
    1817             :     {
    1818             :         OSL_FAIL("SetCutMode without bIsClip");
    1819             :     }
    1820           0 : }
    1821             : 
    1822             : 
    1823          32 : bool ScDocument::IsCutMode()
    1824             : {
    1825          32 :     if (bIsClip)
    1826          32 :         return GetClipParam().mbCutMode;
    1827             :     else
    1828             :     {
    1829             :         OSL_FAIL("IsCutMode without bIsClip");
    1830           0 :         return false;
    1831             :     }
    1832             : }
    1833             : 
    1834             : 
    1835         265 : void ScDocument::CopyToDocument(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
    1836             :                             SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
    1837             :                             sal_uInt16 nFlags, bool bOnlyMarked, ScDocument* pDestDoc,
    1838             :                             const ScMarkData* pMarks, bool bColRowFlags )
    1839             : {
    1840         265 :     PutInOrder( nCol1, nCol2 );
    1841         265 :     PutInOrder( nRow1, nRow2 );
    1842         265 :     PutInOrder( nTab1, nTab2 );
    1843         265 :     if( pDestDoc->aDocName.isEmpty() )
    1844         194 :         pDestDoc->aDocName = aDocName;
    1845         265 :     if (ValidTab(nTab1) && ValidTab(nTab2))
    1846             :     {
    1847         265 :         sc::CopyToDocContext aCxt(*pDestDoc);
    1848         265 :         bool bOldAutoCalc = pDestDoc->GetAutoCalc();
    1849         265 :         pDestDoc->SetAutoCalc( false );     // avoid multiple calculations
    1850         265 :         SCTAB nMinSizeBothTabs = static_cast<SCTAB>(std::min(maTabs.size(), pDestDoc->maTabs.size()));
    1851         540 :         for (SCTAB i = nTab1; i <= nTab2 && i < nMinSizeBothTabs; i++)
    1852             :         {
    1853         275 :             if (maTabs[i] && pDestDoc->maTabs[i])
    1854         273 :                 maTabs[i]->CopyToTable(aCxt, nCol1, nRow1, nCol2, nRow2, nFlags,
    1855         273 :                                       bOnlyMarked, pDestDoc->maTabs[i], pMarks,
    1856         819 :                                       false, bColRowFlags );
    1857             :         }
    1858         265 :         pDestDoc->SetAutoCalc( bOldAutoCalc );
    1859             :     }
    1860         265 : }
    1861             : 
    1862             : 
    1863           0 : void ScDocument::UndoToDocument(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
    1864             :                             SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
    1865             :                             sal_uInt16 nFlags, bool bOnlyMarked, ScDocument* pDestDoc,
    1866             :                             const ScMarkData* pMarks)
    1867             : {
    1868           0 :     PutInOrder( nCol1, nCol2 );
    1869           0 :     PutInOrder( nRow1, nRow2 );
    1870           0 :     PutInOrder( nTab1, nTab2 );
    1871           0 :     if (ValidTab(nTab1) && ValidTab(nTab2))
    1872             :     {
    1873           0 :         bool bOldAutoCalc = pDestDoc->GetAutoCalc();
    1874           0 :         pDestDoc->SetAutoCalc( false );     // avoid multiple calculations
    1875           0 :         if (nTab1 > 0)
    1876           0 :             CopyToDocument( 0,0,0, MAXCOL,MAXROW,nTab1-1, IDF_FORMULA, false, pDestDoc, pMarks );
    1877             : 
    1878           0 :         sc::CopyToDocContext aCxt(*pDestDoc);
    1879             :         OSL_ASSERT( nTab2 < static_cast<SCTAB>(maTabs.size()) && nTab2 < static_cast<SCTAB>(pDestDoc->maTabs.size()));
    1880           0 :         for (SCTAB i = nTab1; i <= nTab2; i++)
    1881             :         {
    1882           0 :             if (maTabs[i] && pDestDoc->maTabs[i])
    1883           0 :                 maTabs[i]->UndoToTable(aCxt, nCol1, nRow1, nCol2, nRow2, nFlags,
    1884           0 :                                     bOnlyMarked, pDestDoc->maTabs[i], pMarks);
    1885             :         }
    1886             : 
    1887           0 :         if (nTab2 < MAXTAB)
    1888           0 :             CopyToDocument( 0,0,nTab2+1, MAXCOL,MAXROW,MAXTAB, IDF_FORMULA, false, pDestDoc, pMarks );
    1889           0 :         pDestDoc->SetAutoCalc( bOldAutoCalc );
    1890             :     }
    1891           0 : }
    1892             : 
    1893             : 
    1894         644 : void ScDocument::CopyToDocument(const ScRange& rRange,
    1895             :                             sal_uInt16 nFlags, bool bOnlyMarked, ScDocument* pDestDoc,
    1896             :                             const ScMarkData* pMarks, bool bColRowFlags)
    1897             : {
    1898         644 :     ScRange aNewRange = rRange;
    1899         644 :     aNewRange.Justify();
    1900             : 
    1901         644 :     if( pDestDoc->aDocName.isEmpty() )
    1902         644 :         pDestDoc->aDocName = aDocName;
    1903         644 :     bool bOldAutoCalc = pDestDoc->GetAutoCalc();
    1904         644 :     pDestDoc->SetAutoCalc( false );     // avoid multiple calculations
    1905         644 :     sc::CopyToDocContext aCxt(*pDestDoc);
    1906         644 :     SCTAB nMinSizeBothTabs = static_cast<SCTAB>(std::min(maTabs.size(), pDestDoc->maTabs.size()));
    1907        1281 :     for (SCTAB i = aNewRange.aStart.Tab(); i <= aNewRange.aEnd.Tab() && i < nMinSizeBothTabs; i++)
    1908             :     {
    1909         637 :         if (!TableExists(i) || !pDestDoc->TableExists(i))
    1910           1 :             continue;
    1911             : 
    1912        1272 :         maTabs[i]->CopyToTable(aCxt, aNewRange.aStart.Col(), aNewRange.aStart.Row(),
    1913         636 :                                aNewRange.aEnd.Col(), aNewRange.aEnd.Row(),
    1914         636 :                                nFlags, bOnlyMarked, pDestDoc->maTabs[i],
    1915        3180 :                                pMarks, false, bColRowFlags);
    1916             :     }
    1917         644 :     pDestDoc->SetAutoCalc( bOldAutoCalc );
    1918         644 : }
    1919             : 
    1920             : 
    1921           2 : void ScDocument::UndoToDocument(const ScRange& rRange,
    1922             :                             sal_uInt16 nFlags, bool bOnlyMarked, ScDocument* pDestDoc,
    1923             :                             const ScMarkData* pMarks)
    1924             : {
    1925           2 :     sc::AutoCalcSwitch aAutoCalcSwitch(*this, false);
    1926             : 
    1927           2 :     ScRange aNewRange = rRange;
    1928           2 :     aNewRange.Justify();
    1929           2 :     SCTAB nTab1 = aNewRange.aStart.Tab();
    1930           2 :     SCTAB nTab2 = aNewRange.aEnd.Tab();
    1931             : 
    1932           4 :     sc::CopyToDocContext aCxt(*pDestDoc);
    1933           2 :     if (nTab1 > 0)
    1934           2 :         CopyToDocument( 0,0,0, MAXCOL,MAXROW,nTab1-1, IDF_FORMULA, false, pDestDoc, pMarks );
    1935             : 
    1936           2 :     SCTAB nMinSizeBothTabs = static_cast<SCTAB>(std::min(maTabs.size(), pDestDoc->maTabs.size()));
    1937           4 :     for (SCTAB i = nTab1; i <= nTab2 && i < nMinSizeBothTabs; i++)
    1938             :     {
    1939           2 :         if (maTabs[i] && pDestDoc->maTabs[i])
    1940           4 :             maTabs[i]->UndoToTable(aCxt, aNewRange.aStart.Col(), aNewRange.aStart.Row(),
    1941           2 :                                     aNewRange.aEnd.Col(), aNewRange.aEnd.Row(),
    1942           8 :                                     nFlags, bOnlyMarked, pDestDoc->maTabs[i], pMarks);
    1943             :     }
    1944             : 
    1945           2 :     if (nTab2 < static_cast<SCTAB>(maTabs.size()))
    1946           4 :         CopyToDocument( 0,0,nTab2+1, MAXCOL,MAXROW,maTabs.size(), IDF_FORMULA, false, pDestDoc, pMarks );
    1947           2 : }
    1948             : 
    1949             : // bUseRangeForVBA added for VBA api support to allow content of a specified
    1950             : // range to be copied ( e.g. don't use marked data but the just the range
    1951             : // specified by rClipParam
    1952          20 : void ScDocument::CopyToClip(const ScClipParam& rClipParam,
    1953             :                             ScDocument* pClipDoc, const ScMarkData* pMarks,
    1954             :                             bool bAllTabs, bool bKeepScenarioFlags, bool bIncludeObjects, bool bCloneNoteCaptions, bool bUseRangeForVBA )
    1955             : {
    1956             :     OSL_ENSURE( !bUseRangeForVBA && ( bAllTabs ||  pMarks ), "CopyToClip: ScMarkData fails" );
    1957             : 
    1958          20 :     if (bIsClip)
    1959          20 :         return;
    1960             : 
    1961          20 :     if (!pClipDoc)
    1962             :     {
    1963             :         OSL_TRACE("CopyToClip: no ClipDoc");
    1964           0 :         pClipDoc = SC_MOD()->GetClipDoc();
    1965             :     }
    1966             : 
    1967          20 :     if (pShell->GetMedium())
    1968             :     {
    1969          20 :         pClipDoc->maFileURL = pShell->GetMedium()->GetURLObject().GetMainURL(INetURLObject::DECODE_TO_IURI);
    1970             :         // for unsaved files use the title name and adjust during save of file
    1971          20 :         if (pClipDoc->maFileURL.isEmpty())
    1972           2 :             pClipDoc->maFileURL = pShell->GetName();
    1973             :     }
    1974             :     else
    1975             :     {
    1976           0 :         pClipDoc->maFileURL = pShell->GetName();
    1977             :     }
    1978             : 
    1979             :     //init maTabNames
    1980          75 :     for (TableContainer::iterator itr = maTabs.begin(); itr != maTabs.end(); ++itr)
    1981             :     {
    1982          55 :         if( *itr )
    1983             :         {
    1984          55 :             OUString aTabName;
    1985          55 :             (*itr)->GetName(aTabName);
    1986          55 :             pClipDoc->maTabNames.push_back(aTabName);
    1987             :         }
    1988             :         else
    1989           0 :             pClipDoc->maTabNames.push_back(OUString());
    1990             :     }
    1991             : 
    1992          20 :     pClipDoc->aDocName = aDocName;
    1993          20 :     pClipDoc->SetClipParam(rClipParam);
    1994          20 :     ScRange aClipRange = rClipParam.getWholeRange();
    1995          20 :     SCTAB nTab = aClipRange.aStart.Tab();
    1996          20 :     SCTAB i = 0;
    1997          20 :     SCTAB nEndTab =  static_cast<SCTAB>(maTabs.size());
    1998             : 
    1999          20 :     if ( bUseRangeForVBA )
    2000             :     {
    2001           0 :         pClipDoc->ResetClip( this, nTab );
    2002           0 :         i = nTab;
    2003           0 :         nEndTab = nTab + 1;
    2004             :     }
    2005             :     else
    2006          20 :         pClipDoc->ResetClip(this, pMarks);
    2007             : 
    2008          20 :     sc::CopyToClipContext aCxt(*pClipDoc, bKeepScenarioFlags, bCloneNoteCaptions);
    2009          20 :     CopyRangeNamesToClip(pClipDoc, aClipRange, pMarks, bAllTabs);
    2010             : 
    2011          75 :     for ( ; i < nEndTab; ++i)
    2012             :     {
    2013          55 :         if (!maTabs[i] || i >= static_cast<SCTAB>(pClipDoc->maTabs.size()) || !pClipDoc->maTabs[i])
    2014          36 :             continue;
    2015             : 
    2016          19 :         if ( !bUseRangeForVBA && ( pMarks && !pMarks->GetTableSelect(i) ) )
    2017           0 :             continue;
    2018             : 
    2019          19 :         maTabs[i]->CopyToClip(aCxt, rClipParam.maRanges, pClipDoc->maTabs[i]);
    2020             : 
    2021          19 :         if (pDrawLayer && bIncludeObjects)
    2022             :         {
    2023             :             //  also copy drawing objects
    2024             :             Rectangle aObjRect = GetMMRect(
    2025          13 :                 aClipRange.aStart.Col(), aClipRange.aStart.Row(), aClipRange.aEnd.Col(), aClipRange.aEnd.Row(), i);
    2026          13 :             pDrawLayer->CopyToClip(pClipDoc, i, aObjRect);
    2027             :         }
    2028             :     }
    2029             : 
    2030             :     // Make sure to mark overlapped cells.
    2031          20 :     pClipDoc->ExtendMerge(aClipRange, true);
    2032             : }
    2033             : 
    2034           3 : void ScDocument::CopyStaticToDocument(const ScRange& rSrcRange, SCTAB nDestTab, ScDocument* pDestDoc)
    2035             : {
    2036           3 :     if (!pDestDoc)
    2037           0 :         return;
    2038             : 
    2039           3 :     ScTable* pSrcTab = rSrcRange.aStart.Tab() < static_cast<SCTAB>(maTabs.size()) ? maTabs[rSrcRange.aStart.Tab()] : NULL;
    2040           3 :     ScTable* pDestTab = nDestTab < static_cast<SCTAB>(pDestDoc->maTabs.size()) ? pDestDoc->maTabs[nDestTab] : NULL;
    2041             : 
    2042           3 :     if (!pSrcTab || !pDestTab)
    2043           0 :         return;
    2044             : 
    2045             :     pSrcTab->CopyStaticToDocument(
    2046           3 :         rSrcRange.aStart.Col(), rSrcRange.aStart.Row(), rSrcRange.aEnd.Col(), rSrcRange.aEnd.Row(), pDestTab);
    2047             : }
    2048             : 
    2049           0 : void ScDocument::CopyCellToDocument( const ScAddress& rSrcPos, const ScAddress& rDestPos, ScDocument& rDestDoc )
    2050             : {
    2051           0 :     if (!TableExists(rSrcPos.Tab()) || !rDestDoc.TableExists(rDestPos.Tab()))
    2052           0 :         return;
    2053             : 
    2054           0 :     ScTable& rSrcTab = *maTabs[rSrcPos.Tab()];
    2055           0 :     ScTable& rDestTab = *rDestDoc.maTabs[rDestPos.Tab()];
    2056             : 
    2057           0 :     rSrcTab.CopyCellToDocument(rSrcPos.Col(), rSrcPos.Row(), rDestPos.Col(), rDestPos.Row(), rDestTab);
    2058             : }
    2059             : 
    2060           0 : void ScDocument::CopyTabToClip(SCCOL nCol1, SCROW nRow1,
    2061             :                                 SCCOL nCol2, SCROW nRow2,
    2062             :                                 SCTAB nTab, ScDocument* pClipDoc)
    2063             : {
    2064           0 :     if (!bIsClip)
    2065             :     {
    2066           0 :         if (pShell->GetMedium())
    2067             :         {
    2068           0 :             pClipDoc->maFileURL = pShell->GetMedium()->GetURLObject().GetMainURL(INetURLObject::DECODE_TO_IURI);
    2069             :             // for unsaved files use the title name and adjust during save of file
    2070           0 :             if (pClipDoc->maFileURL.isEmpty())
    2071           0 :                 pClipDoc->maFileURL = pShell->GetName();
    2072             :         }
    2073             :         else
    2074             :         {
    2075           0 :             pClipDoc->maFileURL = pShell->GetName();
    2076             :         }
    2077             : 
    2078             :         //init maTabNames
    2079           0 :         for (TableContainer::iterator itr = maTabs.begin(); itr != maTabs.end(); ++itr)
    2080             :         {
    2081           0 :             if( *itr )
    2082             :             {
    2083           0 :                 OUString aTabName;
    2084           0 :                 (*itr)->GetName(aTabName);
    2085           0 :                 pClipDoc->maTabNames.push_back(aTabName);
    2086             :             }
    2087             :             else
    2088           0 :                 pClipDoc->maTabNames.push_back(OUString());
    2089             :         }
    2090             : 
    2091           0 :         PutInOrder( nCol1, nCol2 );
    2092           0 :         PutInOrder( nRow1, nRow2 );
    2093           0 :         if (!pClipDoc)
    2094             :         {
    2095             :             OSL_TRACE("CopyTabToClip: no ClipDoc");
    2096           0 :             pClipDoc = SC_MOD()->GetClipDoc();
    2097             :         }
    2098             : 
    2099           0 :         ScClipParam& rClipParam = pClipDoc->GetClipParam();
    2100           0 :         pClipDoc->aDocName = aDocName;
    2101           0 :         rClipParam.maRanges.RemoveAll();
    2102           0 :         rClipParam.maRanges.Append(ScRange(nCol1, nRow1, 0, nCol2, nRow2, 0));
    2103           0 :         pClipDoc->ResetClip( this, nTab );
    2104             : 
    2105           0 :         sc::CopyToClipContext aCxt(*pClipDoc, false, true);
    2106           0 :         if (nTab < static_cast<SCTAB>(maTabs.size()) && nTab < static_cast<SCTAB>(pClipDoc->maTabs.size()))
    2107           0 :             if (maTabs[nTab] && pClipDoc->maTabs[nTab])
    2108           0 :                 maTabs[nTab]->CopyToClip(aCxt, nCol1, nRow1, nCol2, nRow2, pClipDoc->maTabs[nTab]);
    2109             : 
    2110           0 :         pClipDoc->GetClipParam().mbCutMode = false;
    2111             :     }
    2112           0 : }
    2113             : 
    2114             : 
    2115           0 : void ScDocument::TransposeClip( ScDocument* pTransClip, sal_uInt16 nFlags, bool bAsLink )
    2116             : {
    2117             :     OSL_ENSURE( bIsClip && pTransClip && pTransClip->bIsClip,
    2118             :                     "TransposeClip with wrong Document" );
    2119             : 
    2120             :         //  initialisieren
    2121             :         //  -> pTransClip muss vor dem Original-Dokument geloescht werden!
    2122             : 
    2123           0 :     pTransClip->ResetClip(this, (ScMarkData*)NULL);     // alle
    2124             : 
    2125             :         //  Bereiche uebernehmen
    2126             : 
    2127           0 :     if (pRangeName)
    2128             :     {
    2129           0 :         pTransClip->GetRangeName()->clear();
    2130           0 :         ScRangeName::const_iterator itr = pRangeName->begin(), itrEnd = pRangeName->end();
    2131           0 :         for (; itr != itrEnd; ++itr)
    2132             :         {
    2133           0 :             sal_uInt16 nIndex = itr->second->GetIndex();
    2134           0 :             ScRangeData* pData = new ScRangeData(*itr->second);
    2135           0 :             if (pTransClip->pRangeName->insert(pData))
    2136           0 :                 pData->SetIndex(nIndex);
    2137             :         }
    2138             :     }
    2139             : 
    2140             :     // The data
    2141             : 
    2142           0 :     ScRange aClipRange = GetClipParam().getWholeRange();
    2143           0 :     if ( ValidRow(aClipRange.aEnd.Row()-aClipRange.aStart.Row()) )
    2144             :     {
    2145           0 :         for (SCTAB i=0; i< static_cast<SCTAB>(maTabs.size()); i++)
    2146           0 :             if (maTabs[i])
    2147             :             {
    2148             :                 OSL_ENSURE( pTransClip->maTabs[i], "TransposeClip: Table not there" );
    2149           0 :                 maTabs[i]->TransposeClip( aClipRange.aStart.Col(), aClipRange.aStart.Row(),
    2150           0 :                                             aClipRange.aEnd.Col(), aClipRange.aEnd.Row(),
    2151           0 :                                             pTransClip->maTabs[i], nFlags, bAsLink );
    2152             : 
    2153           0 :                 if ( pDrawLayer && ( nFlags & IDF_OBJECTS ) )
    2154             :                 {
    2155             :                     //  Drawing objects are copied to the new area without transposing.
    2156             :                     //  CopyFromClip is used to adjust the objects to the transposed block's
    2157             :                     //  cell range area.
    2158             :                     //  (pDrawLayer in the original clipboard document is set only if there
    2159             :                     //  are drawing objects to copy)
    2160             : 
    2161           0 :                     pTransClip->InitDrawLayer();
    2162           0 :                     Rectangle aSourceRect = GetMMRect( aClipRange.aStart.Col(), aClipRange.aStart.Row(),
    2163           0 :                                                         aClipRange.aEnd.Col(), aClipRange.aEnd.Row(), i );
    2164             :                     Rectangle aDestRect = pTransClip->GetMMRect( 0, 0,
    2165           0 :                             static_cast<SCCOL>(aClipRange.aEnd.Row() - aClipRange.aStart.Row()),
    2166           0 :                             static_cast<SCROW>(aClipRange.aEnd.Col() - aClipRange.aStart.Col()), i );
    2167           0 :                     pTransClip->pDrawLayer->CopyFromClip( pDrawLayer, i, aSourceRect, ScAddress(0,0,i), aDestRect );
    2168             :                 }
    2169             :             }
    2170             : 
    2171           0 :         pTransClip->SetClipParam(GetClipParam());
    2172           0 :         pTransClip->GetClipParam().transpose();
    2173             :     }
    2174             :     else
    2175             :     {
    2176             :         OSL_TRACE("TransposeClip: Too big");
    2177             :     }
    2178             : 
    2179             :         //  Dies passiert erst beim Einfuegen...
    2180             : 
    2181           0 :     GetClipParam().mbCutMode = false;
    2182           0 : }
    2183             : 
    2184             : namespace {
    2185             : 
    2186           2 : void copyUsedNamesToClip(ScRangeName* pClipRangeName, ScRangeName* pRangeName, const std::set<sal_uInt16>& rUsedNames)
    2187             : {
    2188           2 :     pClipRangeName->clear();
    2189           2 :     ScRangeName::const_iterator itr = pRangeName->begin(), itrEnd = pRangeName->end();
    2190           5 :     for (; itr != itrEnd; ++itr)        //! DB-Bereiche Pivot-Bereiche auch !!!
    2191             :     {
    2192           3 :         sal_uInt16 nIndex = itr->second->GetIndex();
    2193           3 :         bool bInUse = (rUsedNames.count(nIndex) > 0);
    2194           3 :         if (!bInUse)
    2195           2 :             continue;
    2196             : 
    2197           1 :         ScRangeData* pData = new ScRangeData(*itr->second);
    2198           1 :         if (pClipRangeName->insert(pData))
    2199           1 :             pData->SetIndex(nIndex);
    2200             :     }
    2201           2 : }
    2202             : 
    2203             : }
    2204             : 
    2205          20 : void ScDocument::CopyRangeNamesToClip(ScDocument* pClipDoc, const ScRange& rClipRange, const ScMarkData* pMarks, bool bAllTabs)
    2206             : {
    2207          20 :     if (!pRangeName || pRangeName->empty())
    2208          38 :         return;
    2209             : 
    2210           2 :     std::set<sal_uInt16> aUsedNames;        // indexes of named ranges that are used in the copied cells
    2211           2 :     SCTAB nMinSizeBothTabs = static_cast<SCTAB>(std::min(maTabs.size(), pClipDoc->maTabs.size()));
    2212           4 :     for (SCTAB i = 0; i < nMinSizeBothTabs; ++i)
    2213           2 :         if (maTabs[i] && pClipDoc->maTabs[i])
    2214           2 :             if ( bAllTabs || !pMarks || pMarks->GetTableSelect(i) )
    2215           2 :                 maTabs[i]->FindRangeNamesInUse(
    2216           2 :                     rClipRange.aStart.Col(), rClipRange.aStart.Row(),
    2217           6 :                     rClipRange.aEnd.Col(), rClipRange.aEnd.Row(), aUsedNames);
    2218             : 
    2219           2 :     copyUsedNamesToClip(pClipDoc->GetRangeName(), pRangeName, aUsedNames);
    2220             : }
    2221             : 
    2222          43 : ScDocument::NumFmtMergeHandler::NumFmtMergeHandler(ScDocument* pDoc, ScDocument* pSrcDoc) :
    2223          43 :         mpDoc(pDoc)
    2224             : {
    2225          43 :     mpDoc->MergeNumberFormatter(pSrcDoc);
    2226          43 : }
    2227             : 
    2228          43 : ScDocument::NumFmtMergeHandler::~NumFmtMergeHandler()
    2229             : {
    2230          43 :     mpDoc->pFormatExchangeList = NULL;
    2231          43 : }
    2232             : 
    2233       45997 : SvtBroadcaster* ScDocument::GetBroadcaster( const ScAddress& rPos )
    2234             : {
    2235       45997 :     ScTable* pTab = FetchTable(rPos.Tab());
    2236       45997 :     if (!pTab)
    2237           0 :         return NULL;
    2238             : 
    2239       45997 :     return pTab->GetBroadcaster(rPos.Col(), rPos.Row());
    2240             : }
    2241             : 
    2242          14 : const SvtBroadcaster* ScDocument::GetBroadcaster( const ScAddress& rPos ) const
    2243             : {
    2244          14 :     const ScTable* pTab = FetchTable(rPos.Tab());
    2245          14 :     if (!pTab)
    2246           0 :         return NULL;
    2247             : 
    2248          14 :     return pTab->GetBroadcaster(rPos.Col(), rPos.Row());
    2249             : }
    2250             : 
    2251          16 : void ScDocument::DeleteBroadcasters( sc::ColumnBlockPosition& rBlockPos, const ScAddress& rTopPos, SCROW nLength )
    2252             : {
    2253          16 :     ScTable* pTab = FetchTable(rTopPos.Tab());
    2254          16 :     if (!pTab || nLength <= 0)
    2255          16 :         return;
    2256             : 
    2257          16 :     pTab->DeleteBroadcasters(rBlockPos, rTopPos.Col(), rTopPos.Row(), rTopPos.Row()+nLength-1);
    2258             : }
    2259             : 
    2260           0 : bool ScDocument::HasBroadcaster( SCTAB nTab, SCCOL nCol ) const
    2261             : {
    2262           0 :     const ScTable* pTab = FetchTable(nTab);
    2263           0 :     if (!pTab)
    2264           0 :         return false;
    2265             : 
    2266           0 :     return pTab->HasBroadcaster(nCol);
    2267             : }
    2268             : 
    2269             : #if DEBUG_COLUMN_STORAGE
    2270             : void ScDocument::DumpFormulaGroups( SCTAB nTab, SCCOL nCol ) const
    2271             : {
    2272             :     const ScTable* pTab = FetchTable(nTab);
    2273             :     if (!pTab)
    2274             :         return;
    2275             : 
    2276             :     pTab->DumpFormulaGroups(nCol);
    2277             : }
    2278             : #endif
    2279             : 
    2280      271519 : bool ScDocument::TableExists( SCTAB nTab ) const
    2281             : {
    2282      271519 :     return ValidTab(nTab) && static_cast<size_t>(nTab) < maTabs.size() && maTabs[nTab];
    2283             : }
    2284             : 
    2285       48555 : ScTable* ScDocument::FetchTable( SCTAB nTab )
    2286             : {
    2287       48555 :     if (!TableExists(nTab))
    2288           0 :         return NULL;
    2289             : 
    2290       48555 :     return maTabs[nTab];
    2291             : }
    2292             : 
    2293          40 : const ScTable* ScDocument::FetchTable( SCTAB nTab ) const
    2294             : {
    2295          40 :     if (!TableExists(nTab))
    2296           0 :         return NULL;
    2297             : 
    2298          40 :     return maTabs[nTab];
    2299             : }
    2300             : 
    2301          43 : void ScDocument::MergeNumberFormatter(ScDocument* pSrcDoc)
    2302             : {
    2303          43 :     SvNumberFormatter* pThisFormatter = xPoolHelper->GetFormTable();
    2304          43 :     SvNumberFormatter* pOtherFormatter = pSrcDoc->xPoolHelper->GetFormTable();
    2305          43 :     if (pOtherFormatter && pOtherFormatter != pThisFormatter)
    2306             :     {
    2307             :         SvNumberFormatterIndexTable* pExchangeList =
    2308           7 :                  pThisFormatter->MergeFormatter(*(pOtherFormatter));
    2309           7 :         if (!pExchangeList->empty())
    2310           5 :             pFormatExchangeList = pExchangeList;
    2311             :     }
    2312          43 : }
    2313             : 
    2314         397 : ScClipParam& ScDocument::GetClipParam()
    2315             : {
    2316         397 :     if (!mpClipParam.get())
    2317          19 :         mpClipParam.reset(new ScClipParam);
    2318             : 
    2319         397 :     return *mpClipParam;
    2320             : }
    2321             : 
    2322          21 : void ScDocument::SetClipParam(const ScClipParam& rParam)
    2323             : {
    2324          21 :     mpClipParam.reset(new ScClipParam(rParam));
    2325          21 : }
    2326             : 
    2327         809 : bool ScDocument::IsClipboardSource() const
    2328             : {
    2329         809 :     ScDocument* pClipDoc = SC_MOD()->GetClipDoc();
    2330         809 :     return pClipDoc && pClipDoc->xPoolHelper.is() &&
    2331         809 :             xPoolHelper->GetDocPool() == pClipDoc->xPoolHelper->GetDocPool();
    2332             : }
    2333             : 
    2334             : 
    2335          40 : void ScDocument::StartListeningFromClip( SCCOL nCol1, SCROW nRow1,
    2336             :                                         SCCOL nCol2, SCROW nRow2,
    2337             :                                         const ScMarkData& rMark, sal_uInt16 nInsFlag )
    2338             : {
    2339          40 :     if (nInsFlag & IDF_CONTENTS)
    2340             :     {
    2341          24 :         sc::StartListeningContext aCxt(*this);
    2342          24 :         SCTAB nMax = static_cast<SCTAB>(maTabs.size());
    2343          24 :         ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
    2344          45 :         for (; itr != itrEnd && *itr < nMax; ++itr)
    2345          21 :             if (maTabs[*itr])
    2346          45 :                 maTabs[*itr]->StartListeningInArea(aCxt, nCol1, nRow1, nCol2, nRow2);
    2347             :     }
    2348          40 : }
    2349             : 
    2350             : 
    2351          40 : void ScDocument::BroadcastFromClip( SCCOL nCol1, SCROW nRow1,
    2352             :                                     SCCOL nCol2, SCROW nRow2,
    2353             :                                     const ScMarkData& rMark, sal_uInt16 nInsFlag )
    2354             : {
    2355          40 :     if (nInsFlag & IDF_CONTENTS)
    2356             :     {
    2357          24 :         ScBulkBroadcast aBulkBroadcast( GetBASM());
    2358          24 :         SCTAB nMax = static_cast<SCTAB>(maTabs.size());
    2359          24 :         ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
    2360          45 :         for (; itr != itrEnd && *itr < nMax; ++itr)
    2361          21 :             if (maTabs[*itr])
    2362          45 :                 maTabs[*itr]->BroadcastInArea( nCol1, nRow1, nCol2, nRow2 );
    2363             :     }
    2364          40 : }
    2365             : 
    2366       80167 : bool ScDocument::InitColumnBlockPosition( sc::ColumnBlockPosition& rBlockPos, SCTAB nTab, SCCOL nCol )
    2367             : {
    2368       80167 :     if (!TableExists(nTab))
    2369           0 :         return false;
    2370             : 
    2371       80167 :     return maTabs[nTab]->InitColumnBlockPosition(rBlockPos, nCol);
    2372             : }
    2373             : 
    2374          40 : void ScDocument::CopyBlockFromClip(
    2375             :     sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
    2376             :     const ScMarkData& rMark, SCsCOL nDx, SCsROW nDy )
    2377             : {
    2378          40 :     TableContainer& rClipTabs = rCxt.getClipDoc()->maTabs;
    2379          40 :     SCTAB nTabEnd = rCxt.getTabEnd();
    2380          40 :     SCTAB nClipTab = 0;
    2381          77 :     for (SCTAB i = rCxt.getTabStart(); i <= nTabEnd && i < static_cast<SCTAB>(maTabs.size()); i++)
    2382             :     {
    2383          37 :         if (maTabs[i] && rMark.GetTableSelect(i) )
    2384             :         {
    2385          37 :             while (!rClipTabs[nClipTab]) nClipTab = (nClipTab+1) % (static_cast<SCTAB>(rClipTabs.size()));
    2386             : 
    2387          37 :             maTabs[i]->CopyFromClip(
    2388          74 :                 rCxt, nCol1, nRow1, nCol2, nRow2, nDx, nDy, rClipTabs[nClipTab]);
    2389             : 
    2390          37 :             if (rCxt.getClipDoc()->pDrawLayer && (rCxt.getInsertFlag() & IDF_OBJECTS))
    2391             :             {
    2392             :                 //  also copy drawing objects
    2393             : 
    2394             :                 // drawing layer must be created before calling CopyFromClip
    2395             :                 // (ScDocShell::MakeDrawLayer also does InitItems etc.)
    2396             :                 OSL_ENSURE( pDrawLayer, "CopyBlockFromClip: No drawing layer" );
    2397           0 :                 if ( pDrawLayer )
    2398             :                 {
    2399             :                     //  For GetMMRect, the row heights in the target document must already be valid
    2400             :                     //  (copied in an extra step before pasting, or updated after pasting cells, but
    2401             :                     //  before pasting objects).
    2402             : 
    2403             :                     Rectangle aSourceRect = rCxt.getClipDoc()->GetMMRect(
    2404           0 :                                     nCol1-nDx, nRow1-nDy, nCol2-nDx, nRow2-nDy, nClipTab );
    2405           0 :                     Rectangle aDestRect = GetMMRect( nCol1, nRow1, nCol2, nRow2, i );
    2406           0 :                     pDrawLayer->CopyFromClip(rCxt.getClipDoc()->pDrawLayer, nClipTab, aSourceRect,
    2407           0 :                                                 ScAddress( nCol1, nRow1, i ), aDestRect );
    2408             :                 }
    2409             :             }
    2410             : 
    2411          37 :             nClipTab = (nClipTab+1) % (static_cast<SCTAB>(rClipTabs.size()));
    2412             :         }
    2413             :     }
    2414          40 :     if (rCxt.getInsertFlag() & IDF_CONTENTS)
    2415             :     {
    2416          24 :         nClipTab = 0;
    2417          45 :         for (SCTAB i = rCxt.getTabStart(); i <= nTabEnd && i < static_cast<SCTAB>(maTabs.size()); i++)
    2418             :         {
    2419          21 :             if (maTabs[i] && rMark.GetTableSelect(i) )
    2420             :             {
    2421          21 :                 while (!rClipTabs[nClipTab]) nClipTab = (nClipTab+1) % (static_cast<SCTAB>(rClipTabs.size()));
    2422          21 :                 SCsTAB nDz = ((SCsTAB)i) - nClipTab;
    2423             : 
    2424             :                 //  ranges of consecutive selected tables (in clipboard and dest. doc)
    2425             :                 //  must be handled in one UpdateReference call
    2426          21 :                 SCTAB nFollow = 0;
    2427          63 :                 while ( i + nFollow < nTabEnd
    2428           0 :                         && rMark.GetTableSelect( i + nFollow + 1 )
    2429           0 :                         && nClipTab + nFollow < MAXTAB
    2430          21 :                         && rClipTabs[(nClipTab + nFollow + 1) % static_cast<SCTAB>(rClipTabs.size())] )
    2431           0 :                     ++nFollow;
    2432             : 
    2433          21 :                 if (rCxt.getClipDoc()->GetClipParam().mbCutMode)
    2434             :                 {
    2435           1 :                     bool bOldInserting = IsInsertingFromOtherDoc();
    2436           1 :                     SetInsertingFromOtherDoc( true);
    2437             :                     UpdateReference( URM_MOVE,
    2438             :                         nCol1, nRow1, i, nCol2, nRow2, i+nFollow,
    2439           1 :                         nDx, nDy, nDz, rCxt.getUndoDoc(), false );
    2440           1 :                     SetInsertingFromOtherDoc( bOldInserting);
    2441             :                 }
    2442             :                 else
    2443             :                     UpdateReference( URM_COPY,
    2444             :                         nCol1, nRow1, i, nCol2, nRow2, i+nFollow,
    2445          20 :                         nDx, nDy, nDz, rCxt.getUndoDoc(), false );
    2446             : 
    2447          21 :                 nClipTab = (nClipTab+nFollow+1) % (static_cast<SCTAB>(rClipTabs.size()));
    2448          21 :                 i = sal::static_int_cast<SCTAB>( i + nFollow );
    2449             :             }
    2450             :         }
    2451             :     }
    2452          40 : }
    2453             : 
    2454             : 
    2455          34 : void ScDocument::CopyNonFilteredFromClip(
    2456             :     sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
    2457             :     const ScMarkData& rMark, SCsCOL nDx, SCROW & rClipStartRow )
    2458             : {
    2459             :     //  call CopyBlockFromClip for ranges of consecutive non-filtered rows
    2460             :     //  nCol1/nRow1 etc. is in target doc
    2461             : 
    2462             :     //  filtered state is taken from first used table in clipboard (as in GetClipArea)
    2463          34 :     SCTAB nFlagTab = 0;
    2464          34 :     TableContainer& rClipTabs = rCxt.getClipDoc()->maTabs;
    2465          68 :     while ( nFlagTab < static_cast<SCTAB>(rClipTabs.size()) && !rClipTabs[nFlagTab] )
    2466           0 :         ++nFlagTab;
    2467             : 
    2468          34 :     SCROW nSourceRow = rClipStartRow;
    2469          34 :     SCROW nSourceEnd = 0;
    2470          34 :     if (!rCxt.getClipDoc()->GetClipParam().maRanges.empty())
    2471          34 :         nSourceEnd = rCxt.getClipDoc()->GetClipParam().maRanges.front()->aEnd.Row();
    2472          34 :     SCROW nDestRow = nRow1;
    2473             : 
    2474         102 :     while ( nSourceRow <= nSourceEnd && nDestRow <= nRow2 )
    2475             :     {
    2476             :         // skip filtered rows
    2477          34 :         nSourceRow = rCxt.getClipDoc()->FirstNonFilteredRow(nSourceRow, nSourceEnd, nFlagTab);
    2478             : 
    2479          34 :         if ( nSourceRow <= nSourceEnd )
    2480             :         {
    2481             :             // look for more non-filtered rows following
    2482          34 :             SCROW nLastRow = nSourceRow;
    2483          34 :             rCxt.getClipDoc()->RowFiltered(nSourceRow, nFlagTab, NULL, &nLastRow);
    2484          34 :             SCROW nFollow = nLastRow - nSourceRow;
    2485             : 
    2486          34 :             if (nFollow > nSourceEnd - nSourceRow)
    2487          34 :                 nFollow = nSourceEnd - nSourceRow;
    2488          34 :             if (nFollow > nRow2 - nDestRow)
    2489           0 :                 nFollow = nRow2 - nDestRow;
    2490             : 
    2491          34 :             SCsROW nNewDy = ((SCsROW)nDestRow) - nSourceRow;
    2492             :             CopyBlockFromClip(
    2493          34 :                 rCxt, nCol1, nDestRow, nCol2, nDestRow + nFollow, rMark, nDx, nNewDy);
    2494             : 
    2495          34 :             nSourceRow += nFollow + 1;
    2496          34 :             nDestRow += nFollow + 1;
    2497             :         }
    2498             :     }
    2499          34 :     rClipStartRow = nSourceRow;
    2500          34 : }
    2501             : 
    2502             : 
    2503          41 : void ScDocument::CopyFromClip( const ScRange& rDestRange, const ScMarkData& rMark,
    2504             :                                 sal_uInt16 nInsFlag,
    2505             :                                 ScDocument* pRefUndoDoc, ScDocument* pClipDoc, bool bResetCut,
    2506             :                                 bool bAsLink, bool bIncludeFiltered, bool bSkipAttrForEmpty,
    2507             :                                 const ScRangeList * pDestRanges )
    2508             : {
    2509          41 :     if (bIsClip)
    2510           1 :         return;
    2511             : 
    2512          41 :     if (!pClipDoc)
    2513             :     {
    2514             :         OSL_FAIL("CopyFromClip: no ClipDoc");
    2515           0 :         pClipDoc = SC_MOD()->GetClipDoc();
    2516             :     }
    2517             : 
    2518          41 :     if (!pClipDoc->bIsClip || !pClipDoc->GetTableCount())
    2519           1 :         return;
    2520             : 
    2521          40 :     bool bOldAutoCalc = GetAutoCalc();
    2522          40 :     SetAutoCalc( false );   // avoid multiple recalculations
    2523             : 
    2524          40 :     NumFmtMergeHandler aNumFmtMergeHdl(this, pClipDoc);
    2525             : 
    2526          40 :     SCCOL nAllCol1 = rDestRange.aStart.Col();
    2527          40 :     SCROW nAllRow1 = rDestRange.aStart.Row();
    2528          40 :     SCCOL nAllCol2 = rDestRange.aEnd.Col();
    2529          40 :     SCROW nAllRow2 = rDestRange.aEnd.Row();
    2530             : 
    2531          40 :     SCCOL nXw = 0;
    2532          40 :     SCROW nYw = 0;
    2533          40 :     ScRange aClipRange = pClipDoc->GetClipParam().getWholeRange();
    2534          80 :     for (SCTAB nTab = 0; nTab < static_cast<SCTAB>(pClipDoc->maTabs.size()); nTab++)    // find largest merge overlap
    2535          40 :         if (pClipDoc->maTabs[nTab])                   // all sheets of the clipboard content
    2536             :         {
    2537          40 :             SCCOL nThisEndX = aClipRange.aEnd.Col();
    2538          40 :             SCROW nThisEndY = aClipRange.aEnd.Row();
    2539          40 :             pClipDoc->ExtendMerge( aClipRange.aStart.Col(),
    2540             :                                     aClipRange.aStart.Row(),
    2541          80 :                                     nThisEndX, nThisEndY, nTab );
    2542             :             // only extra value from ExtendMerge
    2543          40 :             nThisEndX = sal::static_int_cast<SCCOL>( nThisEndX - aClipRange.aEnd.Col() );
    2544          40 :             nThisEndY = sal::static_int_cast<SCROW>( nThisEndY - aClipRange.aEnd.Row() );
    2545          40 :             if ( nThisEndX > nXw )
    2546           0 :                 nXw = nThisEndX;
    2547          40 :             if ( nThisEndY > nYw )
    2548           0 :                 nYw = nThisEndY;
    2549             :         }
    2550             : 
    2551             :     SCCOL nDestAddX;
    2552             :     SCROW nDestAddY;
    2553          40 :     pClipDoc->GetClipArea( nDestAddX, nDestAddY, bIncludeFiltered );
    2554          40 :     nXw = sal::static_int_cast<SCCOL>( nXw + nDestAddX );
    2555          40 :     nYw = sal::static_int_cast<SCROW>( nYw + nDestAddY );   // ClipArea, plus ExtendMerge value
    2556             : 
    2557             :     /*  Decide which contents to delete before copying. Delete all
    2558             :         contents if nInsFlag contains any real content flag.
    2559             :         #i102056# Notes are pasted from clipboard in a second pass,
    2560             :         together with the special flag IDF_ADDNOTES that states to not
    2561             :         overwrite/delete existing cells but to insert the notes into
    2562             :         these cells. In this case, just delete old notes from the
    2563             :         destination area. */
    2564          40 :     sal_uInt16 nDelFlag = IDF_NONE;
    2565          40 :     if ( (nInsFlag & (IDF_CONTENTS | IDF_ADDNOTES)) == (IDF_NOTE | IDF_ADDNOTES) )
    2566           0 :         nDelFlag |= IDF_NOTE;
    2567          40 :     else if ( nInsFlag & IDF_CONTENTS )
    2568          24 :         nDelFlag |= IDF_CONTENTS;
    2569             :     //  With bSkipAttrForEmpty, don't remove attributes, copy
    2570             :     //  on top of existing attributes instead.
    2571          40 :     if ( ( nInsFlag & IDF_ATTRIB ) && !bSkipAttrForEmpty )
    2572          24 :         nDelFlag |= IDF_ATTRIB;
    2573             : 
    2574          80 :     sc::CopyFromClipContext aCxt(*this, pRefUndoDoc, pClipDoc, nInsFlag, bAsLink, bSkipAttrForEmpty);
    2575          40 :     std::pair<SCTAB,SCTAB> aTabRanges = getMarkedTableRange(maTabs, rMark);
    2576          40 :     aCxt.setTabRange(aTabRanges.first, aTabRanges.second);
    2577             : 
    2578          80 :     ScRangeList aLocalRangeList;
    2579          40 :     if (!pDestRanges)
    2580             :     {
    2581          40 :         aLocalRangeList.Append( rDestRange);
    2582          40 :         pDestRanges = &aLocalRangeList;
    2583             :     }
    2584             : 
    2585          40 :     bInsertingFromOtherDoc = true;  // kein Broadcast/Listener aufbauen bei Insert
    2586             : 
    2587          40 :     SCCOL nClipStartCol = aClipRange.aStart.Col();
    2588          40 :     SCROW nClipStartRow = aClipRange.aStart.Row();
    2589          40 :     SCROW nClipEndRow = aClipRange.aEnd.Row();
    2590          80 :     for ( size_t nRange = 0; nRange < pDestRanges->size(); ++nRange )
    2591             :     {
    2592          40 :         const ScRange* pRange = (*pDestRanges)[nRange];
    2593          40 :         SCCOL nCol1 = pRange->aStart.Col();
    2594          40 :         SCROW nRow1 = pRange->aStart.Row();
    2595          40 :         SCCOL nCol2 = pRange->aEnd.Col();
    2596          40 :         SCROW nRow2 = pRange->aEnd.Row();
    2597             : 
    2598          40 :         DeleteArea(nCol1, nRow1, nCol2, nRow2, rMark, nDelFlag);
    2599             : 
    2600          40 :         SCCOL nC1 = nCol1;
    2601          40 :         SCROW nR1 = nRow1;
    2602          40 :         SCCOL nC2 = nC1 + nXw;
    2603          40 :         if (nC2 > nCol2)
    2604           0 :             nC2 = nCol2;
    2605          40 :         SCROW nR2 = nR1 + nYw;
    2606          40 :         if (nR2 > nRow2)
    2607           0 :             nR2 = nRow2;
    2608             : 
    2609          40 :         do
    2610             :         {
    2611             :             // Pasting is done column-wise, when pasting to a filtered
    2612             :             // area this results in partitioning and we have to
    2613             :             // remember and reset the start row for each column until
    2614             :             // it can be advanced for the next chunk of unfiltered
    2615             :             // rows.
    2616          40 :             SCROW nSaveClipStartRow = nClipStartRow;
    2617          40 :             do
    2618             :             {
    2619          40 :                 nClipStartRow = nSaveClipStartRow;
    2620          40 :                 SCsCOL nDx = ((SCsCOL)nC1) - nClipStartCol;
    2621          40 :                 SCsROW nDy = ((SCsROW)nR1) - nClipStartRow;
    2622          40 :                 if ( bIncludeFiltered )
    2623             :                 {
    2624             :                     CopyBlockFromClip(
    2625           6 :                         aCxt, nC1, nR1, nC2, nR2, rMark, nDx, nDy);
    2626           6 :                     nClipStartRow += nR2 - nR1 + 1;
    2627             :                 }
    2628             :                 else
    2629             :                 {
    2630             :                     CopyNonFilteredFromClip(
    2631          34 :                         aCxt, nC1, nR1, nC2, nR2, rMark, nDx, nClipStartRow);
    2632             :                 }
    2633          40 :                 nC1 = nC2 + 1;
    2634          40 :                 nC2 = std::min((SCCOL)(nC1 + nXw), nCol2);
    2635          40 :             } while (nC1 <= nCol2);
    2636          40 :             if (nClipStartRow > nClipEndRow)
    2637          40 :                 nClipStartRow = aClipRange.aStart.Row();
    2638          40 :             nC1 = nCol1;
    2639          40 :             nC2 = nC1 + nXw;
    2640          40 :             if (nC2 > nCol2)
    2641           0 :                 nC2 = nCol2;
    2642          40 :             nR1 = nR2 + 1;
    2643          40 :             nR2 = std::min((SCROW)(nR1 + nYw), nRow2);
    2644          40 :         } while (nR1 <= nRow2);
    2645             :     }
    2646             : 
    2647          40 :     bInsertingFromOtherDoc = false;
    2648             : 
    2649             :     // Listener aufbauen nachdem alles inserted wurde
    2650          40 :     StartListeningFromClip( nAllCol1, nAllRow1, nAllCol2, nAllRow2, rMark, nInsFlag );
    2651             :     // nachdem alle Listener aufgebaut wurden, kann gebroadcastet werden
    2652          40 :     BroadcastFromClip( nAllCol1, nAllRow1, nAllCol2, nAllRow2, rMark, nInsFlag );
    2653          40 :     if (bResetCut)
    2654          37 :         pClipDoc->GetClipParam().mbCutMode = false;
    2655          80 :     SetAutoCalc( bOldAutoCalc );
    2656             : }
    2657             : 
    2658           0 : static SCROW lcl_getLastNonFilteredRow(
    2659             :     const ScBitMaskCompressedArray<SCROW, sal_uInt8>& rFlags, SCROW nBegRow, SCROW nEndRow,
    2660             :     SCROW nRowCount)
    2661             : {
    2662             :     SCROW nFilteredRow = rFlags.GetFirstForCondition(
    2663           0 :         nBegRow, nEndRow, CR_FILTERED, CR_FILTERED);
    2664             : 
    2665           0 :     SCROW nRow = nFilteredRow - 1;
    2666           0 :     if (nRow - nBegRow + 1 > nRowCount)
    2667             :         // make sure the row range stays within the data size.
    2668           0 :         nRow = nBegRow + nRowCount - 1;
    2669             : 
    2670           0 :     return nRow;
    2671             : }
    2672             : 
    2673           0 : void ScDocument::CopyMultiRangeFromClip(
    2674             :     const ScAddress& rDestPos, const ScMarkData& rMark, sal_uInt16 nInsFlag, ScDocument* pClipDoc,
    2675             :     bool bResetCut, bool bAsLink, bool /*bIncludeFiltered*/, bool bSkipAttrForEmpty)
    2676             : {
    2677           0 :     if (bIsClip)
    2678           0 :         return;
    2679             : 
    2680           0 :     if (!pClipDoc->bIsClip || !pClipDoc->GetTableCount())
    2681             :         // There is nothing in the clip doc to copy.
    2682           0 :         return;
    2683             : 
    2684           0 :     bool bOldAutoCalc = GetAutoCalc();
    2685           0 :     SetAutoCalc( false );   // avoid multiple recalculations
    2686             : 
    2687           0 :     NumFmtMergeHandler aNumFmtMergeHdl(this, pClipDoc);
    2688             : 
    2689           0 :     SCCOL nCol1 = rDestPos.Col();
    2690           0 :     SCROW nRow1 = rDestPos.Row();
    2691           0 :     ScClipParam& rClipParam = pClipDoc->GetClipParam();
    2692             : 
    2693           0 :     sc::CopyFromClipContext aCxt(*this, NULL, pClipDoc, nInsFlag, bAsLink, bSkipAttrForEmpty);
    2694           0 :     std::pair<SCTAB,SCTAB> aTabRanges = getMarkedTableRange(maTabs, rMark);
    2695           0 :     aCxt.setTabRange(aTabRanges.first, aTabRanges.second);
    2696             : 
    2697           0 :     ScRange aDestRange;
    2698           0 :     rMark.GetMarkArea(aDestRange);
    2699           0 :     SCROW nLastMarkedRow = aDestRange.aEnd.Row();
    2700             : 
    2701           0 :     bInsertingFromOtherDoc = true;  // kein Broadcast/Listener aufbauen bei Insert
    2702             : 
    2703           0 :     SCROW nBegRow = nRow1;
    2704           0 :     sal_uInt16 nDelFlag = IDF_CONTENTS;
    2705           0 :     const ScBitMaskCompressedArray<SCROW, sal_uInt8>& rFlags = GetRowFlagsArray(aCxt.getTabStart());
    2706             : 
    2707           0 :     for ( size_t i = 0, n = rClipParam.maRanges.size(); i < n; ++i )
    2708             :     {
    2709           0 :         ScRange* p = rClipParam.maRanges[ i ];
    2710             :         // The begin row must not be filtered.
    2711             : 
    2712           0 :         SCROW nRowCount = p->aEnd.Row() - p->aStart.Row() + 1;
    2713             : 
    2714           0 :         SCsCOL nDx = static_cast<SCsCOL>(nCol1 - p->aStart.Col());
    2715           0 :         SCsROW nDy = static_cast<SCsROW>(nBegRow - p->aStart.Row());
    2716           0 :         SCCOL nCol2 = nCol1 + p->aEnd.Col() - p->aStart.Col();
    2717             : 
    2718           0 :         SCROW nEndRow = lcl_getLastNonFilteredRow(rFlags, nBegRow, nLastMarkedRow, nRowCount);
    2719             : 
    2720           0 :         if (!bSkipAttrForEmpty)
    2721           0 :             DeleteArea(nCol1, nBegRow, nCol2, nEndRow, rMark, nDelFlag);
    2722             : 
    2723           0 :         CopyBlockFromClip(aCxt, nCol1, nBegRow, nCol2, nEndRow, rMark, nDx, nDy);
    2724           0 :         nRowCount -= nEndRow - nBegRow + 1;
    2725             : 
    2726           0 :         while (nRowCount > 0)
    2727             :         {
    2728             :             // Get the first non-filtered row.
    2729           0 :             SCROW nNonFilteredRow = rFlags.GetFirstForCondition(nEndRow+1, nLastMarkedRow, CR_FILTERED, 0);
    2730           0 :             if (nNonFilteredRow > nLastMarkedRow)
    2731           0 :                 return;
    2732             : 
    2733           0 :             SCROW nRowsSkipped = nNonFilteredRow - nEndRow - 1;
    2734           0 :             nDy += nRowsSkipped;
    2735             : 
    2736           0 :             nBegRow = nNonFilteredRow;
    2737           0 :             nEndRow = lcl_getLastNonFilteredRow(rFlags, nBegRow, nLastMarkedRow, nRowCount);
    2738             : 
    2739           0 :             if (!bSkipAttrForEmpty)
    2740           0 :                 DeleteArea(nCol1, nBegRow, nCol2, nEndRow, rMark, nDelFlag);
    2741             : 
    2742           0 :             CopyBlockFromClip(aCxt, nCol1, nBegRow, nCol2, nEndRow, rMark, nDx, nDy);
    2743           0 :             nRowCount -= nEndRow - nBegRow + 1;
    2744             :         }
    2745             : 
    2746           0 :         if (rClipParam.meDirection == ScClipParam::Row)
    2747             :             // Begin row for the next range being pasted.
    2748           0 :             nBegRow = rFlags.GetFirstForCondition(nEndRow+1, nLastMarkedRow, CR_FILTERED, 0);
    2749             :         else
    2750           0 :             nBegRow = nRow1;
    2751             : 
    2752           0 :         if (rClipParam.meDirection == ScClipParam::Column)
    2753           0 :             nCol1 += p->aEnd.Col() - p->aStart.Col() + 1;
    2754             :     }
    2755             : 
    2756           0 :     bInsertingFromOtherDoc = false;
    2757             : 
    2758           0 :     ScRangeList aRanges;
    2759           0 :     aRanges.Append(aDestRange);
    2760             : 
    2761             :     // Listener aufbauen nachdem alles inserted wurde
    2762           0 :     StartListeningFromClip(aDestRange.aStart.Col(), aDestRange.aStart.Row(),
    2763           0 :                            aDestRange.aEnd.Col(), aDestRange.aEnd.Row(), rMark, nInsFlag );
    2764             :     // nachdem alle Listener aufgebaut wurden, kann gebroadcastet werden
    2765           0 :     BroadcastFromClip(aDestRange.aStart.Col(), aDestRange.aStart.Row(),
    2766           0 :                       aDestRange.aEnd.Col(), aDestRange.aEnd.Row(), rMark, nInsFlag );
    2767             : 
    2768           0 :     if (bResetCut)
    2769           0 :         pClipDoc->GetClipParam().mbCutMode = false;
    2770           0 :     SetAutoCalc( bOldAutoCalc );
    2771             : }
    2772             : 
    2773          16 : void ScDocument::SetClipArea( const ScRange& rArea, bool bCut )
    2774             : {
    2775          16 :     if (bIsClip)
    2776             :     {
    2777          16 :         ScClipParam& rClipParam = GetClipParam();
    2778          16 :         rClipParam.maRanges.RemoveAll();
    2779          16 :         rClipParam.maRanges.Append(rArea);
    2780          16 :         rClipParam.mbCutMode = bCut;
    2781             :     }
    2782             :     else
    2783             :     {
    2784             :         OSL_FAIL("SetClipArea: No Clip");
    2785             :     }
    2786          16 : }
    2787             : 
    2788             : 
    2789          96 : void ScDocument::GetClipArea(SCCOL& nClipX, SCROW& nClipY, bool bIncludeFiltered)
    2790             : {
    2791          96 :     if (!bIsClip)
    2792             :     {
    2793             :         OSL_FAIL("GetClipArea: No Clip");
    2794           0 :         return;
    2795             :     }
    2796             : 
    2797          96 :     ScRangeList& rClipRanges = GetClipParam().maRanges;
    2798          96 :     if (rClipRanges.empty())
    2799             :         // No clip range.  Bail out.
    2800           0 :         return;
    2801             : 
    2802          96 :     ScRange* p = rClipRanges.front();
    2803          96 :     SCCOL nStartCol = p->aStart.Col();
    2804          96 :     SCCOL nEndCol   = p->aEnd.Col();
    2805          96 :     SCROW nStartRow = p->aStart.Row();
    2806          96 :     SCROW nEndRow   = p->aEnd.Row();
    2807          96 :     for ( size_t i = 1, n = rClipRanges.size(); i < n; ++i )
    2808             :     {
    2809           0 :         p = rClipRanges[ i ];
    2810           0 :         if (p->aStart.Col() < nStartCol)
    2811           0 :             nStartCol = p->aStart.Col();
    2812           0 :         if (p->aStart.Row() < nStartRow)
    2813           0 :             nStartRow = p->aStart.Row();
    2814           0 :         if (p->aEnd.Col() > nEndCol)
    2815           0 :             nEndCol = p->aEnd.Col();
    2816           0 :         if (p->aEnd.Row() < nEndRow)
    2817           0 :             nEndRow = p->aEnd.Row();
    2818             :     }
    2819             : 
    2820          96 :     nClipX = nEndCol - nStartCol;
    2821             : 
    2822          96 :     if ( bIncludeFiltered )
    2823          33 :         nClipY = nEndRow - nStartRow;
    2824             :     else
    2825             :     {
    2826             :         //  count non-filtered rows
    2827             :         //  count on first used table in clipboard
    2828          63 :         SCTAB nCountTab = 0;
    2829         126 :         while ( nCountTab < static_cast<SCTAB>(maTabs.size()) && !maTabs[nCountTab] )
    2830           0 :             ++nCountTab;
    2831             : 
    2832          63 :         SCROW nResult = CountNonFilteredRows(nStartRow, nEndRow, nCountTab);
    2833             : 
    2834          63 :         if ( nResult > 0 )
    2835          63 :             nClipY = nResult - 1;
    2836             :         else
    2837           0 :             nClipY = 0;                 // always return at least 1 row
    2838             :     }
    2839             : }
    2840             : 
    2841             : 
    2842          27 : void ScDocument::GetClipStart(SCCOL& nClipX, SCROW& nClipY)
    2843             : {
    2844          27 :     if (bIsClip)
    2845             :     {
    2846          27 :         ScRangeList& rClipRanges = GetClipParam().maRanges;
    2847          27 :         if ( !rClipRanges.empty() )
    2848             :         {
    2849          27 :             nClipX = rClipRanges.front()->aStart.Col();
    2850          27 :             nClipY = rClipRanges.front()->aStart.Row();
    2851             :         }
    2852             :     }
    2853             :     else
    2854             :     {
    2855             :         OSL_FAIL("GetClipStart: No Clip");
    2856             :     }
    2857          27 : }
    2858             : 
    2859             : 
    2860          18 : bool ScDocument::HasClipFilteredRows()
    2861             : {
    2862             :     //  count on first used table in clipboard
    2863          18 :     SCTAB nCountTab = 0;
    2864          36 :     while ( nCountTab < static_cast<SCTAB>(maTabs.size()) && !maTabs[nCountTab] )
    2865           0 :         ++nCountTab;
    2866             : 
    2867          18 :     ScRangeList& rClipRanges = GetClipParam().maRanges;
    2868          18 :     if ( rClipRanges.empty() )
    2869           0 :         return false;
    2870             : 
    2871          36 :     for ( size_t i = 0, n = rClipRanges.size(); i < n; ++i )
    2872             :     {
    2873          18 :         ScRange* p = rClipRanges[ i ];
    2874          18 :         bool bAnswer = maTabs[nCountTab]->HasFilteredRows(p->aStart.Row(), p->aEnd.Row());
    2875          18 :         if (bAnswer)
    2876           0 :             return true;
    2877             :     }
    2878          18 :     return false;
    2879             : }
    2880             : 
    2881             : 
    2882           0 : void ScDocument::MixDocument( const ScRange& rRange, sal_uInt16 nFunction, bool bSkipEmpty,
    2883             :                                     ScDocument* pSrcDoc )
    2884             : {
    2885           0 :     SCTAB nTab1 = rRange.aStart.Tab();
    2886           0 :     SCTAB nTab2 = rRange.aEnd.Tab();
    2887           0 :     sc::MixDocContext aCxt(*this);
    2888           0 :     SCTAB nMinSizeBothTabs = static_cast<SCTAB>(std::min(maTabs.size(), pSrcDoc->maTabs.size()));
    2889           0 :     for (SCTAB i = nTab1; i <= nTab2 && i < nMinSizeBothTabs; i++)
    2890             :     {
    2891           0 :         ScTable* pTab = FetchTable(i);
    2892           0 :         const ScTable* pSrcTab = pSrcDoc->FetchTable(i);
    2893           0 :         if (!pTab || !pSrcTab)
    2894           0 :             continue;
    2895             : 
    2896             :         pTab->MixData(
    2897           0 :             aCxt, rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row(),
    2898           0 :             nFunction, bSkipEmpty, pSrcTab);
    2899           0 :     }
    2900           0 : }
    2901             : 
    2902             : 
    2903           0 : void ScDocument::FillTab( const ScRange& rSrcArea, const ScMarkData& rMark,
    2904             :                                 sal_uInt16 nFlags, sal_uInt16 nFunction,
    2905             :                                 bool bSkipEmpty, bool bAsLink )
    2906             : {
    2907           0 :     sal_uInt16 nDelFlags = nFlags;
    2908           0 :     if (nDelFlags & IDF_CONTENTS)
    2909           0 :         nDelFlags |= IDF_CONTENTS;          // immer alle Inhalte oder keine loeschen!
    2910             : 
    2911           0 :     SCTAB nSrcTab = rSrcArea.aStart.Tab();
    2912             : 
    2913           0 :     if (ValidTab(nSrcTab) && nSrcTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nSrcTab])
    2914             :     {
    2915           0 :         SCCOL nStartCol = rSrcArea.aStart.Col();
    2916           0 :         SCROW nStartRow = rSrcArea.aStart.Row();
    2917           0 :         SCCOL nEndCol = rSrcArea.aEnd.Col();
    2918           0 :         SCROW nEndRow = rSrcArea.aEnd.Row();
    2919           0 :         boost::scoped_ptr<ScDocument> pMixDoc;
    2920           0 :         bool bDoMix = ( bSkipEmpty || nFunction ) && ( nFlags & IDF_CONTENTS );
    2921             : 
    2922           0 :         bool bOldAutoCalc = GetAutoCalc();
    2923           0 :         SetAutoCalc( false );                   // avoid multiple calculations
    2924             : 
    2925           0 :         sc::CopyToDocContext aCxt(*this);
    2926           0 :         sc::MixDocContext aMixDocCxt(*this);
    2927             : 
    2928           0 :         SCTAB nCount = static_cast<SCTAB>(maTabs.size());
    2929           0 :         ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
    2930           0 :         for (; itr != itrEnd && *itr < nCount; ++itr)
    2931           0 :             if ( *itr!=nSrcTab && maTabs[*itr])
    2932             :             {
    2933           0 :                 SCTAB i = *itr;
    2934           0 :                 if (bDoMix)
    2935             :                 {
    2936           0 :                     if (!pMixDoc)
    2937             :                     {
    2938           0 :                         pMixDoc.reset(new ScDocument(SCDOCMODE_UNDO));
    2939           0 :                         pMixDoc->InitUndo( this, i, i );
    2940             :                     }
    2941             :                     else
    2942           0 :                         pMixDoc->AddUndoTab( i, i );
    2943             : 
    2944             :                     // context used for copying content to the temporary mix document.
    2945           0 :                     sc::CopyToDocContext aMixCxt(*pMixDoc);
    2946           0 :                     maTabs[i]->CopyToTable(aMixCxt, nStartCol,nStartRow, nEndCol,nEndRow,
    2947           0 :                                             IDF_CONTENTS, false, pMixDoc->maTabs[i] );
    2948             :                 }
    2949           0 :                 maTabs[i]->DeleteArea( nStartCol,nStartRow, nEndCol,nEndRow, nDelFlags);
    2950           0 :                 maTabs[nSrcTab]->CopyToTable(aCxt, nStartCol,nStartRow, nEndCol,nEndRow,
    2951           0 :                                                  nFlags, false, maTabs[i], NULL, bAsLink );
    2952             : 
    2953           0 :                 if (bDoMix)
    2954           0 :                     maTabs[i]->MixData(aMixDocCxt, nStartCol,nStartRow, nEndCol,nEndRow,
    2955           0 :                                         nFunction, bSkipEmpty, pMixDoc->maTabs[i] );
    2956             :             }
    2957             : 
    2958           0 :         SetAutoCalc( bOldAutoCalc );
    2959             :     }
    2960             :     else
    2961             :     {
    2962             :         OSL_FAIL("wrong table");
    2963             :     }
    2964           0 : }
    2965             : 
    2966             : 
    2967           0 : void ScDocument::FillTabMarked( SCTAB nSrcTab, const ScMarkData& rMark,
    2968             :                                 sal_uInt16 nFlags, sal_uInt16 nFunction,
    2969             :                                 bool bSkipEmpty, bool bAsLink )
    2970             : {
    2971           0 :     sal_uInt16 nDelFlags = nFlags;
    2972           0 :     if (nDelFlags & IDF_CONTENTS)
    2973           0 :         nDelFlags |= IDF_CONTENTS;          // immer alle Inhalte oder keine loeschen!
    2974             : 
    2975           0 :     if (ValidTab(nSrcTab) && nSrcTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nSrcTab])
    2976             :     {
    2977           0 :         boost::scoped_ptr<ScDocument> pMixDoc;
    2978           0 :         bool bDoMix = ( bSkipEmpty || nFunction ) && ( nFlags & IDF_CONTENTS );
    2979             : 
    2980           0 :         bool bOldAutoCalc = GetAutoCalc();
    2981           0 :         SetAutoCalc( false );                   // avoid multiple calculations
    2982             : 
    2983           0 :         ScRange aArea;
    2984           0 :         rMark.GetMultiMarkArea( aArea );
    2985           0 :         SCCOL nStartCol = aArea.aStart.Col();
    2986           0 :         SCROW nStartRow = aArea.aStart.Row();
    2987           0 :         SCCOL nEndCol = aArea.aEnd.Col();
    2988           0 :         SCROW nEndRow = aArea.aEnd.Row();
    2989             : 
    2990           0 :         sc::CopyToDocContext aCxt(*this);
    2991           0 :         sc::MixDocContext aMixDocCxt(*this);
    2992           0 :         SCTAB nCount = static_cast<SCTAB>(maTabs.size());
    2993           0 :         ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
    2994           0 :         for (; itr != itrEnd && *itr < nCount; ++itr)
    2995           0 :             if ( *itr!=nSrcTab && maTabs[*itr] )
    2996             :             {
    2997           0 :                 SCTAB i = *itr;
    2998           0 :                 if (bDoMix)
    2999             :                 {
    3000           0 :                     if (!pMixDoc)
    3001             :                     {
    3002           0 :                         pMixDoc.reset(new ScDocument(SCDOCMODE_UNDO));
    3003           0 :                         pMixDoc->InitUndo( this, i, i );
    3004             :                     }
    3005             :                     else
    3006           0 :                         pMixDoc->AddUndoTab( i, i );
    3007             : 
    3008           0 :                     sc::CopyToDocContext aMixCxt(*pMixDoc);
    3009           0 :                     maTabs[i]->CopyToTable(aMixCxt, nStartCol,nStartRow, nEndCol,nEndRow,
    3010           0 :                                             IDF_CONTENTS, true, pMixDoc->maTabs[i], &rMark );
    3011             :                 }
    3012             : 
    3013           0 :                 maTabs[i]->DeleteSelection( nDelFlags, rMark );
    3014           0 :                 maTabs[nSrcTab]->CopyToTable(aCxt, nStartCol,nStartRow, nEndCol,nEndRow,
    3015           0 :                                              nFlags, true, maTabs[i], &rMark, bAsLink );
    3016             : 
    3017           0 :                 if (bDoMix)
    3018           0 :                     maTabs[i]->MixMarked(aMixDocCxt, rMark, nFunction, bSkipEmpty, pMixDoc->maTabs[i]);
    3019             :             }
    3020             : 
    3021           0 :         SetAutoCalc( bOldAutoCalc );
    3022             :     }
    3023             :     else
    3024             :     {
    3025             :         OSL_FAIL("wrong table");
    3026             :     }
    3027           0 : }
    3028             : 
    3029             : 
    3030       17195 : bool ScDocument::SetString( SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString& rString,
    3031             :                             ScSetStringParam* pParam )
    3032             : {
    3033       17195 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3034       17195 :         return maTabs[nTab]->SetString( nCol, nRow, nTab, rString, pParam );
    3035             :     else
    3036           0 :         return false;
    3037             : }
    3038             : 
    3039       12973 : bool ScDocument::SetString(
    3040             :     const ScAddress& rPos, const OUString& rString, ScSetStringParam* pParam )
    3041             : {
    3042       12973 :     return SetString(rPos.Col(), rPos.Row(), rPos.Tab(), rString, pParam);
    3043             : }
    3044             : 
    3045         417 : void ScDocument::SetEditText( const ScAddress& rPos, EditTextObject* pEditText )
    3046             : {
    3047         417 :     if (!TableExists(rPos.Tab()))
    3048             :     {
    3049           0 :         delete pEditText;
    3050         417 :         return;
    3051             :     }
    3052             : 
    3053         417 :     maTabs[rPos.Tab()]->SetEditText(rPos.Col(), rPos.Row(), pEditText);
    3054             : }
    3055             : 
    3056           0 : void ScDocument::SetEditText( const ScAddress& rPos, const EditTextObject& rEditText, const SfxItemPool* pEditPool )
    3057             : {
    3058           0 :     if (!TableExists(rPos.Tab()))
    3059           0 :         return;
    3060             : 
    3061           0 :     maTabs[rPos.Tab()]->SetEditText(rPos.Col(), rPos.Row(), rEditText, pEditPool);
    3062             : }
    3063             : 
    3064           0 : void ScDocument::SetEditText( const ScAddress& rPos, const OUString& rStr )
    3065             : {
    3066           0 :     if (!TableExists(rPos.Tab()))
    3067           0 :         return;
    3068             : 
    3069           0 :     ScFieldEditEngine& rEngine = GetEditEngine();
    3070           0 :     rEngine.SetText(rStr);
    3071           0 :     maTabs[rPos.Tab()]->SetEditText(rPos.Col(), rPos.Row(), rEngine.CreateTextObject());
    3072             : }
    3073             : 
    3074        1010 : void ScDocument::SetTextCell( const ScAddress& rPos, const OUString& rStr )
    3075             : {
    3076        1010 :     if (!TableExists(rPos.Tab()))
    3077        1010 :         return;
    3078             : 
    3079        1010 :     if (ScStringUtil::isMultiline(rStr))
    3080             :     {
    3081           0 :         ScFieldEditEngine& rEngine = GetEditEngine();
    3082           0 :         rEngine.SetText(rStr);
    3083           0 :         maTabs[rPos.Tab()]->SetEditText(rPos.Col(), rPos.Row(), rEngine.CreateTextObject());
    3084             :     }
    3085             :     else
    3086             :     {
    3087        1010 :         ScSetStringParam aParam;
    3088        1010 :         aParam.setTextInput();
    3089        1010 :         maTabs[rPos.Tab()]->SetString(rPos.Col(), rPos.Row(), rPos.Tab(), rStr, &aParam);
    3090             :     }
    3091             : }
    3092             : 
    3093         488 : void ScDocument::SetEmptyCell( const ScAddress& rPos )
    3094             : {
    3095         488 :     if (!TableExists(rPos.Tab()))
    3096         488 :         return;
    3097             : 
    3098         488 :     maTabs[rPos.Tab()]->SetEmptyCell(rPos.Col(), rPos.Row());
    3099             : }
    3100             : 
    3101        2959 : void ScDocument::SetValue( SCCOL nCol, SCROW nRow, SCTAB nTab, const double& rVal )
    3102             : {
    3103        2959 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()))
    3104        2959 :         if (maTabs[nTab])
    3105        2959 :             maTabs[nTab]->SetValue( nCol, nRow, rVal );
    3106        2959 : }
    3107             : 
    3108       41204 : void ScDocument::SetValue( const ScAddress& rPos, double fVal )
    3109             : {
    3110       41204 :     if (!TableExists(rPos.Tab()))
    3111       41204 :         return;
    3112             : 
    3113       41204 :     maTabs[rPos.Tab()]->SetValue(rPos.Col(), rPos.Row(), fVal);
    3114             : }
    3115             : 
    3116        6960 : OUString ScDocument::GetString( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
    3117             : {
    3118        6960 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
    3119             :     {
    3120        6960 :         OUString aStr;
    3121        6960 :         maTabs[nTab]->GetString(nCol, nRow, aStr);
    3122        6960 :         return aStr;
    3123             :     }
    3124             :     else
    3125           0 :         return EMPTY_OUSTRING;
    3126             : }
    3127             : 
    3128        6412 : OUString ScDocument::GetString( const ScAddress& rPos ) const
    3129             : {
    3130        6412 :     if (!TableExists(rPos.Tab()))
    3131           0 :         return EMPTY_OUSTRING;
    3132             : 
    3133        6412 :     OUString aStr;
    3134        6412 :     maTabs[rPos.Tab()]->GetString(rPos.Col(), rPos.Row(), aStr);
    3135        6412 :     return aStr;
    3136             : }
    3137             : 
    3138           0 : const OUString* ScDocument::GetStringCell( const ScAddress& rPos ) const
    3139             : {
    3140           0 :     if (!TableExists(rPos.Tab()))
    3141           0 :         return NULL;
    3142             : 
    3143           0 :     return maTabs[rPos.Tab()]->GetStringCell(rPos.Col(), rPos.Row());
    3144             : }
    3145             : 
    3146           5 : double* ScDocument::GetValueCell( const ScAddress& rPos )
    3147             : {
    3148           5 :     if (!TableExists(rPos.Tab()))
    3149           0 :         return NULL;
    3150             : 
    3151           5 :     return maTabs[rPos.Tab()]->GetValueCell(rPos.Col(), rPos.Row());
    3152             : }
    3153             : 
    3154        1811 : void ScDocument::GetInputString( SCCOL nCol, SCROW nRow, SCTAB nTab, OUString& rString )
    3155             : {
    3156        1811 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3157        1811 :         maTabs[nTab]->GetInputString( nCol, nRow, rString );
    3158             :     else
    3159           0 :         rString = OUString();
    3160        1811 : }
    3161             : 
    3162        1763 : void ScDocument::GetInputString( SCCOL nCol, SCROW nRow, SCTAB nTab, String& rString )
    3163             : {
    3164        1763 :     OUString aString;
    3165        1763 :     GetInputString( nCol, nRow, nTab, aString);
    3166        1763 :     rString = aString;
    3167        1763 : }
    3168             : 
    3169          48 : sal_uInt16 ScDocument::GetStringForFormula( const ScAddress& rPos, OUString& rString )
    3170             : {
    3171             :     // Used in formulas (add-in parameters etc), so it must use the same semantics as
    3172             :     // ScInterpreter::GetCellString: always format values as numbers.
    3173             :     // The return value is the error code.
    3174             : 
    3175          48 :     ScRefCellValue aCell;
    3176          48 :     aCell.assign(*this, rPos);
    3177          48 :     if (aCell.isEmpty())
    3178             :     {
    3179           0 :         rString = EMPTY_OUSTRING;
    3180           0 :         return 0;
    3181             :     }
    3182             : 
    3183          48 :     sal_uInt16 nErr = 0;
    3184          96 :     OUString aStr;
    3185          48 :     SvNumberFormatter* pFormatter = GetFormatTable();
    3186          48 :     switch (aCell.meType)
    3187             :     {
    3188             :         case CELLTYPE_STRING:
    3189             :         case CELLTYPE_EDIT:
    3190          48 :             aStr = aCell.getString();
    3191          48 :         break;
    3192             :         case CELLTYPE_FORMULA:
    3193             :         {
    3194           0 :             ScFormulaCell* pFCell = aCell.mpFormula;
    3195           0 :             nErr = pFCell->GetErrCode();
    3196           0 :             if (pFCell->IsValue())
    3197             :             {
    3198           0 :                 double fVal = pFCell->GetValue();
    3199             :                 sal_uInt32 nIndex = pFormatter->GetStandardFormat(
    3200             :                                     NUMBERFORMAT_NUMBER,
    3201           0 :                                     ScGlobal::eLnge);
    3202           0 :                 pFormatter->GetInputLineString(fVal, nIndex, aStr);
    3203             :             }
    3204             :             else
    3205           0 :                 aStr = pFCell->GetString();
    3206             :         }
    3207           0 :         break;
    3208             :         case CELLTYPE_VALUE:
    3209             :         {
    3210           0 :             double fVal = aCell.mfValue;
    3211             :             sal_uInt32 nIndex = pFormatter->GetStandardFormat(
    3212             :                                     NUMBERFORMAT_NUMBER,
    3213           0 :                                     ScGlobal::eLnge);
    3214           0 :             pFormatter->GetInputLineString(fVal, nIndex, aStr);
    3215             :         }
    3216           0 :         break;
    3217             :         default:
    3218             :             ;
    3219             :     }
    3220             : 
    3221          48 :     rString = aStr;
    3222          96 :     return nErr;
    3223             : }
    3224             : 
    3225             : 
    3226         349 : void ScDocument::GetValue( SCCOL nCol, SCROW nRow, SCTAB nTab, double& rValue ) const
    3227             : {
    3228         349 :     if (TableExists(nTab))
    3229         349 :         rValue = maTabs[nTab]->GetValue( nCol, nRow );
    3230             :     else
    3231           0 :         rValue = 0.0;
    3232         349 : }
    3233             : 
    3234          48 : const EditTextObject* ScDocument::GetEditText( const ScAddress& rPos ) const
    3235             : {
    3236          48 :     SCTAB nTab = rPos.Tab();
    3237          48 :     if (!TableExists(nTab))
    3238           0 :         return NULL;
    3239             : 
    3240          48 :     return maTabs[nTab]->GetEditText(rPos.Col(), rPos.Row());
    3241             : }
    3242             : 
    3243           0 : void ScDocument::RemoveEditTextCharAttribs( const ScAddress& rPos, const ScPatternAttr& rAttr )
    3244             : {
    3245           0 :     if (!TableExists(rPos.Tab()))
    3246           0 :         return;
    3247             : 
    3248           0 :     return maTabs[rPos.Tab()]->RemoveEditTextCharAttribs(rPos.Col(), rPos.Row(), rAttr);
    3249             : }
    3250             : 
    3251        7903 : double ScDocument::GetValue( const ScAddress& rPos ) const
    3252             : {
    3253        7903 :     SCTAB nTab = rPos.Tab();
    3254        7903 :     if ( nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3255        7903 :         return maTabs[nTab]->GetValue(rPos.Col(), rPos.Row());
    3256           0 :     return 0.0;
    3257             : }
    3258             : 
    3259             : 
    3260         825 : void ScDocument::GetNumberFormat( SCCOL nCol, SCROW nRow, SCTAB nTab,
    3261             :                                   sal_uInt32& rFormat ) const
    3262             : {
    3263         825 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()))
    3264         825 :         if (maTabs[nTab])
    3265             :         {
    3266         825 :             rFormat = maTabs[nTab]->GetNumberFormat( nCol, nRow );
    3267        1650 :             return ;
    3268             :         }
    3269           0 :     rFormat = 0;
    3270             : }
    3271             : 
    3272          10 : sal_uInt32 ScDocument::GetNumberFormat( const ScRange& rRange ) const
    3273             : {
    3274          10 :     SCTAB nTab1 = rRange.aStart.Tab(), nTab2 = rRange.aEnd.Tab();
    3275          10 :     SCCOL nCol1 = rRange.aStart.Col(), nCol2 = rRange.aEnd.Col();
    3276          10 :     SCROW nRow1 = rRange.aStart.Row(), nRow2 = rRange.aEnd.Row();
    3277             : 
    3278          10 :     if (!ValidTab(nTab1) || !ValidTab(nTab2) || !maTabs[nTab1] || !maTabs[nTab2])
    3279           0 :         return 0;
    3280             : 
    3281          10 :     sal_uInt32 nFormat = 0;
    3282          10 :     bool bFirstItem = true;
    3283          20 :     for (SCTAB nTab = nTab1; nTab <= nTab2 && nTab < static_cast<SCTAB>(maTabs.size()) ; ++nTab)
    3284          20 :         for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
    3285             :         {
    3286          10 :             sal_uInt32 nThisFormat = maTabs[nTab]->GetNumberFormat(nCol, nRow1, nRow2);
    3287          10 :             if (bFirstItem)
    3288             :             {
    3289          10 :                 nFormat = nThisFormat;
    3290          10 :                 bFirstItem = false;
    3291             :             }
    3292           0 :             else if (nThisFormat != nFormat)
    3293           0 :                 return 0;
    3294             :         }
    3295             : 
    3296          10 :     return nFormat;
    3297             : }
    3298             : 
    3299        9472 : sal_uInt32 ScDocument::GetNumberFormat( const ScAddress& rPos ) const
    3300             : {
    3301        9472 :     SCTAB nTab = rPos.Tab();
    3302        9472 :     if ( maTabs[nTab] )
    3303        9472 :         return maTabs[nTab]->GetNumberFormat( rPos );
    3304           0 :     return 0;
    3305             : }
    3306             : 
    3307         866 : void ScDocument::SetNumberFormat( const ScAddress& rPos, sal_uInt32 nNumberFormat )
    3308             : {
    3309         866 :     if (!TableExists(rPos.Tab()))
    3310         866 :         return;
    3311             : 
    3312         866 :     maTabs[rPos.Tab()]->SetNumberFormat(rPos.Col(), rPos.Row(), nNumberFormat);
    3313             : }
    3314             : 
    3315        2679 : void ScDocument::GetNumberFormatInfo( short& nType, sal_uLong& nIndex,
    3316             :             const ScAddress& rPos ) const
    3317             : {
    3318        2679 :     SCTAB nTab = rPos.Tab();
    3319        2679 :     if ( nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3320             :     {
    3321        2679 :         nIndex = maTabs[nTab]->GetNumberFormat( rPos );
    3322        2679 :         nType = GetFormatTable()->GetType( nIndex );
    3323             :     }
    3324             :     else
    3325             :     {
    3326           0 :         nType = NUMBERFORMAT_UNDEFINED;
    3327           0 :         nIndex = 0;
    3328             :     }
    3329        2679 : }
    3330             : 
    3331             : 
    3332          39 : void ScDocument::GetFormula( SCCOL nCol, SCROW nRow, SCTAB nTab, OUString& rFormula ) const
    3333             : {
    3334          39 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3335          39 :             maTabs[nTab]->GetFormula( nCol, nRow, rFormula );
    3336             :     else
    3337           0 :         rFormula = OUString();
    3338          39 : }
    3339             : 
    3340             : 
    3341          25 : void ScDocument::GetFormula( SCCOL nCol, SCROW nRow, SCTAB nTab, String& rFormula ) const
    3342             : {
    3343          25 :     OUString aString;
    3344          25 :     GetFormula( nCol, nRow, nTab, aString);
    3345          25 :     rFormula = aString;
    3346          25 : }
    3347             : 
    3348           0 : const ScTokenArray* ScDocument::GetFormulaTokens( const ScAddress& rPos ) const
    3349             : {
    3350           0 :     if (!TableExists(rPos.Tab()))
    3351           0 :         return NULL;
    3352             : 
    3353           0 :     return maTabs[rPos.Tab()]->GetFormulaTokens(rPos.Col(), rPos.Row());
    3354             : }
    3355             : 
    3356           0 : const ScFormulaCell* ScDocument::GetFormulaCell( const ScAddress& rPos ) const
    3357             : {
    3358           0 :     if (!TableExists(rPos.Tab()))
    3359           0 :         return NULL;
    3360             : 
    3361           0 :     return maTabs[rPos.Tab()]->GetFormulaCell(rPos.Col(), rPos.Row());
    3362             : }
    3363             : 
    3364         739 : ScFormulaCell* ScDocument::GetFormulaCell( const ScAddress& rPos )
    3365             : {
    3366         739 :     if (!TableExists(rPos.Tab()))
    3367           0 :         return NULL;
    3368             : 
    3369         739 :     return maTabs[rPos.Tab()]->GetFormulaCell(rPos.Col(), rPos.Row());
    3370             : }
    3371             : 
    3372       17682 : CellType ScDocument::GetCellType( const ScAddress& rPos ) const
    3373             : {
    3374       17682 :     SCTAB nTab = rPos.Tab();
    3375       17682 :     if ( nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3376       17682 :         return maTabs[nTab]->GetCellType( rPos );
    3377           0 :     return CELLTYPE_NONE;
    3378             : }
    3379             : 
    3380             : 
    3381          22 : void ScDocument::GetCellType( SCCOL nCol, SCROW nRow, SCTAB nTab,
    3382             :         CellType& rCellType ) const
    3383             : {
    3384          22 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
    3385          22 :         rCellType = maTabs[nTab]->GetCellType( nCol, nRow );
    3386             :     else
    3387           0 :         rCellType = CELLTYPE_NONE;
    3388          22 : }
    3389             : 
    3390           4 : bool ScDocument::HasStringData( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
    3391             : {
    3392           4 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3393           4 :             return maTabs[nTab]->HasStringData( nCol, nRow );
    3394             :     else
    3395           0 :         return false;
    3396             : }
    3397             : 
    3398             : 
    3399        1342 : bool ScDocument::HasValueData( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
    3400             : {
    3401        1342 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3402        1342 :             return maTabs[nTab]->HasValueData( nCol, nRow );
    3403             :     else
    3404           0 :         return false;
    3405             : }
    3406             : 
    3407           0 : bool ScDocument::HasValueData( const ScAddress& rPos ) const
    3408             : {
    3409           0 :     return HasValueData(rPos.Col(), rPos.Row(), rPos.Tab());
    3410             : }
    3411             : 
    3412           0 : bool ScDocument::HasStringCells( const ScRange& rRange ) const
    3413             : {
    3414             :     //  true, wenn String- oder Editzellen im Bereich
    3415             : 
    3416           0 :     SCCOL nStartCol = rRange.aStart.Col();
    3417           0 :     SCROW nStartRow = rRange.aStart.Row();
    3418           0 :     SCTAB nStartTab = rRange.aStart.Tab();
    3419           0 :     SCCOL nEndCol = rRange.aEnd.Col();
    3420           0 :     SCROW nEndRow = rRange.aEnd.Row();
    3421           0 :     SCTAB nEndTab = rRange.aEnd.Tab();
    3422             : 
    3423           0 :     for ( SCTAB nTab=nStartTab; nTab<=nEndTab && nTab < static_cast<SCTAB>(maTabs.size()); nTab++ )
    3424           0 :         if ( maTabs[nTab] && maTabs[nTab]->HasStringCells( nStartCol, nStartRow, nEndCol, nEndRow ) )
    3425           0 :             return true;
    3426             : 
    3427           0 :     return false;
    3428             : }
    3429             : 
    3430             : 
    3431           0 : bool ScDocument::HasSelectionData( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
    3432             : {
    3433           0 :     sal_uInt32 nValidation = static_cast< const SfxUInt32Item* >( GetAttr( nCol, nRow, nTab, ATTR_VALIDDATA ) )->GetValue();
    3434           0 :     if( nValidation )
    3435             :     {
    3436           0 :         const ScValidationData* pData = GetValidationEntry( nValidation );
    3437           0 :         if( pData && pData->HasSelectionList() )
    3438           0 :             return true;
    3439             :     }
    3440           0 :     return HasStringCells( ScRange( nCol, 0, nTab, nCol, MAXROW, nTab ) );
    3441             : }
    3442             : 
    3443             : 
    3444         834 : void ScDocument::InitializeNoteCaptions( SCTAB nTab, bool bForced )
    3445             : {
    3446         834 :     if( ValidTab( nTab ) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[ nTab ] )
    3447         834 :         maTabs[ nTab ]->InitializeNoteCaptions( bForced );
    3448         834 : }
    3449             : 
    3450         247 : void ScDocument::SetDirty()
    3451             : {
    3452         247 :     bool bOldAutoCalc = GetAutoCalc();
    3453         247 :     bAutoCalc = false;      // keine Mehrfachberechnung
    3454             :     {   // scope for bulk broadcast
    3455         247 :         ScBulkBroadcast aBulkBroadcast( GetBASM());
    3456         247 :         TableContainer::iterator it = maTabs.begin();
    3457         650 :         for (;it != maTabs.end(); ++it)
    3458         403 :             if (*it)
    3459         650 :                 (*it)->SetDirty();
    3460             :     }
    3461             : 
    3462             :     //  Charts werden zwar auch ohne AutoCalc im Tracking auf Dirty gesetzt,
    3463             :     //  wenn alle Formeln dirty sind, werden die Charts aber nicht mehr erwischt
    3464             :     //  (#45205#) - darum alle Charts nochmal explizit
    3465         247 :     if (pChartListenerCollection)
    3466         247 :         pChartListenerCollection->SetDirty();
    3467             : 
    3468         247 :     SetAutoCalc( bOldAutoCalc );
    3469         247 : }
    3470             : 
    3471             : 
    3472         144 : void ScDocument::SetDirty( const ScRange& rRange )
    3473             : {
    3474         144 :     bool bOldAutoCalc = GetAutoCalc();
    3475         144 :     bAutoCalc = false;      // keine Mehrfachberechnung
    3476             :     {   // scope for bulk broadcast
    3477         144 :         ScBulkBroadcast aBulkBroadcast( GetBASM());
    3478         144 :         SCTAB nTab2 = rRange.aEnd.Tab();
    3479         288 :         for (SCTAB i=rRange.aStart.Tab(); i<=nTab2 && i < static_cast<SCTAB>(maTabs.size()); i++)
    3480         288 :             if (maTabs[i]) maTabs[i]->SetDirty( rRange );
    3481             :     }
    3482         144 :     SetAutoCalc( bOldAutoCalc );
    3483         144 : }
    3484             : 
    3485             : 
    3486          32 : void ScDocument::SetTableOpDirty( const ScRange& rRange )
    3487             : {
    3488          32 :     bool bOldAutoCalc = GetAutoCalc();
    3489          32 :     bAutoCalc = false;      // no multiple recalculation
    3490          32 :     SCTAB nTab2 = rRange.aEnd.Tab();
    3491          64 :     for (SCTAB i=rRange.aStart.Tab(); i<=nTab2 && i < static_cast<SCTAB>(maTabs.size()); i++)
    3492          32 :         if (maTabs[i]) maTabs[i]->SetTableOpDirty( rRange );
    3493          32 :     SetAutoCalc( bOldAutoCalc );
    3494          32 : }
    3495             : 
    3496        1486 : void ScDocument::InterpretDirtyCells( const ScRangeList& rRanges )
    3497             : {
    3498        1486 :     if (!GetAutoCalc())
    3499           0 :         return;
    3500             : 
    3501        2999 :     for (size_t nPos=0, nRangeCount = rRanges.size(); nPos < nRangeCount; nPos++)
    3502             :     {
    3503        1513 :         const ScRange& rRange = *rRanges[nPos];
    3504        3026 :         for (SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab)
    3505             :         {
    3506        1513 :             ScTable* pTab = FetchTable(nTab);
    3507        1513 :             if (!pTab)
    3508           0 :                 return;
    3509             : 
    3510             :             pTab->InterpretDirtyCells(
    3511        1513 :                 rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row());
    3512             :         }
    3513             :     }
    3514             : }
    3515             : 
    3516             : 
    3517           0 : void ScDocument::AddTableOpFormulaCell( ScFormulaCell* pCell )
    3518             : {
    3519           0 :     if ( !aTableOpList.empty() )
    3520             :     {
    3521           0 :         ScInterpreterTableOpParams* p = &aTableOpList.back();
    3522           0 :         if ( p->bCollectNotifications )
    3523             :         {
    3524           0 :             if ( p->bRefresh )
    3525             :             {   // refresh pointers only
    3526           0 :                 p->aNotifiedFormulaCells.push_back( pCell );
    3527             :             }
    3528             :             else
    3529             :             {   // init both, address and pointer
    3530           0 :                 p->aNotifiedFormulaCells.push_back( pCell );
    3531           0 :                 p->aNotifiedFormulaPos.push_back( pCell->aPos );
    3532             :             }
    3533             :         }
    3534             :     }
    3535           0 : }
    3536             : 
    3537             : 
    3538         113 : void ScDocument::CalcAll()
    3539             : {
    3540         113 :     ClearLookupCaches();    // Ensure we don't deliver zombie data.
    3541         113 :     sc::AutoCalcSwitch aSwitch(*this, true);
    3542         113 :     TableContainer::iterator it = maTabs.begin();
    3543         299 :     for (; it != maTabs.end(); ++it)
    3544         186 :         if (*it)
    3545         186 :             (*it)->SetDirtyVar();
    3546         299 :     for (it = maTabs.begin(); it != maTabs.end(); ++it)
    3547         186 :         if (*it)
    3548         186 :             (*it)->CalcAll();
    3549         113 :     ClearFormulaTree();
    3550         113 : }
    3551             : 
    3552             : 
    3553           1 : void ScDocument::CompileAll()
    3554             : {
    3555           1 :     TableContainer::iterator it = maTabs.begin();
    3556           3 :     for (; it != maTabs.end(); ++it)
    3557           2 :         if (*it)
    3558           2 :             (*it)->CompileAll();
    3559           1 :     SetDirty();
    3560           1 : }
    3561             : 
    3562             : 
    3563          75 : void ScDocument::CompileXML()
    3564             : {
    3565          75 :     bool bOldAutoCalc = GetAutoCalc();
    3566          75 :     SetAutoCalc( false );
    3567             :     ScProgress aProgress( GetDocumentShell(), ScGlobal::GetRscString(
    3568          75 :                 STR_PROGRESS_CALCULATING ), GetXMLImportedFormulaCount() );
    3569             : 
    3570             :     // set AutoNameCache to speed up automatic name lookup
    3571             :     OSL_ENSURE( !pAutoNameCache, "AutoNameCache already set" );
    3572          75 :     pAutoNameCache = new ScAutoNameCache( this );
    3573             : 
    3574          75 :     if (pRangeName)
    3575           7 :         pRangeName->CompileUnresolvedXML();
    3576             : 
    3577          75 :     TableContainer::iterator it = maTabs.begin();
    3578         243 :     for (; it != maTabs.end(); ++it)
    3579         168 :         if (*it)
    3580         168 :             (*it)->CompileXML( aProgress );
    3581             : 
    3582          75 :     DELETEZ( pAutoNameCache );  // valid only during CompileXML, where cell contents don't change
    3583             : 
    3584          75 :     if ( pValidationList )
    3585           1 :         pValidationList->CompileXML();
    3586             : 
    3587          75 :     SetAutoCalc( bOldAutoCalc );
    3588          75 : }
    3589             : 
    3590           0 : bool ScDocument::CompileErrorCells(sal_uInt16 nErrCode)
    3591             : {
    3592           0 :     bool bCompiled = false;
    3593           0 :     TableContainer::iterator it = maTabs.begin(), itEnd = maTabs.end();
    3594           0 :     for (; it != itEnd; ++it)
    3595             :     {
    3596           0 :         ScTable* pTab = *it;
    3597           0 :         if (!pTab)
    3598           0 :             continue;
    3599             : 
    3600           0 :         if (pTab->CompileErrorCells(nErrCode))
    3601           0 :             bCompiled = true;
    3602             :     }
    3603             : 
    3604           0 :     return bCompiled;
    3605             : }
    3606             : 
    3607          50 : void ScDocument::CalcAfterLoad()
    3608             : {
    3609          50 :     if (bIsClip)    // Excel-Dateien werden aus dem Clipboard in ein Clip-Doc geladen
    3610          50 :         return;     // dann wird erst beim Einfuegen in das richtige Doc berechnet
    3611             : 
    3612          50 :     bCalcingAfterLoad = true;
    3613             :     {
    3614          50 :         TableContainer::iterator it = maTabs.begin();
    3615         213 :         for (; it != maTabs.end(); ++it)
    3616         163 :             if (*it)
    3617         163 :                 (*it)->CalcAfterLoad();
    3618         213 :         for (it = maTabs.begin(); it != maTabs.end(); ++it)
    3619         163 :             if (*it)
    3620         163 :                 (*it)->SetDirtyAfterLoad();
    3621             :     }
    3622          50 :     bCalcingAfterLoad = false;
    3623             : 
    3624          50 :     SetDetectiveDirty(false);   // noch keine wirklichen Aenderungen
    3625             : 
    3626             :     // #i112436# If formula cells are already dirty, they don't broadcast further changes.
    3627             :     // So the source ranges of charts must be interpreted even if they are not visible,
    3628             :     // similar to ScMyShapeResizer::CreateChartListener for loading own files (i104899).
    3629          50 :     if (pChartListenerCollection)
    3630             :     {
    3631          50 :         const ScChartListenerCollection::ListenersType& rListeners = pChartListenerCollection->getListeners();
    3632          50 :         ScChartListenerCollection::ListenersType::const_iterator it = rListeners.begin(), itEnd = rListeners.end();
    3633          90 :         for (; it != itEnd; ++it)
    3634             :         {
    3635          40 :             const ScChartListener* p = it->second;
    3636          40 :             InterpretDirtyCells(*p->GetRangeList());
    3637             :         }
    3638             :     }
    3639             : }
    3640             : 
    3641             : 
    3642         890 : sal_uInt16 ScDocument::GetErrCode( const ScAddress& rPos ) const
    3643             : {
    3644         890 :     SCTAB nTab = rPos.Tab();
    3645         890 :     if ( nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3646         890 :         return maTabs[nTab]->GetErrCode( rPos );
    3647           0 :     return 0;
    3648             : }
    3649             : 
    3650             : 
    3651        1143 : void ScDocument::ResetChanged( const ScRange& rRange )
    3652             : {
    3653        1143 :     SCTAB nTabSize = static_cast<SCTAB>(maTabs.size());
    3654        1143 :     SCTAB nTab1 = rRange.aStart.Tab();
    3655        1143 :     SCTAB nTab2 = rRange.aEnd.Tab();
    3656        2878 :     for (SCTAB nTab = nTab1; nTab1 <= nTab2 && nTab < nTabSize; ++nTab)
    3657        1735 :         if (maTabs[nTab])
    3658        1735 :             maTabs[nTab]->ResetChanged(rRange);
    3659        1143 : }
    3660             : 
    3661             : //
    3662             : //  Spaltenbreiten / Zeilenhoehen   --------------------------------------
    3663             : //
    3664             : 
    3665             : 
    3666        7622 : void ScDocument::SetColWidth( SCCOL nCol, SCTAB nTab, sal_uInt16 nNewWidth )
    3667             : {
    3668        7622 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3669        7622 :         maTabs[nTab]->SetColWidth( nCol, nNewWidth );
    3670        7622 : }
    3671             : 
    3672      203776 : void ScDocument::SetColWidthOnly( SCCOL nCol, SCTAB nTab, sal_uInt16 nNewWidth )
    3673             : {
    3674      203776 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3675      203776 :         maTabs[nTab]->SetColWidthOnly( nCol, nNewWidth );
    3676      203776 : }
    3677             : 
    3678           1 : void ScDocument::SetRowHeight( SCROW nRow, SCTAB nTab, sal_uInt16 nNewHeight )
    3679             : {
    3680           1 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3681           1 :         maTabs[nTab]->SetRowHeight( nRow, nNewHeight );
    3682           1 : }
    3683             : 
    3684             : 
    3685           5 : void ScDocument::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, sal_uInt16 nNewHeight )
    3686             : {
    3687           5 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3688           5 :         maTabs[nTab]->SetRowHeightRange
    3689          10 :             ( nStartRow, nEndRow, nNewHeight, 1.0, 1.0 );
    3690           5 : }
    3691             : 
    3692        3180 : void ScDocument::SetRowHeightOnly( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, sal_uInt16 nNewHeight )
    3693             : {
    3694        3180 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3695        3180 :         maTabs[nTab]->SetRowHeightOnly( nStartRow, nEndRow, nNewHeight );
    3696        3180 : }
    3697             : 
    3698         112 : void ScDocument::SetManualHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bManual )
    3699             : {
    3700         112 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3701         112 :         maTabs[nTab]->SetManualHeight( nStartRow, nEndRow, bManual );
    3702         112 : }
    3703             : 
    3704             : 
    3705      456088 : sal_uInt16 ScDocument::GetColWidth( SCCOL nCol, SCTAB nTab, bool bHiddenAsZero ) const
    3706             : {
    3707      456088 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3708      456088 :         return maTabs[nTab]->GetColWidth( nCol, bHiddenAsZero );
    3709             :     OSL_FAIL("wrong table number");
    3710           0 :     return 0;
    3711             : }
    3712             : 
    3713             : 
    3714         553 : sal_uInt16 ScDocument::GetOriginalWidth( SCCOL nCol, SCTAB nTab ) const
    3715             : {
    3716         553 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3717         553 :         return maTabs[nTab]->GetOriginalWidth( nCol );
    3718             :     OSL_FAIL("wrong table number");
    3719           0 :     return 0;
    3720             : }
    3721             : 
    3722             : 
    3723           0 : sal_uInt16 ScDocument::GetCommonWidth( SCCOL nEndCol, SCTAB nTab ) const
    3724             : {
    3725           0 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3726           0 :         return maTabs[nTab]->GetCommonWidth( nEndCol );
    3727             :     OSL_FAIL("Wrong table number");
    3728           0 :     return 0;
    3729             : }
    3730             : 
    3731             : 
    3732       70664 : sal_uInt16 ScDocument::GetOriginalHeight( SCROW nRow, SCTAB nTab ) const
    3733             : {
    3734       70664 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3735       70664 :         return maTabs[nTab]->GetOriginalHeight( nRow );
    3736             :     OSL_FAIL("Wrong table number");
    3737           0 :     return 0;
    3738             : }
    3739             : 
    3740             : 
    3741    20702065 : sal_uInt16 ScDocument::GetRowHeight( SCROW nRow, SCTAB nTab, bool bHiddenAsZero ) const
    3742             : {
    3743    20702065 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3744    20702065 :         return maTabs[nTab]->GetRowHeight( nRow, NULL, NULL, bHiddenAsZero );
    3745             :     OSL_FAIL("Wrong sheet number");
    3746           0 :     return 0;
    3747             : }
    3748             : 
    3749             : 
    3750       78026 : sal_uInt16 ScDocument::GetRowHeight( SCROW nRow, SCTAB nTab, SCROW* pStartRow, SCROW* pEndRow, bool bHiddenAsZero ) const
    3751             : {
    3752       78026 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3753       78026 :         return maTabs[nTab]->GetRowHeight( nRow, pStartRow, pEndRow, bHiddenAsZero );
    3754             :     OSL_FAIL("Wrong sheet number");
    3755           0 :     return 0;
    3756             : }
    3757             : 
    3758             : 
    3759        4317 : sal_uLong ScDocument::GetRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bHiddenAsZero ) const
    3760             : {
    3761        4317 :     if (nStartRow == nEndRow)
    3762        1628 :         return GetRowHeight( nStartRow, nTab, bHiddenAsZero );  // faster for a single row
    3763             : 
    3764             :     // check bounds because this method replaces former for(i=start;i<=end;++i) loops
    3765        2689 :     if (nStartRow > nEndRow)
    3766        1217 :         return 0;
    3767             : 
    3768        1472 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3769        1472 :         return maTabs[nTab]->GetRowHeight( nStartRow, nEndRow, bHiddenAsZero );
    3770             : 
    3771             :     OSL_FAIL("wrong sheet number");
    3772           0 :     return 0;
    3773             : }
    3774             : 
    3775        1044 : SCROW ScDocument::GetRowForHeight( SCTAB nTab, sal_uLong nHeight ) const
    3776             : {
    3777        1044 :     return maTabs[nTab]->GetRowForHeight(nHeight);
    3778             : }
    3779             : 
    3780       24244 : sal_uLong ScDocument::GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow,
    3781             :         SCTAB nTab, double fScale ) const
    3782             : {
    3783             :     // faster for a single row
    3784       24244 :     if (nStartRow == nEndRow)
    3785         112 :         return (sal_uLong) (GetRowHeight( nStartRow, nTab) * fScale);
    3786             : 
    3787             :     // check bounds because this method replaces former for(i=start;i<=end;++i) loops
    3788       24132 :     if (nStartRow > nEndRow)
    3789       24130 :         return 0;
    3790             : 
    3791           2 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3792           2 :         return maTabs[nTab]->GetScaledRowHeight( nStartRow, nEndRow, fScale);
    3793             : 
    3794             :     OSL_FAIL("wrong sheet number");
    3795           0 :     return 0;
    3796             : }
    3797             : 
    3798          56 : SCROW ScDocument::GetHiddenRowCount( SCROW nRow, SCTAB nTab ) const
    3799             : {
    3800          56 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3801          56 :         return maTabs[nTab]->GetHiddenRowCount( nRow );
    3802             :     OSL_FAIL("wrong table number");
    3803           0 :     return 0;
    3804             : }
    3805             : 
    3806             : 
    3807        1102 : sal_uLong ScDocument::GetColOffset( SCCOL nCol, SCTAB nTab, bool bHiddenAsZero ) const
    3808             : {
    3809        1102 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3810        1102 :         return maTabs[nTab]->GetColOffset( nCol, bHiddenAsZero );
    3811             :     OSL_FAIL("wrong table number");
    3812           0 :     return 0;
    3813             : }
    3814             : 
    3815             : 
    3816        1102 : sal_uLong ScDocument::GetRowOffset( SCROW nRow, SCTAB nTab, bool bHiddenAsZero ) const
    3817             : {
    3818        1102 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3819        1102 :         return maTabs[nTab]->GetRowOffset( nRow, bHiddenAsZero );
    3820             :     OSL_FAIL("wrong table number");
    3821           0 :     return 0;
    3822             : }
    3823             : 
    3824             : 
    3825          89 : sal_uInt16 ScDocument::GetOptimalColWidth( SCCOL nCol, SCTAB nTab, OutputDevice* pDev,
    3826             :                                        double nPPTX, double nPPTY,
    3827             :                                        const Fraction& rZoomX, const Fraction& rZoomY,
    3828             :                                        bool bFormula, const ScMarkData* pMarkData,
    3829             :                                        const ScColWidthParam* pParam )
    3830             : {
    3831          89 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3832          89 :         return maTabs[nTab]->GetOptimalColWidth( nCol, pDev, nPPTX, nPPTY,
    3833         178 :             rZoomX, rZoomY, bFormula, pMarkData, pParam );
    3834             :     OSL_FAIL("wrong table number");
    3835           0 :     return 0;
    3836             : }
    3837             : 
    3838             : 
    3839           0 : long ScDocument::GetNeededSize( SCCOL nCol, SCROW nRow, SCTAB nTab,
    3840             :                                     OutputDevice* pDev,
    3841             :                                     double nPPTX, double nPPTY,
    3842             :                                     const Fraction& rZoomX, const Fraction& rZoomY,
    3843             :                                     bool bWidth, bool bTotalSize )
    3844             : {
    3845           0 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3846           0 :         return maTabs[nTab]->GetNeededSize
    3847           0 :                 ( nCol, nRow, pDev, nPPTX, nPPTY, rZoomX, rZoomY, bWidth, bTotalSize );
    3848             :     OSL_FAIL("wrong table number");
    3849           0 :     return 0;
    3850             : }
    3851             : 
    3852             : 
    3853         853 : bool ScDocument::SetOptimalHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, sal_uInt16 nExtra,
    3854             :                                     OutputDevice* pDev,
    3855             :                                     double nPPTX, double nPPTY,
    3856             :                                     const Fraction& rZoomX, const Fraction& rZoomY,
    3857             :                                     bool bShrink )
    3858             : {
    3859             : //! MarkToMulti();
    3860         853 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3861         849 :         return maTabs[nTab]->SetOptimalHeight( nStartRow, nEndRow, nExtra,
    3862        1698 :                                                 pDev, nPPTX, nPPTY, rZoomX, rZoomY, bShrink );
    3863             :     OSL_FAIL("wrong table number");
    3864           4 :     return false;
    3865             : }
    3866             : 
    3867             : 
    3868           0 : void ScDocument::UpdateAllRowHeights( OutputDevice* pDev, double nPPTX, double nPPTY,
    3869             :                                     const Fraction& rZoomX, const Fraction& rZoomY, const ScMarkData* pTabMark )
    3870             : {
    3871             :     // one progress across all (selected) sheets
    3872             : 
    3873           0 :     sal_uLong nCellCount = 0;
    3874           0 :     for ( SCTAB nTab=0; nTab< static_cast<SCTAB>(maTabs.size()); nTab++ )
    3875           0 :         if ( maTabs[nTab] && ( !pTabMark || pTabMark->GetTableSelect(nTab) ) )
    3876           0 :             nCellCount += maTabs[nTab]->GetWeightedCount();
    3877             : 
    3878           0 :     ScProgress aProgress( GetDocumentShell(), ScGlobal::GetRscString(STR_PROGRESS_HEIGHTING), nCellCount );
    3879             : 
    3880           0 :     sal_uLong nProgressStart = 0;
    3881           0 :     for ( SCTAB nTab=0; nTab< static_cast<SCTAB>(maTabs.size()); nTab++ )
    3882           0 :         if ( maTabs[nTab] && ( !pTabMark || pTabMark->GetTableSelect(nTab) ) )
    3883             :         {
    3884           0 :             maTabs[nTab]->SetOptimalHeightOnly( 0, MAXROW, 0,
    3885           0 :                         pDev, nPPTX, nPPTY, rZoomX, rZoomY, false, &aProgress, nProgressStart );
    3886           0 :             maTabs[nTab]->SetDrawPageSize(true, true);
    3887           0 :             nProgressStart += maTabs[nTab]->GetWeightedCount();
    3888           0 :         }
    3889           0 : }
    3890             : 
    3891             : 
    3892             : //
    3893             : //  Spalten-/Zeilen-Flags   ----------------------------------------------
    3894             : //
    3895             : 
    3896        6972 : void ScDocument::ShowCol(SCCOL nCol, SCTAB nTab, bool bShow)
    3897             : {
    3898        6972 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3899        6972 :         maTabs[nTab]->ShowCol( nCol, bShow );
    3900        6972 : }
    3901             : 
    3902             : 
    3903           0 : void ScDocument::ShowRow(SCROW nRow, SCTAB nTab, bool bShow)
    3904             : {
    3905           0 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3906           0 :         maTabs[nTab]->ShowRow( nRow, bShow );
    3907           0 : }
    3908             : 
    3909             : 
    3910          51 : void ScDocument::ShowRows(SCROW nRow1, SCROW nRow2, SCTAB nTab, bool bShow)
    3911             : {
    3912          51 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3913          51 :         maTabs[nTab]->ShowRows( nRow1, nRow2, bShow );
    3914          51 : }
    3915             : 
    3916             : 
    3917           0 : void ScDocument::SetRowFlags( SCROW nRow, SCTAB nTab, sal_uInt8 nNewFlags )
    3918             : {
    3919           0 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3920           0 :         maTabs[nTab]->SetRowFlags( nRow, nNewFlags );
    3921           0 : }
    3922             : 
    3923             : 
    3924           8 : void ScDocument::SetRowFlags( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, sal_uInt8 nNewFlags )
    3925             : {
    3926           8 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3927           8 :         maTabs[nTab]->SetRowFlags( nStartRow, nEndRow, nNewFlags );
    3928           8 : }
    3929             : 
    3930             : 
    3931           0 : sal_uInt8 ScDocument::GetColFlags( SCCOL nCol, SCTAB nTab ) const
    3932             : {
    3933           0 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3934           0 :         return maTabs[nTab]->GetColFlags( nCol );
    3935             :     OSL_FAIL("wrong table number");
    3936           0 :     return 0;
    3937             : }
    3938             : 
    3939        1716 : sal_uInt8 ScDocument::GetRowFlags( SCROW nRow, SCTAB nTab ) const
    3940             : {
    3941        1716 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3942        1716 :         return maTabs[nTab]->GetRowFlags( nRow );
    3943             :     OSL_FAIL("wrong table number");
    3944           0 :     return 0;
    3945             : }
    3946             : 
    3947           0 : const ScBitMaskCompressedArray< SCROW, sal_uInt8> & ScDocument::GetRowFlagsArray(
    3948             :         SCTAB nTab ) const
    3949             : {
    3950             :     const ScBitMaskCompressedArray< SCROW, sal_uInt8> * pFlags;
    3951           0 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    3952           0 :         pFlags = maTabs[nTab]->GetRowFlagsArray();
    3953             :     else
    3954             :     {
    3955             :         OSL_FAIL("wrong sheet number");
    3956           0 :         pFlags = 0;
    3957             :     }
    3958           0 :     if (!pFlags)
    3959             :     {
    3960             :         OSL_FAIL("no row flags at sheet");
    3961           0 :         static ScBitMaskCompressedArray< SCROW, sal_uInt8> aDummy( MAXROW, 0);
    3962           0 :         pFlags = &aDummy;
    3963             :     }
    3964           0 :     return *pFlags;
    3965             : }
    3966             : 
    3967          14 : void ScDocument::GetAllRowBreaks(set<SCROW>& rBreaks, SCTAB nTab, bool bPage, bool bManual) const
    3968             : {
    3969          14 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab])
    3970          14 :         return;
    3971          14 :     maTabs[nTab]->GetAllRowBreaks(rBreaks, bPage, bManual);
    3972             : }
    3973             : 
    3974          14 : void ScDocument::GetAllColBreaks(set<SCCOL>& rBreaks, SCTAB nTab, bool bPage, bool bManual) const
    3975             : {
    3976          14 :     if (!ValidTab(nTab) || !maTabs[nTab])
    3977          14 :         return;
    3978             : 
    3979          14 :     maTabs[nTab]->GetAllColBreaks(rBreaks, bPage, bManual);
    3980             : }
    3981             : 
    3982       18580 : ScBreakType ScDocument::HasRowBreak(SCROW nRow, SCTAB nTab) const
    3983             : {
    3984       18580 :     ScBreakType nType = BREAK_NONE;
    3985       18580 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab] || !ValidRow(nRow))
    3986           0 :         return nType;
    3987             : 
    3988       18580 :     if (maTabs[nTab]->HasRowPageBreak(nRow))
    3989           4 :         nType |= BREAK_PAGE;
    3990             : 
    3991       18580 :     if (maTabs[nTab]->HasRowManualBreak(nRow))
    3992           3 :         nType |= BREAK_MANUAL;
    3993             : 
    3994       18580 :     return nType;
    3995             : }
    3996             : 
    3997       29827 : ScBreakType ScDocument::HasColBreak(SCCOL nCol, SCTAB nTab) const
    3998             : {
    3999       29827 :     ScBreakType nType = BREAK_NONE;
    4000       29827 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab] || !ValidCol(nCol))
    4001           0 :         return nType;
    4002             : 
    4003       29827 :     if (maTabs[nTab]->HasColPageBreak(nCol))
    4004          43 :         nType |= BREAK_PAGE;
    4005             : 
    4006       29827 :     if (maTabs[nTab]->HasColManualBreak(nCol))
    4007          11 :         nType |= BREAK_MANUAL;
    4008             : 
    4009       29827 :     return nType;
    4010             : }
    4011             : 
    4012           1 : void ScDocument::SetRowBreak(SCROW nRow, SCTAB nTab, bool bPage, bool bManual)
    4013             : {
    4014           1 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab] || !ValidRow(nRow))
    4015           1 :         return;
    4016             : 
    4017           1 :     maTabs[nTab]->SetRowBreak(nRow, bPage, bManual);
    4018             : }
    4019             : 
    4020           1 : void ScDocument::SetColBreak(SCCOL nCol, SCTAB nTab, bool bPage, bool bManual)
    4021             : {
    4022           1 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab] || !ValidCol(nCol))
    4023           1 :         return;
    4024             : 
    4025           1 :     maTabs[nTab]->SetColBreak(nCol, bPage, bManual);
    4026             : }
    4027             : 
    4028           1 : void ScDocument::RemoveRowBreak(SCROW nRow, SCTAB nTab, bool bPage, bool bManual)
    4029             : {
    4030           1 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab] || !ValidRow(nRow))
    4031           1 :         return;
    4032             : 
    4033           1 :     maTabs[nTab]->RemoveRowBreak(nRow, bPage, bManual);
    4034             : }
    4035             : 
    4036           1 : void ScDocument::RemoveColBreak(SCCOL nCol, SCTAB nTab, bool bPage, bool bManual)
    4037             : {
    4038           1 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab] || !ValidCol(nCol))
    4039           1 :         return;
    4040             : 
    4041           1 :     maTabs[nTab]->RemoveColBreak(nCol, bPage, bManual);
    4042             : }
    4043             : 
    4044           6 : Sequence<TablePageBreakData> ScDocument::GetRowBreakData(SCTAB nTab) const
    4045             : {
    4046           6 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab])
    4047           0 :         return Sequence<TablePageBreakData>();
    4048             : 
    4049           6 :     return maTabs[nTab]->GetRowBreakData();
    4050             : }
    4051             : 
    4052     7297388 : bool ScDocument::RowHidden(SCROW nRow, SCTAB nTab, SCROW* pFirstRow, SCROW* pLastRow) const
    4053             : {
    4054     7297388 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab])
    4055           0 :         return false;
    4056             : 
    4057     7297388 :     return maTabs[nTab]->RowHidden(nRow, pFirstRow, pLastRow);
    4058             : }
    4059             : 
    4060           0 : bool ScDocument::HasHiddenRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) const
    4061             : {
    4062           0 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab])
    4063           0 :         return false;
    4064             : 
    4065           0 :     return maTabs[nTab]->HasHiddenRows(nStartRow, nEndRow);
    4066             : }
    4067             : 
    4068      176002 : bool ScDocument::ColHidden(SCCOL nCol, SCTAB nTab, SCCOL* pFirstCol, SCCOL* pLastCol) const
    4069             : {
    4070      176002 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab])
    4071             :     {
    4072           0 :         if (pFirstCol)
    4073           0 :             *pFirstCol = nCol;
    4074           0 :         if (pLastCol)
    4075           0 :             *pLastCol = nCol;
    4076           0 :         return false;
    4077             :     }
    4078             : 
    4079      176002 :     return maTabs[nTab]->ColHidden(nCol, pFirstCol, pLastCol);
    4080             : }
    4081             : 
    4082          33 : void ScDocument::SetRowHidden(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bHidden)
    4083             : {
    4084          33 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab])
    4085          33 :         return;
    4086             : 
    4087          33 :     maTabs[nTab]->SetRowHidden(nStartRow, nEndRow, bHidden);
    4088             : }
    4089             : 
    4090           1 : void ScDocument::SetColHidden(SCCOL nStartCol, SCCOL nEndCol, SCTAB nTab, bool bHidden)
    4091             : {
    4092           1 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab])
    4093           1 :         return;
    4094             : 
    4095           1 :     maTabs[nTab]->SetColHidden(nStartCol, nEndCol, bHidden);
    4096             : }
    4097             : 
    4098         176 : SCROW ScDocument::FirstVisibleRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) const
    4099             : {
    4100         176 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab])
    4101           0 :         return ::std::numeric_limits<SCROW>::max();;
    4102             : 
    4103         176 :     return maTabs[nTab]->FirstVisibleRow(nStartRow, nEndRow);
    4104             : }
    4105             : 
    4106           0 : SCROW ScDocument::LastVisibleRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) const
    4107             : {
    4108           0 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab])
    4109           0 :         return ::std::numeric_limits<SCROW>::max();;
    4110             : 
    4111           0 :     return maTabs[nTab]->LastVisibleRow(nStartRow, nEndRow);
    4112             : }
    4113             : 
    4114          40 : SCROW ScDocument::CountVisibleRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) const
    4115             : {
    4116          40 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab])
    4117           0 :         return 0;
    4118             : 
    4119          40 :     return maTabs[nTab]->CountVisibleRows(nStartRow, nEndRow);
    4120             : }
    4121             : 
    4122     3145969 : bool ScDocument::RowFiltered(SCROW nRow, SCTAB nTab, SCROW* pFirstRow, SCROW* pLastRow) const
    4123             : {
    4124     3145969 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab])
    4125           0 :         return false;
    4126             : 
    4127     3145969 :     return maTabs[nTab]->RowFiltered(nRow, pFirstRow, pLastRow);
    4128             : }
    4129             : 
    4130         894 : bool ScDocument::HasFilteredRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) const
    4131             : {
    4132         894 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab])
    4133           0 :         return false;
    4134             : 
    4135         894 :     return maTabs[nTab]->HasFilteredRows(nStartRow, nEndRow);
    4136             : }
    4137             : 
    4138          14 : bool ScDocument::ColFiltered(SCCOL nCol, SCTAB nTab, SCCOL* pFirstCol, SCCOL* pLastCol) const
    4139             : {
    4140          14 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab])
    4141           0 :         return false;
    4142             : 
    4143          14 :     return maTabs[nTab]->ColFiltered(nCol, pFirstCol, pLastCol);
    4144             : }
    4145             : 
    4146          39 : void ScDocument::SetRowFiltered(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bFiltered)
    4147             : {
    4148          39 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab])
    4149          39 :         return;
    4150             : 
    4151          39 :     maTabs[nTab]->SetRowFiltered(nStartRow, nEndRow, bFiltered);
    4152             : }
    4153             : 
    4154             : 
    4155          34 : SCROW ScDocument::FirstNonFilteredRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) const
    4156             : {
    4157          34 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab])
    4158           0 :         return ::std::numeric_limits<SCROW>::max();;
    4159             : 
    4160          34 :     return maTabs[nTab]->FirstNonFilteredRow(nStartRow, nEndRow);
    4161             : }
    4162             : 
    4163           0 : SCROW ScDocument::LastNonFilteredRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) const
    4164             : {
    4165           0 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab])
    4166           0 :         return ::std::numeric_limits<SCROW>::max();;
    4167             : 
    4168           0 :     return maTabs[nTab]->LastNonFilteredRow(nStartRow, nEndRow);
    4169             : }
    4170             : 
    4171          64 : SCROW ScDocument::CountNonFilteredRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) const
    4172             : {
    4173          64 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab])
    4174           0 :         return 0;
    4175             : 
    4176          64 :     return maTabs[nTab]->CountNonFilteredRows(nStartRow, nEndRow);
    4177             : }
    4178             : 
    4179           7 : bool ScDocument::IsManualRowHeight(SCROW nRow, SCTAB nTab) const
    4180             : {
    4181           7 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab])
    4182           0 :         return false;
    4183             : 
    4184           7 :     return maTabs[nTab]->IsManualRowHeight(nRow);
    4185             : }
    4186             : 
    4187           9 : void ScDocument::SyncColRowFlags()
    4188             : {
    4189           9 :     TableContainer::iterator it = maTabs.begin();
    4190          20 :     for (; it != maTabs.end(); ++it)
    4191             :     {
    4192          11 :         if (*it)
    4193          11 :             (*it)->SyncColRowFlags();
    4194             :     }
    4195           9 : }
    4196             : 
    4197          14 : SCROW ScDocument::GetLastFlaggedRow( SCTAB nTab ) const
    4198             : {
    4199          14 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    4200          14 :         return maTabs[nTab]->GetLastFlaggedRow();
    4201           0 :     return 0;
    4202             : }
    4203             : 
    4204             : 
    4205           9 : SCCOL ScDocument::GetLastChangedCol( SCTAB nTab ) const
    4206             : {
    4207           9 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    4208           9 :         return maTabs[nTab]->GetLastChangedCol();
    4209           0 :     return 0;
    4210             : }
    4211             : 
    4212           9 : SCROW ScDocument::GetLastChangedRow( SCTAB nTab ) const
    4213             : {
    4214           9 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    4215           9 :         return maTabs[nTab]->GetLastChangedRow();
    4216           0 :     return 0;
    4217             : }
    4218             : 
    4219             : 
    4220          10 : SCCOL ScDocument::GetNextDifferentChangedCol( SCTAB nTab, SCCOL nStart) const
    4221             : {
    4222          10 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    4223             :     {
    4224          10 :         sal_uInt8 nStartFlags = maTabs[nTab]->GetColFlags(nStart);
    4225          10 :         sal_uInt16 nStartWidth = maTabs[nTab]->GetOriginalWidth(nStart);
    4226        9216 :         for (SCCOL nCol = nStart + 1; nCol <= MAXCOL; nCol++)
    4227             :         {
    4228       27621 :             if (((nStartFlags & CR_MANUALBREAK) != (maTabs[nTab]->GetColFlags(nCol) & CR_MANUALBREAK)) ||
    4229       18413 :                 (nStartWidth != maTabs[nTab]->GetOriginalWidth(nCol)) ||
    4230        9206 :                 ((nStartFlags & CR_HIDDEN) != (maTabs[nTab]->GetColFlags(nCol) & CR_HIDDEN)) )
    4231           1 :                 return nCol;
    4232             :         }
    4233           9 :         return MAXCOL+1;
    4234             :     }
    4235           0 :     return 0;
    4236             : }
    4237             : 
    4238          13 : SCROW ScDocument::GetNextDifferentChangedRow( SCTAB nTab, SCROW nStart, bool bCareManualSize) const
    4239             : {
    4240          13 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab])
    4241           0 :         return 0;
    4242             : 
    4243          13 :     const ScBitMaskCompressedArray<SCROW, sal_uInt8>* pRowFlagsArray = maTabs[nTab]->GetRowFlagsArray();
    4244          13 :     if (!pRowFlagsArray)
    4245           0 :         return 0;
    4246             : 
    4247          13 :     if (!maTabs[nTab]->mpRowHeights || !maTabs[nTab]->mpHiddenRows)
    4248           0 :         return 0;
    4249             : 
    4250             :     size_t nIndex;          // ignored
    4251             :     SCROW nFlagsEndRow;
    4252             :     SCROW nHiddenEndRow;
    4253             :     SCROW nHeightEndRow;
    4254             :     sal_uInt8 nFlags;
    4255             :     bool bHidden;
    4256             :     sal_uInt16 nHeight;
    4257          13 :     sal_uInt8 nStartFlags = nFlags = pRowFlagsArray->GetValue( nStart, nIndex, nFlagsEndRow);
    4258          13 :     bool bStartHidden = bHidden = maTabs[nTab]->RowHidden( nStart, NULL, &nHiddenEndRow);
    4259          13 :     sal_uInt16 nStartHeight = nHeight = maTabs[nTab]->GetRowHeight( nStart, NULL, &nHeightEndRow, false);
    4260             :     SCROW nRow;
    4261          26 :     while ((nRow = std::min( nHiddenEndRow, std::min( nFlagsEndRow, nHeightEndRow)) + 1) <= MAXROW)
    4262             :     {
    4263           4 :         if (nFlagsEndRow < nRow)
    4264           0 :             nFlags = pRowFlagsArray->GetValue( nRow, nIndex, nFlagsEndRow);
    4265           4 :         if (nHiddenEndRow < nRow)
    4266           0 :             bHidden = maTabs[nTab]->RowHidden( nRow, NULL, &nHiddenEndRow);
    4267           4 :         if (nHeightEndRow < nRow)
    4268           4 :             nHeight = maTabs[nTab]->GetRowHeight( nRow, NULL, &nHeightEndRow, false);
    4269             : 
    4270           8 :         if (((nStartFlags & CR_MANUALBREAK) != (nFlags & CR_MANUALBREAK)) ||
    4271           8 :             ((nStartFlags & CR_MANUALSIZE) != (nFlags & CR_MANUALSIZE)) ||
    4272           4 :             (bStartHidden != bHidden) ||
    4273           4 :             (bCareManualSize && (nStartFlags & CR_MANUALSIZE) && (nStartHeight != nHeight)) ||
    4274           8 :             (!bCareManualSize && ((nStartHeight != nHeight))))
    4275           4 :             return nRow;
    4276             :     }
    4277             : 
    4278           9 :     return MAXROW+1;
    4279             : }
    4280             : 
    4281        2080 : bool ScDocument::GetColDefault( SCTAB nTab, SCCOL nCol, SCROW nLastRow, SCROW& nDefault)
    4282             : {
    4283        2080 :     bool bRet(false);
    4284        2080 :     nDefault = 0;
    4285        2080 :     ScDocAttrIterator aDocAttrItr(this, nTab, nCol, 0, nCol, nLastRow);
    4286             :     SCCOL nColumn;
    4287             :     SCROW nStartRow;
    4288             :     SCROW nEndRow;
    4289        2080 :     const ScPatternAttr* pAttr = aDocAttrItr.GetNext(nColumn, nStartRow, nEndRow);
    4290        2080 :     if (nEndRow < nLastRow)
    4291             :     {
    4292          14 :         ScDefaultAttrSet aSet;
    4293          14 :         ScDefaultAttrSet::iterator aItr = aSet.end();
    4294          64 :         while (pAttr)
    4295             :         {
    4296          36 :             ScDefaultAttr aAttr(pAttr);
    4297          36 :             aItr = aSet.find(aAttr);
    4298          36 :             if (aItr == aSet.end())
    4299             :             {
    4300          28 :                 aAttr.nCount = static_cast<SCSIZE>(nEndRow - nStartRow + 1);
    4301          28 :                 aAttr.nFirst = nStartRow;
    4302          28 :                 aSet.insert(aAttr);
    4303             :             }
    4304             :             else
    4305             :             {
    4306           8 :                 aAttr.nCount = aItr->nCount + static_cast<SCSIZE>(nEndRow - nStartRow + 1);
    4307           8 :                 aAttr.nFirst = aItr->nFirst;
    4308           8 :                 aSet.erase(aItr);
    4309           8 :                 aSet.insert(aAttr);
    4310             :             }
    4311          36 :             pAttr = aDocAttrItr.GetNext(nColumn, nStartRow, nEndRow);
    4312             :         }
    4313          14 :         ScDefaultAttrSet::iterator aDefaultItr = aSet.begin();
    4314          14 :         aItr = aDefaultItr;
    4315          14 :         ++aItr;
    4316          42 :         while (aItr != aSet.end())
    4317             :         {
    4318             :             // for entries with equal count, use the one with the lowest start row,
    4319             :             // don't use the random order of pointer comparisons
    4320          28 :             if ( aItr->nCount > aDefaultItr->nCount ||
    4321           8 :                  ( aItr->nCount == aDefaultItr->nCount && aItr->nFirst < aDefaultItr->nFirst ) )
    4322           6 :                 aDefaultItr = aItr;
    4323          14 :             ++aItr;
    4324             :         }
    4325          14 :         nDefault = aDefaultItr->nFirst;
    4326          14 :         bRet = true;
    4327             :     }
    4328             :     else
    4329        2066 :         bRet = true;
    4330        2080 :     return bRet;
    4331             : }
    4332             : 
    4333     3145745 : bool ScDocument::GetRowDefault( SCTAB /* nTab */, SCROW /* nRow */, SCCOL /* nLastCol */, SCCOL& /* nDefault */ )
    4334             : {
    4335     3145745 :     return false;
    4336             : }
    4337             : 
    4338        9444 : void ScDocument::StripHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2, SCTAB nTab )
    4339             : {
    4340        9444 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    4341        9444 :         maTabs[nTab]->StripHidden( rX1, rY1, rX2, rY2 );
    4342        9444 : }
    4343             : 
    4344             : 
    4345        9467 : void ScDocument::ExtendHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2, SCTAB nTab )
    4346             : {
    4347        9467 :     if ( ValidTab(nTab) && maTabs[nTab] )
    4348        9467 :         maTabs[nTab]->ExtendHidden( rX1, rY1, rX2, rY2 );
    4349        9467 : }
    4350             : 
    4351             : //
    4352             : //  Attribute   ----------------------------------------------------------
    4353             : //
    4354             : 
    4355        9781 : const SfxPoolItem* ScDocument::GetAttr( SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt16 nWhich ) const
    4356             : {
    4357        9781 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    4358             :     {
    4359        9781 :         const SfxPoolItem* pTemp = maTabs[nTab]->GetAttr( nCol, nRow, nWhich );
    4360        9781 :         if (pTemp)
    4361        9781 :             return pTemp;
    4362             :         else
    4363             :         {
    4364             :             OSL_FAIL( "Attribut Null" );
    4365             :         }
    4366             :     }
    4367           0 :     return &xPoolHelper->GetDocPool()->GetDefaultItem( nWhich );
    4368             : }
    4369             : 
    4370        1330 : const SfxPoolItem* ScDocument::GetAttr( const ScAddress& rPos, sal_uInt16 nWhich ) const
    4371             : {
    4372        1330 :     return GetAttr(rPos.Col(), rPos.Row(), rPos.Tab(), nWhich);
    4373             : }
    4374             : 
    4375       18053 : const ScPatternAttr* ScDocument::GetPattern( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
    4376             : {
    4377       18053 :     if (TableExists(nTab))
    4378       18053 :         return maTabs[nTab]->GetPattern( nCol, nRow );
    4379           0 :     return NULL;
    4380             : }
    4381             : 
    4382           0 : const ScPatternAttr* ScDocument::GetPattern( const ScAddress& rPos ) const
    4383             : {
    4384           0 :     if (TableExists(rPos.Tab()))
    4385           0 :         return maTabs[rPos.Tab()]->GetPattern(rPos.Col(), rPos.Row());
    4386             : 
    4387           0 :     return NULL;
    4388             : }
    4389             : 
    4390       10496 : const ScPatternAttr* ScDocument::GetMostUsedPattern( SCCOL nCol, SCROW nStartRow, SCROW nEndRow, SCTAB nTab ) const
    4391             : {
    4392       10496 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    4393       10496 :         return maTabs[nTab]->GetMostUsedPattern( nCol, nStartRow, nEndRow );
    4394           0 :     return NULL;
    4395             : }
    4396             : 
    4397             : 
    4398        2121 : void ScDocument::ApplyAttr( SCCOL nCol, SCROW nRow, SCTAB nTab, const SfxPoolItem& rAttr )
    4399             : {
    4400        2121 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    4401        2121 :         maTabs[nTab]->ApplyAttr( nCol, nRow, rAttr );
    4402        2121 : }
    4403             : 
    4404             : 
    4405           9 : void ScDocument::ApplyPattern( SCCOL nCol, SCROW nRow, SCTAB nTab, const ScPatternAttr& rAttr )
    4406             : {
    4407           9 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    4408           9 :         maTabs[nTab]->ApplyPattern( nCol, nRow, rAttr );
    4409           9 : }
    4410             : 
    4411             : 
    4412         632 : void ScDocument::ApplyPatternArea( SCCOL nStartCol, SCROW nStartRow,
    4413             :                         SCCOL nEndCol, SCROW nEndRow,
    4414             :                         const ScMarkData& rMark,
    4415             :                         const ScPatternAttr& rAttr,
    4416             :                         ScEditDataArray* pDataArray )
    4417             : {
    4418         632 :     SCTAB nMax = static_cast<SCTAB>(maTabs.size());
    4419         632 :     ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
    4420        1264 :     for (; itr != itrEnd && *itr < nMax; ++itr)
    4421         632 :         if (maTabs[*itr])
    4422         632 :             maTabs[*itr]->ApplyPatternArea( nStartCol, nStartRow, nEndCol, nEndRow, rAttr, pDataArray );
    4423         632 : }
    4424             : 
    4425             : 
    4426          98 : void ScDocument::ApplyPatternAreaTab( SCCOL nStartCol, SCROW nStartRow,
    4427             :                         SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, const ScPatternAttr& rAttr )
    4428             : {
    4429          98 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()))
    4430          98 :         if (maTabs[nTab])
    4431          98 :             maTabs[nTab]->ApplyPatternArea( nStartCol, nStartRow, nEndCol, nEndRow, rAttr );
    4432          98 : }
    4433             : 
    4434       25281 : bool ScDocument::SetAttrEntries(SCCOL nCol, SCTAB nTab, ScAttrEntry* pData, SCSIZE nSize)
    4435             : {
    4436       25281 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab])
    4437           0 :         return false;
    4438             : 
    4439       25281 :     return maTabs[nTab]->SetAttrEntries(nCol, pData, nSize);
    4440             : }
    4441             : 
    4442           0 : void ScDocument::ApplyPatternIfNumberformatIncompatible( const ScRange& rRange,
    4443             :         const ScMarkData& rMark, const ScPatternAttr& rPattern, short nNewType )
    4444             : {
    4445           0 :     SCTAB nMax = static_cast<SCTAB>(maTabs.size());
    4446           0 :     ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
    4447           0 :     for (; itr != itrEnd && *itr < nMax; ++itr)
    4448           0 :         if (maTabs[*itr])
    4449           0 :             maTabs[*itr]->ApplyPatternIfNumberformatIncompatible( rRange, rPattern, nNewType );
    4450           0 : }
    4451             : 
    4452         666 : void ScDocument::AddCondFormatData( const ScRangeList& rRange, SCTAB nTab, sal_uInt32 nIndex )
    4453             : {
    4454         666 :     if(!(static_cast<size_t>(nTab) < maTabs.size()))
    4455           0 :         return;
    4456             : 
    4457         666 :     if(!maTabs[nTab])
    4458           0 :         return;
    4459             : 
    4460         666 :     maTabs[nTab]->AddCondFormatData(rRange, nIndex);
    4461             : }
    4462             : 
    4463           0 : void ScDocument::RemoveCondFormatData( const ScRangeList& rRange, SCTAB nTab, sal_uInt32 nIndex )
    4464             : {
    4465           0 :     if(!(static_cast<size_t>(nTab) < maTabs.size()))
    4466           0 :         return;
    4467             : 
    4468           0 :     if(!maTabs[nTab])
    4469           0 :         return;
    4470             : 
    4471           0 :     maTabs[nTab]->RemoveCondFormatData(rRange, nIndex);
    4472             : }
    4473             : 
    4474             : 
    4475           0 : void ScDocument::ApplyStyle( SCCOL nCol, SCROW nRow, SCTAB nTab, const ScStyleSheet& rStyle)
    4476             : {
    4477           0 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()))
    4478           0 :         if (maTabs[nTab])
    4479           0 :             maTabs[nTab]->ApplyStyle( nCol, nRow, rStyle );
    4480           0 : }
    4481             : 
    4482             : 
    4483         446 : void ScDocument::ApplyStyleArea( SCCOL nStartCol, SCROW nStartRow,
    4484             :                         SCCOL nEndCol, SCROW nEndRow,
    4485             :                         const ScMarkData& rMark,
    4486             :                         const ScStyleSheet& rStyle)
    4487             : {
    4488         446 :     SCTAB nMax = static_cast<SCTAB>(maTabs.size());
    4489         446 :     ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
    4490         892 :     for (; itr != itrEnd && *itr < nMax; ++itr)
    4491         446 :         if (maTabs[*itr])
    4492         446 :             maTabs[*itr]->ApplyStyleArea( nStartCol, nStartRow, nEndCol, nEndRow, rStyle );
    4493         446 : }
    4494             : 
    4495             : 
    4496        1031 : void ScDocument::ApplyStyleAreaTab( SCCOL nStartCol, SCROW nStartRow,
    4497             :                         SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, const ScStyleSheet& rStyle)
    4498             : {
    4499        1031 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()))
    4500        1031 :         if (maTabs[nTab])
    4501        1031 :             maTabs[nTab]->ApplyStyleArea( nStartCol, nStartRow, nEndCol, nEndRow, rStyle );
    4502        1031 : }
    4503             : 
    4504             : 
    4505         553 : void ScDocument::ApplySelectionStyle(const ScStyleSheet& rStyle, const ScMarkData& rMark)
    4506             : {
    4507             :     // ApplySelectionStyle needs multi mark
    4508         553 :     if ( rMark.IsMarked() && !rMark.IsMultiMarked() )
    4509             :     {
    4510         446 :         ScRange aRange;
    4511         446 :         rMark.GetMarkArea( aRange );
    4512         446 :         ApplyStyleArea( aRange.aStart.Col(), aRange.aStart.Row(),
    4513         892 :                           aRange.aEnd.Col(), aRange.aEnd.Row(), rMark, rStyle );
    4514             :     }
    4515             :     else
    4516             :     {
    4517         107 :         SCTAB nMax = static_cast<SCTAB>(maTabs.size());
    4518         107 :         ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
    4519         214 :         for (; itr != itrEnd && *itr < nMax; ++itr)
    4520         107 :             if ( maTabs[*itr] )
    4521         107 :                     maTabs[*itr]->ApplySelectionStyle( rStyle, rMark );
    4522             :     }
    4523         553 : }
    4524             : 
    4525             : 
    4526           0 : void ScDocument::ApplySelectionLineStyle( const ScMarkData& rMark,
    4527             :                     const SvxBorderLine* pLine, bool bColorOnly )
    4528             : {
    4529           0 :     if ( bColorOnly && !pLine )
    4530           0 :         return;
    4531             : 
    4532           0 :     SCTAB nMax = static_cast<SCTAB>(maTabs.size());
    4533           0 :     ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
    4534           0 :     for (; itr != itrEnd && *itr < nMax; ++itr)
    4535           0 :         if (maTabs[*itr])
    4536           0 :             maTabs[*itr]->ApplySelectionLineStyle( rMark, pLine, bColorOnly );
    4537             : }
    4538             : 
    4539             : 
    4540          44 : const ScStyleSheet* ScDocument::GetStyle( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
    4541             : {
    4542          44 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    4543          44 :         return maTabs[nTab]->GetStyle(nCol, nRow);
    4544             :     else
    4545           0 :         return NULL;
    4546             : }
    4547             : 
    4548             : 
    4549          96 : const ScStyleSheet* ScDocument::GetSelectionStyle( const ScMarkData& rMark ) const
    4550             : {
    4551          96 :     bool    bEqual = true;
    4552             :     bool    bFound;
    4553             : 
    4554          96 :     const ScStyleSheet* pStyle = NULL;
    4555             :     const ScStyleSheet* pNewStyle;
    4556             : 
    4557          96 :     if ( rMark.IsMultiMarked() )
    4558             :     {
    4559          22 :         SCTAB nMax = static_cast<SCTAB>(maTabs.size());
    4560          22 :         ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
    4561          44 :         for (; itr != itrEnd && *itr < nMax; ++itr)
    4562          22 :             if (maTabs[*itr])
    4563             :             {
    4564          22 :                 pNewStyle = maTabs[*itr]->GetSelectionStyle( rMark, bFound );
    4565          22 :                 if (bFound)
    4566             :                 {
    4567          22 :                     if ( !pNewStyle || ( pStyle && pNewStyle != pStyle ) )
    4568           0 :                         bEqual = false;                                             // unterschiedliche
    4569          22 :                     pStyle = pNewStyle;
    4570             :                 }
    4571             :             }
    4572             :     }
    4573          96 :     if ( rMark.IsMarked() )
    4574             :     {
    4575          74 :         ScRange aRange;
    4576          74 :         rMark.GetMarkArea( aRange );
    4577         148 :         for (SCTAB i=aRange.aStart.Tab(); i<=aRange.aEnd.Tab() && bEqual && i < static_cast<SCTAB>(maTabs.size()); i++)
    4578          74 :             if (maTabs[i] && rMark.GetTableSelect(i))
    4579             :             {
    4580          74 :                 pNewStyle = maTabs[i]->GetAreaStyle( bFound,
    4581          74 :                                         aRange.aStart.Col(), aRange.aStart.Row(),
    4582         222 :                                         aRange.aEnd.Col(),   aRange.aEnd.Row()   );
    4583          74 :                 if (bFound)
    4584             :                 {
    4585          74 :                     if ( !pNewStyle || ( pStyle && pNewStyle != pStyle ) )
    4586           0 :                         bEqual = false;                                             // unterschiedliche
    4587          74 :                     pStyle = pNewStyle;
    4588             :                 }
    4589             :             }
    4590             :     }
    4591             : 
    4592          96 :     return bEqual ? pStyle : NULL;
    4593             : }
    4594             : 
    4595             : 
    4596        3003 : void ScDocument::StyleSheetChanged( const SfxStyleSheetBase* pStyleSheet, bool bRemoved,
    4597             :                                     OutputDevice* pDev,
    4598             :                                     double nPPTX, double nPPTY,
    4599             :                                     const Fraction& rZoomX, const Fraction& rZoomY )
    4600             : {
    4601        3003 :     TableContainer::iterator it = maTabs.begin();
    4602        6006 :     for (; it != maTabs.end(); ++it)
    4603        3003 :         if (*it)
    4604        3003 :             (*it)->StyleSheetChanged
    4605        6006 :                 ( pStyleSheet, bRemoved, pDev, nPPTX, nPPTY, rZoomX, rZoomY );
    4606             : 
    4607        3003 :     if ( pStyleSheet && pStyleSheet->GetName() == ScGlobal::GetRscString(STR_STYLENAME_STANDARD) )
    4608             :     {
    4609             :         //  update attributes for all note objects
    4610         877 :         ScDetectiveFunc::UpdateAllComments( *this );
    4611             :     }
    4612        3003 : }
    4613             : 
    4614             : 
    4615           0 : bool ScDocument::IsStyleSheetUsed( const ScStyleSheet& rStyle, bool bGatherAllStyles ) const
    4616             : {
    4617           0 :     if ( bStyleSheetUsageInvalid || rStyle.GetUsage() == ScStyleSheet::UNKNOWN )
    4618             :     {
    4619           0 :         if ( bGatherAllStyles )
    4620             :         {
    4621           0 :             SfxStyleSheetIterator aIter( xPoolHelper->GetStylePool(),
    4622           0 :                     SFX_STYLE_FAMILY_PARA );
    4623           0 :             for ( const SfxStyleSheetBase* pStyle = aIter.First(); pStyle;
    4624             :                                            pStyle = aIter.Next() )
    4625             :             {
    4626           0 :                 const ScStyleSheet* pScStyle = PTR_CAST( ScStyleSheet, pStyle );
    4627           0 :                 if ( pScStyle )
    4628           0 :                     pScStyle->SetUsage( ScStyleSheet::NOTUSED );
    4629           0 :             }
    4630             :         }
    4631             : 
    4632           0 :         bool bIsUsed = false;
    4633             : 
    4634           0 :         TableContainer::const_iterator it = maTabs.begin();
    4635           0 :         for (; it != maTabs.end(); ++it)
    4636           0 :             if (*it)
    4637             :             {
    4638           0 :                 if ( (*it)->IsStyleSheetUsed( rStyle, bGatherAllStyles ) )
    4639             :                 {
    4640           0 :                     if ( !bGatherAllStyles )
    4641           0 :                         return true;
    4642           0 :                     bIsUsed = true;
    4643             :                 }
    4644             :             }
    4645             : 
    4646           0 :         if ( bGatherAllStyles )
    4647           0 :             bStyleSheetUsageInvalid = false;
    4648             : 
    4649           0 :         return bIsUsed;
    4650             :     }
    4651             : 
    4652           0 :     return rStyle.GetUsage() == ScStyleSheet::USED;
    4653             : }
    4654             : 
    4655             : 
    4656         834 : bool ScDocument::ApplyFlagsTab( SCCOL nStartCol, SCROW nStartRow,
    4657             :                         SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, sal_Int16 nFlags )
    4658             : {
    4659         834 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()))
    4660         833 :         if (maTabs[nTab])
    4661         833 :             return maTabs[nTab]->ApplyFlags( nStartCol, nStartRow, nEndCol, nEndRow, nFlags );
    4662             : 
    4663             :     OSL_FAIL("ApplyFlags: wrong table");
    4664           1 :     return false;
    4665             : }
    4666             : 
    4667             : 
    4668         247 : bool ScDocument::RemoveFlagsTab( SCCOL nStartCol, SCROW nStartRow,
    4669             :                         SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, sal_Int16 nFlags )
    4670             : {
    4671         247 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()))
    4672         246 :         if (maTabs[nTab])
    4673         246 :             return maTabs[nTab]->RemoveFlags( nStartCol, nStartRow, nEndCol, nEndRow, nFlags );
    4674             : 
    4675             :     OSL_FAIL("RemoveFlags: wrong table");
    4676           1 :     return false;
    4677             : }
    4678             : 
    4679             : 
    4680           6 : void ScDocument::SetPattern( SCCOL nCol, SCROW nRow, SCTAB nTab, const ScPatternAttr& rAttr,
    4681             :                                 bool bPutToPool )
    4682             : {
    4683           6 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()))
    4684           6 :         if (maTabs[nTab])
    4685           6 :             maTabs[nTab]->SetPattern( nCol, nRow, rAttr, bPutToPool );
    4686           6 : }
    4687             : 
    4688             : 
    4689           0 : void ScDocument::SetPattern( const ScAddress& rPos, const ScPatternAttr& rAttr,
    4690             :                                 bool bPutToPool )
    4691             : {
    4692           0 :     SCTAB nTab = rPos.Tab();
    4693           0 :     if ( nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
    4694           0 :         maTabs[nTab]->SetPattern( rPos, rAttr, bPutToPool );
    4695           0 : }
    4696             : 
    4697             : 
    4698       10406 : ScPatternAttr* ScDocument::CreateSelectionPattern( const ScMarkData& rMark, bool bDeep )
    4699             : {
    4700       10406 :     ScMergePatternState aState;
    4701             : 
    4702       10406 :     if ( rMark.IsMultiMarked() )                                // multi selection
    4703             :     {
    4704         125 :         SCTAB nMax = static_cast<SCTAB>(maTabs.size());
    4705         125 :         ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
    4706         250 :         for (; itr != itrEnd && *itr < nMax; ++itr)
    4707         125 :             if (maTabs[*itr])
    4708         125 :                 maTabs[*itr]->MergeSelectionPattern( aState, rMark, bDeep );
    4709             :     }
    4710       10406 :     if ( rMark.IsMarked() )                                     // simle selection
    4711             :     {
    4712       10281 :         ScRange aRange;
    4713       10281 :         rMark.GetMarkArea(aRange);
    4714       10281 :         SCTAB nMax = static_cast<SCTAB>(maTabs.size());
    4715       10281 :         ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
    4716       20562 :         for (; itr != itrEnd && *itr < nMax; ++itr)
    4717       10281 :             if (maTabs[*itr])
    4718       10281 :                 maTabs[*itr]->MergePatternArea( aState,
    4719       10281 :                                 aRange.aStart.Col(), aRange.aStart.Row(),
    4720       30843 :                                 aRange.aEnd.Col(), aRange.aEnd.Row(), bDeep );
    4721             :     }
    4722             : 
    4723             :     OSL_ENSURE( aState.pItemSet, "SelectionPattern Null" );
    4724       10406 :     if (aState.pItemSet)
    4725       10406 :         return new ScPatternAttr( aState.pItemSet );
    4726             :     else
    4727           0 :         return new ScPatternAttr( GetPool() );      // empty
    4728             : }
    4729             : 
    4730             : 
    4731        4783 : const ScPatternAttr* ScDocument::GetSelectionPattern( const ScMarkData& rMark, bool bDeep )
    4732             : {
    4733        4783 :     delete pSelectionAttr;
    4734        4783 :     pSelectionAttr = CreateSelectionPattern( rMark, bDeep );
    4735        4783 :     return pSelectionAttr;
    4736             : }
    4737             : 
    4738             : 
    4739          54 : void ScDocument::GetSelectionFrame( const ScMarkData& rMark,
    4740             :                                     SvxBoxItem&     rLineOuter,
    4741             :                                     SvxBoxInfoItem& rLineInner )
    4742             : {
    4743          54 :     rLineOuter.SetLine(NULL, BOX_LINE_TOP);
    4744          54 :     rLineOuter.SetLine(NULL, BOX_LINE_BOTTOM);
    4745          54 :     rLineOuter.SetLine(NULL, BOX_LINE_LEFT);
    4746          54 :     rLineOuter.SetLine(NULL, BOX_LINE_RIGHT);
    4747          54 :     rLineOuter.SetDistance(0);
    4748             : 
    4749          54 :     rLineInner.SetLine(NULL, BOXINFO_LINE_HORI);
    4750          54 :     rLineInner.SetLine(NULL, BOXINFO_LINE_VERT);
    4751          54 :     rLineInner.SetTable(true);
    4752          54 :     rLineInner.SetDist(true);
    4753          54 :     rLineInner.SetMinDist(false);
    4754             : 
    4755          54 :     ScLineFlags aFlags;
    4756             : 
    4757          54 :     if (rMark.IsMarked())
    4758             :     {
    4759          54 :         ScRange aRange;
    4760          54 :         rMark.GetMarkArea(aRange);
    4761          54 :         rLineInner.EnableHor( aRange.aStart.Row() != aRange.aEnd.Row() );
    4762          54 :         rLineInner.EnableVer( aRange.aStart.Col() != aRange.aEnd.Col() );
    4763          54 :         SCTAB nMax = static_cast<SCTAB>(maTabs.size());
    4764          54 :         ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
    4765         108 :         for (; itr != itrEnd && *itr < nMax; ++itr)
    4766          54 :             if (maTabs[*itr])
    4767          54 :                 maTabs[*itr]->MergeBlockFrame( &rLineOuter, &rLineInner, aFlags,
    4768          54 :                                           aRange.aStart.Col(), aRange.aStart.Row(),
    4769         162 :                                           aRange.aEnd.Col(),   aRange.aEnd.Row() );
    4770             :     }
    4771             : 
    4772             :         //  Don't care Status auswerten
    4773             : 
    4774          54 :     rLineInner.SetValid( VALID_LEFT,   ( aFlags.nLeft != SC_LINE_DONTCARE ) );
    4775          54 :     rLineInner.SetValid( VALID_RIGHT,  ( aFlags.nRight != SC_LINE_DONTCARE ) );
    4776          54 :     rLineInner.SetValid( VALID_TOP,    ( aFlags.nTop != SC_LINE_DONTCARE ) );
    4777          54 :     rLineInner.SetValid( VALID_BOTTOM, ( aFlags.nBottom != SC_LINE_DONTCARE ) );
    4778          54 :     rLineInner.SetValid( VALID_HORI,   ( aFlags.nHori != SC_LINE_DONTCARE ) );
    4779          54 :     rLineInner.SetValid( VALID_VERT,   ( aFlags.nVert != SC_LINE_DONTCARE ) );
    4780          54 : }
    4781             : 
    4782             : 
    4783       21760 : bool ScDocument::HasAttrib( SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
    4784             :                             SCCOL nCol2, SCROW nRow2, SCTAB nTab2, sal_uInt16 nMask ) const
    4785             : {
    4786       21760 :     if ( nMask & HASATTR_ROTATE )
    4787             :     {
    4788             :         //  Attribut im Dokument ueberhaupt verwendet?
    4789             :         //  (wie in fillinfo)
    4790             : 
    4791       12968 :         ScDocumentPool* pPool = xPoolHelper->GetDocPool();
    4792             : 
    4793       12968 :         bool bAnyItem = false;
    4794       12968 :         sal_uInt32 nRotCount = pPool->GetItemCount2( ATTR_ROTATE_VALUE );
    4795       33211 :         for (sal_uInt32 nItem=0; nItem<nRotCount; nItem++)
    4796             :         {
    4797       20767 :             const SfxPoolItem* pItem = pPool->GetItem2( ATTR_ROTATE_VALUE, nItem );
    4798       20767 :             if ( pItem )
    4799             :             {
    4800             :                 // 90 or 270 degrees is former SvxOrientationItem - only look for other values
    4801             :                 // (see ScPatternAttr::GetCellOrientation)
    4802       20627 :                 sal_Int32 nAngle = static_cast<const SfxInt32Item*>(pItem)->GetValue();
    4803       20627 :                 if ( nAngle != 0 && nAngle != 9000 && nAngle != 27000 )
    4804             :                 {
    4805         524 :                     bAnyItem = true;
    4806         524 :                     break;
    4807             :                 }
    4808             :             }
    4809             :         }
    4810       12968 :         if (!bAnyItem)
    4811       12444 :             nMask &= ~HASATTR_ROTATE;
    4812             :     }
    4813             : 
    4814       21760 :     if ( nMask & HASATTR_RTL )
    4815             :     {
    4816             :         //  first check if right-to left is in the pool at all
    4817             :         //  (the same item is used in cell and page format)
    4818             : 
    4819           0 :         ScDocumentPool* pPool = xPoolHelper->GetDocPool();
    4820             : 
    4821           0 :         bool bHasRtl = false;
    4822           0 :         sal_uInt32 nDirCount = pPool->GetItemCount2( ATTR_WRITINGDIR );
    4823           0 :         for (sal_uInt32 nItem=0; nItem<nDirCount; nItem++)
    4824             :         {
    4825           0 :             const SfxPoolItem* pItem = pPool->GetItem2( ATTR_WRITINGDIR, nItem );
    4826           0 :             if ( pItem && ((const SvxFrameDirectionItem*)pItem)->GetValue() == FRMDIR_HORI_RIGHT_TOP )
    4827             :             {
    4828           0 :                 bHasRtl = true;
    4829           0 :                 break;
    4830             :             }
    4831             :         }
    4832           0 :         if (!bHasRtl)
    4833           0 :             nMask &= ~HASATTR_RTL;
    4834             :     }
    4835             : 
    4836       21760 :     if (!nMask)
    4837           0 :         return false;
    4838             : 
    4839       21760 :     bool bFound = false;
    4840       43509 :     for (SCTAB i=nTab1; i<=nTab2 && !bFound && i < static_cast<SCTAB>(maTabs.size()); i++)
    4841       21749 :         if (maTabs[i])
    4842             :         {
    4843       21749 :             if ( nMask & HASATTR_RTL )
    4844             :             {
    4845           0 :                 if ( GetEditTextDirection(i) == EE_HTEXTDIR_R2L )       // sheet default
    4846           0 :                     bFound = true;
    4847             :             }
    4848       21749 :             if ( nMask & HASATTR_RIGHTORCENTER )
    4849             :             {
    4850             :                 //  On a RTL sheet, don't start to look for the default left value
    4851             :                 //  (which is then logically right), instead always assume true.
    4852             :                 //  That way, ScAttrArray::HasAttrib doesn't have to handle RTL sheets.
    4853             : 
    4854        3520 :                 if ( IsLayoutRTL(i) )
    4855           1 :                     bFound = true;
    4856             :             }
    4857             : 
    4858       21749 :             if ( !bFound )
    4859       21748 :                 bFound = maTabs[i]->HasAttrib( nCol1, nRow1, nCol2, nRow2, nMask );
    4860             :         }
    4861             : 
    4862       21760 :     return bFound;
    4863             : }
    4864             : 
    4865        9142 : bool ScDocument::HasAttrib( const ScRange& rRange, sal_uInt16 nMask ) const
    4866             : {
    4867       18284 :     return HasAttrib( rRange.aStart.Col(), rRange.aStart.Row(), rRange.aStart.Tab(),
    4868       18284 :                       rRange.aEnd.Col(),   rRange.aEnd.Row(),   rRange.aEnd.Tab(),
    4869       45710 :                       nMask );
    4870             : }
    4871             : 
    4872         345 : void ScDocument::FindMaxRotCol( SCTAB nTab, RowInfo* pRowInfo, SCSIZE nArrCount,
    4873             :                                 SCCOL nX1, SCCOL nX2 ) const
    4874             : {
    4875         345 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    4876         345 :         maTabs[nTab]->FindMaxRotCol( pRowInfo, nArrCount, nX1, nX2 );
    4877             :     else
    4878             :     {
    4879             :         OSL_FAIL("FindMaxRotCol: wrong table");
    4880             :     }
    4881         345 : }
    4882             : 
    4883         143 : void ScDocument::GetBorderLines( SCCOL nCol, SCROW nRow, SCTAB nTab,
    4884             :                         const SvxBorderLine** ppLeft, const SvxBorderLine** ppTop,
    4885             :                         const SvxBorderLine** ppRight, const SvxBorderLine** ppBottom ) const
    4886             : {
    4887             :     //! Seitengrenzen fuer Druck beruecksichtigen !!!!!
    4888             : 
    4889         143 :     const SvxBoxItem* pThisAttr = (const SvxBoxItem*) GetEffItem( nCol, nRow, nTab, ATTR_BORDER );
    4890             :     OSL_ENSURE(pThisAttr,"where is the attribute?");
    4891             : 
    4892         143 :     const SvxBorderLine* pLeftLine   = pThisAttr->GetLeft();
    4893         143 :     const SvxBorderLine* pTopLine    = pThisAttr->GetTop();
    4894         143 :     const SvxBorderLine* pRightLine  = pThisAttr->GetRight();
    4895         143 :     const SvxBorderLine* pBottomLine = pThisAttr->GetBottom();
    4896             : 
    4897         143 :     if ( nCol > 0 )
    4898             :     {
    4899             :         const SvxBorderLine* pOther = ((const SvxBoxItem*)
    4900         120 :                                 GetEffItem( nCol-1, nRow, nTab, ATTR_BORDER ))->GetRight();
    4901         120 :         if ( ScHasPriority( pOther, pLeftLine ) )
    4902          19 :             pLeftLine = pOther;
    4903             :     }
    4904         143 :     if ( nRow > 0 )
    4905             :     {
    4906             :         const SvxBorderLine* pOther = ((const SvxBoxItem*)
    4907         137 :                                 GetEffItem( nCol, nRow-1, nTab, ATTR_BORDER ))->GetBottom();
    4908         137 :         if ( ScHasPriority( pOther, pTopLine ) )
    4909          18 :             pTopLine = pOther;
    4910             :     }
    4911         143 :     if ( nCol < MAXCOL )
    4912             :     {
    4913             :         const SvxBorderLine* pOther = ((const SvxBoxItem*)
    4914         143 :                                 GetEffItem( nCol+1, nRow, nTab, ATTR_BORDER ))->GetLeft();
    4915         143 :         if ( ScHasPriority( pOther, pRightLine ) )
    4916          18 :             pRightLine = pOther;
    4917             :     }
    4918         143 :     if ( nRow < MAXROW )
    4919             :     {
    4920             :         const SvxBorderLine* pOther = ((const SvxBoxItem*)
    4921         143 :                                 GetEffItem( nCol, nRow+1, nTab, ATTR_BORDER ))->GetTop();
    4922         143 :         if ( ScHasPriority( pOther, pBottomLine ) )
    4923          17 :             pBottomLine = pOther;
    4924             :     }
    4925             : 
    4926         143 :     if (ppLeft)
    4927         143 :         *ppLeft = pLeftLine;
    4928         143 :     if (ppTop)
    4929         143 :         *ppTop = pTopLine;
    4930         143 :     if (ppRight)
    4931         143 :         *ppRight = pRightLine;
    4932         143 :     if (ppBottom)
    4933         143 :         *ppBottom = pBottomLine;
    4934         143 : }
    4935             : 
    4936         159 : bool ScDocument::IsBlockEmpty( SCTAB nTab, SCCOL nStartCol, SCROW nStartRow,
    4937             :                                         SCCOL nEndCol, SCROW nEndRow, bool bIgnoreNotes ) const
    4938             : {
    4939         159 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()))
    4940         159 :         if (maTabs[nTab])
    4941         159 :             return maTabs[nTab]->IsBlockEmpty( nStartCol, nStartRow, nEndCol, nEndRow, bIgnoreNotes );
    4942             : 
    4943             :     OSL_FAIL("wrong table number");
    4944           0 :     return false;
    4945             : }
    4946             : 
    4947             : 
    4948           0 : void ScDocument::LockTable(SCTAB nTab)
    4949             : {
    4950           0 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    4951           0 :         maTabs[nTab]->LockTable();
    4952             :     else
    4953             :     {
    4954             :         OSL_FAIL("wrong table number");
    4955             :     }
    4956           0 : }
    4957             : 
    4958             : 
    4959           0 : void ScDocument::UnlockTable(SCTAB nTab)
    4960             : {
    4961           0 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    4962           0 :         maTabs[nTab]->UnlockTable();
    4963             :     else
    4964             :     {
    4965             :         OSL_FAIL("wrong table number");
    4966             :     }
    4967           0 : }
    4968             : 
    4969             : 
    4970        3184 : bool ScDocument::IsBlockEditable( SCTAB nTab, SCCOL nStartCol, SCROW nStartRow,
    4971             :                                         SCCOL nEndCol, SCROW nEndRow,
    4972             :                                         bool* pOnlyNotBecauseOfMatrix /* = NULL */ ) const
    4973             : {
    4974             :     // import into read-only document is possible
    4975        3184 :     if (!bImportingXML && !mbChangeReadOnlyEnabled && pShell && pShell->IsReadOnly())
    4976             :     {
    4977           0 :         if ( pOnlyNotBecauseOfMatrix )
    4978           0 :             *pOnlyNotBecauseOfMatrix = false;
    4979           0 :         return false;
    4980             :     }
    4981             : 
    4982        3184 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()))
    4983        3184 :         if (maTabs[nTab])
    4984        3184 :             return maTabs[nTab]->IsBlockEditable( nStartCol, nStartRow, nEndCol,
    4985        6368 :                 nEndRow, pOnlyNotBecauseOfMatrix );
    4986             : 
    4987             :     OSL_FAIL("wrong table number");
    4988           0 :     if ( pOnlyNotBecauseOfMatrix )
    4989           0 :         *pOnlyNotBecauseOfMatrix = false;
    4990           0 :     return false;
    4991             : }
    4992             : 
    4993             : 
    4994         669 : bool ScDocument::IsSelectionEditable( const ScMarkData& rMark,
    4995             :             bool* pOnlyNotBecauseOfMatrix /* = NULL */ ) const
    4996             : {
    4997             :     // import into read-only document is possible
    4998         669 :     if ( !bImportingXML && !mbChangeReadOnlyEnabled && pShell && pShell->IsReadOnly() )
    4999             :     {
    5000           0 :         if ( pOnlyNotBecauseOfMatrix )
    5001           0 :             *pOnlyNotBecauseOfMatrix = false;
    5002           0 :         return false;
    5003             :     }
    5004             : 
    5005         669 :     ScRange aRange;
    5006         669 :     rMark.GetMarkArea(aRange);
    5007             : 
    5008         669 :     bool bOk = true;
    5009         669 :     bool bMatrix = ( pOnlyNotBecauseOfMatrix != NULL );
    5010         669 :     SCTAB nMax = static_cast<SCTAB>(maTabs.size());
    5011         669 :     ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
    5012        1338 :     for (; itr != itrEnd && *itr < nMax && (bOk || bMatrix); ++itr)
    5013             :     {
    5014         669 :         if ( maTabs[*itr] )
    5015             :         {
    5016         669 :             if (rMark.IsMarked())
    5017             :             {
    5018        1806 :                 if ( !maTabs[*itr]->IsBlockEditable( aRange.aStart.Col(),
    5019         602 :                         aRange.aStart.Row(), aRange.aEnd.Col(),
    5020        2408 :                         aRange.aEnd.Row(), pOnlyNotBecauseOfMatrix ) )
    5021             :                 {
    5022           0 :                     bOk = false;
    5023           0 :                     if ( pOnlyNotBecauseOfMatrix )
    5024           0 :                         bMatrix = *pOnlyNotBecauseOfMatrix;
    5025             :                 }
    5026             :             }
    5027         669 :             if (rMark.IsMultiMarked())
    5028             :             {
    5029          67 :                 if ( !maTabs[*itr]->IsSelectionEditable( rMark, pOnlyNotBecauseOfMatrix ) )
    5030             :                 {
    5031           0 :                     bOk = false;
    5032           0 :                     if ( pOnlyNotBecauseOfMatrix )
    5033           0 :                         bMatrix = *pOnlyNotBecauseOfMatrix;
    5034             :                 }
    5035             :             }
    5036             :         }
    5037             :     }
    5038             : 
    5039         669 :     if ( pOnlyNotBecauseOfMatrix )
    5040         669 :         *pOnlyNotBecauseOfMatrix = ( !bOk && bMatrix );
    5041             : 
    5042         669 :     return bOk;
    5043             : }
    5044             : 
    5045             : 
    5046          13 : bool ScDocument::HasSelectedBlockMatrixFragment( SCCOL nStartCol, SCROW nStartRow,
    5047             :                                 SCCOL nEndCol, SCROW nEndRow,
    5048             :                                 const ScMarkData& rMark ) const
    5049             : {
    5050          13 :     bool bOk = true;
    5051          13 :     SCTAB nMax = static_cast<SCTAB>(maTabs.size());
    5052          13 :     ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
    5053          26 :     for (; itr != itrEnd && *itr < nMax && bOk; ++itr)
    5054          13 :         if (maTabs[*itr])
    5055          13 :             if (maTabs[*itr]->HasBlockMatrixFragment( nStartCol, nStartRow, nEndCol, nEndRow ))
    5056           0 :                 bOk = false;
    5057             : 
    5058          13 :     return !bOk;
    5059             : }
    5060             : 
    5061           0 : bool ScDocument::GetMatrixFormulaRange( const ScAddress& rCellPos, ScRange& rMatrix )
    5062             : {
    5063             :     //  if rCell is part of a matrix formula, return its complete range
    5064             : 
    5065           0 :     ScFormulaCell* pFCell = GetFormulaCell(rCellPos);
    5066           0 :     if (!pFCell)
    5067             :         // not a formula cell.  Bail out.
    5068           0 :         return false;
    5069             : 
    5070           0 :     ScAddress aOrigin = rCellPos;
    5071           0 :     if (!pFCell->GetMatrixOrigin(aOrigin))
    5072             :         // Failed to get the address of the matrix origin.
    5073           0 :         return false;
    5074             : 
    5075           0 :     if (aOrigin != rCellPos)
    5076             :     {
    5077           0 :         pFCell = GetFormulaCell(aOrigin);
    5078           0 :         if (!pFCell)
    5079             :             // The matrix origin cell is not a formula cell !?  Something is up...
    5080           0 :             return false;
    5081             :     }
    5082             : 
    5083             :     SCCOL nSizeX;
    5084             :     SCROW nSizeY;
    5085           0 :     pFCell->GetMatColsRows(nSizeX, nSizeY);
    5086           0 :     if (nSizeX <= 0 || nSizeY <= 0)
    5087             :     {
    5088             :         // GetMatrixEdge computes also dimensions of the matrix
    5089             :         // if not already done (may occur if document is loaded
    5090             :         // from old file format).
    5091             :         // Needs an "invalid" initialized address.
    5092           0 :         aOrigin.SetInvalid();
    5093           0 :         pFCell->GetMatrixEdge(aOrigin);
    5094           0 :         pFCell->GetMatColsRows(nSizeX, nSizeY);
    5095             :     }
    5096             : 
    5097           0 :     if (nSizeX <= 0 || nSizeY <= 0)
    5098             :         // Matrix size is still invalid. Give up.
    5099           0 :         return false;
    5100             : 
    5101           0 :     ScAddress aEnd( aOrigin.Col() + nSizeX - 1,
    5102           0 :                     aOrigin.Row() + nSizeY - 1,
    5103           0 :                     aOrigin.Tab() );
    5104             : 
    5105           0 :     rMatrix.aStart = aOrigin;
    5106           0 :     rMatrix.aEnd = aEnd;
    5107             : 
    5108           0 :     return true;
    5109             : }
    5110             : 
    5111             : 
    5112         167 : bool ScDocument::ExtendOverlapped( SCCOL& rStartCol, SCROW& rStartRow,
    5113             :                                 SCCOL nEndCol, SCROW nEndRow, SCTAB nTab ) const
    5114             : {
    5115         167 :     bool bFound = false;
    5116         167 :     if ( ValidColRow(rStartCol,rStartRow) && ValidColRow(nEndCol,nEndRow) && ValidTab(nTab) )
    5117             :     {
    5118         167 :         if (nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
    5119             :         {
    5120             :             SCCOL nCol;
    5121         167 :             SCCOL nOldCol = rStartCol;
    5122         167 :             SCROW nOldRow = rStartRow;
    5123        1402 :             for (nCol=nOldCol; nCol<=nEndCol; nCol++)
    5124        2473 :                 while (((ScMergeFlagAttr*)GetAttr(nCol,rStartRow,nTab,ATTR_MERGE_FLAG))->
    5125             :                             IsVerOverlapped())
    5126           3 :                     --rStartRow;
    5127             : 
    5128             :             //!     weiterreichen ?
    5129             : 
    5130         167 :             ScAttrArray* pAttrArray = maTabs[nTab]->aCol[nOldCol].pAttrArray;
    5131             :             SCSIZE nIndex;
    5132         167 :             pAttrArray->Search( nOldRow, nIndex );
    5133         167 :             SCROW nAttrPos = nOldRow;
    5134         537 :             while (nAttrPos<=nEndRow)
    5135             :             {
    5136             :                 OSL_ENSURE( nIndex < pAttrArray->nCount, "Wrong index in AttrArray" );
    5137             : 
    5138         406 :                 if (((ScMergeFlagAttr&)pAttrArray->pData[nIndex].pPattern->
    5139         203 :                         GetItem(ATTR_MERGE_FLAG)).IsHorOverlapped())
    5140             :                 {
    5141           5 :                     SCROW nLoopEndRow = std::min( nEndRow, pAttrArray->pData[nIndex].nRow );
    5142          10 :                     for (SCROW nAttrRow = nAttrPos; nAttrRow <= nLoopEndRow; nAttrRow++)
    5143             :                     {
    5144           5 :                         SCCOL nTempCol = nOldCol;
    5145           5 :                         do
    5146           5 :                             --nTempCol;
    5147           5 :                         while (((ScMergeFlagAttr*)GetAttr(nTempCol,nAttrRow,nTab,ATTR_MERGE_FLAG))
    5148             :                                 ->IsHorOverlapped());
    5149           5 :                         if (nTempCol < rStartCol)
    5150           5 :                             rStartCol = nTempCol;
    5151             :                     }
    5152             :                 }
    5153         203 :                 nAttrPos = pAttrArray->pData[nIndex].nRow + 1;
    5154         203 :                 ++nIndex;
    5155             :             }
    5156             :         }
    5157             :     }
    5158             :     else
    5159             :     {
    5160             :         OSL_FAIL("ExtendOverlapped: invalid range");
    5161             :     }
    5162             : 
    5163         167 :     return bFound;
    5164             : }
    5165             : 
    5166             : 
    5167          32 : bool ScDocument::ExtendMergeSel( SCCOL nStartCol, SCROW nStartRow,
    5168             :                               SCCOL& rEndCol, SCROW& rEndRow,
    5169             :                               const ScMarkData& rMark, bool bRefresh )
    5170             : {
    5171             :     // use all selected sheets from rMark
    5172             : 
    5173          32 :     bool bFound = false;
    5174          32 :     SCCOL nOldEndCol = rEndCol;
    5175          32 :     SCROW nOldEndRow = rEndRow;
    5176             : 
    5177          32 :     SCTAB nMax = static_cast<SCTAB>(maTabs.size());
    5178          32 :     ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
    5179          64 :     for (; itr != itrEnd && *itr < nMax; ++itr)
    5180          32 :         if ( maTabs[*itr] )
    5181             :         {
    5182          32 :             SCCOL nThisEndCol = nOldEndCol;
    5183          32 :             SCROW nThisEndRow = nOldEndRow;
    5184          32 :             if ( ExtendMerge( nStartCol, nStartRow, nThisEndCol, nThisEndRow, *itr, bRefresh ) )
    5185           0 :                 bFound = true;
    5186          32 :             if ( nThisEndCol > rEndCol )
    5187           0 :                 rEndCol = nThisEndCol;
    5188          32 :             if ( nThisEndRow > rEndRow )
    5189           0 :                 rEndRow = nThisEndRow;
    5190             :         }
    5191             : 
    5192          32 :     return bFound;
    5193             : }
    5194             : 
    5195             : 
    5196        4036 : bool ScDocument::ExtendMerge( SCCOL nStartCol, SCROW nStartRow,
    5197             :                               SCCOL& rEndCol,  SCROW& rEndRow,
    5198             :                               SCTAB nTab, bool bRefresh )
    5199             : {
    5200        4036 :     bool bFound = false;
    5201        4036 :     if ( ValidColRow(nStartCol,nStartRow) && ValidColRow(rEndCol,rEndRow) && ValidTab(nTab) )
    5202             :     {
    5203        4036 :         if (nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
    5204        4036 :             bFound = maTabs[nTab]->ExtendMerge( nStartCol, nStartRow, rEndCol, rEndRow, bRefresh );
    5205             : 
    5206        4036 :         if (bRefresh)
    5207         132 :             RefreshAutoFilter( nStartCol, nStartRow, rEndCol, rEndRow, nTab );
    5208             :     }
    5209             :     else
    5210             :     {
    5211             :         OSL_FAIL("ExtendMerge: invalid range");
    5212             :     }
    5213             : 
    5214        4036 :     return bFound;
    5215             : }
    5216             : 
    5217             : 
    5218         249 : bool ScDocument::ExtendMerge( ScRange& rRange, bool bRefresh )
    5219             : {
    5220         249 :     bool bFound = false;
    5221         249 :     SCTAB nStartTab = rRange.aStart.Tab();
    5222         249 :     SCTAB nEndTab   = rRange.aEnd.Tab();
    5223         249 :     SCCOL nEndCol   = rRange.aEnd.Col();
    5224         249 :     SCROW nEndRow   = rRange.aEnd.Row();
    5225             : 
    5226         249 :     PutInOrder( nStartTab, nEndTab );
    5227         497 :     for (SCTAB nTab = nStartTab; nTab <= nEndTab && nTab < static_cast<SCTAB>(maTabs.size()); nTab++ )
    5228             :     {
    5229         248 :         SCCOL nExtendCol = rRange.aEnd.Col();
    5230         248 :         SCROW nExtendRow = rRange.aEnd.Row();
    5231         496 :         if (ExtendMerge( rRange.aStart.Col(), rRange.aStart.Row(),
    5232             :                          nExtendCol,          nExtendRow,
    5233         496 :                          nTab, bRefresh ) )
    5234             :         {
    5235          23 :             bFound = true;
    5236          23 :             if (nExtendCol > nEndCol) nEndCol = nExtendCol;
    5237          23 :             if (nExtendRow > nEndRow) nEndRow = nExtendRow;
    5238             :         }
    5239             :     }
    5240             : 
    5241         249 :     rRange.aEnd.SetCol(nEndCol);
    5242         249 :     rRange.aEnd.SetRow(nEndRow);
    5243             : 
    5244         249 :     return bFound;
    5245             : }
    5246             : 
    5247           0 : bool ScDocument::ExtendTotalMerge( ScRange& rRange ) const
    5248             : {
    5249             :     //  Bereich genau dann auf zusammengefasste Zellen erweitern, wenn
    5250             :     //  dadurch keine neuen nicht-ueberdeckten Zellen getroffen werden
    5251             : 
    5252           0 :     bool bRet = false;
    5253           0 :     ScRange aExt = rRange;
    5254             :     // ExtendMerge() is non-const, but called withouth refresh.
    5255           0 :     if (const_cast<ScDocument*>(this)->ExtendMerge( aExt, false))
    5256             :     {
    5257           0 :         if ( aExt.aEnd.Row() > rRange.aEnd.Row() )
    5258             :         {
    5259           0 :             ScRange aTest = aExt;
    5260           0 :             aTest.aStart.SetRow( rRange.aEnd.Row() + 1 );
    5261           0 :             if ( HasAttrib( aTest, HASATTR_NOTOVERLAPPED ) )
    5262           0 :                 aExt.aEnd.SetRow(rRange.aEnd.Row());
    5263             :         }
    5264           0 :         if ( aExt.aEnd.Col() > rRange.aEnd.Col() )
    5265             :         {
    5266           0 :             ScRange aTest = aExt;
    5267           0 :             aTest.aStart.SetCol( rRange.aEnd.Col() + 1 );
    5268           0 :             if ( HasAttrib( aTest, HASATTR_NOTOVERLAPPED ) )
    5269           0 :                 aExt.aEnd.SetCol(rRange.aEnd.Col());
    5270             :         }
    5271             : 
    5272           0 :         bRet = ( aExt.aEnd != rRange.aEnd );
    5273           0 :         rRange = aExt;
    5274             :     }
    5275           0 :     return bRet;
    5276             : }
    5277             : 
    5278         136 : bool ScDocument::ExtendOverlapped( ScRange& rRange ) const
    5279             : {
    5280         136 :     bool bFound = false;
    5281         136 :     SCTAB nStartTab = rRange.aStart.Tab();
    5282         136 :     SCTAB nEndTab   = rRange.aEnd.Tab();
    5283         136 :     SCCOL nStartCol = rRange.aStart.Col();
    5284         136 :     SCROW nStartRow = rRange.aStart.Row();
    5285             : 
    5286         136 :     PutInOrder( nStartTab, nEndTab );
    5287         272 :     for (SCTAB nTab = nStartTab; nTab <= nEndTab && nTab < static_cast<SCTAB>(maTabs.size()); nTab++ )
    5288             :     {
    5289         136 :         SCCOL nExtendCol = rRange.aStart.Col();
    5290         136 :         SCROW nExtendRow = rRange.aStart.Row();
    5291             :         ExtendOverlapped( nExtendCol, nExtendRow,
    5292         136 :                                 rRange.aEnd.Col(), rRange.aEnd.Row(), nTab );
    5293         136 :         if (nExtendCol < nStartCol)
    5294             :         {
    5295           5 :             nStartCol = nExtendCol;
    5296           5 :             bFound = true;
    5297             :         }
    5298         136 :         if (nExtendRow < nStartRow)
    5299             :         {
    5300           2 :             nStartRow = nExtendRow;
    5301           2 :             bFound = true;
    5302             :         }
    5303             :     }
    5304             : 
    5305         136 :     rRange.aStart.SetCol(nStartCol);
    5306         136 :     rRange.aStart.SetRow(nStartRow);
    5307             : 
    5308         136 :     return bFound;
    5309             : }
    5310             : 
    5311         141 : bool ScDocument::RefreshAutoFilter( SCCOL nStartCol, SCROW nStartRow,
    5312             :                                     SCCOL nEndCol, SCROW nEndRow, SCTAB nTab )
    5313             : {
    5314             :     SCTAB nDBTab;
    5315             :     SCCOL nDBStartCol;
    5316             :     SCROW nDBStartRow;
    5317             :     SCCOL nDBEndCol;
    5318             :     SCROW nDBEndRow;
    5319             : 
    5320             :     //      Autofilter loeschen
    5321             : 
    5322         141 :     bool bChange = RemoveFlagsTab( nStartCol,nStartRow, nEndCol,nEndRow, nTab, SC_MF_AUTO );
    5323             : 
    5324             :     //      Autofilter setzen
    5325             : 
    5326         141 :     const ScDBData* pData = NULL;
    5327         141 :     ScDBCollection::NamedDBs& rDBs = pDBCollection->getNamedDBs();
    5328         141 :     ScDBCollection::NamedDBs::const_iterator itr = rDBs.begin(), itrEnd = rDBs.end();
    5329         141 :     for (; itr != itrEnd; ++itr)
    5330             :     {
    5331           0 :         if (itr->HasAutoFilter())
    5332             :         {
    5333           0 :             itr->GetArea( nDBTab, nDBStartCol,nDBStartRow, nDBEndCol,nDBEndRow );
    5334           0 :             if ( nDBTab==nTab && nDBStartRow<=nEndRow && nDBEndRow>=nStartRow &&
    5335           0 :                                     nDBStartCol<=nEndCol && nDBEndCol>=nStartCol )
    5336             :             {
    5337           0 :                 if (ApplyFlagsTab( nDBStartCol,nDBStartRow, nDBEndCol,nDBStartRow,
    5338           0 :                                     nDBTab, SC_MF_AUTO ))
    5339           0 :                     bChange = true;
    5340             :             }
    5341             :         }
    5342             :     }
    5343         141 :     if (nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
    5344         141 :         pData = maTabs[nTab]->GetAnonymousDBData();
    5345             :     else
    5346           0 :         pData=NULL;
    5347         141 :     if (pData)
    5348             :     {
    5349          14 :         if (pData->HasAutoFilter())
    5350             :         {
    5351           0 :             pData->GetArea( nDBTab, nDBStartCol,nDBStartRow, nDBEndCol,nDBEndRow );
    5352           0 :             if ( nDBTab==nTab && nDBStartRow<=nEndRow && nDBEndRow>=nStartRow &&
    5353           0 :                                     nDBStartCol<=nEndCol && nDBEndCol>=nStartCol )
    5354             :             {
    5355           0 :                 if (ApplyFlagsTab( nDBStartCol,nDBStartRow, nDBEndCol,nDBStartRow,
    5356           0 :                                     nDBTab, SC_MF_AUTO ))
    5357           0 :                     bChange = true;
    5358             :             }
    5359             :         }
    5360             :     }
    5361         141 :     return bChange;
    5362             : }
    5363             : 
    5364          75 : void ScDocument::SkipOverlapped( SCCOL& rCol, SCROW& rRow, SCTAB nTab ) const
    5365             : {
    5366         150 :     while (IsHorOverlapped(rCol, rRow, nTab))
    5367           0 :         --rCol;
    5368         150 :     while (IsVerOverlapped(rCol, rRow, nTab))
    5369           0 :         --rRow;
    5370          75 : }
    5371             : 
    5372          86 : bool ScDocument::IsHorOverlapped( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
    5373             : {
    5374             :     const ScMergeFlagAttr* pAttr = (const ScMergeFlagAttr*)
    5375          86 :                                         GetAttr( nCol, nRow, nTab, ATTR_MERGE_FLAG );
    5376          86 :     if (pAttr)
    5377          86 :         return pAttr->IsHorOverlapped();
    5378             :     else
    5379             :     {
    5380             :         OSL_FAIL("Overlapped: Attr==0");
    5381           0 :         return false;
    5382             :     }
    5383             : }
    5384             : 
    5385             : 
    5386          86 : bool ScDocument::IsVerOverlapped( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
    5387             : {
    5388             :     const ScMergeFlagAttr* pAttr = (const ScMergeFlagAttr*)
    5389          86 :                                         GetAttr( nCol, nRow, nTab, ATTR_MERGE_FLAG );
    5390          86 :     if (pAttr)
    5391          86 :         return pAttr->IsVerOverlapped();
    5392             :     else
    5393             :     {
    5394             :         OSL_FAIL("Overlapped: Attr==0");
    5395           0 :         return false;
    5396             :     }
    5397             : }
    5398             : 
    5399             : 
    5400           4 : void ScDocument::ApplySelectionFrame( const ScMarkData& rMark,
    5401             :                                       const SvxBoxItem* pLineOuter,
    5402             :                                       const SvxBoxInfoItem* pLineInner )
    5403             : {
    5404           4 :     ScRangeList aRangeList;
    5405           4 :     rMark.FillRangeListWithMarks( &aRangeList, false );
    5406           4 :     size_t nRangeCount = aRangeList.size();
    5407           4 :     SCTAB nMax = static_cast<SCTAB>(maTabs.size());
    5408           4 :     ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
    5409           8 :     for (; itr != itrEnd && *itr < nMax; ++itr)
    5410             :     {
    5411           4 :         if (maTabs[*itr])
    5412             :         {
    5413           8 :             for ( size_t j=0; j < nRangeCount; j++ )
    5414             :             {
    5415           4 :                 ScRange aRange = *aRangeList[ j ];
    5416           4 :                 maTabs[*itr]->ApplyBlockFrame( pLineOuter, pLineInner,
    5417           4 :                     aRange.aStart.Col(), aRange.aStart.Row(),
    5418          12 :                     aRange.aEnd.Col(),   aRange.aEnd.Row() );
    5419             :             }
    5420             :         }
    5421           4 :     }
    5422           4 : }
    5423             : 
    5424             : 
    5425         850 : void ScDocument::ApplyFrameAreaTab( const ScRange& rRange,
    5426             :                                     const SvxBoxItem* pLineOuter,
    5427             :                                     const SvxBoxInfoItem* pLineInner )
    5428             : {
    5429         850 :     SCTAB nStartTab = rRange.aStart.Tab();
    5430         850 :     SCTAB nEndTab = rRange.aStart.Tab();
    5431        1700 :     for (SCTAB nTab=nStartTab; nTab<=nEndTab && nTab < static_cast<SCTAB>(maTabs.size()); nTab++)
    5432         850 :         if (maTabs[nTab])
    5433         850 :             maTabs[nTab]->ApplyBlockFrame( pLineOuter, pLineInner,
    5434         850 :                                          rRange.aStart.Col(), rRange.aStart.Row(),
    5435        2550 :                                          rRange.aEnd.Col(),   rRange.aEnd.Row() );
    5436         850 : }
    5437             : 
    5438             : 
    5439         699 : void ScDocument::ApplySelectionPattern( const ScPatternAttr& rAttr, const ScMarkData& rMark, ScEditDataArray* pDataArray )
    5440             : {
    5441         699 :     const SfxItemSet* pSet = &rAttr.GetItemSet();
    5442         699 :     bool bSet = false;
    5443             :     sal_uInt16 i;
    5444       20391 :     for (i=ATTR_PATTERN_START; i<=ATTR_PATTERN_END && !bSet; i++)
    5445       19692 :         if (pSet->GetItemState(i) == SFX_ITEM_SET)
    5446         699 :             bSet = true;
    5447             : 
    5448         699 :     if (bSet)
    5449             :     {
    5450             :         // ApplySelectionCache needs multi mark
    5451         699 :         if ( rMark.IsMarked() && !rMark.IsMultiMarked() )
    5452             :         {
    5453         632 :             ScRange aRange;
    5454         632 :             rMark.GetMarkArea( aRange );
    5455         632 :             ApplyPatternArea( aRange.aStart.Col(), aRange.aStart.Row(),
    5456        1264 :                               aRange.aEnd.Col(), aRange.aEnd.Row(), rMark, rAttr, pDataArray );
    5457             :         }
    5458             :         else
    5459             :         {
    5460          67 :             SfxItemPoolCache aCache( xPoolHelper->GetDocPool(), pSet );
    5461          67 :             SCTAB nMax = static_cast<SCTAB>(maTabs.size());
    5462          67 :             ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
    5463         134 :             for (; itr != itrEnd && *itr < nMax; ++itr)
    5464          67 :                 if (maTabs[*itr])
    5465         134 :                     maTabs[*itr]->ApplySelectionCache( &aCache, rMark, pDataArray );
    5466             :         }
    5467             :     }
    5468         699 : }
    5469             : 
    5470             : 
    5471           6 : void ScDocument::ChangeSelectionIndent( bool bIncrement, const ScMarkData& rMark )
    5472             : {
    5473           6 :     SCTAB nMax = static_cast<SCTAB>(maTabs.size());
    5474           6 :     ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
    5475          12 :     for (; itr != itrEnd && *itr < nMax; ++itr)
    5476           6 :         if (maTabs[*itr])
    5477           6 :             maTabs[*itr]->ChangeSelectionIndent( bIncrement, rMark );
    5478           6 : }
    5479             : 
    5480             : 
    5481           0 : void ScDocument::ClearSelectionItems( const sal_uInt16* pWhich, const ScMarkData& rMark )
    5482             : {
    5483           0 :     SCTAB nMax = static_cast<SCTAB>(maTabs.size());
    5484           0 :     ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
    5485           0 :     for (; itr != itrEnd && *itr < nMax; ++itr)
    5486           0 :         if (maTabs[*itr])
    5487           0 :             maTabs[*itr]->ClearSelectionItems( pWhich, rMark );
    5488           0 : }
    5489             : 
    5490             : 
    5491          78 : void ScDocument::DeleteSelection( sal_uInt16 nDelFlag, const ScMarkData& rMark )
    5492             : {
    5493          78 :     SCTAB nMax = static_cast<SCTAB>(maTabs.size());
    5494          78 :     ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
    5495         156 :     for (; itr != itrEnd && *itr < nMax; ++itr)
    5496          78 :         if (maTabs[*itr])
    5497          78 :             maTabs[*itr]->DeleteSelection( nDelFlag, rMark );
    5498          78 : }
    5499             : 
    5500             : 
    5501           0 : void ScDocument::DeleteSelectionTab( SCTAB nTab, sal_uInt16 nDelFlag, const ScMarkData& rMark )
    5502             : {
    5503           0 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
    5504           0 :         maTabs[nTab]->DeleteSelection( nDelFlag, rMark );
    5505             :     else
    5506             :     {
    5507             :         OSL_FAIL("wrong table");
    5508             :     }
    5509           0 : }
    5510             : 
    5511             : 
    5512     1713098 : ScPatternAttr* ScDocument::GetDefPattern() const
    5513             : {
    5514     1713098 :     return (ScPatternAttr*) &xPoolHelper->GetDocPool()->GetDefaultItem(ATTR_PATTERN);
    5515             : }
    5516             : 
    5517             : 
    5518     1952466 : ScDocumentPool* ScDocument::GetPool()
    5519             : {
    5520     1952466 :     return xPoolHelper->GetDocPool();
    5521             : }
    5522             : 
    5523             : 
    5524             : 
    5525       32902 : ScStyleSheetPool* ScDocument::GetStyleSheetPool() const
    5526             : {
    5527       32902 :     return xPoolHelper->GetStylePool();
    5528             : }
    5529             : 
    5530             : 
    5531        2369 : SCSIZE ScDocument::GetEmptyLinesInBlock( SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab,
    5532             :                             SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, ScDirection eDir )
    5533             : {
    5534        2369 :     PutInOrder(nStartCol, nEndCol);
    5535        2369 :     PutInOrder(nStartRow, nEndRow);
    5536        2369 :     PutInOrder(nStartTab, nEndTab);
    5537        2369 :     if (ValidTab(nStartTab) && nStartTab < static_cast<SCTAB>(maTabs.size()))
    5538             :     {
    5539        2369 :         if (maTabs[nStartTab])
    5540        2369 :             return maTabs[nStartTab]->GetEmptyLinesInBlock(nStartCol, nStartRow, nEndCol, nEndRow, eDir);
    5541             :         else
    5542           0 :             return 0;
    5543             :     }
    5544             :     else
    5545           0 :         return 0;
    5546             : }
    5547             : 
    5548             : 
    5549          26 : void ScDocument::FindAreaPos( SCCOL& rCol, SCROW& rRow, SCTAB nTab, ScMoveDirection eDirection ) const
    5550             : {
    5551          26 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
    5552          26 :         maTabs[nTab]->FindAreaPos( rCol, rRow, eDirection );
    5553          26 : }
    5554             : 
    5555             : 
    5556           0 : void ScDocument::GetNextPos( SCCOL& rCol, SCROW& rRow, SCTAB nTab, SCsCOL nMovX, SCsROW nMovY,
    5557             :                                 bool bMarked, bool bUnprotected, const ScMarkData& rMark ) const
    5558             : {
    5559             :     OSL_ENSURE( !nMovX || !nMovY, "GetNextPos: only X or Y" );
    5560             : 
    5561           0 :     ScMarkData aCopyMark = rMark;
    5562           0 :     aCopyMark.SetMarking(false);
    5563           0 :     aCopyMark.MarkToMulti();
    5564             : 
    5565           0 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
    5566           0 :         maTabs[nTab]->GetNextPos( rCol, rRow, nMovX, nMovY, bMarked, bUnprotected, aCopyMark );
    5567           0 : }
    5568             : 
    5569             : //
    5570             : //  Datei-Operationen
    5571             : //
    5572             : 
    5573             : 
    5574         313 : void ScDocument::UpdStlShtPtrsFrmNms()
    5575             : {
    5576         313 :     ScPatternAttr::pDoc = this;
    5577             : 
    5578         313 :     ScDocumentPool* pPool = xPoolHelper->GetDocPool();
    5579             : 
    5580         313 :     sal_uInt32 nCount = pPool->GetItemCount2(ATTR_PATTERN);
    5581             :     ScPatternAttr* pPattern;
    5582         313 :     for (sal_uInt32 i=0; i<nCount; i++)
    5583             :     {
    5584           0 :         pPattern = (ScPatternAttr*)pPool->GetItem2(ATTR_PATTERN, i);
    5585           0 :         if (pPattern)
    5586           0 :             pPattern->UpdateStyleSheet();
    5587             :     }
    5588         313 :     ((ScPatternAttr&)pPool->GetDefaultItem(ATTR_PATTERN)).UpdateStyleSheet();
    5589         313 : }
    5590             : 
    5591             : 
    5592           0 : void ScDocument::StylesToNames()
    5593             : {
    5594           0 :     ScPatternAttr::pDoc = this;
    5595             : 
    5596           0 :     ScDocumentPool* pPool = xPoolHelper->GetDocPool();
    5597             : 
    5598           0 :     sal_uInt32 nCount = pPool->GetItemCount2(ATTR_PATTERN);
    5599             :     ScPatternAttr* pPattern;
    5600           0 :     for (sal_uInt32 i=0; i<nCount; i++)
    5601             :     {
    5602           0 :         pPattern = (ScPatternAttr*)pPool->GetItem2(ATTR_PATTERN, i);
    5603           0 :         if (pPattern)
    5604           0 :             pPattern->StyleToName();
    5605             :     }
    5606           0 :     ((ScPatternAttr&)pPool->GetDefaultItem(ATTR_PATTERN)).StyleToName();
    5607           0 : }
    5608             : 
    5609             : 
    5610          26 : sal_uLong ScDocument::GetCellCount() const
    5611             : {
    5612          26 :     sal_uLong nCellCount = 0L;
    5613             : 
    5614          26 :     TableContainer::const_iterator it = maTabs.begin();
    5615          52 :     for (; it != maTabs.end(); ++it)
    5616          26 :         if ( *it )
    5617          26 :             nCellCount += (*it)->GetCellCount();
    5618             : 
    5619          26 :     return nCellCount;
    5620             : }
    5621             : 
    5622           0 : SCSIZE ScDocument::GetCellCount(SCTAB nTab, SCCOL nCol) const
    5623             : {
    5624           0 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab])
    5625           0 :         return 0;
    5626             : 
    5627           0 :     return maTabs[nTab]->GetCellCount(nCol);
    5628             : }
    5629             : 
    5630           0 : sal_uLong ScDocument::GetCodeCount() const
    5631             : {
    5632           0 :     sal_uLong nCodeCount = 0;
    5633             : 
    5634           0 :     TableContainer::const_iterator it = maTabs.begin();
    5635           0 :     for (; it != maTabs.end(); ++it)
    5636           0 :         if ( *it )
    5637           0 :             nCodeCount += (*it)->GetCodeCount();
    5638             : 
    5639           0 :     return nCodeCount;
    5640             : }
    5641             : 
    5642             : 
    5643          75 : void ScDocument::PageStyleModified( SCTAB nTab, const OUString& rNewName )
    5644             : {
    5645          75 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    5646          75 :         maTabs[nTab]->PageStyleModified( rNewName );
    5647          75 : }
    5648             : 
    5649             : 
    5650         207 : void ScDocument::SetPageStyle( SCTAB nTab, const OUString& rName )
    5651             : {
    5652         207 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    5653         207 :         maTabs[nTab]->SetPageStyle( rName );
    5654         207 : }
    5655             : 
    5656             : 
    5657       22622 : const OUString ScDocument::GetPageStyle( SCTAB nTab ) const
    5658             : {
    5659       22622 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    5660       22622 :         return maTabs[nTab]->GetPageStyle();
    5661             : 
    5662           0 :     return OUString();
    5663             : }
    5664             : 
    5665             : 
    5666         248 : void ScDocument::SetPageSize( SCTAB nTab, const Size& rSize )
    5667             : {
    5668         248 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    5669         248 :         maTabs[nTab]->SetPageSize( rSize );
    5670         248 : }
    5671             : 
    5672        1362 : Size ScDocument::GetPageSize( SCTAB nTab ) const
    5673             : {
    5674        1362 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    5675        1362 :         return maTabs[nTab]->GetPageSize();
    5676             : 
    5677             :     OSL_FAIL("invalid tab");
    5678           0 :     return Size();
    5679             : }
    5680             : 
    5681             : 
    5682         202 : void ScDocument::SetRepeatArea( SCTAB nTab, SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCROW nEndRow )
    5683             : {
    5684         202 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    5685         202 :         maTabs[nTab]->SetRepeatArea( nStartCol, nEndCol, nStartRow, nEndRow );
    5686         202 : }
    5687             : 
    5688          30 : void ScDocument::InvalidatePageBreaks(SCTAB nTab)
    5689             : {
    5690          30 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
    5691          30 :         maTabs[nTab]->InvalidatePageBreaks();
    5692          30 : }
    5693             : 
    5694         901 : void ScDocument::UpdatePageBreaks( SCTAB nTab, const ScRange* pUserArea )
    5695             : {
    5696         901 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    5697         901 :         maTabs[nTab]->UpdatePageBreaks( pUserArea );
    5698         901 : }
    5699             : 
    5700           0 : void ScDocument::RemoveManualBreaks( SCTAB nTab )
    5701             : {
    5702           0 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    5703           0 :         maTabs[nTab]->RemoveManualBreaks();
    5704           0 : }
    5705             : 
    5706           0 : bool ScDocument::HasManualBreaks( SCTAB nTab ) const
    5707             : {
    5708           0 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    5709           0 :         return maTabs[nTab]->HasManualBreaks();
    5710             : 
    5711             :     OSL_FAIL("invalid tab");
    5712           0 :     return false;
    5713             : }
    5714             : 
    5715             : 
    5716           0 : void ScDocument::GetDocStat( ScDocStat& rDocStat )
    5717             : {
    5718           0 :     rDocStat.nTableCount = GetTableCount();
    5719           0 :     rDocStat.aDocName    = aDocName;
    5720           0 :     rDocStat.nCellCount  = GetCellCount();
    5721           0 : }
    5722             : 
    5723             : 
    5724         250 : bool ScDocument::HasPrintRange()
    5725             : {
    5726         250 :     bool bResult = false;
    5727             : 
    5728         250 :     TableContainer::iterator it = maTabs.begin();
    5729         500 :     for (; it != maTabs.end() && !bResult; ++it)
    5730         250 :         if ( *it )
    5731         250 :             bResult = (*it)->IsPrintEntireSheet() || ((*it)->GetPrintRangeCount() > 0);
    5732             : 
    5733         250 :     return bResult;
    5734             : }
    5735             : 
    5736             : 
    5737         243 : bool ScDocument::IsPrintEntireSheet( SCTAB nTab ) const
    5738             : {
    5739         243 :     return (ValidTab(nTab) ) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] && maTabs[nTab]->IsPrintEntireSheet();
    5740             : }
    5741             : 
    5742             : 
    5743          60 : sal_uInt16 ScDocument::GetPrintRangeCount( SCTAB nTab )
    5744             : {
    5745          60 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
    5746          60 :         return maTabs[nTab]->GetPrintRangeCount();
    5747             : 
    5748           0 :     return 0;
    5749             : }
    5750             : 
    5751             : 
    5752         236 : const ScRange* ScDocument::GetPrintRange( SCTAB nTab, sal_uInt16 nPos )
    5753             : {
    5754         236 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
    5755         236 :         return maTabs[nTab]->GetPrintRange(nPos);
    5756             : 
    5757           0 :     return NULL;
    5758             : }
    5759             : 
    5760             : 
    5761         270 : const ScRange* ScDocument::GetRepeatColRange( SCTAB nTab )
    5762             : {
    5763         270 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
    5764         270 :         return maTabs[nTab]->GetRepeatColRange();
    5765             : 
    5766           0 :     return NULL;
    5767             : }
    5768             : 
    5769             : 
    5770         276 : const ScRange* ScDocument::GetRepeatRowRange( SCTAB nTab )
    5771             : {
    5772         276 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
    5773         276 :         return maTabs[nTab]->GetRepeatRowRange();
    5774             : 
    5775           0 :     return NULL;
    5776             : }
    5777             : 
    5778             : 
    5779          45 : void ScDocument::ClearPrintRanges( SCTAB nTab )
    5780             : {
    5781          45 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
    5782          45 :         maTabs[nTab]->ClearPrintRanges();
    5783          45 : }
    5784             : 
    5785             : 
    5786           8 : void ScDocument::AddPrintRange( SCTAB nTab, const ScRange& rNew )
    5787             : {
    5788           8 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
    5789           8 :         maTabs[nTab]->AddPrintRange( rNew );
    5790           8 : }
    5791             : 
    5792             : 
    5793          11 : void ScDocument::SetPrintEntireSheet( SCTAB nTab )
    5794             : {
    5795          11 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
    5796          11 :         maTabs[nTab]->SetPrintEntireSheet();
    5797          11 : }
    5798             : 
    5799             : 
    5800           1 : void ScDocument::SetRepeatColRange( SCTAB nTab, const ScRange* pNew )
    5801             : {
    5802           1 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
    5803           1 :         maTabs[nTab]->SetRepeatColRange( pNew );
    5804           1 : }
    5805             : 
    5806             : 
    5807           5 : void ScDocument::SetRepeatRowRange( SCTAB nTab, const ScRange* pNew )
    5808             : {
    5809           5 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
    5810           5 :         maTabs[nTab]->SetRepeatRowRange( pNew );
    5811           5 : }
    5812             : 
    5813             : 
    5814          78 : ScPrintRangeSaver* ScDocument::CreatePrintRangeSaver() const
    5815             : {
    5816          78 :     SCTAB nCount = static_cast<SCTAB>(maTabs.size());
    5817          78 :     ScPrintRangeSaver* pNew = new ScPrintRangeSaver( nCount );
    5818         228 :     for (SCTAB i=0; i<nCount; i++)
    5819         150 :         if (maTabs[i])
    5820         150 :             maTabs[i]->FillPrintSaver( pNew->GetTabData(i) );
    5821          78 :     return pNew;
    5822             : }
    5823             : 
    5824             : 
    5825           0 : void ScDocument::RestorePrintRanges( const ScPrintRangeSaver& rSaver )
    5826             : {
    5827           0 :     SCTAB nCount = rSaver.GetTabCount();
    5828           0 :     for (SCTAB i=0; i<nCount && i < static_cast<SCTAB>(maTabs.size()); i++)
    5829           0 :         if (maTabs[i])
    5830           0 :             maTabs[i]->RestorePrintRanges( rSaver.GetTabData(i) );
    5831           0 : }
    5832             : 
    5833             : 
    5834           0 : bool ScDocument::NeedPageResetAfterTab( SCTAB nTab ) const
    5835             : {
    5836             :     //  Die Seitennummern-Zaehlung faengt bei einer Tabelle neu an, wenn eine
    5837             :     //  andere Vorlage als bei der vorherigen gesetzt ist (nur Namen vergleichen)
    5838             :     //  und eine Seitennummer angegeben ist (nicht 0)
    5839             : 
    5840           0 :     if ( nTab + 1 < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] && maTabs[nTab+1] )
    5841             :     {
    5842           0 :         OUString aNew = maTabs[nTab+1]->GetPageStyle();
    5843           0 :         if ( aNew != maTabs[nTab]->GetPageStyle() )
    5844             :         {
    5845           0 :             SfxStyleSheetBase* pStyle = xPoolHelper->GetStylePool()->Find( aNew, SFX_STYLE_FAMILY_PAGE );
    5846           0 :             if ( pStyle )
    5847             :             {
    5848           0 :                 const SfxItemSet& rSet = pStyle->GetItemSet();
    5849           0 :                 sal_uInt16 nFirst = ((const SfxUInt16Item&)rSet.Get(ATTR_PAGE_FIRSTPAGENO)).GetValue();
    5850           0 :                 if ( nFirst != 0 )
    5851           0 :                     return true;        // Seitennummer in neuer Vorlage angegeben
    5852             :             }
    5853           0 :         }
    5854             :     }
    5855             : 
    5856           0 :     return false;       // sonst nicht
    5857             : }
    5858             : 
    5859       25307 : SfxUndoManager* ScDocument::GetUndoManager()
    5860             : {
    5861       25307 :     if (!mpUndoManager)
    5862             :     {
    5863             :         // to support enhanced text edit for draw objects, use an SdrUndoManager
    5864         308 :         mpUndoManager = new SdrUndoManager;
    5865             :     }
    5866             : 
    5867       25307 :     return mpUndoManager;
    5868             : }
    5869             : 
    5870          80 : ScRowBreakIterator* ScDocument::GetRowBreakIterator(SCTAB nTab) const
    5871             : {
    5872          80 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
    5873          80 :         return new ScRowBreakIterator(maTabs[nTab]->maRowPageBreaks);
    5874           0 :     return NULL;
    5875             : }
    5876             : 
    5877          12 : void ScDocument::AddSubTotalCell(ScFormulaCell* pCell)
    5878             : {
    5879          12 :     maSubTotalCells.insert(pCell);
    5880          12 : }
    5881             : 
    5882        5104 : void ScDocument::RemoveSubTotalCell(ScFormulaCell* pCell)
    5883             : {
    5884        5104 :     maSubTotalCells.erase(pCell);
    5885        5104 : }
    5886             : 
    5887             : namespace {
    5888             : 
    5889           0 : bool lcl_hasDirtyRange(ScFormulaCell* pCell, const ScRange& rDirtyRange)
    5890             : {
    5891           0 :     ScDetectiveRefIter aRefIter(pCell);
    5892           0 :     ScRange aRange;
    5893           0 :     while (aRefIter.GetNextRef(aRange))
    5894             :     {
    5895           0 :         if (aRange.Intersects(rDirtyRange))
    5896           0 :             return true;
    5897             :     }
    5898           0 :     return false;
    5899             : }
    5900             : 
    5901             : }
    5902             : 
    5903          14 : void ScDocument::SetSubTotalCellsDirty(const ScRange& rDirtyRange)
    5904             : {
    5905             :     // to update the list by skipping cells that no longer contain subtotal function.
    5906          14 :     set<ScFormulaCell*> aNewSet;
    5907             : 
    5908          14 :     bool bOldRecalc = GetAutoCalc();
    5909          14 :     SetAutoCalc(false);
    5910          14 :     set<ScFormulaCell*>::iterator itr = maSubTotalCells.begin(), itrEnd = maSubTotalCells.end();
    5911          14 :     for (; itr != itrEnd; ++itr)
    5912             :     {
    5913           0 :         ScFormulaCell* pCell = *itr;
    5914           0 :         if (pCell->IsSubTotal())
    5915             :         {
    5916           0 :             aNewSet.insert(pCell);
    5917           0 :             if (lcl_hasDirtyRange(pCell, rDirtyRange))
    5918           0 :                 pCell->SetDirty();
    5919             :         }
    5920             :     }
    5921             : 
    5922          14 :     SetAutoCalc(bOldRecalc);
    5923          14 :     maSubTotalCells.swap(aNewSet); // update the list.
    5924          14 : }
    5925             : 
    5926           6 : void ScDocument::MarkSubTotalCells( sc::ColumnSpanSet& rSet, const ScRange& rRange, bool bVal ) const
    5927             : {
    5928          12 :     for (SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab)
    5929             :     {
    5930           6 :         const ScTable* pTab = FetchTable(nTab);
    5931           6 :         if (!pTab)
    5932           0 :             continue;
    5933             : 
    5934             :         pTab->MarkSubTotalCells(
    5935           6 :             rSet, rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row(), bVal);
    5936             :     }
    5937           6 : }
    5938             : 
    5939           1 : sal_uInt16 ScDocument::GetTextWidth( const ScAddress& rPos ) const
    5940             : {
    5941           1 :     SCTAB nTab = rPos.Tab();
    5942           1 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
    5943           1 :         return maTabs[nTab]->GetTextWidth(rPos.Col(), rPos.Row());
    5944             : 
    5945           0 :     return 0;
    5946             : }
    5947             : 
    5948       14453 : sal_uInt8 ScDocument::GetScriptType( const ScAddress& rPos ) const
    5949             : {
    5950       14453 :     SCTAB nTab = rPos.Tab();
    5951       14453 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
    5952       14453 :         return maTabs[nTab]->GetScriptType(rPos.Col(), rPos.Row());
    5953             : 
    5954           0 :     return 0;
    5955             : }
    5956             : 
    5957        4617 : void ScDocument::SetScriptType( const ScAddress& rPos, sal_uInt8 nType )
    5958             : {
    5959        4617 :     SCTAB nTab = rPos.Tab();
    5960        4617 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
    5961        4617 :         maTabs[nTab]->SetScriptType(rPos.Col(), rPos.Row(), nType);
    5962        4617 : }
    5963             : 
    5964        8434 : void ScDocument::EnableUndo( bool bVal )
    5965             : {
    5966             :     // The undo manager increases lock count every time undo is disabled.
    5967             :     // Because of this, we shouldn't disable undo unless it's currently
    5968             :     // enabled, or else re-enabling it may not actually re-enable undo unless
    5969             :     // the lock count becomes zero.
    5970             : 
    5971        8434 :     if (bVal != GetUndoManager()->IsUndoEnabled())
    5972             :     {
    5973        8080 :         GetUndoManager()->EnableUndo(bVal);
    5974        8080 :         if( pDrawLayer ) pDrawLayer->EnableUndo(bVal);
    5975             :     }
    5976             : 
    5977        8434 :     mbUndoEnabled = bVal;
    5978        8434 : }
    5979             : 
    5980           0 : bool ScDocument::IsUserInteractionEnabled() const
    5981             : {
    5982           0 :     return mbUserInteractionEnabled;
    5983             : }
    5984             : 
    5985          98 : void ScDocument::EnableUserInteraction( bool bVal )
    5986             : {
    5987          98 :     mbUserInteractionEnabled = bVal;
    5988          98 : }
    5989             : 
    5990         131 : bool ScDocument::IsInVBAMode() const
    5991             : {
    5992         131 :     if (!pShell)
    5993           0 :         return false;
    5994             : 
    5995             :     try
    5996             :     {
    5997             :         uno::Reference<script::vba::XVBACompatibility> xVBA(
    5998         131 :             pShell->GetBasicContainer(), uno::UNO_QUERY);
    5999             : 
    6000         131 :         return xVBA.is() && xVBA->getVBACompatibilityMode();
    6001             :     }
    6002           0 :     catch (const lang::NotInitializedException&) {}
    6003             : 
    6004           0 :     return false;
    6005             : }
    6006             : 
    6007      186028 : ScNotes* ScDocument::GetNotes(SCTAB nTab)
    6008             : {
    6009      186028 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()))
    6010      186028 :         return maTabs[nTab]->GetNotes();
    6011             : 
    6012           0 :     return NULL;
    6013             : }
    6014             : 
    6015          42 : void ScDocument::SetAutoNameCache(  ScAutoNameCache* pCache )
    6016             : {
    6017          42 :     delete pAutoNameCache;
    6018          42 :     pAutoNameCache = pCache;
    6019         135 : }
    6020             : 
    6021             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10