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

Generated by: LCOV version 1.10