LCOV - code coverage report
Current view: top level - sc/source/core/data - document10.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 136 234 58.1 %
Date: 2014-11-03 Functions: 17 22 77.3 %
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             : 
      23             : #include "dociter.hxx"
      24             : #include "patattr.hxx"
      25             : #include <svl/whiter.hxx>
      26             : #include <editeng/colritem.hxx>
      27             : #include "scitems.hxx"
      28             : 
      29             : // Add totally brand-new methods to this source file.
      30             : 
      31           6 : bool ScDocument::IsMerged( const ScAddress& rPos ) const
      32             : {
      33           6 :     const ScTable* pTab = FetchTable(rPos.Tab());
      34           6 :     if (!pTab)
      35           0 :         return false;
      36             : 
      37           6 :     return pTab->IsMerged(rPos.Col(), rPos.Row());
      38             : }
      39             : 
      40           4 : void ScDocument::DeleteBeforeCopyFromClip( sc::CopyFromClipContext& rCxt, const ScMarkData& rMark )
      41             : {
      42           4 :     SCTAB nClipTab = 0;
      43           4 :     const TableContainer& rClipTabs = rCxt.getClipDoc()->maTabs;
      44           4 :     SCTAB nClipTabCount = rClipTabs.size();
      45             : 
      46           8 :     for (SCTAB nTab = rCxt.getTabStart(); nTab <= rCxt.getTabEnd(); ++nTab)
      47             :     {
      48           4 :         ScTable* pTab = FetchTable(nTab);
      49           4 :         if (!pTab)
      50           0 :             continue;
      51             : 
      52           4 :         if (!rMark.GetTableSelect(nTab))
      53           0 :             continue;
      54             : 
      55           8 :         while (!rClipTabs[nClipTab])
      56           0 :             nClipTab = (nClipTab+1) % nClipTabCount;
      57             : 
      58           4 :         pTab->DeleteBeforeCopyFromClip(rCxt, *rClipTabs[nClipTab]);
      59             : 
      60           4 :         nClipTab = (nClipTab+1) % nClipTabCount;
      61             :     }
      62           4 : }
      63             : 
      64         138 : bool ScDocument::CopyOneCellFromClip(
      65             :     sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
      66             : {
      67         138 :     ScDocument* pClipDoc = rCxt.getClipDoc();
      68         138 :     if (pClipDoc->GetClipParam().mbCutMode)
      69             :         // We don't handle cut and paste or moving of cells here.
      70          32 :         return false;
      71             : 
      72         106 :     ScRange aClipRange = pClipDoc->GetClipParam().getWholeRange();
      73         106 :     if (aClipRange.aStart != aClipRange.aEnd)
      74             :         // The source is not really a single cell. Bail out.
      75         100 :         return false;
      76             : 
      77           6 :     ScAddress aSrcPos = aClipRange.aStart;
      78           6 :     if (pClipDoc->IsMerged(aSrcPos))
      79             :         // We don't handle merged source cell for this.
      80           0 :         return false;
      81             : 
      82           6 :     ScTable* pSrcTab = pClipDoc->FetchTable(aSrcPos.Tab());
      83           6 :     if (!pSrcTab)
      84           0 :         return false;
      85             : 
      86           6 :     ScCellValue& rSrcCell = rCxt.getSingleCell();
      87           6 :     const ScPatternAttr* pAttr = pClipDoc->GetPattern(aSrcPos);
      88           6 :     rCxt.setSingleCellPattern(pAttr);
      89           6 :     if (rCxt.isAsLink())
      90             :     {
      91             :         ScSingleRefData aRef;
      92           0 :         aRef.InitAddress(aSrcPos);
      93           0 :         aRef.SetFlag3D(true);
      94             : 
      95           0 :         ScTokenArray aArr;
      96           0 :         aArr.AddSingleReference(aRef);
      97           0 :         rSrcCell.set(new ScFormulaCell(pClipDoc, aSrcPos, aArr));
      98             :     }
      99             :     else
     100             :     {
     101           6 :         rSrcCell.set(pClipDoc->GetRefCellValue(aSrcPos));
     102             : 
     103             :         // Check the paste flag to see whether we want to paste this cell.  If the
     104             :         // flag says we don't want to paste this cell, we'll return with true.
     105           6 :         InsertDeleteFlags nFlags = rCxt.getInsertFlag();
     106           6 :         bool bNumeric  = (nFlags & IDF_VALUE) != IDF_NONE;
     107           6 :         bool bDateTime = (nFlags & IDF_DATETIME) != IDF_NONE;
     108           6 :         bool bString   = (nFlags & IDF_STRING) != IDF_NONE;
     109           6 :         bool bBoolean  = (nFlags & IDF_SPECIAL_BOOLEAN) != IDF_NONE;
     110           6 :         bool bFormula  = (nFlags & IDF_FORMULA) != IDF_NONE;
     111             : 
     112           6 :         switch (rSrcCell.meType)
     113             :         {
     114             :             case CELLTYPE_VALUE:
     115             :             {
     116           0 :                 bool bPaste = rCxt.isDateCell(pSrcTab->aCol[aSrcPos.Col()], aSrcPos.Row()) ? bDateTime : bNumeric;
     117           0 :                 if (!bPaste)
     118             :                     // Don't paste this.
     119           0 :                     rSrcCell.clear();
     120             :             }
     121           0 :             break;
     122             :             case CELLTYPE_STRING:
     123             :             case CELLTYPE_EDIT:
     124             :             {
     125           2 :                 if (!bString)
     126             :                     // Skip pasting.
     127           0 :                     rSrcCell.clear();
     128             :             }
     129           2 :             break;
     130             :             case CELLTYPE_FORMULA:
     131             :             {
     132           2 :                 if (bBoolean)
     133             :                 {
     134             :                     // Check if this formula cell is a boolean cell, and if so, go ahead and paste it.
     135           0 :                     ScTokenArray* pCode = rSrcCell.mpFormula->GetCode();
     136           0 :                     if (pCode && pCode->GetLen() == 1)
     137             :                     {
     138           0 :                         const formula::FormulaToken* p = pCode->First();
     139           0 :                         if (p->GetOpCode() == ocTrue || p->GetOpCode() == ocFalse)
     140             :                             // This is a boolean formula. Good.
     141           0 :                             break;
     142             :                     }
     143             :                 }
     144             : 
     145           2 :                 if (bFormula)
     146             :                     // Good.
     147           2 :                     break;
     148             : 
     149           0 :                 sal_uInt16 nErr = rSrcCell.mpFormula->GetErrCode();
     150           0 :                 if (nErr)
     151             :                 {
     152             :                     // error codes are cloned with values
     153           0 :                     if (!bNumeric)
     154             :                         // Error code is treated as numeric value. Don't paste it.
     155           0 :                         rSrcCell.clear();
     156             :                 }
     157           0 :                 else if (rSrcCell.mpFormula->IsValue())
     158             :                 {
     159           0 :                     bool bPaste = rCxt.isDateCell(pSrcTab->aCol[aSrcPos.Col()], aSrcPos.Row()) ? bDateTime : bNumeric;
     160           0 :                     if (!bPaste)
     161             :                     {
     162             :                         // Don't paste this.
     163           0 :                         rSrcCell.clear();
     164           0 :                         break;
     165             :                     }
     166             : 
     167             :                     // Turn this into a numeric cell.
     168           0 :                     rSrcCell.set(rSrcCell.mpFormula->GetValue());
     169             :                 }
     170           0 :                 else if (bString)
     171             :                 {
     172           0 :                     svl::SharedString aStr = rSrcCell.mpFormula->GetString();
     173           0 :                     if (aStr.isEmpty())
     174             :                     {
     175             :                         // do not clone empty string
     176           0 :                         rSrcCell.clear();
     177           0 :                         break;
     178             :                     }
     179             : 
     180             :                     // Turn this into a string or edit cell.
     181           0 :                     if (rSrcCell.mpFormula->IsMultilineResult())
     182             :                     {
     183             :                         // TODO : Add shared string support to the edit engine to
     184             :                         // make this process simpler.
     185           0 :                         ScFieldEditEngine& rEngine = GetEditEngine();
     186           0 :                         rEngine.SetText(rSrcCell.mpFormula->GetString().getString());
     187           0 :                         boost::scoped_ptr<EditTextObject> pObj(rEngine.CreateTextObject());
     188           0 :                         pObj->NormalizeString(GetSharedStringPool());
     189           0 :                         rSrcCell.set(*pObj);
     190             :                     }
     191             :                     else
     192           0 :                         rSrcCell.set(rSrcCell.mpFormula->GetString());
     193             :                 }
     194             :                 else
     195             :                     // We don't want to paste this.
     196           0 :                     rSrcCell.clear();
     197             :             }
     198           0 :             break;
     199             :             case CELLTYPE_NONE:
     200             :             default:
     201             :                 // There is nothing to paste.
     202           2 :                 rSrcCell.clear();
     203             :         }
     204             :     }
     205             : 
     206           6 :     if ((rCxt.getInsertFlag() & (IDF_NOTE | IDF_ADDNOTES)) != IDF_NONE)
     207           6 :         rCxt.setSingleCellNote(pClipDoc->GetNote(aSrcPos));
     208             : 
     209             :     // All good. Proceed with the pasting.
     210             : 
     211           6 :     SCTAB nTabEnd = rCxt.getTabEnd();
     212          12 :     for (SCTAB i = rCxt.getTabStart(); i <= nTabEnd && i < static_cast<SCTAB>(maTabs.size()); ++i)
     213             :     {
     214           6 :         maTabs[i]->CopyOneCellFromClip(rCxt, nCol1, nRow1, nCol2, nRow2);
     215           6 :         if (rCxt.getInsertFlag() & IDF_ATTRIB)
     216          12 :             maTabs[i]->CopyConditionalFormat(nCol1, nRow1, nCol2, nRow2, nCol1 - aClipRange.aStart.Col(),
     217          18 :                     nRow1 - aClipRange.aStart.Row(), pSrcTab);
     218             :     }
     219             : 
     220           6 :     return true;
     221             : }
     222             : 
     223           0 : void ScDocument::SetValues( const ScAddress& rPos, const std::vector<double>& rVals )
     224             : {
     225           0 :     ScTable* pTab = FetchTable(rPos.Tab());
     226           0 :     if (!pTab)
     227           0 :         return;
     228             : 
     229           0 :     pTab->SetValues(rPos.Col(), rPos.Row(), rVals);
     230             : }
     231             : 
     232           0 : void ScDocument::TransferCellValuesTo( const ScAddress& rTopPos, size_t nLen, sc::CellValues& rDest )
     233             : {
     234           0 :     ScTable* pTab = FetchTable(rTopPos.Tab());
     235           0 :     if (!pTab)
     236           0 :         return;
     237             : 
     238           0 :     pTab->TransferCellValuesTo(rTopPos.Col(), rTopPos.Row(), nLen, rDest);
     239             : }
     240             : 
     241           0 : void ScDocument::CopyCellValuesFrom( const ScAddress& rTopPos, const sc::CellValues& rSrc )
     242             : {
     243           0 :     ScTable* pTab = FetchTable(rTopPos.Tab());
     244           0 :     if (!pTab)
     245           0 :         return;
     246             : 
     247           0 :     pTab->CopyCellValuesFrom(rTopPos.Col(), rTopPos.Row(), rSrc);
     248             : }
     249             : 
     250           0 : std::vector<Color> ScDocument::GetDocColors()
     251             : {
     252           0 :     std::vector<Color> docColors;
     253             : 
     254           0 :     for( unsigned int nTabIx = 0; nTabIx < maTabs.size(); ++nTabIx )
     255             :     {
     256           0 :         ScUsedAreaIterator aIt(this, nTabIx, 0, 0, MAXCOLCOUNT-1, MAXROWCOUNT-1);
     257             : 
     258           0 :         for( bool bIt = aIt.GetNext(); bIt; bIt = aIt.GetNext() )
     259             :         {
     260           0 :             const ScPatternAttr* pPattern = aIt.GetPattern();
     261             : 
     262           0 :             if( pPattern == 0 )
     263           0 :                 continue;
     264             : 
     265           0 :             const SfxItemSet& rItemSet = pPattern->GetItemSet();
     266             : 
     267           0 :             SfxWhichIter aIter( rItemSet );
     268           0 :             sal_uInt16 nWhich = aIter.FirstWhich();
     269           0 :             while( nWhich )
     270             :             {
     271             :                 const SfxPoolItem *pItem;
     272           0 :                 if( SfxItemState::SET == rItemSet.GetItemState( nWhich, false, &pItem ) )
     273             :                 {
     274           0 :                     sal_uInt16 aWhich = pItem->Which();
     275           0 :                     switch (aWhich)
     276             :                     {
     277             :                         // attributes we want to collect
     278             :                         case ATTR_FONT_COLOR:
     279             :                         case ATTR_BACKGROUND:
     280             :                             {
     281           0 :                                 Color aColor( static_cast<const SvxColorItem*>(pItem)->GetValue() );
     282           0 :                                 if( COL_AUTO != aColor.GetColor() &&
     283           0 :                                         std::find(docColors.begin(), docColors.end(), aColor) == docColors.end() )
     284             :                                 {
     285           0 :                                     docColors.push_back( aColor );
     286             :                                 }
     287             :                             }
     288           0 :                             break;
     289             :                         default:
     290           0 :                             break;
     291             :                     }
     292             :                 }
     293             : 
     294           0 :                 nWhich = aIter.NextWhich();
     295             :             }
     296           0 :         }
     297           0 :     }
     298           0 :     return docColors;
     299             : }
     300             : 
     301         980 : void ScDocument::SetCalcConfig( const ScCalcConfig& rConfig )
     302             : {
     303         980 :     maCalcConfig = rConfig;
     304         980 : }
     305             : 
     306           4 : void ScDocument::ConvertFormulaToValue( const ScRange& rRange, sc::TableValues* pUndo )
     307             : {
     308           4 :     sc::EndListeningContext aCxt(*this);
     309             : 
     310           8 :     for (SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab)
     311             :     {
     312           4 :         ScTable* pTab = FetchTable(nTab);
     313           4 :         if (!pTab)
     314           0 :             continue;
     315             : 
     316             :         pTab->ConvertFormulaToValue(
     317           8 :             aCxt, rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row(),
     318          12 :             pUndo);
     319             :     }
     320             : 
     321           4 :     aCxt.purgeEmptyBroadcasters();
     322           4 : }
     323             : 
     324           8 : void ScDocument::SwapNonEmpty( sc::TableValues& rValues )
     325             : {
     326           8 :     const ScRange& rRange = rValues.getRange();
     327           8 :     if (!rRange.IsValid())
     328           8 :         return;
     329             : 
     330           8 :     boost::shared_ptr<sc::ColumnBlockPositionSet> pPosSet(new sc::ColumnBlockPositionSet(*this));
     331          16 :     sc::StartListeningContext aStartCxt(*this, pPosSet);
     332          16 :     sc::EndListeningContext aEndCxt(*this, pPosSet);
     333             : 
     334          16 :     for (SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab)
     335             :     {
     336           8 :         ScTable* pTab = FetchTable(nTab);
     337           8 :         if (!pTab)
     338           0 :             continue;
     339             : 
     340           8 :         pTab->SwapNonEmpty(rValues, aStartCxt, aEndCxt);
     341             :     }
     342             : 
     343          16 :     aEndCxt.purgeEmptyBroadcasters();
     344             : }
     345             : 
     346          64 : void ScDocument::PreprocessRangeNameUpdate()
     347             : {
     348          64 :     sc::EndListeningContext aEndListenCxt(*this);
     349         128 :     sc::CompileFormulaContext aCompileCxt(this);
     350             : 
     351          64 :     TableContainer::iterator it = maTabs.begin(), itEnd = maTabs.end();
     352         204 :     for (; it != itEnd; ++it)
     353             :     {
     354         140 :         ScTable* p = *it;
     355         140 :         p->PreprocessRangeNameUpdate(aEndListenCxt, aCompileCxt);
     356          64 :     }
     357          64 : }
     358             : 
     359          18 : void ScDocument::PreprocessDBDataUpdate()
     360             : {
     361          18 :     sc::EndListeningContext aEndListenCxt(*this);
     362          36 :     sc::CompileFormulaContext aCompileCxt(this);
     363             : 
     364          18 :     TableContainer::iterator it = maTabs.begin(), itEnd = maTabs.end();
     365          40 :     for (; it != itEnd; ++it)
     366             :     {
     367          22 :         ScTable* p = *it;
     368          22 :         p->PreprocessDBDataUpdate(aEndListenCxt, aCompileCxt);
     369          18 :     }
     370          18 : }
     371             : 
     372          82 : void ScDocument::CompileHybridFormula()
     373             : {
     374          82 :     sc::StartListeningContext aStartListenCxt(*this);
     375         164 :     sc::CompileFormulaContext aCompileCxt(this);
     376          82 :     TableContainer::iterator it = maTabs.begin(), itEnd = maTabs.end();
     377         244 :     for (; it != itEnd; ++it)
     378             :     {
     379         162 :         ScTable* p = *it;
     380         162 :         p->CompileHybridFormula(aStartListenCxt, aCompileCxt);
     381          82 :     }
     382          82 : }
     383             : 
     384        1994 : void ScDocument::SharePooledResources( ScDocument* pSrcDoc )
     385             : {
     386        1994 :     xPoolHelper = pSrcDoc->xPoolHelper;
     387        1994 :     mpCellStringPool = pSrcDoc->mpCellStringPool;
     388        1994 : }
     389             : 
     390        1154 : void ScDocument::UpdateScriptTypes( const ScAddress& rPos, SCCOL nColSize, SCROW nRowSize )
     391             : {
     392        1154 :     ScTable* pTab = FetchTable(rPos.Tab());
     393        1154 :     if (!pTab)
     394        1154 :         return;
     395             : 
     396        1154 :     pTab->UpdateScriptTypes(rPos.Col(), rPos.Row(), rPos.Col()+nColSize-1, rPos.Row()+nRowSize-1);
     397             : }
     398             : 
     399          46 : bool ScDocument::HasUniformRowHeight( SCTAB nTab, SCROW nRow1, SCROW nRow2 ) const
     400             : {
     401          46 :     const ScTable* pTab = FetchTable(nTab);
     402          46 :     if (!pTab)
     403           0 :         return false;
     404             : 
     405          46 :     return pTab->HasUniformRowHeight(nRow1, nRow2);
     406             : }
     407             : 
     408          10 : void ScDocument::UnshareFormulaCells( SCTAB nTab, SCCOL nCol, std::vector<SCROW>& rRows )
     409             : {
     410          10 :     ScTable* pTab = FetchTable(nTab);
     411          10 :     if (!pTab)
     412          10 :         return;
     413             : 
     414          10 :     pTab->UnshareFormulaCells(nCol, rRows);
     415             : }
     416             : 
     417          10 : void ScDocument::RegroupFormulaCells( SCTAB nTab, SCCOL nCol )
     418             : {
     419          10 :     ScTable* pTab = FetchTable(nTab);
     420          10 :     if (!pTab)
     421          10 :         return;
     422             : 
     423          10 :     pTab->RegroupFormulaCells(nCol);
     424             : }
     425             : 
     426          12 : void ScDocument::CollectAllAreaListeners(
     427             :     std::vector<SvtListener*>& rListener, const ScRange& rRange, sc::AreaOverlapType eType )
     428             : {
     429          12 :     if (!pBASM)
     430          12 :         return;
     431             : 
     432          12 :     std::vector<sc::AreaListener> aAL = pBASM->GetAllListeners(rRange, eType);
     433          12 :     std::vector<sc::AreaListener>::iterator it = aAL.begin(), itEnd = aAL.end();
     434          14 :     for (; it != itEnd; ++it)
     435          14 :         rListener.push_back(it->mpListener);
     436             : }
     437             : 
     438           0 : bool ScDocument::HasFormulaCell( const ScRange& rRange ) const
     439             : {
     440           0 :     if (!rRange.IsValid())
     441           0 :         return false;
     442             : 
     443           0 :     for (SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab)
     444             :     {
     445           0 :         const ScTable* pTab = FetchTable(nTab);
     446           0 :         if (!pTab)
     447           0 :             continue;
     448             : 
     449           0 :         if (pTab->HasFormulaCell(rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row()))
     450           0 :             return true;
     451             :     }
     452             : 
     453           0 :     return false;
     454         228 : }
     455             : 
     456             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10