LCOV - code coverage report
Current view: top level - sc/source/core/data - columnspanset.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 131 145 90.3 %
Date: 2014-04-11 Functions: 24 28 85.7 %
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 "columnspanset.hxx"
      11             : #include "stlalgorithm.hxx"
      12             : #include "column.hxx"
      13             : #include "table.hxx"
      14             : #include "document.hxx"
      15             : #include "mtvfunctions.hxx"
      16             : #include "markdata.hxx"
      17             : #include "rangelst.hxx"
      18             : #include <fstalgorithm.hxx>
      19             : 
      20             : #include <algorithm>
      21             : 
      22             : namespace sc {
      23             : 
      24        6301 : RowSpan::RowSpan(SCROW nRow1, SCROW nRow2) : mnRow1(nRow1), mnRow2(nRow2) {}
      25             : 
      26        4592 : ColRowSpan::ColRowSpan(SCCOLROW nStart, SCCOLROW nEnd) : mnStart(nStart), mnEnd(nEnd) {}
      27             : 
      28        1190 : ColumnSpanSet::ColumnType::ColumnType(SCROW nStart, SCROW nEnd, bool bInit) :
      29        1190 :     maSpans(nStart, nEnd+1, bInit), miPos(maSpans.begin()) {}
      30             : 
      31         111 : ColumnSpanSet::Action::~Action() {}
      32           0 : void ColumnSpanSet::Action::startColumn(SCTAB /*nTab*/, SCCOL /*nCol*/) {}
      33             : 
      34         830 : ColumnSpanSet::ColumnAction::~ColumnAction() {}
      35             : 
      36         992 : ColumnSpanSet::ColumnSpanSet(bool bInit) : mbInit(bInit) {}
      37             : 
      38        1984 : ColumnSpanSet::~ColumnSpanSet()
      39             : {
      40         992 :     DocType::iterator itTab = maDoc.begin(), itTabEnd = maDoc.end();
      41        4620 :     for (; itTab != itTabEnd; ++itTab)
      42             :     {
      43        3628 :         TableType* pTab = *itTab;
      44        3628 :         if (!pTab)
      45        2723 :             continue;
      46             : 
      47         905 :         std::for_each(pTab->begin(), pTab->end(), ScDeleteObjectByPtr<ColumnType>());
      48         905 :         delete pTab;
      49             :     }
      50         992 : }
      51             : 
      52        1311 : ColumnSpanSet::ColumnType& ColumnSpanSet::getColumn(SCTAB nTab, SCCOL nCol)
      53             : {
      54        1311 :     if (static_cast<size_t>(nTab) >= maDoc.size())
      55         905 :         maDoc.resize(nTab+1, NULL);
      56             : 
      57        1311 :     if (!maDoc[nTab])
      58         905 :         maDoc[nTab] = new TableType;
      59             : 
      60        1311 :     TableType& rTab = *maDoc[nTab];
      61        1311 :     if (static_cast<size_t>(nCol) >= rTab.size())
      62        1189 :         rTab.resize(nCol+1, NULL);
      63             : 
      64        1311 :     if (!rTab[nCol])
      65        1190 :         rTab[nCol] = new ColumnType(0, MAXROW, mbInit);
      66             : 
      67        1311 :     return *rTab[nCol];
      68             : }
      69             : 
      70         199 : void ColumnSpanSet::set(SCTAB nTab, SCCOL nCol, SCROW nRow, bool bVal)
      71             : {
      72         199 :     if (!ValidTab(nTab) || !ValidCol(nCol) || !ValidRow(nRow))
      73         199 :         return;
      74             : 
      75         199 :     ColumnType& rCol = getColumn(nTab, nCol);
      76         199 :     rCol.miPos = rCol.maSpans.insert(rCol.miPos, nRow, nRow+1, bVal).first;
      77             : }
      78             : 
      79          12 : void ColumnSpanSet::set(SCTAB nTab, SCCOL nCol, SCROW nRow1, SCROW nRow2, bool bVal)
      80             : {
      81          12 :     if (!ValidTab(nTab) || !ValidCol(nCol) || !ValidRow(nRow1) || !ValidRow(nRow2))
      82          12 :         return;
      83             : 
      84          12 :     ColumnType& rCol = getColumn(nTab, nCol);
      85          12 :     rCol.miPos = rCol.maSpans.insert(rCol.miPos, nRow1, nRow2+1, bVal).first;
      86             : }
      87             : 
      88         830 : void ColumnSpanSet::set(const ScRange& rRange, bool bVal)
      89             : {
      90        1660 :     for (SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab)
      91             :     {
      92        1930 :         for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
      93             :         {
      94        1100 :             ColumnType& rCol = getColumn(nTab, nCol);
      95        1100 :             rCol.miPos = rCol.maSpans.insert(rCol.miPos, rRange.aStart.Row(), rRange.aEnd.Row()+1, bVal).first;
      96             :         }
      97             :     }
      98         830 : }
      99             : 
     100         111 : void ColumnSpanSet::executeAction(Action& ac) const
     101             : {
     102         176 :     for (size_t nTab = 0; nTab < maDoc.size(); ++nTab)
     103             :     {
     104          65 :         if (!maDoc[nTab])
     105           1 :             continue;
     106             : 
     107          64 :         const TableType& rTab = *maDoc[nTab];
     108         433 :         for (size_t nCol = 0; nCol < rTab.size(); ++nCol)
     109             :         {
     110         369 :             if (!rTab[nCol])
     111         291 :                 continue;
     112             : 
     113          78 :             ac.startColumn(nTab, nCol);
     114          78 :             ColumnType& rCol = *rTab[nCol];
     115          78 :             ColumnSpansType::const_iterator it = rCol.maSpans.begin(), itEnd = rCol.maSpans.end();
     116             :             SCROW nRow1, nRow2;
     117          78 :             nRow1 = it->first;
     118          78 :             bool bVal = it->second;
     119         299 :             for (++it; it != itEnd; ++it)
     120             :             {
     121         221 :                 nRow2 = it->first-1;
     122         221 :                 ac.execute(ScAddress(nCol, nRow1, nTab), nRow2-nRow1+1, bVal);
     123             : 
     124         221 :                 nRow1 = nRow2+1; // for the next iteration.
     125         221 :                 bVal = it->second;
     126             :             }
     127             :         }
     128             :     }
     129         111 : }
     130             : 
     131         830 : void ColumnSpanSet::executeColumnAction(ScDocument& rDoc, ColumnAction& ac) const
     132             : {
     133        4382 :     for (size_t nTab = 0; nTab < maDoc.size(); ++nTab)
     134             :     {
     135        3552 :         if (!maDoc[nTab])
     136        2722 :             continue;
     137             : 
     138         830 :         const TableType& rTab = *maDoc[nTab];
     139        9386 :         for (size_t nCol = 0; nCol < rTab.size(); ++nCol)
     140             :         {
     141        8556 :             if (!rTab[nCol])
     142       14912 :                 continue;
     143             : 
     144        1100 :             ScTable* pTab = rDoc.FetchTable(nTab);
     145        1100 :             if (!pTab)
     146           0 :                 continue;
     147             : 
     148        1100 :             if (!ValidCol(nCol))
     149             :             {
     150             :                 // End the loop.
     151           0 :                 nCol = rTab.size();
     152           0 :                 continue;
     153             :             }
     154             : 
     155        1100 :             ScColumn& rColumn = pTab->aCol[nCol];
     156        1100 :             ac.startColumn(&rColumn);
     157        1100 :             ColumnType& rCol = *rTab[nCol];
     158        1100 :             ColumnSpansType::const_iterator it = rCol.maSpans.begin(), itEnd = rCol.maSpans.end();
     159             :             SCROW nRow1, nRow2;
     160        1100 :             nRow1 = it->first;
     161        1100 :             bool bVal = it->second;
     162        4254 :             for (++it; it != itEnd; ++it)
     163             :             {
     164        3154 :                 nRow2 = it->first-1;
     165        3154 :                 ac.execute(nRow1, nRow2, bVal);
     166             : 
     167        3154 :                 nRow1 = nRow2+1; // for the next iteration.
     168        3154 :                 bVal = it->second;
     169             :             }
     170             :         }
     171             :     }
     172         830 : }
     173             : 
     174             : namespace {
     175             : 
     176             : class Scanner
     177             : {
     178             :     SingleColumnSpanSet::ColumnSpansType& mrRanges;
     179             : public:
     180     1582038 :     Scanner(SingleColumnSpanSet::ColumnSpansType& rRanges) : mrRanges(rRanges) {}
     181             : 
     182     1583498 :     void operator() (const sc::CellStoreType::value_type& node, size_t nOffset, size_t nDataSize)
     183             :     {
     184     1583498 :         if (node.type == sc::element_type_empty)
     185     3162132 :             return;
     186             : 
     187        4864 :         size_t nRow = node.position + nOffset;
     188        4864 :         size_t nEndRow = nRow + nDataSize; // Last row of current block plus 1
     189        4864 :         mrRanges.insert_back(nRow, nEndRow, true);
     190             :     }
     191             : };
     192             : 
     193             : }
     194             : 
     195     1811070 : SingleColumnSpanSet::SingleColumnSpanSet() : maSpans(0, MAXROWCOUNT, false) {}
     196             : 
     197           0 : void SingleColumnSpanSet::scan(const ScColumn& rColumn)
     198             : {
     199           0 :     const CellStoreType& rCells = rColumn.maCells;
     200           0 :     sc::CellStoreType::const_iterator it = rCells.begin(), itEnd = rCells.end();
     201           0 :     SCROW nCurRow = 0;
     202           0 :     for (;it != itEnd; ++it)
     203             :     {
     204           0 :         SCROW nEndRow = nCurRow + it->size; // Last row of current block plus 1.
     205           0 :         if (it->type != sc::element_type_empty)
     206           0 :             maSpans.insert_back(nCurRow, nEndRow, true);
     207             : 
     208           0 :         nCurRow = nEndRow;
     209             :     }
     210           0 : }
     211             : 
     212     1582000 : void SingleColumnSpanSet::scan(const ScColumn& rColumn, SCROW nStart, SCROW nEnd)
     213             : {
     214     1582000 :     const CellStoreType& rCells = rColumn.maCells;
     215     1582000 :     Scanner aScanner(maSpans);
     216     1582000 :     sc::ParseBlock(rCells.begin(), rCells, aScanner, nStart, nEnd);
     217     1582000 : }
     218             : 
     219          38 : void SingleColumnSpanSet::scan(
     220             :     ColumnBlockConstPosition& rBlockPos, const ScColumn& rColumn, SCROW nStart, SCROW nEnd)
     221             : {
     222          38 :     const CellStoreType& rCells = rColumn.maCells;
     223          38 :     Scanner aScanner(maSpans);
     224          38 :     rBlockPos.miCellPos = sc::ParseBlock(rBlockPos.miCellPos, rCells, aScanner, nStart, nEnd);
     225          38 : }
     226             : 
     227      221254 : void SingleColumnSpanSet::scan(const ScMarkData& rMark, SCTAB nTab, SCCOL nCol)
     228             : {
     229      221254 :     if (!rMark.GetTableSelect(nTab))
     230             :         // This table is not selected. Nothing to scan.
     231      221254 :         return;
     232             : 
     233      221254 :     ScRangeList aRanges = rMark.GetMarkedRanges();
     234      462988 :     for (size_t i = 0, n = aRanges.size(); i < n; ++i)
     235             :     {
     236      241734 :         const ScRange* p = aRanges[i];
     237      241734 :         if (nCol < p->aStart.Col() || p->aEnd.Col() < nCol)
     238             :             // This column is not in this range. Skip it.
     239      241410 :             continue;
     240             : 
     241         324 :         maSpans.insert_back(p->aStart.Row(), p->aEnd.Row()+1, true);
     242      221254 :     }
     243             : }
     244             : 
     245       38151 : void SingleColumnSpanSet::set(SCROW nRow1, SCROW nRow2, bool bVal)
     246             : {
     247       38151 :     maSpans.insert_back(nRow1, nRow2+1, bVal);
     248       38151 : }
     249             : 
     250        7763 : void SingleColumnSpanSet::getRows(std::vector<SCROW> &rRows) const
     251             : {
     252        7763 :     std::vector<SCROW> aRows;
     253             : 
     254       15526 :     SpansType aRanges;
     255        7763 :     getSpans(aRanges);
     256        7763 :     SpansType::const_iterator it = aRanges.begin(), itEnd = aRanges.end();
     257        8792 :     for (; it != itEnd; ++it)
     258             :     {
     259        3753 :         for (SCROW nRow = it->mnRow1; nRow <= it->mnRow2; ++nRow)
     260        2724 :             aRows.push_back(nRow);
     261             :     }
     262             : 
     263       15526 :     rRows.swap(aRows);
     264        7763 : }
     265             : 
     266     1815418 : void SingleColumnSpanSet::getSpans(SpansType& rSpans) const
     267             : {
     268     1815418 :     SpansType aSpans = toSpanArray<SCROW,RowSpan>(maSpans);
     269     1815418 :     rSpans.swap(aSpans);
     270     1815418 : }
     271             : 
     272         102 : }
     273             : 
     274             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10