LCOV - code coverage report
Current view: top level - sc/source/core/data - documen3.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 613 1045 58.7 %
Date: 2015-06-13 12:38:46 Functions: 96 134 71.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
      21             : #include "scitems.hxx"
      22             : #include <editeng/langitem.hxx>
      23             : #include <svl/srchitem.hxx>
      24             : #include <sfx2/linkmgr.hxx>
      25             : #include <sfx2/bindings.hxx>
      26             : #include <sfx2/objsh.hxx>
      27             : #include <svl/zforlist.hxx>
      28             : #include <svl/PasswordHelper.hxx>
      29             : #include <vcl/svapp.hxx>
      30             : #include "document.hxx"
      31             : #include "attrib.hxx"
      32             : #include "table.hxx"
      33             : #include "rangenam.hxx"
      34             : #include "dbdata.hxx"
      35             : #include "pivot.hxx"
      36             : #include "docpool.hxx"
      37             : #include "poolhelp.hxx"
      38             : #include "autoform.hxx"
      39             : #include "rangelst.hxx"
      40             : #include "chartarr.hxx"
      41             : #include "chartlock.hxx"
      42             : #include "refupdat.hxx"
      43             : #include "docoptio.hxx"
      44             : #include "viewopti.hxx"
      45             : #include "scextopt.hxx"
      46             : #include "brdcst.hxx"
      47             : #include "bcaslot.hxx"
      48             : #include "tablink.hxx"
      49             : #include "externalrefmgr.hxx"
      50             : #include "markdata.hxx"
      51             : #include "validat.hxx"
      52             : #include "dociter.hxx"
      53             : #include "detdata.hxx"
      54             : #include "detfunc.hxx"
      55             : #include "inputopt.hxx"
      56             : #include "chartlis.hxx"
      57             : #include "sc.hrc"
      58             : #include "hints.hxx"
      59             : #include "dpobject.hxx"
      60             : #include "drwlayer.hxx"
      61             : #include "unoreflist.hxx"
      62             : #include "listenercalls.hxx"
      63             : #include "dpshttab.hxx"
      64             : #include "dpcache.hxx"
      65             : #include "tabprotection.hxx"
      66             : #include "formulaparserpool.hxx"
      67             : #include "clipparam.hxx"
      68             : #include "sheetevents.hxx"
      69             : #include "colorscale.hxx"
      70             : #include "queryentry.hxx"
      71             : #include "formulacell.hxx"
      72             : #include "refupdatecontext.hxx"
      73             : #include "scopetools.hxx"
      74             : 
      75             : #include "globalnames.hxx"
      76             : #include <boost/scoped_ptr.hpp>
      77             : #include <LibreOfficeKit/LibreOfficeKitEnums.h>
      78             : 
      79             : using namespace com::sun::star;
      80             : 
      81             : namespace {
      82             : 
      83           2 : void sortAndRemoveDuplicates(std::vector<ScTypedStrData>& rStrings, bool bCaseSens)
      84             : {
      85           2 :     if (bCaseSens)
      86             :     {
      87           2 :         std::sort(rStrings.begin(), rStrings.end(), ScTypedStrData::LessCaseSensitive());
      88             :         std::vector<ScTypedStrData>::iterator it =
      89           2 :             std::unique(rStrings.begin(), rStrings.end(), ScTypedStrData::EqualCaseSensitive());
      90           2 :         rStrings.erase(it, rStrings.end());
      91             :     }
      92             :     else
      93             :     {
      94           0 :         std::sort(rStrings.begin(), rStrings.end(), ScTypedStrData::LessCaseInsensitive());
      95             :         std::vector<ScTypedStrData>::iterator it =
      96           0 :             std::unique(rStrings.begin(), rStrings.end(), ScTypedStrData::EqualCaseInsensitive());
      97           0 :         rStrings.erase(it, rStrings.end());
      98             :     }
      99           2 : }
     100             : 
     101             : }
     102             : 
     103         104 : void ScDocument::GetAllTabRangeNames(ScRangeName::TabNameCopyMap& rNames) const
     104             : {
     105         104 :     ScRangeName::TabNameCopyMap aNames;
     106         297 :     for (SCTAB i = 0; i < static_cast<SCTAB>(maTabs.size()); ++i)
     107             :     {
     108         193 :         if (!maTabs[i])
     109             :             // no more tables to iterate through.
     110           0 :             break;
     111             : 
     112         193 :         const ScRangeName* p = maTabs[i]->mpRangeName;
     113         193 :         if (!p || p->empty())
     114             :             // ignore empty ones.
     115         186 :             continue;
     116             : 
     117           7 :         aNames.insert(ScRangeName::TabNameCopyMap::value_type(i, p));
     118             :     }
     119         104 :     rNames.swap(aNames);
     120         104 : }
     121             : 
     122           1 : void ScDocument::SetAllRangeNames( const boost::ptr_map<OUString, ScRangeName>& rRangeMap)
     123             : {
     124           1 :     OUString aGlobalStr(STR_GLOBAL_RANGE_NAME);
     125           1 :     boost::ptr_map<OUString,ScRangeName>::const_iterator itr = rRangeMap.begin(), itrEnd = rRangeMap.end();
     126           2 :     for (; itr!=itrEnd; ++itr)
     127             :     {
     128           1 :         if (itr->first == aGlobalStr)
     129             :         {
     130           1 :             delete pRangeName;
     131           1 :             const ScRangeName* pName = itr->second;
     132           1 :             if (pName->empty())
     133           0 :                 pRangeName = NULL;
     134             :             else
     135           1 :                 pRangeName = new ScRangeName( *pName );
     136             :         }
     137             :         else
     138             :         {
     139           0 :             const ScRangeName* pName = itr->second;
     140             :             SCTAB nTab;
     141           0 :             bool bFound = GetTable(itr->first, nTab);
     142             :             assert(bFound); (void)bFound;   // fouled up?
     143           0 :             if (pName->empty())
     144           0 :                 SetRangeName( nTab, NULL );
     145             :             else
     146           0 :                 SetRangeName( nTab, new ScRangeName( *pName ) );
     147             :         }
     148           1 :     }
     149           1 : }
     150             : 
     151           1 : void ScDocument::GetTabRangeNameMap(std::map<OUString, ScRangeName*>& aRangeNameMap)
     152             : {
     153           2 :     for (SCTAB i = 0; i < static_cast<SCTAB>(maTabs.size()); ++i)
     154             :     {
     155           1 :         if (!maTabs[i])
     156           0 :             continue;
     157           1 :         ScRangeName* p = maTabs[i]->GetRangeName();
     158           1 :         if (!p )
     159             :         {
     160           0 :             p = new ScRangeName();
     161           0 :             SetRangeName(i, p);
     162             :         }
     163           1 :         OUString aTableName;
     164           1 :         maTabs[i]->GetName(aTableName);
     165           1 :         aRangeNameMap.insert(std::pair<OUString, ScRangeName*>(aTableName,p));
     166           1 :     }
     167           1 : }
     168             : 
     169           1 : void ScDocument::GetRangeNameMap(std::map<OUString, ScRangeName*>& aRangeNameMap)
     170             : {
     171           1 :     GetTabRangeNameMap(aRangeNameMap);
     172           1 :     if (!pRangeName)
     173             :     {
     174           0 :         pRangeName = new ScRangeName();
     175             :     }
     176           1 :     OUString aGlobal(STR_GLOBAL_RANGE_NAME);
     177           1 :     aRangeNameMap.insert(std::pair<OUString, ScRangeName*>(aGlobal, pRangeName));
     178           1 : }
     179             : 
     180        2365 : ScRangeName* ScDocument::GetRangeName(SCTAB nTab) const
     181             : {
     182        2365 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab])
     183           1 :         return NULL;
     184             : 
     185        2364 :     return maTabs[nTab]->GetRangeName();
     186             : }
     187             : 
     188        4583 : ScRangeName* ScDocument::GetRangeName() const
     189             : {
     190        4583 :     if (!pRangeName)
     191         485 :         pRangeName = new ScRangeName;
     192        4583 :     return pRangeName;
     193             : }
     194             : 
     195           1 : void ScDocument::SetRangeName(SCTAB nTab, ScRangeName* pNew)
     196             : {
     197           1 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab])
     198           0 :         return;
     199             : 
     200           1 :     return maTabs[nTab]->SetRangeName(pNew);
     201             : }
     202             : 
     203          40 : void ScDocument::SetRangeName( ScRangeName* pNewRangeName )
     204             : {
     205          40 :     if (pRangeName == pNewRangeName)
     206          40 :         return;
     207             : 
     208          40 :     delete pRangeName;
     209          40 :     pRangeName = pNewRangeName;
     210             : }
     211             : 
     212           9 : bool ScDocument::InsertNewRangeName( const OUString& rName, const ScAddress& rPos, const OUString& rExpr )
     213             : {
     214           9 :     ScRangeName* pGlobalNames = GetRangeName();
     215           9 :     if (!pGlobalNames)
     216           0 :         return false;
     217             : 
     218           9 :     ScRangeData* pName = new ScRangeData(this, rName, rExpr, rPos, RT_NAME, GetGrammar());
     219           9 :     return pGlobalNames->insert(pName);
     220             : }
     221             : 
     222        1311 : const ScRangeData* ScDocument::GetRangeAtBlock( const ScRange& rBlock, OUString* pName ) const
     223             : {
     224        1311 :     const ScRangeData* pData = NULL;
     225        1311 :     if ( pRangeName )
     226             :     {
     227         663 :         pData = pRangeName->findByRange( rBlock );
     228         663 :         if (pData && pName)
     229           6 :             *pName = pData->GetName();
     230             :     }
     231        1311 :     return pData;
     232             : }
     233             : 
     234           3 : void ScDocument::SetDBCollection( ScDBCollection* pNewDBCollection, bool bRemoveAutoFilter )
     235             : {
     236           3 :     if (pDBCollection && bRemoveAutoFilter)
     237             :     {
     238             :         //  remove auto filter attribute if new db data don't contain auto filter flag
     239             :         //  start position is also compared, so bRemoveAutoFilter must not be set from ref-undo!
     240             : 
     241           2 :         ScDBCollection::NamedDBs& rNamedDBs = pDBCollection->getNamedDBs();
     242           2 :         ScDBCollection::NamedDBs::const_iterator itr = rNamedDBs.begin(), itrEnd = rNamedDBs.end();
     243           4 :         for (; itr != itrEnd; ++itr)
     244             :         {
     245           2 :             const ScDBData& rOldData = *itr;
     246           2 :             if (!rOldData.HasAutoFilter())
     247           2 :                 continue;
     248             : 
     249           0 :             ScRange aOldRange;
     250           0 :             rOldData.GetArea(aOldRange);
     251             : 
     252           0 :             bool bFound = false;
     253           0 :             if (pNewDBCollection)
     254             :             {
     255           0 :                 ScDBData* pNewData = pNewDBCollection->getNamedDBs().findByUpperName(rOldData.GetUpperName());
     256           0 :                 if (pNewData)
     257             :                 {
     258           0 :                     if (pNewData->HasAutoFilter())
     259             :                     {
     260           0 :                         ScRange aNewRange;
     261           0 :                         pNewData->GetArea(aNewRange);
     262           0 :                         if (aOldRange.aStart == aNewRange.aStart)
     263           0 :                             bFound = true;
     264             :                     }
     265             :                 }
     266             :             }
     267             : 
     268           0 :             if (!bFound)
     269             :             {
     270           0 :                 aOldRange.aEnd.SetRow(aOldRange.aStart.Row());
     271           0 :                 RemoveFlagsTab( aOldRange.aStart.Col(), aOldRange.aStart.Row(),
     272           0 :                                 aOldRange.aEnd.Col(),   aOldRange.aEnd.Row(),
     273           0 :                                 aOldRange.aStart.Tab(), SC_MF_AUTO );
     274           0 :                 RepaintRange( aOldRange );
     275             :             }
     276             :         }
     277             :     }
     278             : 
     279           3 :     delete pDBCollection;
     280             : 
     281           3 :     pDBCollection = pNewDBCollection;
     282           3 : }
     283             : 
     284           0 : const ScDBData* ScDocument::GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, bool bStartOnly) const
     285             : {
     286           0 :     if (pDBCollection)
     287           0 :         return pDBCollection->GetDBAtCursor(nCol, nRow, nTab, bStartOnly);
     288             :     else
     289           0 :         return NULL;
     290             : }
     291             : 
     292         259 : ScDBData* ScDocument::GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, bool bStartOnly)
     293             : {
     294         259 :     if (pDBCollection)
     295         259 :         return pDBCollection->GetDBAtCursor(nCol, nRow, nTab, bStartOnly);
     296             :     else
     297           0 :         return NULL;
     298             : }
     299             : 
     300           0 : const ScDBData* ScDocument::GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const
     301             : {
     302           0 :     if (pDBCollection)
     303           0 :         return pDBCollection->GetDBAtArea(nTab, nCol1, nRow1, nCol2, nRow2);
     304             :     else
     305           0 :         return NULL;
     306             : }
     307             : 
     308          69 : ScDBData* ScDocument::GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
     309             : {
     310          69 :     if (pDBCollection)
     311          69 :         return pDBCollection->GetDBAtArea(nTab, nCol1, nRow1, nCol2, nRow2);
     312             :     else
     313           0 :         return NULL;
     314             : }
     315             : 
     316        1046 : bool ScDocument::HasPivotTable() const
     317             : {
     318        1046 :     return pDPCollection && pDPCollection->GetCount();
     319             : }
     320             : 
     321        1326 : ScDPCollection* ScDocument::GetDPCollection()
     322             : {
     323        1326 :     if (!pDPCollection)
     324         251 :         pDPCollection = new ScDPCollection(this);
     325        1326 :     return pDPCollection;
     326             : }
     327             : 
     328          72 : const ScDPCollection* ScDocument::GetDPCollection() const
     329             : {
     330          72 :     return pDPCollection;
     331             : }
     332             : 
     333         784 : ScDPObject* ScDocument::GetDPAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab) const
     334             : {
     335         784 :     if (!pDPCollection)
     336         656 :         return NULL;
     337             : 
     338         128 :     sal_uInt16 nCount = pDPCollection->GetCount();
     339         128 :     ScAddress aPos( nCol, nRow, nTab );
     340         227 :     for (sal_uInt16 i=0; i<nCount; i++)
     341         106 :         if ( (*pDPCollection)[i]->GetOutRange().In( aPos ) )
     342           7 :             return (*pDPCollection)[i];
     343             : 
     344         121 :     return NULL;
     345             : }
     346             : 
     347         292 : ScDPObject* ScDocument::GetDPAtBlock( const ScRange & rBlock ) const
     348             : {
     349         292 :     if (!pDPCollection)
     350         233 :         return NULL;
     351             : 
     352             :     /* Walk the collection in reverse order to get something of an
     353             :      * approximation of MS Excels 'most recent' effect. */
     354          59 :     sal_uInt16 i = pDPCollection->GetCount();
     355         149 :     while ( i-- > 0 )
     356          74 :         if ( (*pDPCollection)[i]->GetOutRange().In( rBlock ) )
     357          43 :             return (*pDPCollection)[i];
     358             : 
     359          16 :     return NULL;
     360             : }
     361             : 
     362          29 : void ScDocument::StopTemporaryChartLock()
     363             : {
     364          29 :     if( apTemporaryChartLock.get() )
     365          29 :         apTemporaryChartLock->StopLocking();
     366          29 : }
     367             : 
     368           0 : void ScDocument::SetChartListenerCollection(
     369             :             ScChartListenerCollection* pNewChartListenerCollection,
     370             :             bool bSetChartRangeLists )
     371             : {
     372           0 :     ScChartListenerCollection* pOld = pChartListenerCollection;
     373           0 :     pChartListenerCollection = pNewChartListenerCollection;
     374           0 :     if ( pChartListenerCollection )
     375             :     {
     376           0 :         if ( pOld )
     377           0 :             pChartListenerCollection->SetDiffDirty( *pOld, bSetChartRangeLists );
     378           0 :         pChartListenerCollection->StartAllListeners();
     379             :     }
     380           0 :     delete pOld;
     381           0 : }
     382             : 
     383           1 : void ScDocument::SetScenario( SCTAB nTab, bool bFlag )
     384             : {
     385           1 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
     386           1 :         maTabs[nTab]->SetScenario(bFlag);
     387           1 : }
     388             : 
     389        6160 : bool ScDocument::IsScenario( SCTAB nTab ) const
     390             : {
     391        6160 :     return ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] &&maTabs[nTab]->IsScenario();
     392             : }
     393             : 
     394           1 : void ScDocument::SetScenarioData( SCTAB nTab, const OUString& rComment,
     395             :                                         const Color& rColor, sal_uInt16 nFlags )
     396             : {
     397           1 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] && maTabs[nTab]->IsScenario())
     398             :     {
     399           1 :         maTabs[nTab]->SetScenarioComment( rComment );
     400           1 :         maTabs[nTab]->SetScenarioColor( rColor );
     401           1 :         maTabs[nTab]->SetScenarioFlags( nFlags );
     402             :     }
     403           1 : }
     404             : 
     405        4277 : Color ScDocument::GetTabBgColor( SCTAB nTab ) const
     406             : {
     407        4277 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
     408        4277 :         return maTabs[nTab]->GetTabBgColor();
     409           0 :     return Color(COL_AUTO);
     410             : }
     411             : 
     412          50 : void ScDocument::SetTabBgColor( SCTAB nTab, const Color& rColor )
     413             : {
     414          50 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
     415          50 :         maTabs[nTab]->SetTabBgColor(rColor);
     416          50 : }
     417             : 
     418         837 : bool ScDocument::IsDefaultTabBgColor( SCTAB nTab ) const
     419             : {
     420         837 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
     421         837 :         return maTabs[nTab]->GetTabBgColor() == COL_AUTO;
     422           0 :     return true;
     423             : }
     424             : 
     425           1 : void ScDocument::GetScenarioData( SCTAB nTab, OUString& rComment,
     426             :                                         Color& rColor, sal_uInt16& rFlags ) const
     427             : {
     428           1 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] && maTabs[nTab]->IsScenario())
     429             :     {
     430           1 :         maTabs[nTab]->GetScenarioComment( rComment );
     431           1 :         rColor = maTabs[nTab]->GetScenarioColor();
     432           1 :         rFlags = maTabs[nTab]->GetScenarioFlags();
     433             :     }
     434           1 : }
     435             : 
     436           0 : void ScDocument::GetScenarioFlags( SCTAB nTab, sal_uInt16& rFlags ) const
     437             : {
     438           0 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] && maTabs[nTab]->IsScenario())
     439           0 :         rFlags = maTabs[nTab]->GetScenarioFlags();
     440           0 : }
     441             : 
     442        1481 : bool ScDocument::IsLinked( SCTAB nTab ) const
     443             : {
     444        1481 :     return ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] && maTabs[nTab]->IsLinked();
     445             :     // euqivalent to
     446             :     //if (ValidTab(nTab) && pTab[nTab])
     447             :     //  return pTab[nTab]->IsLinked();
     448             :     //return false;
     449             : }
     450             : 
     451       56517 : formula::FormulaGrammar::AddressConvention ScDocument::GetAddressConvention() const
     452             : {
     453       56517 :     return formula::FormulaGrammar::extractRefConvention(eGrammar);
     454             : }
     455             : 
     456         646 : void ScDocument::SetGrammar( formula::FormulaGrammar::Grammar eGram )
     457             : {
     458         646 :     eGrammar = eGram;
     459         646 : }
     460             : 
     461         164 : sal_uInt8 ScDocument::GetLinkMode( SCTAB nTab ) const
     462             : {
     463         164 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
     464         164 :         return maTabs[nTab]->GetLinkMode();
     465           0 :     return SC_LINK_NONE;
     466             : }
     467             : 
     468          20 : const OUString ScDocument::GetLinkDoc( SCTAB nTab ) const
     469             : {
     470          20 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
     471          20 :         return maTabs[nTab]->GetLinkDoc();
     472           0 :     return OUString();
     473             : }
     474             : 
     475           2 : const OUString ScDocument::GetLinkFlt( SCTAB nTab ) const
     476             : {
     477           2 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
     478           2 :         return maTabs[nTab]->GetLinkFlt();
     479           0 :     return OUString();
     480             : }
     481             : 
     482           2 : const OUString ScDocument::GetLinkOpt( SCTAB nTab ) const
     483             : {
     484           2 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
     485           2 :         return maTabs[nTab]->GetLinkOpt();
     486           0 :     return OUString();
     487             : }
     488             : 
     489           2 : const OUString ScDocument::GetLinkTab( SCTAB nTab ) const
     490             : {
     491           2 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
     492           2 :         return maTabs[nTab]->GetLinkTab();
     493           0 :     return OUString();
     494             : }
     495             : 
     496           2 : sal_uLong ScDocument::GetLinkRefreshDelay( SCTAB nTab ) const
     497             : {
     498           2 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
     499           2 :         return maTabs[nTab]->GetLinkRefreshDelay();
     500           0 :     return 0;
     501             : }
     502             : 
     503           4 : void ScDocument::SetLink( SCTAB nTab, sal_uInt8 nMode, const OUString& rDoc,
     504             :                             const OUString& rFilter, const OUString& rOptions,
     505             :                             const OUString& rTabName, sal_uLong nRefreshDelay )
     506             : {
     507           4 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
     508           4 :         maTabs[nTab]->SetLink( nMode, rDoc, rFilter, rOptions, rTabName, nRefreshDelay );
     509           4 : }
     510             : 
     511           0 : bool ScDocument::HasLink( const OUString& rDoc,
     512             :                             const OUString& rFilter, const OUString& rOptions ) const
     513             : {
     514           0 :     SCTAB nCount = static_cast<SCTAB>(maTabs.size());
     515           0 :     for (SCTAB i=0; i<nCount; i++)
     516           0 :         if (maTabs[i]->IsLinked()
     517           0 :                 && maTabs[i]->GetLinkDoc() == rDoc
     518           0 :                 && maTabs[i]->GetLinkFlt() == rFilter
     519           0 :                 && maTabs[i]->GetLinkOpt() == rOptions)
     520           0 :             return true;
     521             : 
     522           0 :     return false;
     523             : }
     524             : 
     525           0 : bool ScDocument::LinkExternalTab( SCTAB& rTab, const OUString& aDocTab,
     526             :         const OUString& aFileName, const OUString& aTabName )
     527             : {
     528           0 :     if ( IsClipboard() )
     529             :     {
     530             :         OSL_FAIL( "LinkExternalTab in Clipboard" );
     531           0 :         return false;
     532             :     }
     533           0 :     rTab = 0;
     534           0 :     OUString  aFilterName; // Is filled by the Loader
     535           0 :     OUString  aOptions; // Filter options
     536           0 :     sal_uInt32 nLinkCnt = pExtDocOptions ? pExtDocOptions->GetDocSettings().mnLinkCnt : 0;
     537           0 :     ScDocumentLoader aLoader( aFileName, aFilterName, aOptions, nLinkCnt + 1 );
     538           0 :     if ( aLoader.IsError() )
     539           0 :         return false;
     540           0 :     ScDocument* pSrcDoc = aLoader.GetDocument();
     541             : 
     542             :     // Copy table
     543             :     SCTAB nSrcTab;
     544           0 :     if ( pSrcDoc->GetTable( aTabName, nSrcTab ) )
     545             :     {
     546           0 :         if ( !InsertTab( SC_TAB_APPEND, aDocTab, true ) )
     547             :         {
     548             :             OSL_FAIL("can't insert external document table");
     549           0 :             return false;
     550             :         }
     551           0 :         rTab = GetTableCount() - 1;
     552             :         // Don't insert anew, just the results
     553           0 :         TransferTab( pSrcDoc, nSrcTab, rTab, false, true );
     554             :     }
     555             :     else
     556           0 :         return false;
     557             : 
     558           0 :     sal_uLong nRefreshDelay = 0;
     559             : 
     560           0 :     bool bWasThere = HasLink( aFileName, aFilterName, aOptions );
     561           0 :     SetLink( rTab, SC_LINK_VALUE, aFileName, aFilterName, aOptions, aTabName, nRefreshDelay );
     562           0 :     if ( !bWasThere ) // Add link only once per source document
     563             :     {
     564           0 :         ScTableLink* pLink = new ScTableLink( pShell, aFileName, aFilterName, aOptions, nRefreshDelay );
     565           0 :         pLink->SetInCreate( true );
     566           0 :         OUString aFilName = aFilterName;
     567             :         GetLinkManager()->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, OUString(aFileName),
     568           0 :                                         &aFilName );
     569           0 :         pLink->Update();
     570           0 :         pLink->SetInCreate( false );
     571           0 :         SfxBindings* pBindings = GetViewBindings();
     572           0 :         if (pBindings)
     573           0 :             pBindings->Invalidate( SID_LINKS );
     574             :     }
     575           0 :     return true;
     576             : }
     577             : 
     578        5945 : ScExternalRefManager* ScDocument::GetExternalRefManager() const
     579             : {
     580        5945 :     ScDocument* pThis = const_cast<ScDocument*>(this);
     581        5945 :     if (!pExternalRefMgr.get())
     582         477 :         pThis->pExternalRefMgr.reset( new ScExternalRefManager( pThis));
     583             : 
     584        5945 :     return pExternalRefMgr.get();
     585             : }
     586             : 
     587          42 : bool ScDocument::IsInExternalReferenceMarking() const
     588             : {
     589          42 :     return pExternalRefMgr.get() && pExternalRefMgr->isInReferenceMarking();
     590             : }
     591             : 
     592           0 : void ScDocument::MarkUsedExternalReferences()
     593             : {
     594           0 :     if (!pExternalRefMgr.get())
     595           0 :         return;
     596           0 :     if (!pExternalRefMgr->hasExternalData())
     597           0 :         return;
     598             :     // Charts.
     599           0 :     pExternalRefMgr->markUsedByLinkListeners();
     600             :     // Formula cells.
     601           0 :     pExternalRefMgr->markUsedExternalRefCells();
     602             : 
     603             :     /* NOTE: Conditional formats and validation objects are marked when
     604             :      * collecting them during export. */
     605             : }
     606             : 
     607           0 : ScFormulaParserPool& ScDocument::GetFormulaParserPool() const
     608             : {
     609           0 :     if( !mxFormulaParserPool.get() )
     610           0 :         mxFormulaParserPool.reset( new ScFormulaParserPool( *this ) );
     611           0 :     return *mxFormulaParserPool;
     612             : }
     613             : 
     614        3658 : const ScSheetEvents* ScDocument::GetSheetEvents( SCTAB nTab ) const
     615             : {
     616        3658 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
     617        3658 :         return maTabs[nTab]->GetSheetEvents();
     618           0 :     return NULL;
     619             : }
     620             : 
     621          22 : void ScDocument::SetSheetEvents( SCTAB nTab, const ScSheetEvents* pNew )
     622             : {
     623          22 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
     624          22 :         maTabs[nTab]->SetSheetEvents( pNew );
     625          22 : }
     626             : 
     627       65636 : bool ScDocument::HasSheetEventScript( SCTAB nTab, sal_Int32 nEvent, bool bWithVbaEvents ) const
     628             : {
     629       65636 :     if (nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
     630             :     {
     631             :         // check if any event handler script has been configured
     632       65636 :         const ScSheetEvents* pEvents = maTabs[nTab]->GetSheetEvents();
     633       65636 :         if ( pEvents && pEvents->GetScript( nEvent ) )
     634           0 :             return true;
     635             :         // check if VBA event handlers exist
     636       65636 :         if (bWithVbaEvents && mxVbaEvents.is()) try
     637             :         {
     638         369 :             uno::Sequence< uno::Any > aArgs( 1 );
     639         369 :             aArgs[ 0 ] <<= nTab;
     640        1388 :             if (mxVbaEvents->hasVbaEventHandler( ScSheetEvents::GetVbaSheetEventId( nEvent ), aArgs ) ||
     641        1344 :                 mxVbaEvents->hasVbaEventHandler( ScSheetEvents::GetVbaDocumentEventId( nEvent ), uno::Sequence< uno::Any >() ))
     642          44 :                 return true;
     643             :         }
     644          44 :         catch( uno::Exception& )
     645             :         {
     646             :         }
     647             :     }
     648       65636 :     return false;
     649             : }
     650             : 
     651       48000 : bool ScDocument::HasAnySheetEventScript( sal_Int32 nEvent, bool bWithVbaEvents ) const
     652             : {
     653       48000 :     SCTAB nSize = static_cast<SCTAB>(maTabs.size());
     654      113636 :     for (SCTAB nTab = 0; nTab < nSize; nTab++)
     655       65636 :         if (HasSheetEventScript( nTab, nEvent, bWithVbaEvents ))
     656           0 :             return true;
     657       48000 :     return false;
     658             : }
     659             : 
     660        4356 : bool ScDocument::HasAnyCalcNotification() const
     661             : {
     662        4356 :     SCTAB nSize = static_cast<SCTAB>(maTabs.size());
     663       18005 :     for (SCTAB nTab = 0; nTab < nSize; nTab++)
     664       13649 :         if (maTabs[nTab] && maTabs[nTab]->GetCalcNotification())
     665           0 :             return true;
     666        4356 :     return false;
     667             : }
     668             : 
     669           0 : bool ScDocument::HasCalcNotification( SCTAB nTab ) const
     670             : {
     671           0 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
     672           0 :         return maTabs[nTab]->GetCalcNotification();
     673           0 :     return false;
     674             : }
     675             : 
     676           0 : void ScDocument::SetCalcNotification( SCTAB nTab )
     677             : {
     678             :     // set only if not set before
     679           0 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] && !maTabs[nTab]->GetCalcNotification())
     680           0 :         maTabs[nTab]->SetCalcNotification(true);
     681           0 : }
     682             : 
     683           0 : void ScDocument::ResetCalcNotifications()
     684             : {
     685           0 :     SCTAB nSize = static_cast<SCTAB>(maTabs.size());
     686           0 :     for (SCTAB nTab = 0; nTab < nSize; nTab++)
     687           0 :         if (maTabs[nTab] && maTabs[nTab]->GetCalcNotification())
     688           0 :             maTabs[nTab]->SetCalcNotification(false);
     689           0 : }
     690             : 
     691       14814 : ScOutlineTable* ScDocument::GetOutlineTable( SCTAB nTab, bool bCreate )
     692             : {
     693       14814 :     ScOutlineTable* pVal = NULL;
     694             : 
     695       14814 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()))
     696       14814 :         if (maTabs[nTab])
     697             :         {
     698       14814 :             pVal = maTabs[nTab]->GetOutlineTable();
     699       14814 :             if (!pVal)
     700       11351 :                 if (bCreate)
     701             :                 {
     702         226 :                     maTabs[nTab]->StartOutlineTable();
     703         226 :                     pVal = maTabs[nTab]->GetOutlineTable();
     704             :                 }
     705             :         }
     706             : 
     707       14814 :     return pVal;
     708             : }
     709             : 
     710           4 : bool ScDocument::SetOutlineTable( SCTAB nTab, const ScOutlineTable* pNewOutline )
     711             : {
     712           4 :     return ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] && maTabs[nTab]->SetOutlineTable(pNewOutline);
     713             : }
     714             : 
     715           1 : void ScDocument::DoAutoOutline( SCCOL nStartCol, SCROW nStartRow,
     716             :                                 SCCOL nEndCol, SCROW nEndRow, SCTAB nTab )
     717             : {
     718           1 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
     719           1 :         maTabs[nTab]->DoAutoOutline( nStartCol, nStartRow, nEndCol, nEndRow );
     720           1 : }
     721             : 
     722           2 : bool ScDocument::TestRemoveSubTotals( SCTAB nTab, const ScSubTotalParam& rParam )
     723             : {
     724           2 :     return ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] && maTabs[nTab]->TestRemoveSubTotals( rParam );
     725             : }
     726             : 
     727           2 : void ScDocument::RemoveSubTotals( SCTAB nTab, ScSubTotalParam& rParam )
     728             : {
     729           2 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
     730           2 :         maTabs[nTab]->RemoveSubTotals( rParam );
     731           2 : }
     732             : 
     733           1 : bool ScDocument::DoSubTotals( SCTAB nTab, ScSubTotalParam& rParam )
     734             : {
     735           1 :     return ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] && maTabs[nTab]->DoSubTotals( rParam );
     736             : }
     737             : 
     738           0 : bool ScDocument::HasSubTotalCells( const ScRange& rRange )
     739             : {
     740           0 :     ScCellIterator aIter( this, rRange );
     741           0 :     for (bool bHas = aIter.first(); bHas; bHas = aIter.next())
     742             :     {
     743           0 :         if (aIter.getType() != CELLTYPE_FORMULA)
     744           0 :             continue;
     745             : 
     746           0 :         if (aIter.getFormulaCell()->IsSubTotal())
     747           0 :             return true;
     748             :     }
     749           0 :     return false;   // none found
     750             : }
     751             : 
     752             : /**
     753             :  * From this document this method copies the cells of positions at which
     754             :  * there are also cells in pPosDoc to pDestDoc
     755             :  */
     756           0 : void ScDocument::CopyUpdated( ScDocument* pPosDoc, ScDocument* pDestDoc )
     757             : {
     758           0 :     SCTAB nCount = static_cast<SCTAB>(maTabs.size());
     759           0 :     for (SCTAB nTab=0; nTab<nCount; nTab++)
     760           0 :         if (maTabs[nTab] && pPosDoc->maTabs[nTab] && pDestDoc->maTabs[nTab])
     761           0 :             maTabs[nTab]->CopyUpdated( pPosDoc->maTabs[nTab], pDestDoc->maTabs[nTab] );
     762           0 : }
     763             : 
     764           1 : void ScDocument::CopyScenario( SCTAB nSrcTab, SCTAB nDestTab, bool bNewScenario )
     765             : {
     766           3 :     if (ValidTab(nSrcTab) && ValidTab(nDestTab) && nSrcTab < static_cast<SCTAB>(maTabs.size())
     767           2 :                 && nDestTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nSrcTab] && maTabs[nDestTab])
     768             :     {
     769             :         // Set flags correctly for active scenarios
     770             :         // and write current values back to recently active scenarios
     771           1 :         ScRangeList aRanges = *maTabs[nSrcTab]->GetScenarioRanges();
     772             : 
     773             :         // nDestTab is the target table
     774           4 :         for ( SCTAB nTab = nDestTab+1;
     775           2 :                 nTab< static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] && maTabs[nTab]->IsScenario();
     776             :                 nTab++ )
     777             :         {
     778           1 :             if ( maTabs[nTab]->IsActiveScenario() ) // Even if it's the same scenario
     779             :             {
     780           0 :                 bool bTouched = false;
     781           0 :                 for ( size_t nR=0, nRangeCount = aRanges.size(); nR < nRangeCount && !bTouched; nR++ )
     782             :                 {
     783           0 :                     const ScRange* pRange = aRanges[ nR ];
     784           0 :                     if ( maTabs[nTab]->HasScenarioRange( *pRange ) )
     785           0 :                         bTouched = true;
     786             :                 }
     787           0 :                 if (bTouched)
     788             :                 {
     789           0 :                     maTabs[nTab]->SetActiveScenario(false);
     790           0 :                     if ( maTabs[nTab]->GetScenarioFlags() & SC_SCENARIO_TWOWAY )
     791           0 :                         maTabs[nTab]->CopyScenarioFrom( maTabs[nDestTab] );
     792             :                 }
     793             :             }
     794             :         }
     795             : 
     796           1 :         maTabs[nSrcTab]->SetActiveScenario(true); // This is where it's from ...
     797           1 :         if (!bNewScenario) // Copy data from the selected scenario
     798             :         {
     799           0 :             sc::AutoCalcSwitch aACSwitch(*this, false);
     800           0 :             maTabs[nSrcTab]->CopyScenarioTo( maTabs[nDestTab] );
     801             : 
     802           0 :             sc::SetFormulaDirtyContext aCxt;
     803           0 :             SetAllFormulasDirty(aCxt);
     804           1 :         }
     805             :     }
     806           1 : }
     807             : 
     808           1 : void ScDocument::MarkScenario( SCTAB nSrcTab, SCTAB nDestTab, ScMarkData& rDestMark,
     809             :                                 bool bResetMark, sal_uInt16 nNeededBits ) const
     810             : {
     811           1 :     if (bResetMark)
     812           0 :         rDestMark.ResetMark();
     813             : 
     814           1 :     if (ValidTab(nSrcTab) && nSrcTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nSrcTab])
     815           1 :         maTabs[nSrcTab]->MarkScenarioIn( rDestMark, nNeededBits );
     816             : 
     817           1 :     rDestMark.SetAreaTab( nDestTab );
     818           1 : }
     819             : 
     820           1 : bool ScDocument::HasScenarioRange( SCTAB nTab, const ScRange& rRange ) const
     821             : {
     822           1 :     return ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] && maTabs[nTab]->HasScenarioRange( rRange );
     823             : }
     824             : 
     825           0 : const ScRangeList* ScDocument::GetScenarioRanges( SCTAB nTab ) const
     826             : {
     827           0 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
     828           0 :         return maTabs[nTab]->GetScenarioRanges();
     829             : 
     830           0 :     return NULL;
     831             : }
     832             : 
     833           1 : bool ScDocument::IsActiveScenario( SCTAB nTab ) const
     834             : {
     835           1 :     return ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] && maTabs[nTab]->IsActiveScenario(  );
     836             : }
     837             : 
     838           0 : void ScDocument::SetActiveScenario( SCTAB nTab, bool bActive )
     839             : {
     840           0 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
     841           0 :         maTabs[nTab]->SetActiveScenario( bActive );
     842           0 : }
     843             : 
     844           0 : bool ScDocument::TestCopyScenario( SCTAB nSrcTab, SCTAB nDestTab ) const
     845             : {
     846           0 :     if (ValidTab(nSrcTab) && nSrcTab < static_cast<SCTAB>(maTabs.size())
     847           0 :                 && nDestTab < static_cast<SCTAB>(maTabs.size())&& ValidTab(nDestTab))
     848           0 :         return maTabs[nSrcTab]->TestCopyScenarioTo( maTabs[nDestTab] );
     849             : 
     850             :     OSL_FAIL("wrong table at TestCopyScenario");
     851           0 :     return false;
     852             : }
     853             : 
     854       59070 : void ScDocument::AddUnoObject( SfxListener& rObject )
     855             : {
     856       59070 :     if (!pUnoBroadcaster)
     857        1320 :         pUnoBroadcaster = new SfxBroadcaster;
     858             : 
     859       59070 :     rObject.StartListening( *pUnoBroadcaster );
     860       59070 : }
     861             : 
     862       52882 : void ScDocument::RemoveUnoObject( SfxListener& rObject )
     863             : {
     864       52882 :     if (pUnoBroadcaster)
     865             :     {
     866       52882 :         rObject.EndListening( *pUnoBroadcaster );
     867             : 
     868       52882 :         if ( bInUnoBroadcast )
     869             :         {
     870             :             // Broadcasts from ScDocument::BroadcastUno are the only way that
     871             :             // uno object methods are called without holding a reference.
     872             :             //
     873             :             // If RemoveUnoObject is called from an object dtor in the finalizer thread
     874             :             // while the main thread is calling BroadcastUno, the dtor thread must wait
     875             :             // (or the object's Notify might try to access a deleted object).
     876             :             // The SolarMutex can't be locked here because if a component is called from
     877             :             // a VCL event, the main thread has the SolarMutex locked all the time.
     878             :             //
     879             :             // This check is done after calling EndListening, so a later BroadcastUno call
     880             :             // won't touch this object.
     881             : 
     882           0 :             vcl::SolarMutexTryAndBuyGuard g;
     883           0 :             if (g.isAcquired())
     884             :             {
     885             :                 // BroadcastUno is always called with the SolarMutex locked, so if it
     886             :                 // can be acquired, this is within the same thread (should not happen)
     887             :                 OSL_FAIL( "RemoveUnoObject called from BroadcastUno" );
     888             :             }
     889             :             else
     890             :             {
     891             :                 // Let the thread that called BroadcastUno continue
     892           0 :                 while ( bInUnoBroadcast )
     893             :                 {
     894           0 :                     osl::Thread::yield();
     895             :                 }
     896           0 :             }
     897             :         }
     898             :     }
     899             :     else
     900             :     {
     901             :         OSL_FAIL("No Uno broadcaster");
     902             :     }
     903       52882 : }
     904             : 
     905       33872 : void ScDocument::BroadcastUno( const SfxHint &rHint )
     906             : {
     907       33872 :     if (pUnoBroadcaster)
     908             :     {
     909       33872 :         bInUnoBroadcast = true;
     910       33872 :         pUnoBroadcaster->Broadcast( rHint );
     911       33872 :         bInUnoBroadcast = false;
     912             : 
     913             :         // During Broadcast notification, Uno objects can add to pUnoListenerCalls.
     914             :         // The listener calls must be processed after completing the broadcast,
     915             :         // because they can add or remove objects from pUnoBroadcaster.
     916             : 
     917       33872 :         const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
     918       34360 :         if ( pUnoListenerCalls && pSimpleHint &&
     919       34360 :                 pSimpleHint->GetId() == SFX_HINT_DATACHANGED &&
     920         244 :                 !bInUnoListenerCall )
     921             :         {
     922             :             // Listener calls may lead to BroadcastUno calls again. The listener calls
     923             :             // are not nested, instead the calls are collected in the list, and the
     924             :             // outermost call executes them all.
     925             : 
     926         244 :             ScChartLockGuard aChartLockGuard(this);
     927         244 :             bInUnoListenerCall = true;
     928         244 :             pUnoListenerCalls->ExecuteAndClear();
     929         244 :             bInUnoListenerCall = false;
     930             :         }
     931             :     }
     932       33872 : }
     933             : 
     934         234 : void ScDocument::AddUnoListenerCall( const uno::Reference<util::XModifyListener>& rListener,
     935             :                                         const lang::EventObject& rEvent )
     936             : {
     937             :     OSL_ENSURE( bInUnoBroadcast, "AddUnoListenerCall is supposed to be called from BroadcastUno only" );
     938             : 
     939         234 :     if ( !pUnoListenerCalls )
     940          61 :         pUnoListenerCalls = new ScUnoListenerCalls;
     941         234 :     pUnoListenerCalls->Add( rListener, rEvent );
     942         234 : }
     943             : 
     944          66 : void ScDocument::BeginUnoRefUndo()
     945             : {
     946             :     OSL_ENSURE( !pUnoRefUndoList, "BeginUnoRefUndo twice" );
     947          66 :     delete pUnoRefUndoList;
     948             : 
     949          66 :     pUnoRefUndoList = new ScUnoRefList;
     950          66 : }
     951             : 
     952          66 : ScUnoRefList* ScDocument::EndUnoRefUndo()
     953             : {
     954          66 :     ScUnoRefList* pRet = pUnoRefUndoList;
     955          66 :     pUnoRefUndoList = NULL;
     956          66 :     return pRet; // Must be deleted by caller!
     957             : }
     958             : 
     959         981 : void ScDocument::AddUnoRefChange( sal_Int64 nId, const ScRangeList& rOldRanges )
     960             : {
     961         981 :     if ( pUnoRefUndoList )
     962         981 :         pUnoRefUndoList->Add( nId, rOldRanges );
     963         981 : }
     964             : 
     965         218 : void ScDocument::UpdateReference(
     966             :     sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc, bool bIncludeDraw, bool bUpdateNoteCaptionPos )
     967             : {
     968         218 :     if (!ValidRange(rCxt.maRange))
     969         218 :         return;
     970             : 
     971         218 :     boost::scoped_ptr<sc::ExpandRefsSwitch> pExpandRefsSwitch;
     972         218 :     if (rCxt.isInserted())
     973          91 :         pExpandRefsSwitch.reset(new sc::ExpandRefsSwitch(*this, SC_MOD()->GetInputOptions().GetExpandRefs()));
     974             : 
     975             :     size_t nFirstTab, nLastTab;
     976         218 :     if (rCxt.meMode == URM_COPY)
     977             :     {
     978          34 :         nFirstTab = rCxt.maRange.aStart.Tab();
     979          34 :         nLastTab = rCxt.maRange.aEnd.Tab();
     980             :     }
     981             :     else
     982             :     {
     983             :         // TODO: Have these methods use the context object directly.
     984         184 :         ScRange aRange = rCxt.maRange;
     985         184 :         UpdateRefMode eUpdateRefMode = rCxt.meMode;
     986         184 :         SCCOL nDx = rCxt.mnColDelta;
     987         184 :         SCROW nDy = rCxt.mnRowDelta;
     988         184 :         SCTAB nDz = rCxt.mnTabDelta;
     989         184 :         SCCOL nCol1 = rCxt.maRange.aStart.Col(), nCol2 = rCxt.maRange.aEnd.Col();
     990         184 :         SCROW nRow1 = rCxt.maRange.aStart.Row(), nRow2 = rCxt.maRange.aEnd.Row();
     991         184 :         SCTAB nTab1 = rCxt.maRange.aStart.Tab(), nTab2 = rCxt.maRange.aEnd.Tab();
     992             : 
     993         184 :         xColNameRanges->UpdateReference( eUpdateRefMode, this, aRange, nDx, nDy, nDz );
     994         184 :         xRowNameRanges->UpdateReference( eUpdateRefMode, this, aRange, nDx, nDy, nDz );
     995         184 :         pDBCollection->UpdateReference( eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz );
     996         184 :         if (pRangeName)
     997          86 :             pRangeName->UpdateReference(rCxt, -1);
     998         184 :         if ( pDPCollection )
     999           2 :             pDPCollection->UpdateReference( eUpdateRefMode, aRange, nDx, nDy, nDz );
    1000         184 :         UpdateChartRef( eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz );
    1001         184 :         UpdateRefAreaLinks( eUpdateRefMode, aRange, nDx, nDy, nDz );
    1002         184 :         if ( pValidationList )
    1003           7 :             pValidationList->UpdateReference(rCxt);
    1004         184 :         if ( pDetOpList )
    1005           0 :             pDetOpList->UpdateReference( this, eUpdateRefMode, aRange, nDx, nDy, nDz );
    1006         184 :         if ( pUnoBroadcaster )
    1007             :             pUnoBroadcaster->Broadcast( ScUpdateRefHint(
    1008         184 :                                 eUpdateRefMode, aRange, nDx, nDy, nDz ) );
    1009             : 
    1010         184 :         nFirstTab = 0;
    1011         184 :         nLastTab = maTabs.size()-1;
    1012             :     }
    1013             : 
    1014         458 :     for (size_t i = nFirstTab, n = maTabs.size() ; i <= nLastTab && i < n; ++i)
    1015             :     {
    1016         240 :         if (!maTabs[i])
    1017           0 :             continue;
    1018             : 
    1019         240 :         maTabs[i]->UpdateReference(rCxt, pUndoDoc, bIncludeDraw, bUpdateNoteCaptionPos);
    1020             :     }
    1021             : 
    1022         218 :     if ( bIsEmbedded )
    1023             :     {
    1024             :         SCCOL theCol1;
    1025             :         SCROW theRow1;
    1026             :         SCTAB theTab1;
    1027             :         SCCOL theCol2;
    1028             :         SCROW theRow2;
    1029             :         SCTAB theTab2;
    1030           0 :         theCol1 = aEmbedRange.aStart.Col();
    1031           0 :         theRow1 = aEmbedRange.aStart.Row();
    1032           0 :         theTab1 = aEmbedRange.aStart.Tab();
    1033           0 :         theCol2 = aEmbedRange.aEnd.Col();
    1034           0 :         theRow2 = aEmbedRange.aEnd.Row();
    1035           0 :         theTab2 = aEmbedRange.aEnd.Tab();
    1036             : 
    1037             :         // TODO: Have ScRefUpdate::Update() use the context object directly.
    1038           0 :         UpdateRefMode eUpdateRefMode = rCxt.meMode;
    1039           0 :         SCCOL nDx = rCxt.mnColDelta;
    1040           0 :         SCROW nDy = rCxt.mnRowDelta;
    1041           0 :         SCTAB nDz = rCxt.mnTabDelta;
    1042           0 :         SCCOL nCol1 = rCxt.maRange.aStart.Col(), nCol2 = rCxt.maRange.aEnd.Col();
    1043           0 :         SCROW nRow1 = rCxt.maRange.aStart.Row(), nRow2 = rCxt.maRange.aEnd.Row();
    1044           0 :         SCTAB nTab1 = rCxt.maRange.aStart.Tab(), nTab2 = rCxt.maRange.aEnd.Tab();
    1045             : 
    1046           0 :         if ( ScRefUpdate::Update( this, eUpdateRefMode, nCol1,nRow1,nTab1, nCol2,nRow2,nTab2,
    1047           0 :                                     nDx,nDy,nDz, theCol1,theRow1,theTab1, theCol2,theRow2,theTab2 ) )
    1048             :         {
    1049           0 :             aEmbedRange = ScRange( theCol1,theRow1,theTab1, theCol2,theRow2,theTab2 );
    1050             :         }
    1051             :     }
    1052             : 
    1053             :     // After moving, no clipboard move ref-updates are possible
    1054         218 :     if (rCxt.meMode != URM_COPY && IsClipboardSource())
    1055             :     {
    1056           0 :         ScDocument* pClipDoc = ScModule::GetClipDoc();
    1057           0 :         if (pClipDoc)
    1058           0 :             pClipDoc->GetClipParam().mbCutMode = false;
    1059         218 :     }
    1060             : }
    1061             : 
    1062           0 : void ScDocument::UpdateTranspose( const ScAddress& rDestPos, ScDocument* pClipDoc,
    1063             :                                         const ScMarkData& rMark, ScDocument* pUndoDoc )
    1064             : {
    1065             :     OSL_ENSURE(pClipDoc->bIsClip, "UpdateTranspose: No Clip");
    1066             : 
    1067           0 :     ScRange aSource;
    1068           0 :     ScClipParam& rClipParam = GetClipParam();
    1069           0 :     if (!rClipParam.maRanges.empty())
    1070           0 :         aSource = *rClipParam.maRanges.front();
    1071           0 :     ScAddress aDest = rDestPos;
    1072             : 
    1073           0 :     SCTAB nClipTab = 0;
    1074           0 :     for (SCTAB nDestTab=0; nDestTab< static_cast<SCTAB>(maTabs.size()) && maTabs[nDestTab]; nDestTab++)
    1075           0 :         if (rMark.GetTableSelect(nDestTab))
    1076             :         {
    1077           0 :             while (!pClipDoc->maTabs[nClipTab]) nClipTab = (nClipTab+1) % (MAXTAB+1);
    1078           0 :             aSource.aStart.SetTab( nClipTab );
    1079           0 :             aSource.aEnd.SetTab( nClipTab );
    1080           0 :             aDest.SetTab( nDestTab );
    1081             : 
    1082             :             // Like UpdateReference
    1083           0 :             if (pRangeName)
    1084           0 :                 pRangeName->UpdateTranspose( aSource, aDest ); // Before the cells!
    1085           0 :             for (SCTAB i=0; i< static_cast<SCTAB>(maTabs.size()); i++)
    1086           0 :                 if (maTabs[i])
    1087           0 :                     maTabs[i]->UpdateTranspose( aSource, aDest, pUndoDoc );
    1088             : 
    1089           0 :             nClipTab = (nClipTab+1) % (MAXTAB+1);
    1090             :         }
    1091           0 : }
    1092             : 
    1093           0 : void ScDocument::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
    1094             : {
    1095             :     //TODO: pDBCollection
    1096             :     //TODO: pPivotCollection
    1097             :     //TODO: UpdateChartRef
    1098             : 
    1099           0 :     if (pRangeName)
    1100           0 :         pRangeName->UpdateGrow( rArea, nGrowX, nGrowY );
    1101             : 
    1102           0 :     for (SCTAB i=0; i< static_cast<SCTAB>(maTabs.size()) && maTabs[i]; i++)
    1103           0 :         maTabs[i]->UpdateGrow( rArea, nGrowX, nGrowY );
    1104           0 : }
    1105             : 
    1106          24 : void ScDocument::Fill(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScProgress* pProgress, const ScMarkData& rMark,
    1107             :                         sal_uLong nFillCount, FillDir eFillDir, FillCmd eFillCmd, FillDateCmd eFillDateCmd,
    1108             :                         double nStepValue, double nMaxValue)
    1109             : {
    1110          24 :     PutInOrder( nCol1, nCol2 );
    1111          24 :     PutInOrder( nRow1, nRow2 );
    1112          24 :     SCTAB nMax = maTabs.size();
    1113          24 :     ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
    1114          48 :     for (; itr != itrEnd && *itr < nMax; ++itr)
    1115          24 :         if (maTabs[*itr])
    1116          24 :             maTabs[*itr]->Fill(nCol1, nRow1, nCol2, nRow2,
    1117             :                             nFillCount, eFillDir, eFillCmd, eFillDateCmd,
    1118          48 :                             nStepValue, nMaxValue, pProgress);
    1119          24 : }
    1120             : 
    1121           0 : OUString ScDocument::GetAutoFillPreview( const ScRange& rSource, SCCOL nEndX, SCROW nEndY )
    1122             : {
    1123           0 :     SCTAB nTab = rSource.aStart.Tab();
    1124           0 :     if (nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
    1125           0 :         return maTabs[nTab]->GetAutoFillPreview( rSource, nEndX, nEndY );
    1126             : 
    1127           0 :     return OUString();
    1128             : }
    1129             : 
    1130           0 : void ScDocument::AutoFormat( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
    1131             :                                     sal_uInt16 nFormatNo, const ScMarkData& rMark )
    1132             : {
    1133           0 :     PutInOrder( nStartCol, nEndCol );
    1134           0 :     PutInOrder( nStartRow, nEndRow );
    1135           0 :     SCTAB nMax = maTabs.size();
    1136           0 :     ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
    1137           0 :     for (; itr != itrEnd && *itr < nMax; ++itr)
    1138           0 :         if (maTabs[*itr])
    1139           0 :             maTabs[*itr]->AutoFormat( nStartCol, nStartRow, nEndCol, nEndRow, nFormatNo );
    1140           0 : }
    1141             : 
    1142           0 : void ScDocument::GetAutoFormatData(SCTAB nTab, SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
    1143             :                                     ScAutoFormatData& rData)
    1144             : {
    1145           0 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()))
    1146             :     {
    1147           0 :         if (maTabs[nTab])
    1148             :         {
    1149           0 :             PutInOrder(nStartCol, nEndCol);
    1150           0 :             PutInOrder(nStartRow, nEndRow);
    1151           0 :             maTabs[nTab]->GetAutoFormatData(nStartCol, nStartRow, nEndCol, nEndRow, rData);
    1152             :         }
    1153             :     }
    1154           0 : }
    1155             : 
    1156          37 : void ScDocument::GetSearchAndReplaceStart( const SvxSearchItem& rSearchItem,
    1157             :         SCCOL& rCol, SCROW& rRow )
    1158             : {
    1159          37 :     SvxSearchCmd nCommand = rSearchItem.GetCommand();
    1160          37 :     bool bReplace = ( nCommand == SvxSearchCmd::REPLACE ||
    1161          37 :         nCommand == SvxSearchCmd::REPLACE_ALL );
    1162          37 :     if ( rSearchItem.GetBackward() )
    1163             :     {
    1164           8 :         if ( rSearchItem.GetRowDirection() )
    1165             :         {
    1166           8 :             if ( rSearchItem.GetPattern() )
    1167             :             {
    1168           0 :                 rCol = MAXCOL;
    1169           0 :                 rRow = MAXROW+1;
    1170             :             }
    1171           8 :             else if ( bReplace )
    1172             :             {
    1173           0 :                 rCol = MAXCOL;
    1174           0 :                 rRow = MAXROW;
    1175             :             }
    1176             :             else
    1177             :             {
    1178           8 :                 rCol = MAXCOL+1;
    1179           8 :                 rRow = MAXROW;
    1180             :             }
    1181             :         }
    1182             :         else
    1183             :         {
    1184           0 :             if ( rSearchItem.GetPattern() )
    1185             :             {
    1186           0 :                 rCol = MAXCOL+1;
    1187           0 :                 rRow = MAXROW;
    1188             :             }
    1189           0 :             else if ( bReplace )
    1190             :             {
    1191           0 :                 rCol = MAXCOL;
    1192           0 :                 rRow = MAXROW;
    1193             :             }
    1194             :             else
    1195             :             {
    1196           0 :                 rCol = MAXCOL;
    1197           0 :                 rRow = MAXROW+1;
    1198             :             }
    1199             :         }
    1200             :     }
    1201             :     else
    1202             :     {
    1203          29 :         if ( rSearchItem.GetRowDirection() )
    1204             :         {
    1205           0 :             if ( rSearchItem.GetPattern() )
    1206             :             {
    1207           0 :                 rCol = 0;
    1208           0 :                 rRow = (SCROW) -1;
    1209             :             }
    1210           0 :             else if ( bReplace )
    1211             :             {
    1212           0 :                 rCol = 0;
    1213           0 :                 rRow = 0;
    1214             :             }
    1215             :             else
    1216             :             {
    1217           0 :                 rCol = (SCCOL) -1;
    1218           0 :                 rRow = 0;
    1219             :             }
    1220             :         }
    1221             :         else
    1222             :         {
    1223          29 :             if ( rSearchItem.GetPattern() )
    1224             :             {
    1225           0 :                 rCol = (SCCOL) -1;
    1226           0 :                 rRow = 0;
    1227             :             }
    1228          29 :             else if ( bReplace )
    1229             :             {
    1230           0 :                 rCol = 0;
    1231           0 :                 rRow = 0;
    1232             :             }
    1233             :             else
    1234             :             {
    1235          29 :                 rCol = 0;
    1236          29 :                 rRow = (SCROW) -1;
    1237             :             }
    1238             :         }
    1239             :     }
    1240          37 : }
    1241             : 
    1242          80 : bool ScDocument::SearchAndReplace(
    1243             :     const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow, SCTAB& rTab,
    1244             :     const ScMarkData& rMark, ScRangeList& rMatchedRanges,
    1245             :     OUString& rUndoStr, ScDocument* pUndoDoc)
    1246             : {
    1247             :     // FIXME: Manage separated marks per table!
    1248          80 :     bool bFound = false;
    1249          80 :     if (rTab >= static_cast<SCTAB>(maTabs.size()))
    1250             :         OSL_FAIL("table out of range");
    1251          80 :     if (ValidTab(rTab))
    1252             :     {
    1253             :         SCCOL nCol;
    1254             :         SCROW nRow;
    1255             :         SCTAB nTab;
    1256          80 :         SvxSearchCmd nCommand = rSearchItem.GetCommand();
    1257          80 :         if ( nCommand == SvxSearchCmd::FIND_ALL ||
    1258             :              nCommand == SvxSearchCmd::REPLACE_ALL )
    1259             :         {
    1260          49 :             SCTAB nMax = maTabs.size();
    1261          49 :             ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
    1262          98 :             for (; itr != itrEnd && *itr < nMax; ++itr)
    1263          49 :                 if (maTabs[*itr])
    1264             :                 {
    1265          49 :                     nCol = 0;
    1266          49 :                     nRow = 0;
    1267          49 :                     bFound |= maTabs[*itr]->SearchAndReplace(
    1268          49 :                         rSearchItem, nCol, nRow, rMark, rMatchedRanges, rUndoStr, pUndoDoc);
    1269          49 :                 }
    1270             : 
    1271             :             // Mark is set completely inside already
    1272             :         }
    1273             :         else
    1274             :         {
    1275          31 :             nCol = rCol;
    1276          31 :             nRow = rRow;
    1277          31 :             if (rSearchItem.GetBackward())
    1278             :             {
    1279          18 :                 for (nTab = rTab; ((SCsTAB)nTab >= 0) && !bFound; nTab--)
    1280          10 :                     if (maTabs[nTab])
    1281             :                     {
    1282          10 :                         if (rMark.GetTableSelect(nTab))
    1283             :                         {
    1284           8 :                             bFound = maTabs[nTab]->SearchAndReplace(
    1285           8 :                                 rSearchItem, nCol, nRow, rMark, rMatchedRanges, rUndoStr, pUndoDoc);
    1286           8 :                             if (bFound)
    1287             :                             {
    1288           4 :                                 rCol = nCol;
    1289           4 :                                 rRow = nRow;
    1290           4 :                                 rTab = nTab;
    1291             :                             }
    1292             :                             else
    1293             :                             {
    1294             :                                 ScDocument::GetSearchAndReplaceStart(
    1295           4 :                                     rSearchItem, nCol, nRow );
    1296             : 
    1297             :                                 // notify LibreOfficeKit about changed page
    1298           4 :                                 if ( GetDrawLayer() && GetDrawLayer()->isTiledRendering() )
    1299             :                                 {
    1300           0 :                                     OString aPayload = OString::number(nTab);
    1301           0 :                                     GetDrawLayer()->libreOfficeKitCallback(LOK_CALLBACK_SET_PART, aPayload.getStr());
    1302             :                                 }
    1303             :                             }
    1304             :                         }
    1305             :                     }
    1306             :             }
    1307             :             else
    1308             :             {
    1309          55 :                 for (nTab = rTab; (nTab < static_cast<SCTAB>(maTabs.size())) && !bFound; nTab++)
    1310          32 :                     if (maTabs[nTab])
    1311             :                     {
    1312          32 :                         if (rMark.GetTableSelect(nTab))
    1313             :                         {
    1314          23 :                             bFound = maTabs[nTab]->SearchAndReplace(
    1315          23 :                                 rSearchItem, nCol, nRow, rMark, rMatchedRanges, rUndoStr, pUndoDoc);
    1316          23 :                             if (bFound)
    1317             :                             {
    1318          15 :                                 rCol = nCol;
    1319          15 :                                 rRow = nRow;
    1320          15 :                                 rTab = nTab;
    1321             :                             }
    1322             :                             else
    1323             :                             {
    1324             :                                 ScDocument::GetSearchAndReplaceStart(
    1325           8 :                                     rSearchItem, nCol, nRow );
    1326             : 
    1327             :                                 // notify LibreOfficeKit about changed page
    1328           8 :                                 if ( GetDrawLayer() && GetDrawLayer()->isTiledRendering() )
    1329             :                                 {
    1330           0 :                                     OString aPayload = OString::number(nTab);
    1331           0 :                                     GetDrawLayer()->libreOfficeKitCallback(LOK_CALLBACK_SET_PART, aPayload.getStr());
    1332             :                                 }
    1333             :                             }
    1334             :                         }
    1335             :                     }
    1336             :             }
    1337             :         }
    1338             :     }
    1339          80 :     return bFound;
    1340             : }
    1341             : 
    1342             : /**
    1343             :  * Adapt Outline
    1344             :  */
    1345        1326 : bool ScDocument::UpdateOutlineCol( SCCOL nStartCol, SCCOL nEndCol, SCTAB nTab, bool bShow )
    1346             : {
    1347        1326 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    1348        1326 :         return maTabs[nTab]->UpdateOutlineCol( nStartCol, nEndCol, bShow );
    1349             : 
    1350             :     OSL_FAIL("missing tab");
    1351           0 :     return false;
    1352             : }
    1353             : 
    1354          29 : bool ScDocument::UpdateOutlineRow( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bShow )
    1355             : {
    1356          29 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    1357          29 :         return maTabs[nTab]->UpdateOutlineRow( nStartRow, nEndRow, bShow );
    1358             : 
    1359             :     OSL_FAIL("missing tab");
    1360           0 :     return false;
    1361             : }
    1362             : 
    1363          35 : void ScDocument::Sort(
    1364             :     SCTAB nTab, const ScSortParam& rSortParam, bool bKeepQuery, bool bUpdateRefs,
    1365             :     ScProgress* pProgress, sc::ReorderParam* pUndo )
    1366             : {
    1367          35 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    1368             :     {
    1369          35 :         bool bOldEnableIdle = IsIdleEnabled();
    1370          35 :         EnableIdle(false);
    1371          35 :         maTabs[nTab]->Sort(rSortParam, bKeepQuery, bUpdateRefs, pProgress, pUndo);
    1372          35 :         EnableIdle(bOldEnableIdle);
    1373             :     }
    1374          35 : }
    1375             : 
    1376          22 : void ScDocument::Reorder( const sc::ReorderParam& rParam, ScProgress* pProgress )
    1377             : {
    1378          22 :     ScTable* pTab = FetchTable(rParam.maSortRange.aStart.Tab());
    1379          22 :     if (!pTab)
    1380          22 :         return;
    1381             : 
    1382          22 :     bool bOldEnableIdle = IsIdleEnabled();
    1383          22 :     EnableIdle(false);
    1384          22 :     pTab->Reorder(rParam, pProgress);
    1385          22 :     EnableIdle(bOldEnableIdle);
    1386             : }
    1387             : 
    1388          18 : SCSIZE ScDocument::Query(SCTAB nTab, const ScQueryParam& rQueryParam, bool bKeepSub)
    1389             : {
    1390          18 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    1391          18 :         return maTabs[nTab]->Query((ScQueryParam&)rQueryParam, bKeepSub);
    1392             : 
    1393             :     OSL_FAIL("missing tab");
    1394           0 :     return 0;
    1395             : }
    1396             : 
    1397           0 : void ScDocument::GetUpperCellString(SCCOL nCol, SCROW nRow, SCTAB nTab, OUString& rStr)
    1398             : {
    1399           0 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    1400           0 :         maTabs[nTab]->GetUpperCellString( nCol, nRow, rStr );
    1401             :     else
    1402           0 :         rStr.clear();
    1403           0 : }
    1404             : 
    1405           1 : bool ScDocument::CreateQueryParam(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCTAB nTab, ScQueryParam& rQueryParam)
    1406             : {
    1407           1 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    1408           1 :         return maTabs[nTab]->CreateQueryParam(nCol1, nRow1, nCol2, nRow2, rQueryParam);
    1409             : 
    1410             :     OSL_FAIL("missing tab");
    1411           0 :     return false;
    1412             : }
    1413             : 
    1414         249 : bool ScDocument::HasAutoFilter( SCCOL nCurCol, SCROW nCurRow, SCTAB nCurTab )
    1415             : {
    1416         249 :     const ScDBData* pDBData = GetDBAtCursor( nCurCol, nCurRow, nCurTab );
    1417         249 :     bool bHasAutoFilter = (pDBData != NULL);
    1418             : 
    1419         249 :     if ( pDBData )
    1420             :     {
    1421           3 :         if ( pDBData->HasHeader() )
    1422             :         {
    1423             :             SCCOL nCol;
    1424             :             SCROW nRow;
    1425             :             sal_Int16  nFlag;
    1426             : 
    1427           2 :             ScQueryParam aParam;
    1428           2 :             pDBData->GetQueryParam( aParam );
    1429           2 :             nRow = aParam.nRow1;
    1430             : 
    1431           4 :             for ( nCol=aParam.nCol1; nCol<=aParam.nCol2 && bHasAutoFilter; nCol++ )
    1432             :             {
    1433             :                 nFlag = static_cast<const ScMergeFlagAttr*>(
    1434           2 :                             GetAttr( nCol, nRow, nCurTab, ATTR_MERGE_FLAG ))->
    1435           2 :                                 GetValue();
    1436             : 
    1437           2 :                 if ( (nFlag & SC_MF_AUTO) == 0 )
    1438           2 :                     bHasAutoFilter = false;
    1439           2 :             }
    1440             :         }
    1441             :         else
    1442           1 :             bHasAutoFilter = false;
    1443             :     }
    1444             : 
    1445         249 :     return bHasAutoFilter;
    1446             : }
    1447             : 
    1448           9 : bool ScDocument::HasColHeader( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
    1449             :                                     SCTAB nTab )
    1450             : {
    1451           9 :     return ValidTab(nTab) && maTabs[nTab] && maTabs[nTab]->HasColHeader( nStartCol, nStartRow, nEndCol, nEndRow );
    1452             : }
    1453             : 
    1454           0 : bool ScDocument::HasRowHeader( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
    1455             :                                     SCTAB nTab )
    1456             : {
    1457           0 :     return ValidTab(nTab) && maTabs[nTab] && maTabs[nTab]->HasRowHeader( nStartCol, nStartRow, nEndCol, nEndRow );
    1458             : }
    1459             : 
    1460             : /**
    1461             :  * Entries for AutoFilter listbox
    1462             :  */
    1463           0 : bool ScDocument::GetFilterEntries(
    1464             :     SCCOL nCol, SCROW nRow, SCTAB nTab, bool bFilter, std::vector<ScTypedStrData>& rStrings, bool& rHasDates)
    1465             : {
    1466           0 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] && pDBCollection )
    1467             :     {
    1468           0 :         ScDBData* pDBData = pDBCollection->GetDBAtCursor(nCol, nRow, nTab, false);  //!??
    1469           0 :         if (pDBData)
    1470             :         {
    1471           0 :             pDBData->ExtendDataArea(this);
    1472             :             SCTAB nAreaTab;
    1473             :             SCCOL nStartCol;
    1474             :             SCROW nStartRow;
    1475             :             SCCOL nEndCol;
    1476             :             SCROW nEndRow;
    1477           0 :             pDBData->GetArea( nAreaTab, nStartCol, nStartRow, nEndCol, nEndRow );
    1478             : 
    1479           0 :             if (pDBData->HasHeader())
    1480           0 :                 ++nStartRow;
    1481             : 
    1482           0 :             ScQueryParam aParam;
    1483           0 :             pDBData->GetQueryParam( aParam );
    1484             : 
    1485             :             // Return all filter entries, if a filter condition is connected with a boolean OR
    1486           0 :             if ( bFilter )
    1487             :             {
    1488           0 :                 SCSIZE nEntryCount = aParam.GetEntryCount();
    1489           0 :                 for ( SCSIZE i = 0; i < nEntryCount && aParam.GetEntry(i).bDoQuery; ++i )
    1490             :                 {
    1491           0 :                     ScQueryEntry& rEntry = aParam.GetEntry(i);
    1492           0 :                     if ( rEntry.eConnect != SC_AND )
    1493             :                     {
    1494           0 :                         bFilter = false;
    1495           0 :                         break;
    1496             :                     }
    1497             :                 }
    1498             :             }
    1499             : 
    1500           0 :             if ( bFilter )
    1501             :             {
    1502           0 :                 maTabs[nTab]->GetFilteredFilterEntries( nCol, nStartRow, nEndRow, aParam, rStrings, rHasDates );
    1503             :             }
    1504             :             else
    1505             :             {
    1506           0 :                 maTabs[nTab]->GetFilterEntries( nCol, nStartRow, nEndRow, rStrings, rHasDates );
    1507             :             }
    1508             : 
    1509           0 :             sortAndRemoveDuplicates(rStrings, aParam.bCaseSens);
    1510           0 :             return true;
    1511             :         }
    1512             :     }
    1513             : 
    1514           0 :     return false;
    1515             : }
    1516             : 
    1517             : /**
    1518             :  * Entries for Filter dialog
    1519             :  */
    1520           0 : bool ScDocument::GetFilterEntriesArea(
    1521             :     SCCOL nCol, SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bCaseSens,
    1522             :     std::vector<ScTypedStrData>& rStrings, bool& rHasDates)
    1523             : {
    1524           0 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    1525             :     {
    1526           0 :         maTabs[nTab]->GetFilterEntries( nCol, nStartRow, nEndRow, rStrings, rHasDates );
    1527           0 :         sortAndRemoveDuplicates(rStrings, bCaseSens);
    1528           0 :         return true;
    1529             :     }
    1530             : 
    1531           0 :     return false;
    1532             : }
    1533             : 
    1534             : /**
    1535             :  * Entries for selection list listbox (no numbers/formulas)
    1536             :  */
    1537           2 : bool ScDocument::GetDataEntries(
    1538             :     SCCOL nCol, SCROW nRow, SCTAB nTab, bool bCaseSens,
    1539             :     std::vector<ScTypedStrData>& rStrings, bool bLimit )
    1540             : {
    1541           2 :     if( !bLimit )
    1542             :     {
    1543             :         /*  Try to generate the list from list validation. This part is skipped,
    1544             :             if bLimit==true, because in that case this function is called to get
    1545             :             cell values for auto completion on input. */
    1546           2 :         sal_uInt32 nValidation = static_cast< const SfxUInt32Item* >( GetAttr( nCol, nRow, nTab, ATTR_VALIDDATA ) )->GetValue();
    1547           2 :         if( nValidation )
    1548             :         {
    1549           0 :             const ScValidationData* pData = GetValidationEntry( nValidation );
    1550           0 :             if( pData && pData->FillSelectionList( rStrings, ScAddress( nCol, nRow, nTab ) ) )
    1551             :             {
    1552           0 :                 if (pData->GetListType() == css::sheet::TableValidationVisibility::SORTEDASCENDING)
    1553           0 :                     sortAndRemoveDuplicates(rStrings, bCaseSens);
    1554             : 
    1555           0 :                 return true;
    1556             :             }
    1557             :         }
    1558             :     }
    1559             : 
    1560           2 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()))
    1561           0 :         return false;
    1562             : 
    1563           2 :     if (!maTabs[nTab])
    1564           0 :         return false;
    1565             : 
    1566           2 :     std::set<ScTypedStrData> aStrings;
    1567           2 :     bool bRet = maTabs[nTab]->GetDataEntries(nCol, nRow, aStrings, bLimit);
    1568           2 :     rStrings.insert(rStrings.end(), aStrings.begin(), aStrings.end());
    1569           2 :     sortAndRemoveDuplicates(rStrings, bCaseSens);
    1570             : 
    1571           2 :     return bRet;
    1572             : }
    1573             : 
    1574             : /**
    1575             :  * Entries for Formula auto input
    1576             :  */
    1577           0 : bool ScDocument::GetFormulaEntries( ScTypedCaseStrSet& rStrings )
    1578             : {
    1579             : 
    1580             :     // Range name
    1581           0 :     if ( pRangeName )
    1582             :     {
    1583           0 :         ScRangeName::const_iterator itr = pRangeName->begin(), itrEnd = pRangeName->end();
    1584           0 :         for (; itr != itrEnd; ++itr)
    1585           0 :             rStrings.insert(ScTypedStrData(itr->second->GetName(), 0.0, ScTypedStrData::Name));
    1586             :     }
    1587             : 
    1588             :     // Database collection
    1589           0 :     if ( pDBCollection )
    1590             :     {
    1591           0 :         const ScDBCollection::NamedDBs& rDBs = pDBCollection->getNamedDBs();
    1592           0 :         ScDBCollection::NamedDBs::const_iterator itr = rDBs.begin(), itrEnd = rDBs.end();
    1593           0 :         for (; itr != itrEnd; ++itr)
    1594           0 :             rStrings.insert(ScTypedStrData(itr->GetName(), 0.0, ScTypedStrData::DbName));
    1595             :     }
    1596             : 
    1597             :     // Content of name ranges
    1598             :     ScRangePairList* pLists[2];
    1599           0 :     pLists[0] = GetColNameRanges();
    1600           0 :     pLists[1] = GetRowNameRanges();
    1601           0 :     for (sal_uInt16 nListNo=0; nListNo<2; nListNo++)
    1602             :     {
    1603           0 :         ScRangePairList* pList = pLists[ nListNo ];
    1604           0 :         if (!pList)
    1605           0 :             continue;
    1606             : 
    1607           0 :         for ( size_t i = 0, nPairs = pList->size(); i < nPairs; ++i )
    1608             :         {
    1609           0 :             ScRangePair* pPair = (*pList)[i];
    1610           0 :             ScRange aRange = pPair->GetRange(0);
    1611           0 :             ScCellIterator aIter( this, aRange );
    1612           0 :             for (bool bHas = aIter.first(); bHas; bHas = aIter.next())
    1613             :             {
    1614           0 :                 if (!aIter.hasString())
    1615           0 :                     continue;
    1616             : 
    1617           0 :                 OUString aStr = aIter.getString();
    1618           0 :                 rStrings.insert(ScTypedStrData(aStr, 0.0, ScTypedStrData::Header));
    1619           0 :             }
    1620           0 :         }
    1621             :     }
    1622             : 
    1623           0 :     return true;
    1624             : }
    1625             : 
    1626           0 : void ScDocument::GetEmbedded( ScRange& rRange ) const
    1627             : {
    1628           0 :     rRange = aEmbedRange;
    1629           0 : }
    1630             : 
    1631           0 : Rectangle ScDocument::GetEmbeddedRect() const // 1/100 mm
    1632             : {
    1633           0 :     Rectangle aRect;
    1634           0 :     ScTable* pTable = NULL;
    1635           0 :     if ( aEmbedRange.aStart.Tab() < static_cast<SCTAB>(maTabs.size()) )
    1636           0 :         pTable = maTabs[aEmbedRange.aStart.Tab()];
    1637             :     else
    1638             :         OSL_FAIL("table out of range");
    1639           0 :     if (!pTable)
    1640             :     {
    1641             :         OSL_FAIL("GetEmbeddedRect without a table");
    1642             :     }
    1643             :     else
    1644             :     {
    1645             :         SCCOL i;
    1646             : 
    1647           0 :         for (i=0; i<aEmbedRange.aStart.Col(); i++)
    1648           0 :             aRect.Left() += pTable->GetColWidth(i);
    1649           0 :         aRect.Top() += pTable->GetRowHeight( 0, aEmbedRange.aStart.Row() - 1);
    1650           0 :         aRect.Right() = aRect.Left();
    1651           0 :         for (i=aEmbedRange.aStart.Col(); i<=aEmbedRange.aEnd.Col(); i++)
    1652           0 :             aRect.Right() += pTable->GetColWidth(i);
    1653           0 :         aRect.Bottom() = aRect.Top();
    1654           0 :         aRect.Bottom() += pTable->GetRowHeight( aEmbedRange.aStart.Row(), aEmbedRange.aEnd.Row());
    1655             : 
    1656           0 :         aRect.Left()   = (long) ( aRect.Left()   * HMM_PER_TWIPS );
    1657           0 :         aRect.Right()  = (long) ( aRect.Right()  * HMM_PER_TWIPS );
    1658           0 :         aRect.Top()    = (long) ( aRect.Top()    * HMM_PER_TWIPS );
    1659           0 :         aRect.Bottom() = (long) ( aRect.Bottom() * HMM_PER_TWIPS );
    1660             :     }
    1661           0 :     return aRect;
    1662             : }
    1663             : 
    1664           0 : void ScDocument::SetEmbedded( const ScRange& rRange )
    1665             : {
    1666           0 :     bIsEmbedded = true;
    1667           0 :     aEmbedRange = rRange;
    1668           0 : }
    1669             : 
    1670           0 : void ScDocument::ResetEmbedded()
    1671             : {
    1672           0 :     bIsEmbedded = false;
    1673           0 :     aEmbedRange = ScRange();
    1674           0 : }
    1675             : 
    1676             : /** Similar to ScViewData::AddPixelsWhile(), but add height twips and only
    1677             :     while result is less than nStopTwips.
    1678             :     @return true if advanced at least one row.
    1679             :  */
    1680        1344 : static bool lcl_AddTwipsWhile( long & rTwips, long nStopTwips, SCROW & rPosY, SCROW nEndRow, const ScTable * pTable, bool bHiddenAsZero = true )
    1681             : {
    1682        1344 :     SCROW nRow = rPosY;
    1683        1344 :     bool bAdded = false;
    1684        1344 :     bool bStop = false;
    1685        4945 :     while (rTwips < nStopTwips && nRow <= nEndRow && !bStop)
    1686             :     {
    1687             :         SCROW nHeightEndRow;
    1688        2257 :         sal_uInt16 nHeight = pTable->GetRowHeight( nRow, NULL, &nHeightEndRow, bHiddenAsZero );
    1689        2257 :         if (nHeightEndRow > nEndRow)
    1690           0 :             nHeightEndRow = nEndRow;
    1691        2257 :         if (!nHeight)
    1692          57 :             nRow = nHeightEndRow + 1;
    1693             :         else
    1694             :         {
    1695        2200 :             SCROW nRows = nHeightEndRow - nRow + 1;
    1696        2200 :             sal_Int64 nAdd = static_cast<sal_Int64>(nHeight) * nRows;
    1697        2200 :             if (nAdd + rTwips >= nStopTwips)
    1698             :             {
    1699        1337 :                 sal_Int64 nDiff = nAdd + rTwips - nStopTwips;
    1700        1337 :                 nRows -= static_cast<SCROW>(nDiff / nHeight);
    1701        1337 :                 nAdd = static_cast<sal_Int64>(nHeight) * nRows;
    1702             :                 // We're looking for a value that satisfies loop condition.
    1703        1337 :                 if (nAdd + rTwips >= nStopTwips)
    1704             :                 {
    1705        1337 :                     --nRows;
    1706        1337 :                     nAdd -= nHeight;
    1707             :                 }
    1708        1337 :                 bStop = true;
    1709             :             }
    1710        2200 :             rTwips += static_cast<long>(nAdd);
    1711        2200 :             nRow += nRows;
    1712             :         }
    1713             :     }
    1714        1344 :     if (nRow > rPosY)
    1715             :     {
    1716        1123 :         --nRow;
    1717        1123 :         bAdded = true;
    1718             :     }
    1719        1344 :     rPosY = nRow;
    1720        1344 :     return bAdded;
    1721             : }
    1722             : 
    1723         672 : ScRange ScDocument::GetRange( SCTAB nTab, const Rectangle& rMMRect, bool bHiddenAsZero ) const
    1724             : {
    1725         672 :     ScTable* pTable = NULL;
    1726         672 :     if (nTab < static_cast<SCTAB>(maTabs.size()))
    1727         672 :         pTable = maTabs[nTab];
    1728             :     else
    1729             :         OSL_FAIL("table out of range");
    1730         672 :     if (!pTable)
    1731             :     {
    1732             :         OSL_FAIL("GetRange without a table");
    1733           0 :         return ScRange();
    1734             :     }
    1735             : 
    1736         672 :     Rectangle aPosRect = rMMRect;
    1737         672 :     if ( IsNegativePage( nTab ) )
    1738           0 :         ScDrawLayer::MirrorRectRTL( aPosRect ); // Always with positive (LTR) values
    1739             : 
    1740             :     long nSize;
    1741             :     long nTwips;
    1742             :     long nAdd;
    1743             :     bool bEnd;
    1744             : 
    1745         672 :     nSize = 0;
    1746         672 :     nTwips = (long) (aPosRect.Left() / HMM_PER_TWIPS);
    1747             : 
    1748         672 :     SCCOL nX1 = 0;
    1749         672 :     bEnd = false;
    1750        5648 :     while (!bEnd)
    1751             :     {
    1752        4304 :         nAdd = (long) pTable->GetColWidth(nX1, bHiddenAsZero);
    1753        4304 :         if (nSize+nAdd <= nTwips+1 && nX1<MAXCOL)
    1754             :         {
    1755        3632 :             nSize += nAdd;
    1756        3632 :             ++nX1;
    1757             :         }
    1758             :         else
    1759         672 :             bEnd = true;
    1760             :     }
    1761             : 
    1762         672 :     nTwips = (long) (aPosRect.Right() / HMM_PER_TWIPS);
    1763             : 
    1764         672 :     SCCOL nX2 = nX1;
    1765         672 :     bEnd = false;
    1766        5403 :     while (!bEnd)
    1767             :     {
    1768        4059 :         nAdd = (long) pTable->GetColWidth(nX2, bHiddenAsZero);
    1769        4059 :         if (nSize+nAdd < nTwips && nX2<MAXCOL)
    1770             :         {
    1771        3387 :             nSize += nAdd;
    1772        3387 :             ++nX2;
    1773             :         }
    1774             :         else
    1775         672 :             bEnd = true;
    1776             :     }
    1777             : 
    1778         672 :     nSize = 0;
    1779         672 :     nTwips = (long) (aPosRect.Top() / HMM_PER_TWIPS);
    1780             : 
    1781         672 :     SCROW nY1 = 0;
    1782             :     // Was if(nSize+nAdd<=nTwips+1) inside loop => if(nSize+nAdd<nTwips+2)
    1783         672 :     if (lcl_AddTwipsWhile( nSize, nTwips+2, nY1, MAXROW, pTable, bHiddenAsZero) && nY1 < MAXROW)
    1784         476 :         ++nY1;  // original loop ended on last matched +1 unless that was MAXROW
    1785             : 
    1786         672 :     nTwips = (long) (aPosRect.Bottom() / HMM_PER_TWIPS);
    1787             : 
    1788         672 :     SCROW nY2 = nY1;
    1789             :     // Was if(nSize+nAdd<nTwips) inside loop => if(nSize+nAdd<nTwips)
    1790         672 :     if (lcl_AddTwipsWhile( nSize, nTwips, nY2, MAXROW, pTable, bHiddenAsZero) && nY2 < MAXROW)
    1791         647 :         ++nY2;  // original loop ended on last matched +1 unless that was MAXROW
    1792             : 
    1793         672 :     return ScRange( nX1,nY1,nTab, nX2,nY2,nTab );
    1794             : }
    1795             : 
    1796           1 : void ScDocument::SetEmbedded( SCTAB nTab, const Rectangle& rRect ) // From VisArea (1/100 mm)
    1797             : {
    1798           1 :     bIsEmbedded = true;
    1799           1 :     aEmbedRange = GetRange( nTab, rRect );
    1800           1 : }
    1801             : 
    1802          92 : ScDocProtection* ScDocument::GetDocProtection() const
    1803             : {
    1804          92 :     return pDocProtection.get();
    1805             : }
    1806             : 
    1807           3 : void ScDocument::SetDocProtection(const ScDocProtection* pProtect)
    1808             : {
    1809           3 :     if (pProtect)
    1810           2 :         pDocProtection.reset(new ScDocProtection(*pProtect));
    1811             :     else
    1812           1 :         pDocProtection.reset();
    1813           3 : }
    1814             : 
    1815         106 : bool ScDocument::IsDocProtected() const
    1816             : {
    1817         106 :     return pDocProtection.get() && pDocProtection->isProtected();
    1818             : }
    1819             : 
    1820          42 : bool ScDocument::IsDocEditable() const
    1821             : {
    1822             :     // Import into read-only document is possible
    1823          42 :     return !IsDocProtected() && ( bImportingXML || mbChangeReadOnlyEnabled || !pShell || !pShell->IsReadOnly() );
    1824             : }
    1825             : 
    1826       32941 : bool ScDocument::IsTabProtected( SCTAB nTab ) const
    1827             : {
    1828       32941 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
    1829       32941 :         return maTabs[nTab]->IsProtected();
    1830             : 
    1831             :     OSL_FAIL("Wrong table number");
    1832           0 :     return false;
    1833             : }
    1834             : 
    1835         354 : ScTableProtection* ScDocument::GetTabProtection( SCTAB nTab ) const
    1836             : {
    1837         354 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
    1838         354 :         return maTabs[nTab]->GetProtection();
    1839             : 
    1840           0 :     return NULL;
    1841             : }
    1842             : 
    1843          18 : void ScDocument::SetTabProtection(SCTAB nTab, const ScTableProtection* pProtect)
    1844             : {
    1845          18 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()))
    1846          18 :         return;
    1847             : 
    1848          18 :     maTabs[nTab]->SetProtection(pProtect);
    1849             : }
    1850             : 
    1851           0 : void ScDocument::CopyTabProtection(SCTAB nTabSrc, SCTAB nTabDest)
    1852             : {
    1853           0 :     if (!ValidTab(nTabSrc) || nTabSrc >= static_cast<SCTAB>(maTabs.size()) || nTabDest >= static_cast<SCTAB>(maTabs.size()) || !ValidTab(nTabDest))
    1854           0 :         return;
    1855             : 
    1856           0 :     maTabs[nTabDest]->SetProtection( maTabs[nTabSrc]->GetProtection() );
    1857             : }
    1858             : 
    1859       47086 : const ScDocOptions& ScDocument::GetDocOptions() const
    1860             : {
    1861             :     assert(pDocOptions && "No DocOptions! :-(");
    1862       47086 :     return *pDocOptions;
    1863             : }
    1864             : 
    1865        2709 : void ScDocument::SetDocOptions( const ScDocOptions& rOpt )
    1866             : {
    1867             :     assert(pDocOptions && "No DocOptions! :-(");
    1868             : 
    1869        2709 :     *pDocOptions = rOpt;
    1870        2709 :     xPoolHelper->SetFormTableOpt(rOpt);
    1871        2709 : }
    1872             : 
    1873        6631 : const ScViewOptions& ScDocument::GetViewOptions() const
    1874             : {
    1875             :     assert(pViewOptions && "No ViewOptions! :-(");
    1876        6631 :     return *pViewOptions;
    1877             : }
    1878             : 
    1879        6001 : void ScDocument::SetViewOptions( const ScViewOptions& rOpt )
    1880             : {
    1881             :     assert(pViewOptions && "No ViewOptions! :-(");
    1882        6001 :     *pViewOptions = rOpt;
    1883        6001 : }
    1884             : 
    1885        1173 : void ScDocument::GetLanguage( LanguageType& rLatin, LanguageType& rCjk, LanguageType& rCtl ) const
    1886             : {
    1887        1173 :     rLatin = eLanguage;
    1888        1173 :     rCjk = eCjkLanguage;
    1889        1173 :     rCtl = eCtlLanguage;
    1890        1173 : }
    1891             : 
    1892        3451 : void ScDocument::SetLanguage( LanguageType eLatin, LanguageType eCjk, LanguageType eCtl )
    1893             : {
    1894        3451 :     eLanguage = eLatin;
    1895        3451 :     eCjkLanguage = eCjk;
    1896        3451 :     eCtlLanguage = eCtl;
    1897        3451 :     if ( xPoolHelper.is() )
    1898             :     {
    1899        2456 :         ScDocumentPool* pPool = xPoolHelper->GetDocPool();
    1900        2456 :         pPool->SetPoolDefaultItem( SvxLanguageItem( eLanguage, ATTR_FONT_LANGUAGE ) );
    1901        2456 :         pPool->SetPoolDefaultItem( SvxLanguageItem( eCjkLanguage, ATTR_CJK_FONT_LANGUAGE ) );
    1902        2456 :         pPool->SetPoolDefaultItem( SvxLanguageItem( eCtlLanguage, ATTR_CTL_FONT_LANGUAGE ) );
    1903             :     }
    1904             : 
    1905        3451 :     UpdateDrawLanguages(); // Set edit engine defaults in drawing layer pool
    1906        3451 : }
    1907             : 
    1908        5148 : Rectangle ScDocument::GetMMRect( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, bool bHiddenAsZero ) const
    1909             : {
    1910        5148 :     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab])
    1911             :     {
    1912             :         OSL_FAIL("GetMMRect: wrong table");
    1913           0 :         return Rectangle(0,0,0,0);
    1914             :     }
    1915             : 
    1916             :     SCCOL i;
    1917        5148 :     Rectangle aRect;
    1918             : 
    1919       28851 :     for (i=0; i<nStartCol; i++)
    1920       23703 :         aRect.Left() += GetColWidth(i,nTab, bHiddenAsZero );
    1921        5148 :     aRect.Top() += GetRowHeight( 0, nStartRow-1, nTab, bHiddenAsZero );
    1922             : 
    1923        5148 :     aRect.Right()  = aRect.Left();
    1924        5148 :     aRect.Bottom() = aRect.Top();
    1925             : 
    1926      327150 :     for (i=nStartCol; i<=nEndCol; i++)
    1927      322002 :         aRect.Right() += GetColWidth(i,nTab, bHiddenAsZero);
    1928        5148 :     aRect.Bottom() += GetRowHeight( nStartRow, nEndRow, nTab, bHiddenAsZero );
    1929             : 
    1930        5148 :     aRect.Left()    = (long)(aRect.Left()   * HMM_PER_TWIPS);
    1931        5148 :     aRect.Right()   = (long)(aRect.Right()  * HMM_PER_TWIPS);
    1932        5148 :     aRect.Top()     = (long)(aRect.Top()    * HMM_PER_TWIPS);
    1933        5148 :     aRect.Bottom()  = (long)(aRect.Bottom() * HMM_PER_TWIPS);
    1934             : 
    1935        5148 :     if ( IsNegativePage( nTab ) )
    1936           0 :         ScDrawLayer::MirrorRectRTL( aRect );
    1937             : 
    1938        5148 :     return aRect;
    1939             : }
    1940             : 
    1941          87 : void ScDocument::SetExtDocOptions( ScExtDocOptions* pNewOptions )
    1942             : {
    1943          87 :     delete pExtDocOptions;
    1944          87 :     pExtDocOptions = pNewOptions;
    1945          87 : }
    1946             : 
    1947           0 : void ScDocument::DoMergeContents( SCTAB nTab, SCCOL nStartCol, SCROW nStartRow,
    1948             :                                     SCCOL nEndCol, SCROW nEndRow )
    1949             : {
    1950           0 :     OUString aEmpty;
    1951           0 :     OUStringBuffer aTotal;
    1952           0 :     OUString aCellStr;
    1953             :     SCCOL nCol;
    1954             :     SCROW nRow;
    1955           0 :     for (nRow=nStartRow; nRow<=nEndRow; nRow++)
    1956           0 :         for (nCol=nStartCol; nCol<=nEndCol; nCol++)
    1957             :         {
    1958           0 :             aCellStr = GetString(nCol, nRow, nTab);
    1959           0 :             if (!aCellStr.isEmpty())
    1960             :             {
    1961           0 :                 if (!aTotal.isEmpty())
    1962           0 :                     aTotal.append(' ');
    1963           0 :                 aTotal.append(aCellStr);
    1964             :             }
    1965           0 :             if (nCol != nStartCol || nRow != nStartRow)
    1966           0 :                 SetString(nCol,nRow,nTab,aEmpty);
    1967             :         }
    1968             : 
    1969           0 :     SetString(nStartCol,nStartRow,nTab,aTotal.makeStringAndClear());
    1970           0 : }
    1971             : 
    1972         742 : void ScDocument::DoMerge( SCTAB nTab, SCCOL nStartCol, SCROW nStartRow,
    1973             :                                     SCCOL nEndCol, SCROW nEndRow, bool bDeleteCaptions )
    1974             : {
    1975         742 :     ScMergeAttr aAttr( nEndCol-nStartCol+1, nEndRow-nStartRow+1 );
    1976         742 :     ApplyAttr( nStartCol, nStartRow, nTab, aAttr );
    1977             : 
    1978         742 :     if ( nEndCol > nStartCol )
    1979         727 :         ApplyFlagsTab( nStartCol+1, nStartRow, nEndCol, nStartRow, nTab, SC_MF_HOR );
    1980         742 :     if ( nEndRow > nStartRow )
    1981          31 :         ApplyFlagsTab( nStartCol, nStartRow+1, nStartCol, nEndRow, nTab, SC_MF_VER );
    1982         742 :     if ( nEndCol > nStartCol && nEndRow > nStartRow )
    1983          16 :         ApplyFlagsTab( nStartCol+1, nStartRow+1, nEndCol, nEndRow, nTab, SC_MF_HOR | SC_MF_VER );
    1984             : 
    1985             :     // Remove all covered notes (removed captions are collected by drawing undo if active)
    1986         742 :     InsertDeleteFlags nDelFlag = IDF_NOTE | (bDeleteCaptions ? IDF_NONE : IDF_NOCAPTIONS);
    1987         742 :     if( nStartCol < nEndCol )
    1988         727 :         DeleteAreaTab( nStartCol + 1, nStartRow, nEndCol, nStartRow, nTab, nDelFlag );
    1989         742 :     if( nStartRow < nEndRow )
    1990          31 :         DeleteAreaTab( nStartCol, nStartRow + 1, nEndCol, nEndRow, nTab, nDelFlag );
    1991         742 : }
    1992             : 
    1993           0 : void ScDocument::RemoveMerge( SCCOL nCol, SCROW nRow, SCTAB nTab )
    1994             : {
    1995             :     const ScMergeAttr* pAttr = static_cast<const ScMergeAttr*>(
    1996           0 :                                     GetAttr( nCol, nRow, nTab, ATTR_MERGE ));
    1997             : 
    1998           0 :     if ( pAttr->GetColMerge() <= 1 && pAttr->GetRowMerge() <= 1 )
    1999           0 :         return;
    2000             : 
    2001           0 :     SCCOL nEndCol = nCol + pAttr->GetColMerge() - 1;
    2002           0 :     SCROW nEndRow = nRow + pAttr->GetRowMerge() - 1;
    2003             : 
    2004           0 :     RemoveFlagsTab( nCol, nRow, nEndCol, nEndRow, nTab, SC_MF_HOR | SC_MF_VER );
    2005             : 
    2006             :     const ScMergeAttr* pDefAttr = static_cast<const ScMergeAttr*>(
    2007           0 :                                         &xPoolHelper->GetDocPool()->GetDefaultItem( ATTR_MERGE ));
    2008           0 :     ApplyAttr( nCol, nRow, nTab, *pDefAttr );
    2009             : }
    2010             : 
    2011          30 : void ScDocument::ExtendPrintArea( OutputDevice* pDev, SCTAB nTab,
    2012             :                     SCCOL nStartCol, SCROW nStartRow, SCCOL& rEndCol, SCROW nEndRow ) const
    2013             : {
    2014          30 :     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    2015          30 :         maTabs[nTab]->ExtendPrintArea( pDev, nStartCol, nStartRow, rEndCol, nEndRow );
    2016          30 : }
    2017             : 
    2018           0 : SCSIZE ScDocument::GetPatternCount( SCTAB nTab, SCCOL nCol ) const
    2019             : {
    2020           0 :     if( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    2021           0 :         return maTabs[nTab]->GetPatternCount( nCol );
    2022             :     else
    2023           0 :         return 0;
    2024             : }
    2025             : 
    2026           0 : SCSIZE ScDocument::GetPatternCount( SCTAB nTab, SCCOL nCol, SCROW nRow1, SCROW nRow2 ) const
    2027             : {
    2028           0 :     if( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    2029           0 :         return maTabs[nTab]->GetPatternCount( nCol, nRow1, nRow2 );
    2030             :     else
    2031           0 :         return 0;
    2032             : }
    2033             : 
    2034           0 : bool ScDocument::ReservePatternCount( SCTAB nTab, SCCOL nCol, SCSIZE nReserve )
    2035             : {
    2036           0 :     if( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
    2037           0 :         return maTabs[nTab]->ReservePatternCount( nCol, nReserve );
    2038             :     else
    2039           0 :         return false;
    2040             : }
    2041             : 
    2042           0 : void ScDocument::GetSortParam( ScSortParam& rParam, SCTAB nTab )
    2043             : {
    2044           0 :     rParam = mSheetSortParams[ nTab ];
    2045           0 : }
    2046             : 
    2047           0 : void ScDocument::SetSortParam( ScSortParam& rParam, SCTAB nTab )
    2048             : {
    2049           0 :     mSheetSortParams[ nTab ] = rParam;
    2050         156 : }
    2051             : 
    2052             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11