LCOV - code coverage report
Current view: top level - sc/source/core/data - document.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 3321 0.0 %
Date: 2014-04-14 Functions: 0 356 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10