LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sc/source/core/data - columnspanset.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 138 153 90.2 %
Date: 2013-07-09 Functions: 22 26 84.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  */
       9             : 
      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             : 
      19             : #include <algorithm>
      20             : 
      21             : namespace sc {
      22             : 
      23        1053 : ColumnSpanSet::ColumnType::ColumnType(SCROW nStart, SCROW nEnd, bool bInit) :
      24        1053 :     maSpans(nStart, nEnd+1, bInit), miPos(maSpans.begin()) {}
      25             : 
      26          55 : ColumnSpanSet::Action::~Action() {}
      27           0 : void ColumnSpanSet::Action::startColumn(SCTAB /*nTab*/, SCCOL /*nCol*/) {}
      28             : 
      29         731 : ColumnSpanSet::ColumnAction::~ColumnAction() {}
      30             : 
      31         786 : ColumnSpanSet::ColumnSpanSet(bool bInit) : mbInit(bInit) {}
      32             : 
      33        1572 : ColumnSpanSet::~ColumnSpanSet()
      34             : {
      35         786 :     DocType::iterator itTab = maDoc.begin(), itTabEnd = maDoc.end();
      36        4240 :     for (; itTab != itTabEnd; ++itTab)
      37             :     {
      38        3454 :         TableType* pTab = *itTab;
      39        3454 :         if (!pTab)
      40        2698 :             continue;
      41             : 
      42         756 :         std::for_each(pTab->begin(), pTab->end(), ScDeleteObjectByPtr<ColumnType>());
      43         756 :         delete pTab;
      44             :     }
      45         786 : }
      46             : 
      47        1074 : ColumnSpanSet::ColumnType& ColumnSpanSet::getColumn(SCTAB nTab, SCCOL nCol)
      48             : {
      49        1074 :     if (static_cast<size_t>(nTab) >= maDoc.size())
      50         756 :         maDoc.resize(nTab+1, NULL);
      51             : 
      52        1074 :     if (!maDoc[nTab])
      53         756 :         maDoc[nTab] = new TableType;
      54             : 
      55        1074 :     TableType& rTab = *maDoc[nTab];
      56        1074 :     if (static_cast<size_t>(nCol) >= rTab.size())
      57        1053 :         rTab.resize(nCol+1, NULL);
      58             : 
      59        1074 :     if (!rTab[nCol])
      60        1053 :         rTab[nCol] = new ColumnType(0, MAXROW, mbInit);
      61             : 
      62        1074 :     return *rTab[nCol];
      63             : }
      64             : 
      65          37 : void ColumnSpanSet::set(SCTAB nTab, SCCOL nCol, SCROW nRow, bool bVal)
      66             : {
      67          37 :     if (!ValidTab(nTab) || !ValidCol(nCol) || !ValidRow(nRow))
      68          37 :         return;
      69             : 
      70          37 :     ColumnType& rCol = getColumn(nTab, nCol);
      71          37 :     rCol.miPos = rCol.maSpans.insert(rCol.miPos, nRow, nRow+1, bVal).first;
      72             : }
      73             : 
      74          70 : void ColumnSpanSet::set(SCTAB nTab, SCCOL nCol, SCROW nRow1, SCROW nRow2, bool bVal)
      75             : {
      76          70 :     if (!ValidTab(nTab) || !ValidCol(nCol) || !ValidRow(nRow1) || !ValidRow(nRow2))
      77          70 :         return;
      78             : 
      79          70 :     ColumnType& rCol = getColumn(nTab, nCol);
      80          70 :     rCol.miPos = rCol.maSpans.insert(rCol.miPos, nRow1, nRow2+1, bVal).first;
      81             : }
      82             : 
      83         731 : void ColumnSpanSet::set(const ScRange& rRange, bool bVal)
      84             : {
      85        1462 :     for (SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab)
      86             :     {
      87        1698 :         for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
      88             :         {
      89         967 :             ColumnType& rCol = getColumn(nTab, nCol);
      90         967 :             rCol.miPos = rCol.maSpans.insert(rCol.miPos, rRange.aStart.Row(), rRange.aEnd.Row()+1, bVal).first;
      91             :         }
      92             :     }
      93         731 : }
      94             : 
      95          55 : void ColumnSpanSet::executeAction(Action& ac) const
      96             : {
      97          80 :     for (size_t nTab = 0; nTab < maDoc.size(); ++nTab)
      98             :     {
      99          25 :         if (!maDoc[nTab])
     100           0 :             continue;
     101             : 
     102          25 :         const TableType& rTab = *maDoc[nTab];
     103         157 :         for (size_t nCol = 0; nCol < rTab.size(); ++nCol)
     104             :         {
     105         132 :             if (!rTab[nCol])
     106          46 :                 continue;
     107             : 
     108          86 :             ac.startColumn(nTab, nCol);
     109          86 :             ColumnType& rCol = *rTab[nCol];
     110          86 :             ColumnSpansType::const_iterator it = rCol.maSpans.begin(), itEnd = rCol.maSpans.end();
     111             :             SCROW nRow1, nRow2;
     112          86 :             nRow1 = it->first;
     113          86 :             bool bVal = it->second;
     114         269 :             for (++it; it != itEnd; ++it)
     115             :             {
     116         183 :                 nRow2 = it->first-1;
     117         183 :                 ac.execute(ScAddress(nCol, nRow1, nTab), nRow2-nRow1+1, bVal);
     118             : 
     119         183 :                 nRow1 = nRow2+1; // for the next iteration.
     120         183 :                 bVal = it->second;
     121             :             }
     122             :         }
     123             :     }
     124          55 : }
     125             : 
     126         731 : void ColumnSpanSet::executeColumnAction(ScDocument& rDoc, ColumnAction& ac) const
     127             : {
     128        4160 :     for (size_t nTab = 0; nTab < maDoc.size(); ++nTab)
     129             :     {
     130        3429 :         if (!maDoc[nTab])
     131        2698 :             continue;
     132             : 
     133         731 :         const TableType& rTab = *maDoc[nTab];
     134        9002 :         for (size_t nCol = 0; nCol < rTab.size(); ++nCol)
     135             :         {
     136        8271 :             if (!rTab[nCol])
     137       14608 :                 continue;
     138             : 
     139         967 :             ScTable* pTab = rDoc.FetchTable(nTab);
     140         967 :             if (!pTab)
     141           0 :                 continue;
     142             : 
     143         967 :             if (!ValidCol(nCol))
     144             :             {
     145             :                 // End the loop.
     146           0 :                 nCol = rTab.size();
     147           0 :                 continue;
     148             :             }
     149             : 
     150         967 :             ScColumn& rColumn = pTab->aCol[nCol];
     151         967 :             ac.startColumn(&rColumn);
     152         967 :             ColumnType& rCol = *rTab[nCol];
     153         967 :             ColumnSpansType::const_iterator it = rCol.maSpans.begin(), itEnd = rCol.maSpans.end();
     154             :             SCROW nRow1, nRow2;
     155         967 :             nRow1 = it->first;
     156         967 :             bool bVal = it->second;
     157        3768 :             for (++it; it != itEnd; ++it)
     158             :             {
     159        2801 :                 nRow2 = it->first-1;
     160        2801 :                 ac.execute(nRow1, nRow2, bVal);
     161             : 
     162        2801 :                 nRow1 = nRow2+1; // for the next iteration.
     163        2801 :                 bVal = it->second;
     164             :             }
     165             :         }
     166             :     }
     167         731 : }
     168             : 
     169             : namespace {
     170             : 
     171             : class Scanner
     172             : {
     173             :     SingleColumnSpanSet::ColumnSpansType& mrRanges;
     174             : public:
     175      886691 :     Scanner(SingleColumnSpanSet::ColumnSpansType& rRanges) : mrRanges(rRanges) {}
     176             : 
     177      888301 :     void operator() (const sc::CellStoreType::value_type& node, size_t nOffset, size_t nDataSize)
     178             :     {
     179      888301 :         if (node.type == sc::element_type_empty)
     180     1772610 :             return;
     181             : 
     182        3992 :         size_t nRow = node.position + nOffset;
     183        3992 :         size_t nEndRow = nRow + nDataSize; // Last row of current block plus 1
     184        3992 :         mrRanges.insert_back(nRow, nEndRow, true);
     185             :     }
     186             : };
     187             : 
     188             : }
     189             : 
     190      898441 : SingleColumnSpanSet::SingleColumnSpanSet() : maSpans(0, MAXROWCOUNT, false) {}
     191             : 
     192           0 : void SingleColumnSpanSet::scan(const ScColumn& rColumn)
     193             : {
     194           0 :     const CellStoreType& rCells = rColumn.maCells;
     195           0 :     sc::CellStoreType::const_iterator it = rCells.begin(), itEnd = rCells.end();
     196           0 :     SCROW nCurRow = 0;
     197           0 :     for (;it != itEnd; ++it)
     198             :     {
     199           0 :         SCROW nEndRow = nCurRow + it->size; // Last row of current block plus 1.
     200           0 :         if (it->type != sc::element_type_empty)
     201           0 :             maSpans.insert_back(nCurRow, nEndRow, true);
     202             : 
     203           0 :         nCurRow = nEndRow;
     204             :     }
     205           0 : }
     206             : 
     207      886688 : void SingleColumnSpanSet::scan(const ScColumn& rColumn, SCROW nStart, SCROW nEnd)
     208             : {
     209      886688 :     const CellStoreType& rCells = rColumn.maCells;
     210      886688 :     Scanner aScanner(maSpans);
     211      886688 :     sc::ParseBlock(rCells.begin(), rCells, aScanner, nStart, nEnd);
     212      886688 : }
     213             : 
     214           3 : void SingleColumnSpanSet::scan(
     215             :     ColumnBlockConstPosition& rBlockPos, const ScColumn& rColumn, SCROW nStart, SCROW nEnd)
     216             : {
     217           3 :     const CellStoreType& rCells = rColumn.maCells;
     218           3 :     Scanner aScanner(maSpans);
     219           3 :     rBlockPos.miCellPos = sc::ParseBlock(rBlockPos.miCellPos, rCells, aScanner, nStart, nEnd);
     220           3 : }
     221             : 
     222        4166 : void SingleColumnSpanSet::scan(const ScMarkData& rMark, SCTAB nTab, SCCOL nCol)
     223             : {
     224        4166 :     if (!rMark.GetTableSelect(nTab))
     225             :         // This table is not selected. Nothing to scan.
     226        4166 :         return;
     227             : 
     228        4166 :     ScRangeList aRanges = rMark.GetMarkedRanges();
     229       14476 :     for (size_t i = 0, n = aRanges.size(); i < n; ++i)
     230             :     {
     231       10310 :         const ScRange* p = aRanges[i];
     232       10310 :         if (nCol < p->aStart.Col() || p->aEnd.Col() < nCol)
     233             :             // This column is not in this range. Skip it.
     234       10214 :             continue;
     235             : 
     236          96 :         maSpans.insert_back(p->aStart.Row(), p->aEnd.Row()+1, true);
     237        4166 :     }
     238             : }
     239             : 
     240        1046 : void SingleColumnSpanSet::set(SCROW nRow1, SCROW nRow2, bool bVal)
     241             : {
     242        1046 :     maSpans.insert_back(nRow1, nRow2+1, bVal);
     243        1046 : }
     244             : 
     245        7573 : void SingleColumnSpanSet::getRows(std::vector<SCROW> &rRows) const
     246             : {
     247        7573 :     std::vector<SCROW> aRows;
     248             : 
     249       15146 :     SpansType aRanges;
     250        7573 :     getSpans(aRanges);
     251        7573 :     SpansType::const_iterator it = aRanges.begin(), itEnd = aRanges.end();
     252        8420 :     for (; it != itEnd; ++it)
     253             :     {
     254        2975 :         for (SCROW nRow = it->mnRow1; nRow <= it->mnRow2; ++nRow)
     255        2128 :             aRows.push_back(nRow);
     256             :     }
     257             : 
     258       15146 :     rRows.swap(aRows);
     259        7573 : }
     260             : 
     261      902638 : void SingleColumnSpanSet::getSpans(SpansType& rSpans) const
     262             : {
     263      902638 :     SpansType aSpans;
     264      902638 :     ColumnSpansType::const_iterator it = maSpans.begin(), itEnd = maSpans.end();
     265      902638 :     SCROW nLastRow = it->first;
     266      902638 :     bool bLastVal = it->second;
     267     1813400 :     for (++it; it != itEnd; ++it)
     268             :     {
     269      910762 :         SCROW nThisRow = it->first;
     270      910762 :         bool bThisVal = it->second;
     271             : 
     272      910762 :         if (bLastVal)
     273        4816 :             aSpans.push_back(Span(nLastRow, nThisRow-1));
     274             : 
     275      910762 :         nLastRow = nThisRow;
     276      910762 :         bLastVal = bThisVal;
     277             :     }
     278             : 
     279      902638 :     rSpans.swap(aSpans);
     280      902638 : }
     281             : 
     282          93 : }
     283             : 
     284             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10