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

Generated by: LCOV version 1.10