LCOV - code coverage report
Current view: top level - sc/source/core/data - document10.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 181 241 75.1 %
Date: 2015-06-13 12:38:46 Functions: 27 33 81.8 %
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             : 
      10             : #include <document.hxx>
      11             : #include <clipcontext.hxx>
      12             : #include <formulacell.hxx>
      13             : #include <clipparam.hxx>
      14             : #include <table.hxx>
      15             : #include <tokenarray.hxx>
      16             : #include <editutil.hxx>
      17             : #include <listenercontext.hxx>
      18             : #include <tokenstringcontext.hxx>
      19             : #include <poolhelp.hxx>
      20             : #include <bcaslot.hxx>
      21             : #include <cellvalues.hxx>
      22             : #include <docpool.hxx>
      23             : 
      24             : #include "dociter.hxx"
      25             : #include "patattr.hxx"
      26             : #include <svl/whiter.hxx>
      27             : #include <editeng/colritem.hxx>
      28             : #include "scitems.hxx"
      29             : 
      30             : // Add totally brand-new methods to this source file.
      31             : 
      32          17 : bool ScDocument::IsMerged( const ScAddress& rPos ) const
      33             : {
      34          17 :     const ScTable* pTab = FetchTable(rPos.Tab());
      35          17 :     if (!pTab)
      36           0 :         return false;
      37             : 
      38          17 :     return pTab->IsMerged(rPos.Col(), rPos.Row());
      39             : }
      40             : 
      41           2 : void ScDocument::DeleteBeforeCopyFromClip(
      42             :     sc::CopyFromClipContext& rCxt, const ScMarkData& rMark, sc::ColumnSpanSet& rBroadcastSpans )
      43             : {
      44           2 :     SCTAB nClipTab = 0;
      45           2 :     const TableContainer& rClipTabs = rCxt.getClipDoc()->maTabs;
      46           2 :     SCTAB nClipTabCount = rClipTabs.size();
      47             : 
      48           4 :     for (SCTAB nTab = rCxt.getTabStart(); nTab <= rCxt.getTabEnd(); ++nTab)
      49             :     {
      50           2 :         ScTable* pTab = FetchTable(nTab);
      51           2 :         if (!pTab)
      52           0 :             continue;
      53             : 
      54           2 :         if (!rMark.GetTableSelect(nTab))
      55           0 :             continue;
      56             : 
      57           4 :         while (!rClipTabs[nClipTab])
      58           0 :             nClipTab = (nClipTab+1) % nClipTabCount;
      59             : 
      60           2 :         pTab->DeleteBeforeCopyFromClip(rCxt, *rClipTabs[nClipTab], rBroadcastSpans);
      61             : 
      62           2 :         nClipTab = (nClipTab+1) % nClipTabCount;
      63             :     }
      64           2 : }
      65             : 
      66          77 : bool ScDocument::CopyOneCellFromClip(
      67             :     sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
      68             : {
      69          77 :     ScDocument* pClipDoc = rCxt.getClipDoc();
      70          77 :     if (pClipDoc->GetClipParam().mbCutMode)
      71             :         // We don't handle cut and paste or moving of cells here.
      72          16 :         return false;
      73             : 
      74          61 :     ScRange aClipRange = pClipDoc->GetClipParam().getWholeRange();
      75          61 :     if (aClipRange.aStart.Row() != aClipRange.aEnd.Row())
      76             :         // The source is not really a single row. Bail out.
      77          49 :         return false;
      78             : 
      79          12 :     SCCOL nSrcColSize = aClipRange.aEnd.Col() - aClipRange.aStart.Col() + 1;
      80          12 :     SCCOL nDestColSize = nCol2 - nCol1 + 1;
      81          12 :     if (nDestColSize < nSrcColSize)
      82           0 :         return false;
      83             : 
      84          12 :     ScAddress aSrcPos = aClipRange.aStart;
      85             : 
      86          29 :     for (SCCOL nCol = aClipRange.aStart.Col(); nCol <= aClipRange.aEnd.Col(); ++nCol)
      87             :     {
      88          17 :         ScAddress aTestPos = aSrcPos;
      89          17 :         aTestPos.SetCol(nCol);
      90          17 :         if (pClipDoc->IsMerged(aTestPos))
      91             :             // We don't handle merged source cell for this.
      92           0 :             return false;
      93             :     }
      94             : 
      95          12 :     ScTable* pSrcTab = pClipDoc->FetchTable(aSrcPos.Tab());
      96          12 :     if (!pSrcTab)
      97           0 :         return false;
      98             : 
      99          12 :     rCxt.setSingleCellColumnSize(nSrcColSize);
     100             : 
     101          29 :     for (SCCOL nColOffset = 0; nColOffset < nSrcColSize; ++nColOffset, aSrcPos.IncCol())
     102             :     {
     103          17 :         const ScPatternAttr* pAttr = pClipDoc->GetPattern(aSrcPos);
     104          17 :         rCxt.setSingleCellPattern(nColOffset, pAttr);
     105             : 
     106          17 :         if ((rCxt.getInsertFlag() & (IDF_NOTE | IDF_ADDNOTES)) != IDF_NONE)
     107          17 :             rCxt.setSingleCellNote(nColOffset, pClipDoc->GetNote(aSrcPos));
     108             : 
     109          17 :         ScColumn& rSrcCol = pSrcTab->aCol[aSrcPos.Col()];
     110             :         // Determine the script type of the copied single cell.
     111          17 :         rSrcCol.UpdateScriptTypes(aSrcPos.Row(), aSrcPos.Row());
     112          17 :         rCxt.setSingleCell(aSrcPos, rSrcCol);
     113             :     }
     114             : 
     115             :     // All good. Proceed with the pasting.
     116             : 
     117          12 :     SCTAB nTabEnd = rCxt.getTabEnd();
     118          24 :     for (SCTAB i = rCxt.getTabStart(); i <= nTabEnd && i < static_cast<SCTAB>(maTabs.size()); ++i)
     119             :     {
     120          12 :         maTabs[i]->CopyOneCellFromClip(rCxt, nCol1, nRow1, nCol2, nRow2);
     121          12 :         if (rCxt.getInsertFlag() & IDF_ATTRIB)
     122          28 :             for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
     123             :             {
     124          34 :                 maTabs[i]->CopyConditionalFormat(nCol1, nRow, nCol2, nRow, nCol1 - aClipRange.aStart.Col(),
     125          51 :                         nRow - aClipRange.aStart.Row(), pSrcTab);
     126             :             }
     127             :     }
     128             : 
     129          12 :     return true;
     130             : }
     131             : 
     132           0 : void ScDocument::SetValues( const ScAddress& rPos, const std::vector<double>& rVals )
     133             : {
     134           0 :     ScTable* pTab = FetchTable(rPos.Tab());
     135           0 :     if (!pTab)
     136           0 :         return;
     137             : 
     138           0 :     pTab->SetValues(rPos.Col(), rPos.Row(), rVals);
     139             : }
     140             : 
     141           0 : void ScDocument::TransferCellValuesTo( const ScAddress& rTopPos, size_t nLen, sc::CellValues& rDest )
     142             : {
     143           0 :     ScTable* pTab = FetchTable(rTopPos.Tab());
     144           0 :     if (!pTab)
     145           0 :         return;
     146             : 
     147           0 :     pTab->TransferCellValuesTo(rTopPos.Col(), rTopPos.Row(), nLen, rDest);
     148             : }
     149             : 
     150           0 : void ScDocument::CopyCellValuesFrom( const ScAddress& rTopPos, const sc::CellValues& rSrc )
     151             : {
     152           0 :     ScTable* pTab = FetchTable(rTopPos.Tab());
     153           0 :     if (!pTab)
     154           0 :         return;
     155             : 
     156           0 :     pTab->CopyCellValuesFrom(rTopPos.Col(), rTopPos.Row(), rSrc);
     157             : }
     158             : 
     159           0 : std::set<Color> ScDocument::GetDocColors()
     160             : {
     161           0 :     std::set<Color> aDocColors;
     162           0 :     ScDocumentPool *pPool = GetPool();
     163           0 :     const sal_uInt16 pAttribs[] = {ATTR_BACKGROUND, ATTR_FONT_COLOR};
     164           0 :     for (size_t i=0; i<SAL_N_ELEMENTS( pAttribs ); i++)
     165             :     {
     166           0 :         const sal_uInt16 nAttrib = pAttribs[i];
     167           0 :         const sal_uInt32 nCount = pPool->GetItemCount2(nAttrib);
     168           0 :         for (sal_uInt32 j=0; j<nCount; j++)
     169             :         {
     170           0 :             const SvxColorItem *pItem = static_cast<const SvxColorItem*>(pPool->GetItem2(nAttrib, j));
     171           0 :             if (pItem == 0)
     172           0 :                 continue;
     173           0 :             Color aColor( pItem->GetValue() );
     174           0 :             if (COL_AUTO != aColor.GetColor())
     175           0 :                 aDocColors.insert(aColor);
     176             :         }
     177             :     }
     178           0 :     return aDocColors;
     179             : }
     180             : 
     181         768 : void ScDocument::SetCalcConfig( const ScCalcConfig& rConfig )
     182             : {
     183         768 :     maCalcConfig = rConfig;
     184         768 : }
     185             : 
     186           2 : void ScDocument::ConvertFormulaToValue( const ScRange& rRange, sc::TableValues* pUndo )
     187             : {
     188           2 :     sc::EndListeningContext aCxt(*this);
     189             : 
     190           4 :     for (SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab)
     191             :     {
     192           2 :         ScTable* pTab = FetchTable(nTab);
     193           2 :         if (!pTab)
     194           0 :             continue;
     195             : 
     196             :         pTab->ConvertFormulaToValue(
     197           4 :             aCxt, rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row(),
     198           6 :             pUndo);
     199             :     }
     200             : 
     201           2 :     aCxt.purgeEmptyBroadcasters();
     202           2 : }
     203             : 
     204           4 : void ScDocument::SwapNonEmpty( sc::TableValues& rValues )
     205             : {
     206           4 :     const ScRange& rRange = rValues.getRange();
     207           4 :     if (!rRange.IsValid())
     208           4 :         return;
     209             : 
     210           4 :     boost::shared_ptr<sc::ColumnBlockPositionSet> pPosSet(new sc::ColumnBlockPositionSet(*this));
     211           8 :     sc::StartListeningContext aStartCxt(*this, pPosSet);
     212           8 :     sc::EndListeningContext aEndCxt(*this, pPosSet);
     213             : 
     214           8 :     for (SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab)
     215             :     {
     216           4 :         ScTable* pTab = FetchTable(nTab);
     217           4 :         if (!pTab)
     218           0 :             continue;
     219             : 
     220           4 :         pTab->SwapNonEmpty(rValues, aStartCxt, aEndCxt);
     221             :     }
     222             : 
     223           8 :     aEndCxt.purgeEmptyBroadcasters();
     224             : }
     225             : 
     226          32 : void ScDocument::PreprocessRangeNameUpdate()
     227             : {
     228          32 :     sc::EndListeningContext aEndListenCxt(*this);
     229          64 :     sc::CompileFormulaContext aCompileCxt(this);
     230             : 
     231          32 :     TableContainer::iterator it = maTabs.begin(), itEnd = maTabs.end();
     232         102 :     for (; it != itEnd; ++it)
     233             :     {
     234          70 :         ScTable* p = *it;
     235          70 :         p->PreprocessRangeNameUpdate(aEndListenCxt, aCompileCxt);
     236          32 :     }
     237          32 : }
     238             : 
     239           9 : void ScDocument::PreprocessDBDataUpdate()
     240             : {
     241           9 :     sc::EndListeningContext aEndListenCxt(*this);
     242          18 :     sc::CompileFormulaContext aCompileCxt(this);
     243             : 
     244           9 :     TableContainer::iterator it = maTabs.begin(), itEnd = maTabs.end();
     245          20 :     for (; it != itEnd; ++it)
     246             :     {
     247          11 :         ScTable* p = *it;
     248          11 :         p->PreprocessDBDataUpdate(aEndListenCxt, aCompileCxt);
     249           9 :     }
     250           9 : }
     251             : 
     252          41 : void ScDocument::CompileHybridFormula()
     253             : {
     254          41 :     sc::StartListeningContext aStartListenCxt(*this);
     255          82 :     sc::CompileFormulaContext aCompileCxt(this);
     256          41 :     TableContainer::iterator it = maTabs.begin(), itEnd = maTabs.end();
     257         122 :     for (; it != itEnd; ++it)
     258             :     {
     259          81 :         ScTable* p = *it;
     260          81 :         p->CompileHybridFormula(aStartListenCxt, aCompileCxt);
     261          41 :     }
     262          41 : }
     263             : 
     264        1000 : void ScDocument::SharePooledResources( ScDocument* pSrcDoc )
     265             : {
     266        1000 :     xPoolHelper = pSrcDoc->xPoolHelper;
     267        1000 :     mpCellStringPool = pSrcDoc->mpCellStringPool;
     268        1000 : }
     269             : 
     270          46 : void ScDocument::UpdateScriptTypes( const ScAddress& rPos, SCCOL nColSize, SCROW nRowSize )
     271             : {
     272          46 :     ScTable* pTab = FetchTable(rPos.Tab());
     273          46 :     if (!pTab)
     274          46 :         return;
     275             : 
     276          46 :     pTab->UpdateScriptTypes(rPos.Col(), rPos.Row(), rPos.Col()+nColSize-1, rPos.Row()+nRowSize-1);
     277             : }
     278             : 
     279          29 : bool ScDocument::HasUniformRowHeight( SCTAB nTab, SCROW nRow1, SCROW nRow2 ) const
     280             : {
     281          29 :     const ScTable* pTab = FetchTable(nTab);
     282          29 :     if (!pTab)
     283           0 :         return false;
     284             : 
     285          29 :     return pTab->HasUniformRowHeight(nRow1, nRow2);
     286             : }
     287             : 
     288           5 : void ScDocument::UnshareFormulaCells( SCTAB nTab, SCCOL nCol, std::vector<SCROW>& rRows )
     289             : {
     290           5 :     ScTable* pTab = FetchTable(nTab);
     291           5 :     if (!pTab)
     292           5 :         return;
     293             : 
     294           5 :     pTab->UnshareFormulaCells(nCol, rRows);
     295             : }
     296             : 
     297           5 : void ScDocument::RegroupFormulaCells( SCTAB nTab, SCCOL nCol )
     298             : {
     299           5 :     ScTable* pTab = FetchTable(nTab);
     300           5 :     if (!pTab)
     301           5 :         return;
     302             : 
     303           5 :     pTab->RegroupFormulaCells(nCol);
     304             : }
     305             : 
     306           6 : void ScDocument::CollectAllAreaListeners(
     307             :     std::vector<SvtListener*>& rListener, const ScRange& rRange, sc::AreaOverlapType eType )
     308             : {
     309           6 :     if (!pBASM)
     310           6 :         return;
     311             : 
     312           6 :     std::vector<sc::AreaListener> aAL = pBASM->GetAllListeners(rRange, eType);
     313           6 :     std::vector<sc::AreaListener>::iterator it = aAL.begin(), itEnd = aAL.end();
     314           7 :     for (; it != itEnd; ++it)
     315           7 :         rListener.push_back(it->mpListener);
     316             : }
     317             : 
     318           0 : bool ScDocument::HasFormulaCell( const ScRange& rRange ) const
     319             : {
     320           0 :     if (!rRange.IsValid())
     321           0 :         return false;
     322             : 
     323           0 :     for (SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab)
     324             :     {
     325           0 :         const ScTable* pTab = FetchTable(nTab);
     326           0 :         if (!pTab)
     327           0 :             continue;
     328             : 
     329           0 :         if (pTab->HasFormulaCell(rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row()))
     330           0 :             return true;
     331             :     }
     332             : 
     333           0 :     return false;
     334             : }
     335             : 
     336          36 : void ScDocument::EndListeningIntersectedGroup(
     337             :     sc::EndListeningContext& rCxt, const ScAddress& rPos, std::vector<ScAddress>* pGroupPos )
     338             : {
     339          36 :     ScTable* pTab = FetchTable(rPos.Tab());
     340          36 :     if (!pTab)
     341          36 :         return;
     342             : 
     343          36 :     pTab->EndListeningIntersectedGroup(rCxt, rPos.Col(), rPos.Row(), pGroupPos);
     344             : }
     345             : 
     346         324 : void ScDocument::EndListeningIntersectedGroups(
     347             :     sc::EndListeningContext& rCxt, const ScRange& rRange, std::vector<ScAddress>* pGroupPos )
     348             : {
     349         648 :     for (SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab)
     350             :     {
     351         324 :         ScTable* pTab = FetchTable(nTab);
     352         324 :         if (!pTab)
     353           0 :             continue;
     354             : 
     355             :         pTab->EndListeningIntersectedGroups(
     356         648 :             rCxt, rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row(),
     357         972 :             pGroupPos);
     358             :     }
     359         324 : }
     360             : 
     361          50 : void ScDocument::EndListeningGroups( const std::vector<ScAddress>& rPosArray )
     362             : {
     363          50 :     sc::EndListeningContext aCxt(*this);
     364          50 :     std::vector<ScAddress>::const_iterator it = rPosArray.begin(), itEnd = rPosArray.end();
     365          56 :     for (; it != itEnd; ++it)
     366             :     {
     367           6 :         const ScAddress& rPos = *it;
     368           6 :         ScTable* pTab = FetchTable(rPos.Tab());
     369           6 :         if (!pTab)
     370          50 :             return;
     371             : 
     372           6 :         pTab->EndListeningGroup(aCxt, rPos.Col(), rPos.Row());
     373             :     }
     374             : 
     375          50 :     aCxt.purgeEmptyBroadcasters();
     376             : }
     377             : 
     378         340 : void ScDocument::SetNeedsListeningGroups( const std::vector<ScAddress>& rPosArray )
     379             : {
     380         340 :     std::vector<ScAddress>::const_iterator it = rPosArray.begin(), itEnd = rPosArray.end();
     381         412 :     for (; it != itEnd; ++it)
     382             :     {
     383          72 :         const ScAddress& rPos = *it;
     384          72 :         ScTable* pTab = FetchTable(rPos.Tab());
     385          72 :         if (!pTab)
     386           0 :             return;
     387             : 
     388          72 :         pTab->SetNeedsListeningGroup(rPos.Col(), rPos.Row());
     389             :     }
     390             : }
     391             : 
     392             : namespace {
     393             : 
     394        1212 : class StartNeededListenersHandler : std::unary_function<ScTable*, void>
     395             : {
     396             :     boost::shared_ptr<sc::StartListeningContext> mpCxt;
     397             : public:
     398         404 :     StartNeededListenersHandler( ScDocument& rDoc ) : mpCxt(new sc::StartListeningContext(rDoc)) {}
     399             : 
     400         491 :     void operator() (ScTable* p)
     401             :     {
     402         491 :         if (p)
     403         491 :             p->StartListeners(*mpCxt, false);
     404         491 :     }
     405             : };
     406             : 
     407             : }
     408             : 
     409         404 : void ScDocument::StartNeededListeners()
     410             : {
     411         404 :     std::for_each(maTabs.begin(), maTabs.end(), StartNeededListenersHandler(*this));
     412         404 : }
     413             : 
     414         762 : void ScDocument::StartAllListeners( const ScRange& rRange )
     415             : {
     416         762 :     boost::shared_ptr<sc::ColumnBlockPositionSet> pPosSet(new sc::ColumnBlockPositionSet(*this));
     417        1524 :     sc::StartListeningContext aStartCxt(*this, pPosSet);
     418        1524 :     sc::EndListeningContext aEndCxt(*this, pPosSet);
     419             : 
     420        1688 :     for (SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab)
     421             :     {
     422         926 :         ScTable* pTab = FetchTable(nTab);
     423         926 :         if (!pTab)
     424         160 :             continue;
     425             : 
     426             :         pTab->StartListeningFormulaCells(
     427             :             aStartCxt, aEndCxt,
     428         766 :             rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row());
     429         762 :     }
     430         762 : }
     431             : 
     432           0 : void ScDocument::EndAllListeners( const ScRange& rRange )
     433             : {
     434           0 :     sc::EndListeningContext aEndCxt(*this);
     435             : 
     436           0 :     for (SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab)
     437             :     {
     438           0 :         ScTable* pTab = FetchTable(nTab);
     439           0 :         if (!pTab)
     440           0 :             continue;
     441             : 
     442             :         pTab->EndListeningFormulaCells(
     443             :             aEndCxt,
     444           0 :             rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row());
     445           0 :     }
     446         156 : }
     447             : 
     448             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11