LCOV - code coverage report
Current view: top level - sc/source/core/data - table2.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 1353 1907 70.9 %
Date: 2015-06-13 12:38:46 Functions: 169 201 84.1 %
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 "table.hxx"
      21             : #include "patattr.hxx"
      22             : #include "docpool.hxx"
      23             : #include "formulacell.hxx"
      24             : #include "document.hxx"
      25             : #include "drwlayer.hxx"
      26             : #include "olinetab.hxx"
      27             : #include "rechead.hxx"
      28             : #include "stlpool.hxx"
      29             : #include "attarray.hxx"
      30             : #include "markdata.hxx"
      31             : #include "progress.hxx"
      32             : #include "dociter.hxx"
      33             : #include "conditio.hxx"
      34             : #include "chartlis.hxx"
      35             : #include "fillinfo.hxx"
      36             : #include "bcaslot.hxx"
      37             : #include "postit.hxx"
      38             : #include "sheetevents.hxx"
      39             : #include "globstr.hrc"
      40             : #include "segmenttree.hxx"
      41             : #include "queryparam.hxx"
      42             : #include "queryentry.hxx"
      43             : #include "dbdata.hxx"
      44             : #include "colorscale.hxx"
      45             : #include "tokenarray.hxx"
      46             : #include "clipcontext.hxx"
      47             : #include "types.hxx"
      48             : #include "editutil.hxx"
      49             : #include "mtvcellfunc.hxx"
      50             : #include "refupdatecontext.hxx"
      51             : #include "scopetools.hxx"
      52             : #include "tabprotection.hxx"
      53             : #include "columnspanset.hxx"
      54             : #include <rowheightcontext.hxx>
      55             : #include <refhint.hxx>
      56             : 
      57             : #include "scitems.hxx"
      58             : #include <editeng/boxitem.hxx>
      59             : #include <editeng/editobj.hxx>
      60             : #include <svl/poolcach.hxx>
      61             : #include <unotools/charclass.hxx>
      62             : #include <math.h>
      63             : #include <svl/PasswordHelper.hxx>
      64             : #include <unotools/transliterationwrapper.hxx>
      65             : 
      66             : namespace {
      67             : 
      68             : class ColumnRegroupFormulaCells
      69             : {
      70             :     ScColumn* mpCols;
      71             :     std::vector<ScAddress>* mpGroupPos;
      72             : 
      73             : public:
      74         114 :     ColumnRegroupFormulaCells( ScColumn* pCols, std::vector<ScAddress>* pGroupPos ) :
      75         114 :         mpCols(pCols), mpGroupPos(pGroupPos) {}
      76             : 
      77          75 :     void operator() (SCCOL nCol)
      78             :     {
      79          75 :         mpCols[nCol].RegroupFormulaCells(mpGroupPos);
      80          75 :     }
      81             : };
      82             : 
      83             : }
      84             : 
      85           1 : sal_uInt16 ScTable::GetTextWidth(SCCOL nCol, SCROW nRow) const
      86             : {
      87           1 :     return aCol[nCol].GetTextWidth(nRow);
      88             : }
      89             : 
      90         339 : bool ScTable::SetOutlineTable( const ScOutlineTable* pNewOutline )
      91             : {
      92         339 :     sal_uInt16 nOldSizeX = 0;
      93         339 :     sal_uInt16 nOldSizeY = 0;
      94         339 :     sal_uInt16 nNewSizeX = 0;
      95         339 :     sal_uInt16 nNewSizeY = 0;
      96             : 
      97         339 :     if (pOutlineTable)
      98             :     {
      99           4 :         nOldSizeX = pOutlineTable->GetColArray().GetDepth();
     100           4 :         nOldSizeY = pOutlineTable->GetRowArray().GetDepth();
     101           4 :         delete pOutlineTable;
     102             :     }
     103             : 
     104         339 :     if (pNewOutline)
     105             :     {
     106          27 :         pOutlineTable = new ScOutlineTable( *pNewOutline );
     107          27 :         nNewSizeX = pOutlineTable->GetColArray().GetDepth();
     108          27 :         nNewSizeY = pOutlineTable->GetRowArray().GetDepth();
     109             :     }
     110             :     else
     111         312 :         pOutlineTable = NULL;
     112             : 
     113         339 :     return ( nNewSizeX != nOldSizeX || nNewSizeY != nOldSizeY );        // changed size?
     114             : }
     115             : 
     116         228 : void ScTable::StartOutlineTable()
     117             : {
     118         228 :     if (!pOutlineTable)
     119         228 :         pOutlineTable = new ScOutlineTable;
     120         228 : }
     121             : 
     122          22 : void ScTable::SetSheetEvents( const ScSheetEvents* pNew )
     123             : {
     124          22 :     delete pSheetEvents;
     125          22 :     if (pNew)
     126           0 :         pSheetEvents = new ScSheetEvents(*pNew);
     127             :     else
     128          22 :         pSheetEvents = NULL;
     129             : 
     130          22 :     SetCalcNotification( false );       // discard notifications before the events were set
     131             : 
     132          22 :     if (IsStreamValid())
     133           0 :         SetStreamValid(false);
     134          22 : }
     135             : 
     136          22 : void ScTable::SetCalcNotification( bool bSet )
     137             : {
     138          22 :     bCalcNotification = bSet;
     139          22 : }
     140             : 
     141          54 : bool ScTable::TestInsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize ) const
     142             : {
     143          54 :     bool bTest = true;
     144             : 
     145          54 :     if ( nStartCol==0 && nEndCol==MAXCOL && pOutlineTable )
     146           0 :         bTest = pOutlineTable->TestInsertRow(nSize);
     147             : 
     148       46143 :     for (SCCOL i=nStartCol; (i<=nEndCol) && bTest; i++)
     149       46089 :         bTest = aCol[i].TestInsertRow(nStartRow, nSize);
     150             : 
     151          54 :     return bTest;
     152             : }
     153             : 
     154          54 : void ScTable::InsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize )
     155             : {
     156          54 :     if (nStartCol==0 && nEndCol==MAXCOL)
     157             :     {
     158          45 :         if (mpRowHeights && pRowFlags)
     159             :         {
     160          45 :             mpRowHeights->insertSegment(nStartRow, nSize, false);
     161          45 :             sal_uInt8 nNewFlags = pRowFlags->Insert( nStartRow, nSize);
     162             :             // only copy manual size flag, clear all others
     163          45 :             if (nNewFlags && (nNewFlags != CR_MANUALSIZE))
     164             :                 pRowFlags->SetValue( nStartRow, nStartRow + nSize - 1,
     165           0 :                         nNewFlags & CR_MANUALSIZE);
     166             :         }
     167             : 
     168          45 :         if (pOutlineTable)
     169           0 :             pOutlineTable->InsertRow( nStartRow, nSize );
     170             : 
     171          45 :         mpFilteredRows->insertSegment(nStartRow, nSize, true);
     172          45 :         mpHiddenRows->insertSegment(nStartRow, nSize, true);
     173             : 
     174          45 :         if (!maRowManualBreaks.empty())
     175             :         {
     176             :             // Copy all breaks up to nStartRow (non-inclusive).
     177           0 :             ::std::set<SCROW>::iterator itr1 = maRowManualBreaks.lower_bound(nStartRow);
     178           0 :             ::std::set<SCROW> aNewBreaks(maRowManualBreaks.begin(), itr1);
     179             : 
     180             :             // Copy all breaks from nStartRow (inclusive) to the last element,
     181             :             // but add nSize to each value.
     182           0 :             ::std::set<SCROW>::iterator itr2 = maRowManualBreaks.end();
     183           0 :             for (; itr1 != itr2; ++itr1)
     184           0 :                 aNewBreaks.insert(static_cast<SCROW>(*itr1 + nSize));
     185             : 
     186           0 :             maRowManualBreaks.swap(aNewBreaks);
     187             :         }
     188             :     }
     189             : 
     190       46143 :     for (SCCOL j=nStartCol; j<=nEndCol; j++)
     191       46089 :         aCol[j].InsertRow( nStartRow, nSize );
     192             : 
     193          54 :     mpCondFormatList->InsertRow(nTab, nStartCol, nEndCol, nStartRow, nSize);
     194             : 
     195          54 :     InvalidatePageBreaks();
     196             : 
     197          54 :     if (IsStreamValid())
     198             :         // TODO: In the future we may want to check if the table has been
     199             :         // really modified before setting the stream invalid.
     200           1 :         SetStreamValid(false);
     201          54 : }
     202             : 
     203          50 : void ScTable::DeleteRow(
     204             :     const sc::ColumnSet& rRegroupCols, SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize,
     205             :     bool* pUndoOutline, std::vector<ScAddress>* pGroupPos )
     206             : {
     207          50 :     if (nStartCol==0 && nEndCol==MAXCOL)
     208             :     {
     209          40 :         if (pRowFlags)
     210          40 :             pRowFlags->Remove( nStartRow, nSize);
     211             : 
     212          40 :         if (mpRowHeights)
     213          40 :             mpRowHeights->removeSegment(nStartRow, nStartRow+nSize);
     214             : 
     215          40 :         if (pOutlineTable)
     216           2 :             if (pOutlineTable->DeleteRow( nStartRow, nSize ))
     217           0 :                 if (pUndoOutline)
     218           0 :                     *pUndoOutline = true;
     219             : 
     220          40 :         mpFilteredRows->removeSegment(nStartRow, nStartRow+nSize);
     221          40 :         mpHiddenRows->removeSegment(nStartRow, nStartRow+nSize);
     222             : 
     223          40 :         if (!maRowManualBreaks.empty())
     224             :         {
     225             :             // Erase all manual breaks between nStartRow and nStartRow + nSize - 1 (inclusive).
     226           0 :             std::set<SCROW>::iterator itr1 = maRowManualBreaks.lower_bound(nStartRow);
     227           0 :             std::set<SCROW>::iterator itr2 = maRowManualBreaks.upper_bound(static_cast<SCROW>(nStartRow + nSize - 1));
     228           0 :             maRowManualBreaks.erase(itr1, itr2);
     229             : 
     230             :             // Copy all breaks from the 1st element up to nStartRow to the new container.
     231           0 :             itr1 = maRowManualBreaks.lower_bound(nStartRow);
     232           0 :             ::std::set<SCROW> aNewBreaks(maRowManualBreaks.begin(), itr1);
     233             : 
     234             :             // Copy all breaks from nStartRow to the last element, but subtract each value by nSize.
     235           0 :             itr2 = maRowManualBreaks.end();
     236           0 :             for (; itr1 != itr2; ++itr1)
     237           0 :                 aNewBreaks.insert(static_cast<SCROW>(*itr1 - nSize));
     238             : 
     239           0 :             maRowManualBreaks.swap(aNewBreaks);
     240             :         }
     241             :     }
     242             : 
     243             :     {   // scope for bulk broadcast
     244          50 :         ScBulkBroadcast aBulkBroadcast( pDocument->GetBASM());
     245       41021 :         for (SCCOL j=nStartCol; j<=nEndCol; j++)
     246       41021 :             aCol[j].DeleteRow(nStartRow, nSize, pGroupPos);
     247             :     }
     248             : 
     249          50 :     std::vector<SCCOL> aRegroupCols;
     250          50 :     rRegroupCols.getColumns(nTab, aRegroupCols);
     251             :     std::for_each(
     252          50 :         aRegroupCols.begin(), aRegroupCols.end(), ColumnRegroupFormulaCells(aCol, pGroupPos));
     253             : 
     254          50 :     InvalidatePageBreaks();
     255             : 
     256          50 :     if (IsStreamValid())
     257             :         // TODO: In the future we may want to check if the table has been
     258             :         // really modified before setting the stream invalid.
     259           0 :         SetStreamValid(false);
     260          50 : }
     261             : 
     262          37 : bool ScTable::TestInsertCol( SCROW nStartRow, SCROW nEndRow, SCSIZE nSize ) const
     263             : {
     264          37 :     bool bTest = true;
     265             : 
     266          37 :     if ( nStartRow==0 && nEndRow==MAXROW && pOutlineTable )
     267           0 :         bTest = pOutlineTable->TestInsertCol(nSize);
     268             : 
     269          37 :     if ( nSize > static_cast<SCSIZE>(MAXCOL) )
     270           0 :         bTest = false;
     271             : 
     272          97 :     for (SCCOL i=MAXCOL; (i+static_cast<SCCOL>(nSize)>MAXCOL) && bTest; i--)
     273          60 :         bTest = aCol[i].TestInsertCol(nStartRow, nEndRow);
     274             : 
     275          37 :     return bTest;
     276             : }
     277             : 
     278          37 : void ScTable::InsertCol(
     279             :     const sc::ColumnSet& rRegroupCols, SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE nSize )
     280             : {
     281          37 :     if (nStartRow==0 && nEndRow==MAXROW)
     282             :     {
     283          28 :         if (pColWidth && pColFlags)
     284             :         {
     285          56 :             memmove( &pColWidth[nStartCol+nSize], &pColWidth[nStartCol],
     286          84 :                     (MAXCOL - nStartCol + 1 - nSize) * sizeof(pColWidth[0]) );
     287          28 :             memmove( &pColFlags[nStartCol+nSize], &pColFlags[nStartCol],
     288          56 :                     (MAXCOL - nStartCol + 1 - nSize) * sizeof(pColFlags[0]) );
     289             :         }
     290          28 :         if (pOutlineTable)
     291           0 :             pOutlineTable->InsertCol( nStartCol, nSize );
     292             : 
     293          28 :         mpHiddenCols->insertSegment(nStartCol, static_cast<SCCOL>(nSize), true);
     294          28 :         mpFilteredCols->insertSegment(nStartCol, static_cast<SCCOL>(nSize), true);
     295             : 
     296          28 :         if (!maColManualBreaks.empty())
     297             :         {
     298             :             // Copy all breaks up to nStartCol (non-inclusive).
     299           0 :             ::std::set<SCCOL>::iterator itr1 = maColManualBreaks.lower_bound(nStartCol);
     300           0 :             ::std::set<SCCOL> aNewBreaks(maColManualBreaks.begin(), itr1);
     301             : 
     302             :             // Copy all breaks from nStartCol (inclusive) to the last element,
     303             :             // but add nSize to each value.
     304           0 :             ::std::set<SCCOL>::iterator itr2 = maColManualBreaks.end();
     305           0 :             for (; itr1 != itr2; ++itr1)
     306           0 :                 aNewBreaks.insert(static_cast<SCCOL>(*itr1 + nSize));
     307             : 
     308           0 :             maColManualBreaks.swap(aNewBreaks);
     309             :         }
     310             :     }
     311             : 
     312          37 :     if ((nStartRow == 0) && (nEndRow == MAXROW))
     313             :     {
     314          72 :         for (SCSIZE i=0; i < nSize; i++)
     315       44964 :             for (SCCOL nCol = MAXCOL; nCol > nStartCol; nCol--)
     316       44948 :                 aCol[nCol].SwapCol(aCol[nCol-1]);
     317             :     }
     318             :     else
     319             :     {
     320        9191 :         for (SCSIZE i=0; static_cast<SCCOL>(i+nSize)+nStartCol <= MAXCOL; i++)
     321        9182 :             aCol[MAXCOL - nSize - i].MoveTo(nStartRow, nEndRow, aCol[MAXCOL - i]);
     322             :     }
     323             : 
     324          37 :     std::vector<SCCOL> aRegroupCols;
     325          37 :     rRegroupCols.getColumns(nTab, aRegroupCols);
     326          37 :     std::for_each(aRegroupCols.begin(), aRegroupCols.end(), ColumnRegroupFormulaCells(aCol, NULL));
     327             : 
     328          37 :     if (nStartCol>0)                        // copy old attributes
     329             :     {
     330             :         sal_uInt16 nWhichArray[2];
     331          25 :         nWhichArray[0] = ATTR_MERGE;
     332          25 :         nWhichArray[1] = 0;
     333             : 
     334          25 :         sc::CopyToDocContext aCxt(*pDocument);
     335          66 :         for (SCSIZE i=0; i<nSize; i++)
     336             :         {
     337          41 :             aCol[nStartCol-1].CopyToColumn(aCxt, nStartRow, nEndRow, IDF_ATTRIB,
     338          82 :                                                 false, aCol[nStartCol+i] );
     339          41 :             aCol[nStartCol+i].RemoveFlags( nStartRow, nEndRow,
     340          41 :                                                 SC_MF_HOR | SC_MF_VER | SC_MF_AUTO );
     341          41 :             aCol[nStartCol+i].ClearItems( nStartRow, nEndRow, nWhichArray );
     342          25 :         }
     343             :     }
     344             : 
     345          37 :     mpCondFormatList->InsertCol(nTab, nStartRow, nEndRow, nStartCol, nSize);
     346             : 
     347          37 :     InvalidatePageBreaks();
     348             : 
     349          37 :     if (IsStreamValid())
     350             :         // TODO: In the future we may want to check if the table has been
     351             :         // really modified before setting the stream invalid.
     352           0 :         SetStreamValid(false);
     353          37 : }
     354             : 
     355          27 : void ScTable::DeleteCol(
     356             :     const sc::ColumnSet& rRegroupCols, SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE nSize, bool* pUndoOutline )
     357             : {
     358          27 :     if (nStartRow==0 && nEndRow==MAXROW)
     359             :     {
     360          22 :         if (pColWidth && pColFlags)
     361             :         {
     362          44 :             memmove( &pColWidth[nStartCol], &pColWidth[nStartCol+nSize],
     363          66 :                     (MAXCOL - nStartCol + 1 - nSize) * sizeof(pColWidth[0]) );
     364          44 :             memmove( &pColFlags[nStartCol], &pColFlags[nStartCol+nSize],
     365          66 :                     (MAXCOL - nStartCol + 1 - nSize) * sizeof(pColFlags[0]) );
     366             :         }
     367          22 :         if (pOutlineTable)
     368           0 :             if (pOutlineTable->DeleteCol( nStartCol, nSize ))
     369           0 :                 if (pUndoOutline)
     370           0 :                     *pUndoOutline = true;
     371             : 
     372          22 :         SCCOL nRmSize = nStartCol + static_cast<SCCOL>(nSize);
     373          22 :         mpHiddenCols->removeSegment(nStartCol, nRmSize);
     374          22 :         mpFilteredCols->removeSegment(nStartCol, nRmSize);
     375             : 
     376          22 :         if (!maColManualBreaks.empty())
     377             :         {
     378             :             // Erase all manual breaks between nStartCol and nStartCol + nSize - 1 (inclusive).
     379           0 :             std::set<SCCOL>::iterator itr1 = maColManualBreaks.lower_bound(nStartCol);
     380           0 :             std::set<SCCOL>::iterator itr2 = maColManualBreaks.upper_bound(static_cast<SCCOL>(nStartCol + nSize - 1));
     381           0 :             maColManualBreaks.erase(itr1, itr2);
     382             : 
     383             :             // Copy all breaks from the 1st element up to nStartCol to the new container.
     384           0 :             itr1 = maColManualBreaks.lower_bound(nStartCol);
     385           0 :             ::std::set<SCCOL> aNewBreaks(maColManualBreaks.begin(), itr1);
     386             : 
     387             :             // Copy all breaks from nStartCol to the last element, but subtract each value by nSize.
     388           0 :             itr2 = maColManualBreaks.end();
     389           0 :             for (; itr1 != itr2; ++itr1)
     390           0 :                 aNewBreaks.insert(static_cast<SCCOL>(*itr1 - nSize));
     391             : 
     392           0 :             maColManualBreaks.swap(aNewBreaks);
     393             :         }
     394             :     }
     395             : 
     396          70 :     for (SCSIZE i = 0; i < nSize; i++)
     397          43 :         aCol[nStartCol + i].DeleteArea(nStartRow, nEndRow, IDF_ALL, false);
     398             : 
     399          27 :     if ((nStartRow == 0) && (nEndRow == MAXROW))
     400             :     {
     401          57 :         for (SCSIZE i=0; i < nSize; i++)
     402       35765 :             for (SCCOL nCol = nStartCol; nCol < MAXCOL; nCol++)
     403       35752 :                 aCol[nCol].SwapCol(aCol[nCol+1]);
     404             :     }
     405             :     else
     406             :     {
     407        5090 :         for (SCSIZE i=0; static_cast<SCCOL>(i+nSize)+nStartCol <= MAXCOL; i++)
     408        5085 :             aCol[nStartCol + nSize + i].MoveTo(nStartRow, nEndRow, aCol[nStartCol + i]);
     409             :     }
     410             : 
     411          27 :     std::vector<SCCOL> aRegroupCols;
     412          27 :     rRegroupCols.getColumns(nTab, aRegroupCols);
     413          27 :     std::for_each(aRegroupCols.begin(), aRegroupCols.end(), ColumnRegroupFormulaCells(aCol, NULL));
     414             : 
     415          27 :     InvalidatePageBreaks();
     416             : 
     417          27 :     if (IsStreamValid())
     418             :         // TODO: In the future we may want to check if the table has been
     419             :         // really modified before setting the stream invalid.
     420           0 :         SetStreamValid(false);
     421          27 : }
     422             : 
     423        1279 : void ScTable::DeleteArea(
     424             :     SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, InsertDeleteFlags nDelFlag,
     425             :     bool bBroadcast, sc::ColumnSpanSet* pBroadcastSpans )
     426             : {
     427        1279 :     if (nCol2 > MAXCOL) nCol2 = MAXCOL;
     428        1279 :     if (nRow2 > MAXROW) nRow2 = MAXROW;
     429        1279 :     if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
     430             :     {
     431             :         {   // scope for bulk broadcast
     432        1279 :             ScBulkBroadcast aBulkBroadcast( pDocument->GetBASM());
     433       51952 :             for (SCCOL i = nCol1; i <= nCol2; i++)
     434       51952 :                 aCol[i].DeleteArea(nRow1, nRow2, nDelFlag, bBroadcast, pBroadcastSpans);
     435             :         }
     436             : 
     437             :             // Do not set protected cell in a protected table
     438             : 
     439        1279 :         if ( IsProtected() && (nDelFlag & IDF_ATTRIB) )
     440             :         {
     441           0 :             ScPatternAttr aPattern(pDocument->GetPool());
     442           0 :             aPattern.GetItemSet().Put( ScProtectionAttr( false ) );
     443           0 :             ApplyPatternArea( nCol1, nRow1, nCol2, nRow2, aPattern );
     444             :         }
     445             : 
     446        1279 :         if( nDelFlag & IDF_ATTRIB )
     447         311 :             mpCondFormatList->DeleteArea( nCol1, nRow1, nCol2, nRow2 );
     448             :     }
     449             : 
     450        1279 :     if (IsStreamValid())
     451             :         // TODO: In the future we may want to check if the table has been
     452             :         // really modified before setting the stream invalid.
     453           0 :         SetStreamValid(false);
     454        1279 : }
     455             : 
     456          93 : void ScTable::DeleteSelection( InsertDeleteFlags nDelFlag, const ScMarkData& rMark, bool bBroadcast )
     457             : {
     458             :     {   // scope for bulk broadcast
     459          93 :         ScBulkBroadcast aBulkBroadcast( pDocument->GetBASM());
     460       95325 :         for (SCCOL i=0; i<=MAXCOL; i++)
     461       95325 :             aCol[i].DeleteSelection(nDelFlag, rMark, bBroadcast);
     462             :     }
     463             : 
     464          93 :     ScRangeList aRangeList;
     465          93 :     rMark.FillRangeListWithMarks(&aRangeList, false);
     466             : 
     467         188 :     for (size_t i = 0; i < aRangeList.size(); ++i)
     468             :     {
     469          95 :         ScRange* pRange = aRangeList[i];
     470             : 
     471          95 :         if((nDelFlag & IDF_ATTRIB) && pRange && pRange->aStart.Tab() == nTab)
     472          71 :             mpCondFormatList->DeleteArea( pRange->aStart.Col(), pRange->aStart.Row(), pRange->aEnd.Col(), pRange->aEnd.Row() );
     473             :     }
     474             : 
     475             :         // Do not set protected cell in a protected sheet
     476             : 
     477          93 :     if ( IsProtected() && (nDelFlag & IDF_ATTRIB) )
     478             :     {
     479           0 :         ScDocumentPool* pPool = pDocument->GetPool();
     480           0 :         SfxItemSet aSet( *pPool, ATTR_PATTERN_START, ATTR_PATTERN_END );
     481           0 :         aSet.Put( ScProtectionAttr( false ) );
     482           0 :         SfxItemPoolCache aCache( pPool, &aSet );
     483           0 :         ApplySelectionCache( &aCache, rMark );
     484             :     }
     485             : 
     486          93 :     if (IsStreamValid())
     487             :         // TODO: In the future we may want to check if the table has been
     488             :         // really modified before setting the stream invalid.
     489           0 :         SetStreamValid(false);
     490          93 : }
     491             : 
     492             : // pTable = Clipboard
     493          56 : void ScTable::CopyToClip(
     494             :     sc::CopyToClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
     495             :     ScTable* pTable )
     496             : {
     497          56 :     if (!ValidColRow(nCol1, nRow1) || !ValidColRow(nCol2, nRow2))
     498          56 :         return;
     499             : 
     500             :     //  copy content
     501             :     //local range names need to be copied first for formula cells
     502          56 :     if (!pTable->mpRangeName && mpRangeName)
     503          20 :         pTable->mpRangeName = new ScRangeName(*mpRangeName);
     504             : 
     505             :     SCCOL i;
     506             : 
     507         136 :     for ( i = nCol1; i <= nCol2; i++)
     508          80 :         aCol[i].CopyToClip(rCxt, nRow1, nRow2, pTable->aCol[i]);  // notes are handled at column level
     509             : 
     510             :     //  copy widths/heights, and only "hidden", "filtered" and "manual" flags
     511             :     //  also for all preceding columns/rows, to have valid positions for drawing objects
     512             : 
     513          56 :     if (pColWidth && pTable->pColWidth)
     514         191 :         for (i=0; i<=nCol2; i++)
     515         135 :             pTable->pColWidth[i] = pColWidth[i];
     516             : 
     517          56 :     pTable->CopyColHidden(*this, 0, nCol2);
     518          56 :     pTable->CopyColFiltered(*this, 0, nCol2);
     519          56 :     if (pDBDataNoName)
     520           4 :         pTable->SetAnonymousDBData(new ScDBData(*pDBDataNoName));
     521             : 
     522          56 :     if (pRowFlags && pTable->pRowFlags && mpRowHeights && pTable->mpRowHeights)
     523             :     {
     524          56 :         pTable->pRowFlags->CopyFromAnded( *pRowFlags, 0, nRow2, CR_MANUALSIZE);
     525          56 :         pTable->CopyRowHeight(*this, 0, nRow2, 0);
     526             :     }
     527             : 
     528          56 :     pTable->CopyRowHidden(*this, 0, nRow2);
     529          56 :     pTable->CopyRowFiltered(*this, 0, nRow2);
     530             : 
     531             :     // If necessary replace formulas with values
     532             : 
     533          56 :     if ( IsProtected() )
     534           0 :         for (i = nCol1; i <= nCol2; i++)
     535           0 :             pTable->aCol[i].RemoveProtected(nRow1, nRow2);
     536             : 
     537          56 :     pTable->mpCondFormatList.reset(new ScConditionalFormatList(pTable->pDocument, *mpCondFormatList));
     538             : }
     539             : 
     540          54 : void ScTable::CopyToClip(
     541             :     sc::CopyToClipContext& rCxt, const ScRangeList& rRanges, ScTable* pTable )
     542             : {
     543          54 :     ScRangeList aRanges(rRanges);
     544         110 :     for ( size_t i = 0, nListSize = aRanges.size(); i < nListSize; ++i )
     545             :     {
     546          56 :         ScRange* p = aRanges[ i ];
     547             :         CopyToClip(
     548          56 :             rCxt, p->aStart.Col(), p->aStart.Row(), p->aEnd.Col(), p->aEnd.Row(), pTable);
     549          54 :     }
     550          54 : }
     551             : 
     552           4 : void ScTable::CopyStaticToDocument(
     553             :     SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, const SvNumberFormatterMergeMap& rMap, ScTable* pDestTab )
     554             : {
     555           4 :     if (nCol1 > nCol2)
     556           4 :         return;
     557             : 
     558          10 :     for (SCCOL i = nCol1; i <= nCol2; ++i)
     559             :     {
     560           6 :         ScColumn& rSrcCol = aCol[i];
     561           6 :         ScColumn& rDestCol = pDestTab->aCol[i];
     562           6 :         rSrcCol.CopyStaticToDocument(nRow1, nRow2, rMap, rDestCol);
     563             :     }
     564             : }
     565             : 
     566           1 : void ScTable::CopyCellToDocument(SCCOL nSrcCol, SCROW nSrcRow, SCCOL nDestCol, SCROW nDestRow, ScTable& rDestTab )
     567             : {
     568           1 :     if (!ValidColRow(nSrcCol, nSrcRow) || !ValidColRow(nDestCol, nDestRow))
     569           1 :         return;
     570             : 
     571           1 :     ScColumn& rSrcCol = aCol[nSrcCol];
     572           1 :     ScColumn& rDestCol = rDestTab.aCol[nDestCol];
     573           1 :     rSrcCol.CopyCellToDocument(nSrcRow, nDestRow, rDestCol);
     574             : }
     575             : 
     576         916 : void ScTable::CopyConditionalFormat( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
     577             :         SCsCOL nDx, SCsROW nDy, ScTable* pTable)
     578             : {
     579         916 :     ScRange aOldRange( nCol1 - nDx, nRow1 - nDy, pTable->nTab, nCol2 - nDx, nRow2 - nDy, pTable->nTab);
     580         916 :     ScRange aNewRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab );
     581         916 :     bool bSameDoc = pDocument == pTable->pDocument;
     582             : 
     583        1880 :     for(ScConditionalFormatList::const_iterator itr = pTable->mpCondFormatList->begin(),
     584         916 :             itrEnd = pTable->mpCondFormatList->end(); itr != itrEnd; ++itr)
     585             :     {
     586          48 :         const ScRangeList& rCondFormatRange = itr->GetRange();
     587          48 :         if(!rCondFormatRange.Intersects( aOldRange ))
     588          36 :             continue;
     589             : 
     590          12 :         ScRangeList aIntersectedRange = rCondFormatRange.GetIntersectedRange(aOldRange);
     591          12 :         ScConditionalFormat* pNewFormat = itr->Clone(pDocument);
     592             : 
     593          12 :         pNewFormat->SetRange(aIntersectedRange);
     594          24 :         sc::RefUpdateContext aRefCxt(*pDocument);
     595          12 :         aRefCxt.meMode = URM_COPY;
     596          12 :         aRefCxt.maRange = aNewRange;
     597          12 :         aRefCxt.mnColDelta = nDx;
     598          12 :         aRefCxt.mnRowDelta = nDy;
     599          12 :         aRefCxt.mnTabDelta = nTab - pTable->nTab;
     600          12 :         pNewFormat->UpdateReference(aRefCxt, true);
     601             : 
     602          12 :         sal_uLong nMax = 0;
     603         108 :         for(ScConditionalFormatList::const_iterator itrCond = mpCondFormatList->begin();
     604          72 :                 itrCond != mpCondFormatList->end(); ++itrCond)
     605             :         {
     606          24 :             if(itrCond->GetKey() > nMax)
     607          24 :                 nMax = itrCond->GetKey();
     608             :         }
     609          12 :         pNewFormat->SetKey(nMax + 1);
     610          12 :         mpCondFormatList->InsertNew(pNewFormat);
     611             : 
     612          12 :         if(!bSameDoc)
     613             :         {
     614          23 :             for(size_t i = 0, n = pNewFormat->size();
     615             :                     i < n; ++i)
     616             :             {
     617          12 :                 OUString aStyleName;
     618          12 :                 const ScFormatEntry* pEntry = pNewFormat->GetEntry(i);
     619          12 :                 if(pEntry->GetType() == condformat::CONDITION)
     620          12 :                     aStyleName = static_cast<const ScCondFormatEntry*>(pEntry)->GetStyle();
     621           0 :                 else if(pEntry->GetType() == condformat::DATE)
     622           0 :                     aStyleName = static_cast<const ScCondDateFormatEntry*>(pEntry)->GetStyleName();
     623             : 
     624          12 :                 if(!aStyleName.isEmpty())
     625             :                 {
     626          12 :                     if(pDocument->GetStyleSheetPool()->Find(aStyleName, SFX_STYLE_FAMILY_PARA))
     627           4 :                         continue;
     628             : 
     629             :                     pDocument->GetStyleSheetPool()->CopyStyleFrom(
     630           8 :                             pTable->pDocument->GetStyleSheetPool(), aStyleName, SFX_STYLE_FAMILY_PARA );
     631             :                 }
     632           8 :             }
     633             :         }
     634             : 
     635          12 :         pDocument->AddCondFormatData( pNewFormat->GetRange(), nTab, pNewFormat->GetKey() );
     636          12 :     }
     637         916 : }
     638             : 
     639      196865 : bool ScTable::InitColumnBlockPosition( sc::ColumnBlockPosition& rBlockPos, SCCOL nCol )
     640             : {
     641      196865 :     if (!ValidCol(nCol))
     642           0 :         return false;
     643             : 
     644      196865 :     return aCol[nCol].InitBlockPosition(rBlockPos);
     645             : }
     646             : 
     647          67 : void ScTable::CopyFromClip(
     648             :     sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
     649             :     SCsCOL nDx, SCsROW nDy, ScTable* pTable )
     650             : {
     651             : 
     652          67 :     if (nCol2 > MAXCOL)
     653           0 :         nCol2 = MAXCOL;
     654          67 :     if (nRow2 > MAXROW)
     655           0 :         nRow2 = MAXROW;
     656             : 
     657          67 :     if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
     658             :     {
     659         276 :         for ( SCCOL i = nCol1; i <= nCol2; i++)
     660         209 :             aCol[i].CopyFromClip(rCxt, nRow1, nRow2, nDy, pTable->aCol[i - nDx]); // notes are handles at column level
     661             : 
     662          67 :         if (rCxt.getInsertFlag() & IDF_ATTRIB)
     663             :         {
     664             :             // make sure that there are no old references to the cond formats
     665             :             sal_uInt16 nWhichArray[2];
     666          44 :             nWhichArray[0] = ATTR_CONDITIONAL;
     667          44 :             nWhichArray[1] = 0;
     668         162 :             for ( SCCOL i = nCol1; i <= nCol2; ++i)
     669         118 :                 aCol[i].ClearItems(nRow1, nRow2, nWhichArray);
     670             :         }
     671             : 
     672          67 :         if ((rCxt.getInsertFlag() & IDF_ATTRIB) != IDF_NONE)
     673             :         {
     674          44 :             if (nRow1==0 && nRow2==MAXROW && pColWidth && pTable->pColWidth)
     675           0 :                 for (SCCOL i=nCol1; i<=nCol2; i++)
     676           0 :                     pColWidth[i] = pTable->pColWidth[i-nDx];
     677             : 
     678          62 :             if (nCol1==0 && nCol2==MAXCOL && mpRowHeights && pTable->mpRowHeights &&
     679          44 :                                              pRowFlags && pTable->pRowFlags)
     680             :             {
     681           0 :                 CopyRowHeight(*pTable, nRow1, nRow2, -nDy);
     682             :                 // Must copy CR_MANUALSIZE bit too, otherwise pRowHeight doesn't make sense
     683           0 :                 for (SCROW j=nRow1; j<=nRow2; j++)
     684             :                 {
     685           0 :                     if ( pTable->pRowFlags->GetValue(j-nDy) & CR_MANUALSIZE )
     686           0 :                         pRowFlags->OrValue( j, CR_MANUALSIZE);
     687             :                     else
     688           0 :                         pRowFlags->AndValue( j, sal::static_int_cast<sal_uInt8>(~CR_MANUALSIZE));
     689             :                 }
     690             :             }
     691             : 
     692             :             // Do not set protected cell in a protected sheet
     693          44 :             if (IsProtected() && (rCxt.getInsertFlag() & IDF_ATTRIB))
     694             :             {
     695           0 :                 ScPatternAttr aPattern(pDocument->GetPool());
     696           0 :                 aPattern.GetItemSet().Put( ScProtectionAttr( false ) );
     697           0 :                 ApplyPatternArea( nCol1, nRow1, nCol2, nRow2, aPattern );
     698             :             }
     699             : 
     700             :             // create deep copies for conditional formatting
     701          44 :             CopyConditionalFormat( nCol1, nRow1, nCol2, nRow2, nDx, nDy, pTable);
     702             :         }
     703             :     }
     704          67 : }
     705             : 
     706           2 : void ScTable::MixData(
     707             :     sc::MixDocContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
     708             :     sal_uInt16 nFunction, bool bSkipEmpty, const ScTable* pSrcTab )
     709             : {
     710           5 :     for (SCCOL i=nCol1; i<=nCol2; i++)
     711           3 :         aCol[i].MixData(rCxt, nRow1, nRow2, nFunction, bSkipEmpty, pSrcTab->aCol[i]);
     712           2 : }
     713             : 
     714             : // Selection form this document
     715           0 : void ScTable::MixMarked(
     716             :     sc::MixDocContext& rCxt, const ScMarkData& rMark, sal_uInt16 nFunction,
     717             :     bool bSkipEmpty, const ScTable* pSrcTab )
     718             : {
     719           0 :     for (SCCOL i=0; i<=MAXCOL; i++)
     720           0 :         aCol[i].MixMarked(rCxt, rMark, nFunction, bSkipEmpty, pSrcTab->aCol[i]);
     721           0 : }
     722             : 
     723             : namespace {
     724             : 
     725             : class TransClipHandler
     726             : {
     727             :     ScTable& mrClipTab;
     728             :     SCTAB mnSrcTab;
     729             :     SCCOL mnSrcCol;
     730             :     size_t mnTopRow;
     731             :     SCROW mnTransRow;
     732             :     bool mbAsLink;
     733             :     bool mbWasCut;
     734             : 
     735           1 :     ScAddress getDestPos(size_t nRow) const
     736             :     {
     737           1 :         return ScAddress(static_cast<SCCOL>(nRow-mnTopRow), mnTransRow, mrClipTab.GetTab());
     738             :     }
     739             : 
     740           0 :     ScFormulaCell* createRefCell(size_t nSrcRow, const ScAddress& rDestPos) const
     741             :     {
     742           0 :         ScAddress aSrcPos(mnSrcCol, nSrcRow, mnSrcTab);
     743             :         ScSingleRefData aRef;
     744           0 :         aRef.InitAddress(aSrcPos); // Absolute reference.
     745           0 :         aRef.SetFlag3D(true);
     746             : 
     747           0 :         ScTokenArray aArr;
     748           0 :         aArr.AddSingleReference(aRef);
     749           0 :         return new ScFormulaCell(&mrClipTab.GetDoc(), rDestPos, aArr);
     750             :     }
     751             : 
     752           0 :     void setLink(size_t nRow)
     753             :     {
     754           0 :         SCCOL nTransCol = nRow - mnTopRow;
     755             :         mrClipTab.SetFormulaCell(
     756           0 :             nTransCol, mnTransRow, createRefCell(nRow, getDestPos(nRow)));
     757           0 :     }
     758             : 
     759             : public:
     760           3 :     TransClipHandler(ScTable& rClipTab, SCTAB nSrcTab, SCCOL nSrcCol, size_t nTopRow, SCROW nTransRow, bool bAsLink, bool bWasCut) :
     761             :         mrClipTab(rClipTab), mnSrcTab(nSrcTab), mnSrcCol(nSrcCol),
     762           3 :         mnTopRow(nTopRow), mnTransRow(nTransRow), mbAsLink(bAsLink), mbWasCut(bWasCut) {}
     763             : 
     764           1 :     void operator() (size_t nRow, double fVal)
     765             :     {
     766           1 :         if (mbAsLink)
     767             :         {
     768           0 :             setLink(nRow);
     769           1 :             return;
     770             :         }
     771             : 
     772           1 :         SCCOL nTransCol = nRow - mnTopRow;
     773           1 :         mrClipTab.SetValue(nTransCol, mnTransRow, fVal);
     774             :     }
     775             : 
     776           1 :     void operator() (size_t nRow, const svl::SharedString& rStr)
     777             :     {
     778           1 :         if (mbAsLink)
     779             :         {
     780           0 :             setLink(nRow);
     781           1 :             return;
     782             :         }
     783             : 
     784           1 :         SCCOL nTransCol = nRow - mnTopRow;
     785           1 :         mrClipTab.SetRawString(nTransCol, mnTransRow, rStr);
     786             :     }
     787             : 
     788           0 :     void operator() (size_t nRow, const EditTextObject* p)
     789             :     {
     790           0 :         if (mbAsLink)
     791             :         {
     792           0 :             setLink(nRow);
     793           0 :             return;
     794             :         }
     795             : 
     796           0 :         SCCOL nTransCol = nRow - mnTopRow;
     797           0 :         mrClipTab.SetEditText(nTransCol, mnTransRow, ScEditUtil::Clone(*p, mrClipTab.GetDoc()));
     798             :     }
     799             : 
     800           1 :     void operator() (size_t nRow, const ScFormulaCell* p)
     801             :     {
     802           1 :         if (mbAsLink)
     803             :         {
     804           0 :             setLink(nRow);
     805           1 :             return;
     806             :         }
     807             : 
     808             :         ScFormulaCell* pNew = new ScFormulaCell(
     809           1 :             *p, mrClipTab.GetDoc(), getDestPos(nRow), SC_CLONECELL_STARTLISTENING);
     810             : 
     811             :         //  rotate reference
     812             :         //  for Cut, the referneces are later adjusted through UpdateTranspose
     813             : 
     814           1 :         if (!mbWasCut)
     815           1 :             pNew->TransposeReference();
     816             : 
     817           1 :         SCCOL nTransCol = nRow - mnTopRow;
     818           1 :         mrClipTab.SetFormulaCell(nTransCol, mnTransRow, pNew);
     819             :     }
     820             : };
     821             : 
     822             : }
     823             : 
     824           1 : void ScTable::TransposeClip( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
     825             :                                 ScTable* pTransClip, InsertDeleteFlags nFlags, bool bAsLink )
     826             : {
     827           1 :     bool bWasCut = pDocument->IsCutMode();
     828             : 
     829           1 :     ScDocument* pDestDoc = pTransClip->pDocument;
     830             : 
     831           4 :     for (SCCOL nCol=nCol1; nCol<=nCol2; nCol++)
     832             :     {
     833             :         SCROW nRow;
     834           3 :         if ( bAsLink && nFlags == IDF_ALL )
     835             :         {
     836             :             //  with IDF_ALL, also create links (formulas) for empty cells
     837             : 
     838           0 :             for ( nRow=nRow1; nRow<=nRow2; nRow++ )
     839             :             {
     840             :                 //  create simple formula, as in ScColumn::CreateRefCell
     841             : 
     842           0 :                 ScAddress aDestPos( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab );
     843             :                 ScSingleRefData aRef;
     844           0 :                 aRef.InitAddress(ScAddress(nCol,nRow,nTab));
     845           0 :                 aRef.SetFlag3D(true);
     846           0 :                 ScTokenArray aArr;
     847           0 :                 aArr.AddSingleReference( aRef );
     848             : 
     849             :                 pTransClip->SetFormulaCell(
     850             :                     static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1),
     851           0 :                     new ScFormulaCell(pDestDoc, aDestPos, aArr));
     852           0 :             }
     853             :         }
     854             :         else
     855             :         {
     856           3 :             TransClipHandler aFunc(*pTransClip, nTab, nCol, nRow1, static_cast<SCROW>(nCol-nCol1), bAsLink, bWasCut);
     857           3 :             const sc::CellStoreType& rCells = aCol[nCol].maCells;
     858           3 :             sc::ParseAllNonEmpty(rCells.begin(), rCells, nRow1, nRow2, aFunc);
     859             :         }
     860             : 
     861             :         //  Attribute
     862             : 
     863             :         SCROW nAttrRow1;
     864             :         SCROW nAttrRow2;
     865             :         const ScPatternAttr* pPattern;
     866           3 :         boost::scoped_ptr<ScAttrIterator> pAttrIter(aCol[nCol].CreateAttrIterator( nRow1, nRow2 ));
     867           9 :         while ( (pPattern = pAttrIter->Next( nAttrRow1, nAttrRow2 )) != 0 )
     868             :         {
     869           3 :             if ( !IsDefaultItem( pPattern ) )
     870             :             {
     871           0 :                 const SfxItemSet& rSet = pPattern->GetItemSet();
     872           0 :                 if ( rSet.GetItemState( ATTR_MERGE, false ) == SfxItemState::DEFAULT &&
     873           0 :                      rSet.GetItemState( ATTR_MERGE_FLAG, false ) == SfxItemState::DEFAULT &&
     874           0 :                      rSet.GetItemState( ATTR_BORDER, false ) == SfxItemState::DEFAULT )
     875             :                 {
     876             :                     // no borders or merge items involved - use pattern as-is
     877           0 :                     for (nRow = nAttrRow1; nRow<=nAttrRow2; nRow++)
     878           0 :                         pTransClip->SetPattern( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), *pPattern, true );
     879             :                 }
     880             :                 else
     881             :                 {
     882             :                     // transpose borders and merge values, remove merge flags (refreshed after pasting)
     883           0 :                     ScPatternAttr aNewPattern( *pPattern );
     884           0 :                     SfxItemSet& rNewSet = aNewPattern.GetItemSet();
     885             : 
     886           0 :                     const SvxBoxItem& rOldBox = static_cast<const SvxBoxItem&>(rSet.Get(ATTR_BORDER));
     887           0 :                     if ( rOldBox.GetTop() || rOldBox.GetBottom() || rOldBox.GetLeft() || rOldBox.GetRight() )
     888             :                     {
     889           0 :                         SvxBoxItem aNew( ATTR_BORDER );
     890           0 :                         aNew.SetLine( rOldBox.GetLine( SvxBoxItemLine::TOP ), SvxBoxItemLine::LEFT );
     891           0 :                         aNew.SetLine( rOldBox.GetLine( SvxBoxItemLine::LEFT ), SvxBoxItemLine::TOP );
     892           0 :                         aNew.SetLine( rOldBox.GetLine( SvxBoxItemLine::BOTTOM ), SvxBoxItemLine::RIGHT );
     893           0 :                         aNew.SetLine( rOldBox.GetLine( SvxBoxItemLine::RIGHT ), SvxBoxItemLine::BOTTOM );
     894           0 :                         aNew.SetDistance( rOldBox.GetDistance( SvxBoxItemLine::TOP ), SvxBoxItemLine::LEFT );
     895           0 :                         aNew.SetDistance( rOldBox.GetDistance( SvxBoxItemLine::LEFT ), SvxBoxItemLine::TOP );
     896           0 :                         aNew.SetDistance( rOldBox.GetDistance( SvxBoxItemLine::BOTTOM ), SvxBoxItemLine::RIGHT );
     897           0 :                         aNew.SetDistance( rOldBox.GetDistance( SvxBoxItemLine::RIGHT ), SvxBoxItemLine::BOTTOM );
     898           0 :                         rNewSet.Put( aNew );
     899             :                     }
     900             : 
     901           0 :                     const ScMergeAttr& rOldMerge = static_cast<const ScMergeAttr&>(rSet.Get(ATTR_MERGE));
     902           0 :                     if (rOldMerge.IsMerged())
     903             :                         rNewSet.Put( ScMergeAttr( std::min(
     904           0 :                                         static_cast<SCsCOL>(rOldMerge.GetRowMerge()),
     905           0 :                                         static_cast<SCsCOL>(MAXCOL+1 - (nAttrRow2-nRow1))),
     906             :                                     std::min(
     907           0 :                                         static_cast<SCsROW>(rOldMerge.GetColMerge()),
     908           0 :                                         static_cast<SCsROW>(MAXROW+1 - (nCol-nCol1)))));
     909           0 :                     const ScMergeFlagAttr& rOldFlag = static_cast<const ScMergeFlagAttr&>(rSet.Get(ATTR_MERGE_FLAG));
     910           0 :                     if (rOldFlag.IsOverlapped())
     911             :                     {
     912           0 :                         sal_Int16 nNewFlags = rOldFlag.GetValue() & ~( SC_MF_HOR | SC_MF_VER );
     913           0 :                         if ( nNewFlags )
     914           0 :                             rNewSet.Put( ScMergeFlagAttr( nNewFlags ) );
     915             :                         else
     916           0 :                             rNewSet.ClearItem( ATTR_MERGE_FLAG );
     917             :                     }
     918             : 
     919           0 :                     for (nRow = nAttrRow1; nRow<=nAttrRow2; nRow++)
     920             :                         pTransClip->SetPattern( static_cast<SCCOL>(nRow-nRow1),
     921           0 :                                 static_cast<SCROW>(nCol-nCol1), aNewPattern, true);
     922             :                 }
     923             :             }
     924             :         }
     925             : 
     926             :         // Cell Notes - fdo#68381 paste cell notes on Transpose
     927           3 :         if ( pDocument->HasColNotes(nCol, nTab) )
     928           3 :             TransposeColNotes(pTransClip, nCol1, nCol, nRow1, nRow2);
     929           3 :     }
     930           1 : }
     931             : 
     932           3 : void ScTable::TransposeColNotes(ScTable* pTransClip, SCCOL nCol1, SCCOL nCol, SCROW nRow1, SCROW nRow2)
     933             : {
     934           3 :     bool bCloneCaption = true;
     935             : 
     936           3 :     sc::CellNoteStoreType::const_iterator itBlk = aCol[nCol].maCellNotes.begin(), itBlkEnd = aCol[nCol].maCellNotes.end();
     937             : 
     938             :     // Locate the top row position.
     939           3 :     size_t nOffsetInBlock = 0;
     940           3 :     size_t nBlockStart = 0, nBlockEnd = 0, nRowPos = static_cast<size_t>(nRow1);
     941           3 :     for (; itBlk != itBlkEnd; ++itBlk, nBlockStart = nBlockEnd)
     942             :     {
     943           3 :         nBlockEnd = nBlockStart + itBlk->size;
     944           3 :         if (nBlockStart <= nRowPos && nRowPos < nBlockEnd)
     945             :         {
     946             :             // Found.
     947           3 :             nOffsetInBlock = nRowPos - nBlockStart;
     948           3 :             break;
     949             :         }
     950             :     }
     951             : 
     952           3 :     if (itBlk != itBlkEnd)
     953             :         // Specified range found
     954             :     {
     955           3 :         nRowPos = static_cast<size_t>(nRow2); // End row position.
     956             : 
     957             :         // Keep processing until we hit the end row position.
     958           3 :         sc::cellnote_block::const_iterator itData, itDataEnd;
     959           3 :         for (; itBlk != itBlkEnd; ++itBlk, nBlockStart = nBlockEnd, nOffsetInBlock = 0)
     960             :         {
     961           3 :             nBlockEnd = nBlockStart + itBlk->size;
     962             : 
     963           3 :             if (itBlk->data)
     964             :             {
     965           3 :                 itData = sc::cellnote_block::begin(*itBlk->data);
     966           3 :                 std::advance(itData, nOffsetInBlock);
     967             : 
     968           3 :                 if (nBlockStart <= nRowPos && nRowPos < nBlockEnd)
     969             :                 {
     970             :                     // This block contains the end row. Only process partially.
     971           3 :                     size_t nOffsetEnd = nRowPos - nBlockStart + 1;
     972           3 :                     itDataEnd = sc::cellnote_block::begin(*itBlk->data);
     973           3 :                     std::advance(itDataEnd, nOffsetEnd);
     974           3 :                     size_t curRow = nBlockStart + nOffsetInBlock;
     975           6 :                     for (; itData != itDataEnd; ++itData, ++curRow)
     976             :                     {
     977           3 :                         ScAddress aDestPos( static_cast<SCCOL>(curRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab );
     978           3 :                         pTransClip->pDocument->ReleaseNote(aDestPos);
     979           3 :                         ScPostIt* pNote = *itData;
     980           3 :                         if (pNote)
     981             :                         {
     982           3 :                             ScPostIt* pClonedNote = pNote->Clone( ScAddress(nCol, curRow, nTab), *pTransClip->pDocument, aDestPos, bCloneCaption );
     983           3 :                             pTransClip->pDocument->SetNote(aDestPos, pClonedNote);
     984             :                         }
     985             :                     }
     986           3 :                     break; // we reached the last valid block
     987             :                 }
     988             :                 else
     989             :                 {
     990           0 :                     itDataEnd = sc::cellnote_block::end(*itBlk->data);
     991           0 :                     size_t curRow = nBlockStart + nOffsetInBlock;
     992           0 :                     for (; itData != itDataEnd; ++itData, ++curRow)
     993             :                     {
     994           0 :                         ScAddress aDestPos( static_cast<SCCOL>(curRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab );
     995           0 :                         pTransClip->pDocument->ReleaseNote(aDestPos);
     996           0 :                         ScPostIt* pNote = *itData;
     997           0 :                         if (pNote)
     998             :                         {
     999           0 :                             ScPostIt* pClonedNote = pNote->Clone( ScAddress(nCol, curRow, nTab), *pTransClip->pDocument, aDestPos, bCloneCaption );
    1000           0 :                             pTransClip->pDocument->SetNote(aDestPos, pClonedNote);
    1001             :                         }
    1002             :                     }
    1003             :                 }
    1004             :             }
    1005             :             else
    1006             :             {
    1007             :                 size_t curRow;
    1008           0 :                 for ( curRow = nBlockStart + nOffsetInBlock; curRow <= nBlockEnd && curRow <= nRowPos; ++curRow)
    1009             :                 {
    1010           0 :                     ScAddress aDestPos( static_cast<SCCOL>(curRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab );
    1011           0 :                     pTransClip->pDocument->ReleaseNote(aDestPos);
    1012             :                 }
    1013           0 :                 if (curRow == nRowPos)
    1014           0 :                     break;
    1015             :             }
    1016             :         }
    1017             :     }
    1018           3 : }
    1019             : 
    1020       44292 : ScColumn* ScTable::FetchColumn( SCCOL nCol )
    1021             : {
    1022       44292 :     if (!ValidCol(nCol))
    1023           0 :         return NULL;
    1024             : 
    1025       44292 :     return &aCol[nCol];
    1026             : }
    1027             : 
    1028         478 : const ScColumn* ScTable::FetchColumn( SCCOL nCol ) const
    1029             : {
    1030         478 :     if (!ValidCol(nCol))
    1031           0 :         return NULL;
    1032             : 
    1033         478 :     return &aCol[nCol];
    1034             : }
    1035             : 
    1036        1243 : void ScTable::StartListeners( sc::StartListeningContext& rCxt, bool bAll )
    1037             : {
    1038     1274075 :     for (SCCOL i=0; i<=MAXCOL; i++)
    1039     1272832 :         aCol[i].StartListeners(rCxt, bAll);
    1040        1243 : }
    1041             : 
    1042          19 : void ScTable::AttachFormulaCells(
    1043             :     sc::StartListeningContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
    1044             : {
    1045          70 :     for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
    1046          51 :         aCol[nCol].AttachFormulaCells(rCxt, nRow1, nRow2);
    1047          19 : }
    1048             : 
    1049          19 : void ScTable::DetachFormulaCells(
    1050             :     sc::EndListeningContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
    1051             : {
    1052          70 :     for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
    1053          51 :         aCol[nCol].DetachFormulaCells(rCxt, nRow1, nRow2);
    1054          19 : }
    1055             : 
    1056          58 : void ScTable::SetDirtyFromClip(
    1057             :     SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, sc::ColumnSpanSet& rBroadcastSpans )
    1058             : {
    1059          58 :     if (nCol2 > MAXCOL) nCol2 = MAXCOL;
    1060          58 :     if (nRow2 > MAXROW) nRow2 = MAXROW;
    1061          58 :     if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
    1062         195 :         for (SCCOL i = nCol1; i <= nCol2; i++)
    1063         137 :             aCol[i].SetDirtyFromClip(nRow1, nRow2, rBroadcastSpans);
    1064          58 : }
    1065             : 
    1066         824 : void ScTable::StartListeningFormulaCells(
    1067             :     sc::StartListeningContext& rStartCxt, sc::EndListeningContext& rEndCxt,
    1068             :     SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
    1069             : {
    1070         824 :     if (nCol2 > MAXCOL) nCol2 = MAXCOL;
    1071         824 :     if (nRow2 > MAXROW) nRow2 = MAXROW;
    1072         824 :     if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
    1073       42393 :         for (SCCOL i = nCol1; i <= nCol2; i++)
    1074       41569 :             aCol[i].StartListeningFormulaCells(rStartCxt, rEndCxt, nRow1, nRow2);
    1075         824 : }
    1076             : 
    1077           0 : void ScTable::EndListeningFormulaCells(
    1078             :     sc::EndListeningContext& rEndCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
    1079             : {
    1080           0 :     if (nCol2 > MAXCOL) nCol2 = MAXCOL;
    1081           0 :     if (nRow2 > MAXROW) nRow2 = MAXROW;
    1082           0 :     if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
    1083           0 :         for (SCCOL i = nCol1; i <= nCol2; ++i)
    1084           0 :             aCol[i].EndListeningFormulaCells(rEndCxt, nRow1, nRow2);
    1085           0 : }
    1086             : 
    1087        1086 : void ScTable::CopyToTable(
    1088             :     sc::CopyToDocContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
    1089             :     InsertDeleteFlags nFlags, bool bMarked, ScTable* pDestTab, const ScMarkData* pMarkData,
    1090             :     bool bAsLink, bool bColRowFlags )
    1091             : {
    1092        1086 :     if (!ValidColRow(nCol1, nRow1) || !ValidColRow(nCol2, nRow2))
    1093           0 :         return;
    1094             : 
    1095        1086 :     if (nFlags)
    1096      187988 :         for (SCCOL i = nCol1; i <= nCol2; i++)
    1097      187009 :             aCol[i].CopyToColumn(rCxt, nRow1, nRow2, nFlags, bMarked,
    1098      374018 :                                 pDestTab->aCol[i], pMarkData, bAsLink);
    1099             : 
    1100        1086 :     if (!bColRowFlags)      // Column widths/Row heights/Flags
    1101          76 :         return;
    1102             : 
    1103        1010 :     if(pDestTab->pDocument->IsUndo() && (nFlags & IDF_ATTRIB))
    1104             :     {
    1105         761 :         pDestTab->mpCondFormatList.reset(new ScConditionalFormatList(pDestTab->pDocument, *mpCondFormatList));
    1106             :     }
    1107             : 
    1108        1010 :     if (pDBDataNoName)
    1109             :     {
    1110         273 :         ScDBData* pNewDBData = new ScDBData(*pDBDataNoName);
    1111             :         SCCOL aCol1, aCol2;
    1112             :         SCROW aRow1, aRow2;
    1113             :         SCTAB aTab;
    1114         273 :         pNewDBData->GetArea(aTab, aCol1, aRow1, aCol2, aRow2);
    1115         273 :         pNewDBData->MoveTo(pDestTab->nTab, aCol1, aRow1, aCol2, aRow2);
    1116         273 :         pDestTab->SetAnonymousDBData(pNewDBData);
    1117             :     }
    1118             :     //  Charts have to be adjusted when hide/show
    1119        1010 :     ScChartListenerCollection* pCharts = pDestTab->pDocument->GetChartListenerCollection();
    1120             : 
    1121        1010 :     bool bFlagChange = false;
    1122             : 
    1123        1010 :     bool bWidth  = (nRow1==0 && nRow2==MAXROW && pColWidth && pDestTab->pColWidth);
    1124        1010 :     bool bHeight = (nCol1==0 && nCol2==MAXCOL && mpRowHeights && pDestTab->mpRowHeights);
    1125             : 
    1126        1010 :     if (bWidth || bHeight)
    1127             :     {
    1128         182 :         if (bWidth)
    1129             :         {
    1130       55811 :             for (SCCOL i = nCol1; i <= nCol2; ++i)
    1131             :             {
    1132       55702 :                 bool bThisHidden = ColHidden(i);
    1133       55702 :                 bool bHiddenChange = (pDestTab->ColHidden(i) != bThisHidden);
    1134       55702 :                 bool bChange = bHiddenChange || (pDestTab->pColWidth[i] != pColWidth[i]);
    1135       55702 :                 pDestTab->pColWidth[i] = pColWidth[i];
    1136       55702 :                 pDestTab->pColFlags[i] = pColFlags[i];
    1137       55702 :                 pDestTab->SetColHidden(i, i, bThisHidden);
    1138             :                 //TODO: collect changes?
    1139       55702 :                 if (bHiddenChange && pCharts)
    1140           0 :                     pCharts->SetRangeDirty(ScRange( i, 0, nTab, i, MAXROW, nTab ));
    1141             : 
    1142       55702 :                 if (bChange)
    1143        9538 :                     bFlagChange = true;
    1144             :             }
    1145         109 :             pDestTab->SetColManualBreaks( maColManualBreaks);
    1146             :         }
    1147             : 
    1148         182 :         if (bHeight)
    1149             :         {
    1150         127 :             bool bChange = pDestTab->GetRowHeight(nRow1, nRow2) != GetRowHeight(nRow1, nRow2);
    1151             : 
    1152         127 :             if (bChange)
    1153          80 :                 bFlagChange = true;
    1154             : 
    1155         127 :             pDestTab->CopyRowHeight(*this, nRow1, nRow2, 0);
    1156         127 :             pDestTab->pRowFlags->CopyFrom(*pRowFlags, nRow1, nRow2);
    1157             : 
    1158             :             // Hidden flags.
    1159         313 :             for (SCROW i = nRow1; i <= nRow2; ++i)
    1160             :             {
    1161             :                 SCROW nLastRow;
    1162         186 :                 bool bHidden = RowHidden(i, NULL, &nLastRow);
    1163         186 :                 if (nLastRow >= nRow2)
    1164             :                     // the last row shouldn't exceed the upper bound the caller specified.
    1165         127 :                     nLastRow = nRow2;
    1166             : 
    1167         186 :                 bool bHiddenChanged = pDestTab->SetRowHidden(i, nLastRow, bHidden);
    1168         186 :                 if (bHiddenChanged && pCharts)
    1169             :                     // Hidden flags differ.
    1170           1 :                     pCharts->SetRangeDirty(ScRange(0, i, nTab, MAXCOL, nLastRow, nTab));
    1171             : 
    1172         186 :                 if (bHiddenChanged)
    1173          28 :                     bFlagChange = true;
    1174             : 
    1175             :                 // Jump to the last row of the identical flag segment.
    1176         186 :                 i = nLastRow;
    1177             :             }
    1178             : 
    1179             :             // Filtered flags.
    1180         306 :             for (SCROW i = nRow1; i <= nRow2; ++i)
    1181             :             {
    1182             :                 SCROW nLastRow;
    1183         179 :                 bool bFiltered = RowFiltered(i, NULL, &nLastRow);
    1184         179 :                 if (nLastRow >= nRow2)
    1185             :                     // the last row shouldn't exceed the upper bound the caller specified.
    1186         127 :                     nLastRow = nRow2;
    1187         179 :                 pDestTab->SetRowFiltered(i, nLastRow, bFiltered);
    1188         179 :                 i = nLastRow;
    1189             :             }
    1190         127 :             pDestTab->SetRowManualBreaks( maRowManualBreaks);
    1191             :         }
    1192             :     }
    1193             : 
    1194        1010 :     if (bFlagChange)
    1195         122 :         pDestTab->InvalidatePageBreaks();
    1196             : 
    1197        1010 :     if(nFlags & IDF_ATTRIB)
    1198             :     {
    1199         855 :         pDestTab->mpCondFormatList->DeleteArea(nCol1, nRow1, nCol2, nRow2);
    1200         855 :         pDestTab->CopyConditionalFormat(nCol1, nRow1, nCol2, nRow2, 0, 0, this);
    1201             :     }
    1202             : 
    1203        1010 :     if(nFlags & IDF_OUTLINE) // also only when bColRowFlags
    1204         335 :         pDestTab->SetOutlineTable( pOutlineTable );
    1205             : }
    1206             : 
    1207           8 : void ScTable::UndoToTable(
    1208             :     sc::CopyToDocContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
    1209             :     InsertDeleteFlags nFlags, bool bMarked, ScTable* pDestTab, const ScMarkData* pMarkData )
    1210             : {
    1211           8 :     if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
    1212             :     {
    1213           8 :         bool bWidth  = (nRow1==0 && nRow2==MAXROW && pColWidth && pDestTab->pColWidth);
    1214           8 :         bool bHeight = (nCol1==0 && nCol2==MAXCOL && mpRowHeights && pDestTab->mpRowHeights);
    1215             : 
    1216        8200 :         for ( SCCOL i = 0; i <= MAXCOL; i++)
    1217             :         {
    1218        8192 :             if ( i >= nCol1 && i <= nCol2 )
    1219          16 :                 aCol[i].UndoToColumn(rCxt, nRow1, nRow2, nFlags, bMarked, pDestTab->aCol[i], pMarkData);
    1220             :             else
    1221        8176 :                 aCol[i].CopyToColumn(rCxt, 0, MAXROW, IDF_FORMULA, false, pDestTab->aCol[i]);
    1222             :         }
    1223             : 
    1224           8 :         if (nFlags & IDF_ATTRIB)
    1225           7 :             pDestTab->mpCondFormatList.reset(new ScConditionalFormatList(pDestTab->pDocument, *mpCondFormatList));
    1226             : 
    1227           8 :         if (bWidth||bHeight)
    1228             :         {
    1229           0 :             if (bWidth)
    1230             :             {
    1231           0 :                 for (SCCOL i=nCol1; i<=nCol2; i++)
    1232           0 :                     pDestTab->pColWidth[i] = pColWidth[i];
    1233           0 :                 pDestTab->SetColManualBreaks( maColManualBreaks);
    1234             :             }
    1235           0 :             if (bHeight)
    1236             :             {
    1237           0 :                 pDestTab->CopyRowHeight(*this, nRow1, nRow2, 0);
    1238           0 :                 pDestTab->SetRowManualBreaks( maRowManualBreaks);
    1239             :             }
    1240             :         }
    1241             :     }
    1242           8 : }
    1243             : 
    1244           0 : void ScTable::CopyUpdated( const ScTable* pPosTab, ScTable* pDestTab ) const
    1245             : {
    1246           0 :     for (SCCOL i=0; i<=MAXCOL; i++)
    1247           0 :         aCol[i].CopyUpdated( pPosTab->aCol[i], pDestTab->aCol[i] );
    1248           0 : }
    1249             : 
    1250       36488 : void ScTable::InvalidateTableArea()
    1251             : {
    1252       36488 :     bTableAreaValid = false;
    1253       36488 : }
    1254             : 
    1255       12864 : void ScTable::InvalidatePageBreaks()
    1256             : {
    1257       12864 :     mbPageBreaksValid = false;
    1258       12864 : }
    1259             : 
    1260           0 : void ScTable::CopyScenarioTo( ScTable* pDestTab ) const
    1261             : {
    1262             :     OSL_ENSURE( bScenario, "bScenario == FALSE" );
    1263             : 
    1264           0 :     for (SCCOL i=0; i<=MAXCOL; i++)
    1265           0 :         aCol[i].CopyScenarioTo( pDestTab->aCol[i] );
    1266           0 : }
    1267             : 
    1268           0 : void ScTable::CopyScenarioFrom( const ScTable* pSrcTab )
    1269             : {
    1270             :     OSL_ENSURE( bScenario, "bScenario == FALSE" );
    1271             : 
    1272           0 :     for (SCCOL i=0; i<=MAXCOL; i++)
    1273           0 :         aCol[i].CopyScenarioFrom( pSrcTab->aCol[i] );
    1274           0 : }
    1275             : 
    1276           3 : void ScTable::MarkScenarioIn( ScMarkData& rDestMark, sal_uInt16 nNeededBits ) const
    1277             : {
    1278             :     OSL_ENSURE( bScenario, "bScenario == FALSE" );
    1279             : 
    1280           3 :     if ( ( nScenarioFlags & nNeededBits ) != nNeededBits )  // Are all Bits set?
    1281           3 :         return;
    1282             : 
    1283        3075 :     for (SCCOL i=0; i<=MAXCOL; i++)
    1284        3072 :         aCol[i].MarkScenarioIn( rDestMark );
    1285             : }
    1286             : 
    1287           1 : bool ScTable::HasScenarioRange( const ScRange& rRange ) const
    1288             : {
    1289             :     OSL_ENSURE( bScenario, "bScenario == FALSE" );
    1290             : 
    1291           1 :     ScRange aTabRange = rRange;
    1292           1 :     aTabRange.aStart.SetTab( nTab );
    1293           1 :     aTabRange.aEnd.SetTab( nTab );
    1294             : 
    1295           1 :     const ScRangeList* pList = GetScenarioRanges();
    1296             : 
    1297           1 :     if (pList)
    1298             :     {
    1299           1 :         for ( size_t j = 0, n = pList->size(); j < n; j++ )
    1300             :         {
    1301           1 :             const ScRange* pR = (*pList)[j];
    1302           1 :             if ( pR->Intersects( aTabRange ) )
    1303           1 :                 return true;
    1304             :         }
    1305             :     }
    1306             : 
    1307           0 :     return false;
    1308             : }
    1309             : 
    1310           1 : void ScTable::InvalidateScenarioRanges()
    1311             : {
    1312           1 :     delete pScenarioRanges;
    1313           1 :     pScenarioRanges = NULL;
    1314           1 : }
    1315             : 
    1316           2 : const ScRangeList* ScTable::GetScenarioRanges() const
    1317             : {
    1318             :     OSL_ENSURE( bScenario, "bScenario == FALSE" );
    1319             : 
    1320           2 :     if (!pScenarioRanges)
    1321             :     {
    1322           2 :         const_cast<ScTable*>(this)->pScenarioRanges = new ScRangeList;
    1323           2 :         ScMarkData aMark;
    1324           2 :         MarkScenarioIn( aMark, 0 );     // always
    1325           2 :         aMark.FillRangeListWithMarks( pScenarioRanges, false );
    1326             :     }
    1327           2 :     return pScenarioRanges;
    1328             : }
    1329             : 
    1330           0 : bool ScTable::TestCopyScenarioTo( const ScTable* pDestTab ) const
    1331             : {
    1332             :     OSL_ENSURE( bScenario, "bScenario == FALSE" );
    1333             : 
    1334           0 :     if (!pDestTab->IsProtected())
    1335           0 :         return true;
    1336             : 
    1337           0 :     bool bOk = true;
    1338           0 :     for (SCCOL i=0; i<=MAXCOL && bOk; i++)
    1339           0 :         bOk = aCol[i].TestCopyScenarioTo( pDestTab->aCol[i] );
    1340           0 :     return bOk;
    1341             : }
    1342             : 
    1343        7037 : bool ScTable::SetString( SCCOL nCol, SCROW nRow, SCTAB nTabP, const OUString& rString,
    1344             :                          ScSetStringParam* pParam )
    1345             : {
    1346        7037 :     if (ValidColRow(nCol,nRow))
    1347        7037 :         return aCol[nCol].SetString(
    1348       14074 :             nRow, nTabP, rString, pDocument->GetAddressConvention(), pParam );
    1349             :     else
    1350           0 :         return false;
    1351             : }
    1352             : 
    1353         195 : bool ScTable::SetEditText( SCCOL nCol, SCROW nRow, EditTextObject* pEditText )
    1354             : {
    1355         195 :     if (!ValidColRow(nCol, nRow))
    1356             :     {
    1357           0 :         delete pEditText;
    1358           0 :         return false;
    1359             :     }
    1360             : 
    1361         195 :     aCol[nCol].SetEditText(nRow, pEditText);
    1362         195 :     return true;
    1363             : }
    1364             : 
    1365           0 : void ScTable::SetEditText( SCCOL nCol, SCROW nRow, const EditTextObject& rEditText, const SfxItemPool* pEditPool )
    1366             : {
    1367           0 :     if (!ValidColRow(nCol, nRow))
    1368           0 :         return;
    1369             : 
    1370           0 :     aCol[nCol].SetEditText(nRow, rEditText, pEditPool);
    1371             : }
    1372             : 
    1373          11 : SCROW ScTable::GetFirstEditTextRow( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const
    1374             : {
    1375          11 :     if (!ValidCol(nCol1) || !ValidCol(nCol2) || nCol2 < nCol1)
    1376           0 :         return -1;
    1377             : 
    1378          11 :     if (!ValidRow(nRow1) || !ValidRow(nRow2) || nRow2 < nRow1)
    1379           0 :         return -1;
    1380             : 
    1381          11 :     SCROW nFirst = MAXROW+1;
    1382          18 :     for (SCCOL i = nCol1; i <= nCol2; ++i)
    1383             :     {
    1384          11 :         const ScColumn& rCol = aCol[i];
    1385          11 :         SCROW nThisFirst = -1;
    1386          11 :         if (const_cast<ScColumn&>(rCol).HasEditCells(nRow1, nRow2, nThisFirst))
    1387             :         {
    1388           4 :             if (nThisFirst == nRow1)
    1389           4 :                 return nRow1;
    1390             : 
    1391           0 :             if (nThisFirst < nFirst)
    1392           0 :                 nFirst = nThisFirst;
    1393             :         }
    1394             :     }
    1395             : 
    1396           7 :     return nFirst == (MAXROW+1) ? -1 : nFirst;
    1397             : }
    1398             : 
    1399         490 : void ScTable::SetEmptyCell( SCCOL nCol, SCROW nRow )
    1400             : {
    1401         490 :     if (!ValidColRow(nCol, nRow))
    1402         490 :         return;
    1403             : 
    1404         490 :     aCol[nCol].Delete(nRow);
    1405             : }
    1406             : 
    1407           0 : void ScTable::SetFormula(
    1408             :     SCCOL nCol, SCROW nRow, const ScTokenArray& rArray, formula::FormulaGrammar::Grammar eGram )
    1409             : {
    1410           0 :     if (!ValidColRow(nCol, nRow))
    1411           0 :         return;
    1412             : 
    1413           0 :     aCol[nCol].SetFormula(nRow, rArray, eGram);
    1414             : }
    1415             : 
    1416           0 : void ScTable::SetFormula(
    1417             :     SCCOL nCol, SCROW nRow, const OUString& rFormula, formula::FormulaGrammar::Grammar eGram )
    1418             : {
    1419           0 :     if (!ValidColRow(nCol, nRow))
    1420           0 :         return;
    1421             : 
    1422           0 :     aCol[nCol].SetFormula(nRow, rFormula, eGram);
    1423             : }
    1424             : 
    1425         388 : ScFormulaCell* ScTable::SetFormulaCell( SCCOL nCol, SCROW nRow, ScFormulaCell* pCell )
    1426             : {
    1427         388 :     if (!ValidColRow(nCol, nRow))
    1428             :     {
    1429           0 :         delete pCell;
    1430           0 :         return NULL;
    1431             :     }
    1432             : 
    1433         388 :     return aCol[nCol].SetFormulaCell(nRow, pCell, sc::ConvertToGroupListening);
    1434             : }
    1435             : 
    1436           6 : bool ScTable::SetFormulaCells( SCCOL nCol, SCROW nRow, std::vector<ScFormulaCell*>& rCells )
    1437             : {
    1438           6 :     if (!ValidCol(nCol))
    1439           0 :         return false;
    1440             : 
    1441           6 :     return aCol[nCol].SetFormulaCells(nRow, rCells);
    1442             : }
    1443             : 
    1444          34 : svl::SharedString ScTable::GetSharedString( SCCOL nCol, SCROW nRow ) const
    1445             : {
    1446          34 :     if (!ValidColRow(nCol, nRow))
    1447           0 :         return svl::SharedString();
    1448             : 
    1449          34 :     return aCol[nCol].GetSharedString(nRow);
    1450             : }
    1451             : 
    1452       26523 : void ScTable::SetValue( SCCOL nCol, SCROW nRow, const double& rVal )
    1453             : {
    1454       26523 :     if (ValidColRow(nCol, nRow))
    1455       26523 :         aCol[nCol].SetValue( nRow, rVal );
    1456       26523 : }
    1457             : 
    1458           1 : void ScTable::SetRawString( SCCOL nCol, SCROW nRow, const svl::SharedString& rStr )
    1459             : {
    1460           1 :     if (ValidColRow(nCol, nRow))
    1461           1 :         aCol[nCol].SetRawString(nRow, rStr);
    1462           1 : }
    1463             : 
    1464       18712 : void ScTable::GetString( SCCOL nCol, SCROW nRow, OUString& rString ) const
    1465             : {
    1466       18712 :     if (ValidColRow(nCol,nRow))
    1467       18712 :         aCol[nCol].GetString( nRow, rString );
    1468             :     else
    1469           0 :         rString.clear();
    1470       18712 : }
    1471             : 
    1472           5 : double* ScTable::GetValueCell( SCCOL nCol, SCROW nRow )
    1473             : {
    1474           5 :     if (!ValidColRow(nCol,nRow))
    1475           0 :         return NULL;
    1476             : 
    1477           5 :     return aCol[nCol].GetValueCell(nRow);
    1478             : }
    1479             : 
    1480        3126 : void ScTable::GetInputString( SCCOL nCol, SCROW nRow, OUString& rString ) const
    1481             : {
    1482        3126 :     if (ValidColRow(nCol,nRow))
    1483        3126 :         aCol[nCol].GetInputString( nRow, rString );
    1484             :     else
    1485           0 :         rString.clear();
    1486        3126 : }
    1487             : 
    1488       13849 : double ScTable::GetValue( SCCOL nCol, SCROW nRow ) const
    1489             : {
    1490       13849 :     if (ValidColRow( nCol, nRow ))
    1491       13849 :         return aCol[nCol].GetValue( nRow );
    1492           0 :     return 0.0;
    1493             : }
    1494             : 
    1495          76 : const EditTextObject* ScTable::GetEditText( SCCOL nCol, SCROW nRow ) const
    1496             : {
    1497          76 :     if (!ValidColRow(nCol, nRow))
    1498           0 :         return NULL;
    1499             : 
    1500          76 :     return aCol[nCol].GetEditText(nRow);
    1501             : }
    1502             : 
    1503           0 : void ScTable::RemoveEditTextCharAttribs( SCCOL nCol, SCROW nRow, const ScPatternAttr& rAttr )
    1504             : {
    1505           0 :     if (!ValidColRow(nCol, nRow))
    1506           0 :         return;
    1507             : 
    1508           0 :     return aCol[nCol].RemoveEditTextCharAttribs(nRow, rAttr);
    1509             : }
    1510             : 
    1511          62 : void ScTable::GetFormula( SCCOL nCol, SCROW nRow, OUString& rFormula ) const
    1512             : {
    1513          62 :     if (ValidColRow(nCol,nRow))
    1514          62 :         aCol[nCol].GetFormula( nRow, rFormula );
    1515             :     else
    1516           0 :         rFormula.clear();
    1517          62 : }
    1518             : 
    1519           0 : const ScFormulaCell* ScTable::GetFormulaCell( SCCOL nCol, SCROW nRow ) const
    1520             : {
    1521           0 :     if (!ValidColRow(nCol, nRow))
    1522           0 :         return NULL;
    1523             : 
    1524           0 :     return aCol[nCol].GetFormulaCell(nRow);
    1525             : }
    1526             : 
    1527       37544 : ScFormulaCell* ScTable::GetFormulaCell( SCCOL nCol, SCROW nRow )
    1528             : {
    1529       37544 :     if (!ValidColRow(nCol, nRow))
    1530          94 :         return NULL;
    1531             : 
    1532       37450 :     return aCol[nCol].GetFormulaCell(nRow);
    1533             : }
    1534             : 
    1535          21 : ScPostIt* ScTable::ReleaseNote( SCCOL nCol, SCROW nRow )
    1536             : {
    1537          21 :     if (!ValidCol(nCol))
    1538           0 :         return NULL;
    1539             : 
    1540          21 :     return aCol[nCol].ReleaseNote(nRow);
    1541             : }
    1542             : 
    1543        1056 : size_t ScTable::GetNoteCount( SCCOL nCol ) const
    1544             : {
    1545        1056 :     if (!ValidCol(nCol))
    1546           0 :         return 0;
    1547             : 
    1548        1056 :     return aCol[nCol].GetNoteCount();
    1549             : }
    1550             : 
    1551           6 : SCROW ScTable::GetNotePosition( SCCOL nCol, size_t nIndex ) const
    1552             : {
    1553           6 :     if (!ValidCol(nCol))
    1554           0 :         return -1;
    1555             : 
    1556           6 :     return aCol[nCol].GetNotePosition(nIndex);
    1557             : }
    1558             : 
    1559          34 : void ScTable::CreateAllNoteCaptions()
    1560             : {
    1561       34850 :     for (SCCOL i = 0; i <= MAXCOL; ++i)
    1562       34816 :         aCol[i].CreateAllNoteCaptions();
    1563          34 : }
    1564             : 
    1565           8 : void ScTable::ForgetNoteCaptions( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
    1566             : {
    1567           8 :     if (!ValidCol(nCol1) || !ValidCol(nCol2))
    1568           8 :         return;
    1569             : 
    1570          24 :     for (SCCOL i = nCol1; i <= nCol2; ++i)
    1571          16 :         aCol[i].ForgetNoteCaptions(nRow1, nRow2);
    1572             : }
    1573             : 
    1574         295 : void ScTable::GetAllNoteEntries( std::vector<sc::NoteEntry>& rNotes ) const
    1575             : {
    1576      302375 :     for (SCCOL nCol = 0; nCol < MAXCOLCOUNT; ++nCol)
    1577      302080 :         aCol[nCol].GetAllNoteEntries(rNotes);
    1578         295 : }
    1579             : 
    1580          12 : void ScTable::GetNotesInRange( const ScRange& rRange, std::vector<sc::NoteEntry>& rNotes ) const
    1581             : {
    1582          12 :     SCROW nStartRow = rRange.aStart.Row();
    1583          12 :     SCROW nEndRow = rRange.aEnd.Row();
    1584       12300 :     for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
    1585             :     {
    1586       12288 :         aCol[nCol].GetNotesInRange(nStartRow, nEndRow, rNotes);
    1587             :     }
    1588          12 : }
    1589             : 
    1590           0 : bool ScTable::ContainsNotesInRange( const ScRange& rRange ) const
    1591             : {
    1592           0 :     SCROW nStartRow = rRange.aStart.Row();
    1593           0 :     SCROW nEndRow = rRange.aEnd.Row();
    1594           0 :     for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
    1595             :     {
    1596           0 :         bool bContainsNote = !aCol[nCol].IsNotesEmptyBlock(nStartRow, nEndRow);
    1597           0 :         if(bContainsNote)
    1598           0 :             return true;
    1599             :     }
    1600             : 
    1601           0 :     return false;
    1602             : }
    1603             : 
    1604          36 : CellType ScTable::GetCellType( SCCOL nCol, SCROW nRow ) const
    1605             : {
    1606          36 :     if (ValidColRow( nCol, nRow ))
    1607          36 :         return aCol[nCol].GetCellType( nRow );
    1608           0 :     return CELLTYPE_NONE;
    1609             : }
    1610             : 
    1611         157 : ScRefCellValue ScTable::GetCellValue( SCCOL nCol, SCROW nRow ) const
    1612             : {
    1613         157 :     if (!ValidColRow(nCol, nRow))
    1614           0 :         return ScRefCellValue();
    1615             : 
    1616         157 :     return aCol[nCol].GetCellValue(nRow);
    1617             : }
    1618             : 
    1619          60 : void ScTable::GetFirstDataPos(SCCOL& rCol, SCROW& rRow) const
    1620             : {
    1621          60 :     rCol = 0;
    1622          60 :     rRow = MAXROW+1;
    1623        1162 :     while (aCol[rCol].IsEmptyData() && rCol < MAXCOL)
    1624        1042 :         ++rCol;
    1625          60 :     SCCOL nCol = rCol;
    1626       18594 :     while (nCol <= MAXCOL && rRow > 0)
    1627             :     {
    1628       18474 :         if (!aCol[nCol].IsEmptyData())
    1629         100 :             rRow = ::std::min( rRow, aCol[nCol].GetFirstDataPos());
    1630       18474 :         ++nCol;
    1631             :     }
    1632          60 : }
    1633             : 
    1634         140 : void ScTable::GetLastDataPos(SCCOL& rCol, SCROW& rRow) const
    1635             : {
    1636         140 :     rCol = MAXCOL;
    1637         140 :     rRow = 0;
    1638      141818 :     while (aCol[rCol].IsEmptyData() && (rCol > 0))
    1639      141538 :         rCol--;
    1640         140 :     SCCOL nCol = rCol;
    1641        2102 :     while (nCol >= 0 && rRow < MAXROW)
    1642        1822 :         rRow = ::std::max( rRow, aCol[nCol--].GetLastDataPos());
    1643         140 : }
    1644             : 
    1645        3020 : bool ScTable::HasData( SCCOL nCol, SCROW nRow ) const
    1646             : {
    1647        3020 :     if (ValidColRow(nCol,nRow))
    1648        3020 :         return aCol[nCol].HasDataAt( nRow );
    1649             :     else
    1650           0 :         return false;
    1651             : }
    1652             : 
    1653           6 : bool ScTable::HasStringData( SCCOL nCol, SCROW nRow ) const
    1654             : {
    1655           6 :     if (ValidColRow(nCol,nRow))
    1656           6 :         return aCol[nCol].HasStringData( nRow );
    1657             :     else
    1658           0 :         return false;
    1659             : }
    1660             : 
    1661        2971 : bool ScTable::HasValueData( SCCOL nCol, SCROW nRow ) const
    1662             : {
    1663        2971 :     if (ValidColRow(nCol,nRow))
    1664        2971 :         return aCol[nCol].HasValueData( nRow );
    1665             :     else
    1666           0 :         return false;
    1667             : }
    1668             : 
    1669           0 : bool ScTable::HasStringCells( SCCOL nStartCol, SCROW nStartRow,
    1670             :                                 SCCOL nEndCol, SCROW nEndRow ) const
    1671             : {
    1672           0 :     if ( ValidCol(nEndCol) )
    1673           0 :         for ( SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++ )
    1674           0 :             if (aCol[nCol].HasStringCells(nStartRow, nEndRow))
    1675           0 :                 return true;
    1676             : 
    1677           0 :     return false;
    1678             : }
    1679             : 
    1680         652 : void ScTable::SetDirtyVar()
    1681             : {
    1682      668300 :     for (SCCOL i=0; i<=MAXCOL; i++)
    1683      667648 :         aCol[i].SetDirtyVar();
    1684         652 : }
    1685             : 
    1686        1103 : void ScTable::SetAllFormulasDirty( const sc::SetFormulaDirtyContext& rCxt )
    1687             : {
    1688        1103 :     sc::AutoCalcSwitch aACSwitch(*pDocument, false);
    1689             : 
    1690     1130575 :     for (SCCOL i=0; i<=MAXCOL; i++)
    1691     1130575 :         aCol[i].SetAllFormulasDirty(rCxt);
    1692        1103 : }
    1693             : 
    1694         200 : void ScTable::SetDirty( const ScRange& rRange, ScColumn::BroadcastMode eMode )
    1695             : {
    1696         200 :     bool bOldAutoCalc = pDocument->GetAutoCalc();
    1697         200 :     pDocument->SetAutoCalc( false );    // avoid multiple recalculations
    1698         200 :     SCCOL nCol2 = rRange.aEnd.Col();
    1699       13813 :     for (SCCOL i=rRange.aStart.Col(); i<=nCol2; i++)
    1700       13613 :         aCol[i].SetDirty(rRange.aStart.Row(), rRange.aEnd.Row(), eMode);
    1701         200 :     pDocument->SetAutoCalc( bOldAutoCalc );
    1702         200 : }
    1703             : 
    1704          44 : void ScTable::SetTableOpDirty( const ScRange& rRange )
    1705             : {
    1706          44 :     bool bOldAutoCalc = pDocument->GetAutoCalc();
    1707          44 :     pDocument->SetAutoCalc( false );    // no multiple recalculation
    1708          44 :     SCCOL nCol2 = rRange.aEnd.Col();
    1709          88 :     for (SCCOL i=rRange.aStart.Col(); i<=nCol2; i++)
    1710          44 :         aCol[i].SetTableOpDirty( rRange );
    1711          44 :     pDocument->SetAutoCalc( bOldAutoCalc );
    1712          44 : }
    1713             : 
    1714         233 : void ScTable::SetDirtyAfterLoad()
    1715             : {
    1716         233 :     bool bOldAutoCalc = pDocument->GetAutoCalc();
    1717         233 :     pDocument->SetAutoCalc( false );    // avoid multiple recalculations
    1718      238825 :     for (SCCOL i=0; i<=MAXCOL; i++)
    1719      238592 :         aCol[i].SetDirtyAfterLoad();
    1720         233 :     pDocument->SetAutoCalc( bOldAutoCalc );
    1721         233 : }
    1722             : 
    1723         184 : void ScTable::SetDirtyIfPostponed()
    1724             : {
    1725         184 :     bool bOldAutoCalc = pDocument->GetAutoCalc();
    1726         184 :     pDocument->SetAutoCalc( false );    // avoid multiple recalculations
    1727      188600 :     for (SCCOL i=0; i<=MAXCOL; i++)
    1728      188416 :         aCol[i].SetDirtyIfPostponed();
    1729         184 :     pDocument->SetAutoCalc( bOldAutoCalc );
    1730         184 : }
    1731             : 
    1732         184 : void ScTable::BroadcastRecalcOnRefMove()
    1733             : {
    1734         184 :     sc::AutoCalcSwitch aSwitch(*pDocument, false);
    1735      188600 :     for (SCCOL i = 0; i <= MAXCOL; ++i)
    1736      188600 :         aCol[i].BroadcastRecalcOnRefMove();
    1737         184 : }
    1738             : 
    1739         144 : bool ScTable::BroadcastBroadcasters( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScHint& rHint )
    1740             : {
    1741         144 :     bool bBroadcasted = false;
    1742         144 :     sc::AutoCalcSwitch aSwitch(*pDocument, false);
    1743         144 :     rHint.GetAddress().SetTab(nTab);
    1744         333 :     for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
    1745         189 :         bBroadcasted |= aCol[nCol].BroadcastBroadcasters( nRow1, nRow2, rHint);
    1746         144 :     return bBroadcasted;
    1747             : }
    1748             : 
    1749           6 : void ScTable::TransferListeners(
    1750             :     ScTable& rDestTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
    1751             :     SCCOL nColDelta, SCROW nRowDelta )
    1752             : {
    1753          13 :     for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
    1754             :     {
    1755           7 :         ScColumn& rSrcCol = aCol[nCol];
    1756           7 :         ScColumn& rDestCol = rDestTab.aCol[nCol+nColDelta];
    1757           7 :         rSrcCol.TransferListeners(rDestCol, nRow1, nRow2, nRowDelta);
    1758             :     }
    1759           6 : }
    1760             : 
    1761        2399 : void ScTable::SetLoadingMedium(bool bLoading)
    1762             : {
    1763        2399 :     mpRowHeights->enableTreeSearch(!bLoading);
    1764        2399 : }
    1765             : 
    1766         652 : void ScTable::CalcAll()
    1767             : {
    1768         652 :     for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CalcAll();
    1769         652 : }
    1770             : 
    1771          14 : void ScTable::CompileAll( sc::CompileFormulaContext& rCxt )
    1772             : {
    1773       14350 :     for (SCCOL i = 0; i <= MAXCOL; ++i)
    1774       14336 :         aCol[i].CompileAll(rCxt);
    1775             : 
    1776          14 :     if(mpCondFormatList)
    1777          14 :         mpCondFormatList->CompileAll();
    1778          14 : }
    1779             : 
    1780         331 : void ScTable::CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rProgress )
    1781             : {
    1782         331 :     if (mpRangeName)
    1783          37 :         mpRangeName->CompileUnresolvedXML(rCxt);
    1784             : 
    1785      339275 :     for (SCCOL i=0; i <= MAXCOL; i++)
    1786             :     {
    1787      338944 :         aCol[i].CompileXML(rCxt, rProgress);
    1788             :     }
    1789             : 
    1790         331 :     if(mpCondFormatList)
    1791         331 :         mpCondFormatList->CompileXML();
    1792         331 : }
    1793             : 
    1794           0 : bool ScTable::CompileErrorCells( sc::CompileFormulaContext& rCxt, sal_uInt16 nErrCode )
    1795             : {
    1796           0 :     bool bCompiled = false;
    1797           0 :     for (SCCOL i = 0; i <= MAXCOL; ++i)
    1798             :     {
    1799           0 :         if (aCol[i].CompileErrorCells(rCxt, nErrCode))
    1800           0 :             bCompiled = true;
    1801             :     }
    1802             : 
    1803           0 :     return bCompiled;
    1804             : }
    1805             : 
    1806         233 : void ScTable::CalcAfterLoad( sc::CompileFormulaContext& rCxt, bool bStartListening )
    1807             : {
    1808      238825 :     for (SCCOL i = 0; i <= MAXCOL; ++i)
    1809      238592 :         aCol[i].CalcAfterLoad(rCxt, bStartListening);
    1810         233 : }
    1811             : 
    1812        3908 : void ScTable::ResetChanged( const ScRange& rRange )
    1813             : {
    1814        3908 :     SCCOL nStartCol = rRange.aStart.Col();
    1815        3908 :     SCROW nStartRow = rRange.aStart.Row();
    1816        3908 :     SCCOL nEndCol = rRange.aEnd.Col();
    1817        3908 :     SCROW nEndRow = rRange.aEnd.Row();
    1818             : 
    1819       34990 :     for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++)
    1820       31082 :         aCol[nCol].ResetChanged(nStartRow, nEndRow);
    1821        3908 : }
    1822             : 
    1823             : //  Attribute
    1824             : 
    1825       14170 : const SfxPoolItem* ScTable::GetAttr( SCCOL nCol, SCROW nRow, sal_uInt16 nWhich ) const
    1826             : {
    1827       14170 :     if (ValidColRow(nCol,nRow))
    1828       14170 :         return aCol[nCol].GetAttr( nRow, nWhich );
    1829             :     else
    1830           0 :         return NULL;
    1831             : }
    1832             : 
    1833       23957 : sal_uInt32 ScTable::GetNumberFormat( const ScAddress& rPos ) const
    1834             : {
    1835       23957 :     return ValidColRow(rPos.Col(),rPos.Row()) ?
    1836       23957 :         aCol[rPos.Col()].GetNumberFormat( rPos.Row() ) :
    1837       47914 :         0;
    1838             : }
    1839             : 
    1840        1089 : sal_uInt32 ScTable::GetNumberFormat( SCCOL nCol, SCROW nRow ) const
    1841             : {
    1842        1089 :     if (ValidColRow(nCol,nRow))
    1843        1089 :         return aCol[nCol].GetNumberFormat( nRow );
    1844             :     else
    1845           0 :         return 0;
    1846             : }
    1847             : 
    1848           0 : sal_uInt32 ScTable::GetNumberFormat( SCCOL nCol, SCROW nStartRow, SCROW nEndRow ) const
    1849             : {
    1850           0 :     if (!ValidCol(nCol) || !ValidRow(nStartRow) || !ValidRow(nEndRow))
    1851           0 :         return 0;
    1852             : 
    1853           0 :     return aCol[nCol].GetNumberFormat(nStartRow, nEndRow);
    1854             : }
    1855             : 
    1856          67 : void ScTable::SetNumberFormat( SCCOL nCol, SCROW nRow, sal_uInt32 nNumberFormat )
    1857             : {
    1858          67 :     if (!ValidColRow(nCol, nRow))
    1859          67 :         return;
    1860             : 
    1861          67 :     aCol[nCol].SetNumberFormat(nRow, nNumberFormat);
    1862             : }
    1863             : 
    1864       20779 : const ScPatternAttr* ScTable::GetPattern( SCCOL nCol, SCROW nRow ) const
    1865             : {
    1866       20779 :     if (ValidColRow(nCol,nRow))
    1867       20779 :         return aCol[nCol].GetPattern( nRow );
    1868             :     else
    1869             :     {
    1870             :         OSL_FAIL("wrong column or row");
    1871           0 :         return pDocument->GetDefPattern();      // for safety
    1872             :     }
    1873             : }
    1874             : 
    1875      109824 : const ScPatternAttr* ScTable::GetMostUsedPattern( SCCOL nCol, SCROW nStartRow, SCROW nEndRow ) const
    1876             : {
    1877      109824 :     if ( ValidColRow( nCol, nStartRow ) && ValidRow( nEndRow ) && (nStartRow <= nEndRow) )
    1878      109824 :         return aCol[nCol].GetMostUsedPattern( nStartRow, nEndRow );
    1879             :     else
    1880           0 :         return NULL;
    1881             : }
    1882             : 
    1883       27736 : bool ScTable::HasAttrib( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, sal_uInt16 nMask ) const
    1884             : {
    1885       27736 :     bool bFound = false;
    1886    15977289 :     for (SCCOL i=nCol1; i<=nCol2 && !bFound; i++)
    1887    15949553 :         bFound |= aCol[i].HasAttrib( nRow1, nRow2, nMask );
    1888       27736 :     return bFound;
    1889             : }
    1890             : 
    1891           0 : bool ScTable::HasAttribSelection( const ScMarkData& rMark, sal_uInt16 nMask ) const
    1892             : {
    1893           0 :     std::vector<sc::ColRowSpan> aSpans = rMark.GetMarkedColSpans();
    1894             : 
    1895           0 :     for (size_t i = 0; i < aSpans.size(); ++i)
    1896             :     {
    1897           0 :         for (SCCOLROW j = aSpans[i].mnStart; j < aSpans[i].mnEnd; ++j)
    1898             :         {
    1899           0 :             if (aCol[j].HasAttribSelection(rMark, nMask))
    1900           0 :               return true;
    1901             :         }
    1902             :     }
    1903           0 :     return false;
    1904             : }
    1905             : 
    1906       10424 : bool ScTable::ExtendMerge( SCCOL nStartCol, SCROW nStartRow,
    1907             :                            SCCOL& rEndCol, SCROW& rEndRow,
    1908             :                            bool bRefresh )
    1909             : {
    1910       10424 :     if (!(ValidCol(nStartCol) && ValidCol(rEndCol)))
    1911             :     {
    1912             :         OSL_FAIL("ScTable::ExtendMerge: invalid column number");
    1913           0 :         return false;
    1914             :     }
    1915       10424 :     bool bFound = false;
    1916       10424 :     SCCOL nOldEndX = rEndCol;
    1917       10424 :     SCROW nOldEndY = rEndRow;
    1918       22804 :     for (SCCOL i=nStartCol; i<=nOldEndX; i++)
    1919       12380 :         bFound |= aCol[i].ExtendMerge( i, nStartRow, nOldEndY, rEndCol, rEndRow, bRefresh );
    1920       10424 :     return bFound;
    1921             : }
    1922             : 
    1923         138 : bool ScTable::IsBlockEmpty( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool bIgnoreNotes ) const
    1924             : {
    1925         138 :     if (!(ValidCol(nCol1) && ValidCol(nCol2)))
    1926             :     {
    1927             :         OSL_FAIL("ScTable::IsBlockEmpty: invalid column number");
    1928           0 :         return false;
    1929             :     }
    1930         138 :     bool bEmpty = true;
    1931         777 :     for (SCCOL i=nCol1; i<=nCol2 && bEmpty; i++)
    1932             :     {
    1933         639 :         bEmpty = aCol[i].IsEmptyBlock( nRow1, nRow2 );
    1934         639 :         if (!bIgnoreNotes && bEmpty)
    1935             :         {
    1936         417 :             bEmpty = aCol[i].IsNotesEmptyBlock(nRow1, nRow2);
    1937             :         }
    1938             :     }
    1939         138 :     return bEmpty;
    1940             : }
    1941             : 
    1942      417047 : SCSIZE ScTable::FillMaxRot( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2,
    1943             :                             SCCOL nCol, SCROW nAttrRow1, SCROW nAttrRow2, SCSIZE nArrY,
    1944             :                             const ScPatternAttr* pPattern, const SfxItemSet* pCondSet )
    1945             : {
    1946             :     //  Return value = new nArrY
    1947             : 
    1948      417047 :     sal_uInt8 nRotDir = pPattern->GetRotateDir( pCondSet );
    1949      417047 :     if ( nRotDir != SC_ROTDIR_NONE )
    1950             :     {
    1951        1274 :         bool bHit = true;
    1952        1274 :         if ( nCol+1 < nX1 )                             // column to the left
    1953           0 :             bHit = ( nRotDir != SC_ROTDIR_LEFT );
    1954        1274 :         else if ( nCol > nX2+1 )                        // column to the right
    1955           0 :             bHit = ( nRotDir != SC_ROTDIR_RIGHT );      // SC_ROTDIR_STANDARD may now also be extended to the left
    1956             : 
    1957        1274 :         if ( bHit )
    1958             :         {
    1959        1274 :             double nFactor = 0.0;
    1960        1274 :             if ( nCol > nX2+1 )
    1961             :             {
    1962             :                 long nRotVal = static_cast<const SfxInt32Item&>( pPattern->
    1963           0 :                         GetItem( ATTR_ROTATE_VALUE, pCondSet )).GetValue();
    1964           0 :                 double nRealOrient = nRotVal * F_PI18000;   // 1/100 Grad
    1965           0 :                 double nCos = cos( nRealOrient );
    1966           0 :                 double nSin = sin( nRealOrient );
    1967             :                 //TODO: limit !!!
    1968             :                 //TODO: additional factor for varying PPT X/Y !!!
    1969             : 
    1970             :                 // for SC_ROTDIR_LEFT this gives a negative value,
    1971             :                 // if the Modus is considered
    1972           0 :                 nFactor = -fabs( nCos / nSin );
    1973             :             }
    1974             : 
    1975        6548 :             for ( SCROW nRow = nAttrRow1; nRow <= nAttrRow2; nRow++ )
    1976             :             {
    1977        5274 :                 if (!RowHidden(nRow))
    1978             :                 {
    1979        5274 :                     bool bHitOne = true;
    1980        5274 :                     if ( nCol > nX2+1 )
    1981             :                     {
    1982             :                         // Does the rotated cell extend into the visable range?
    1983             : 
    1984           0 :                         SCCOL nTouchedCol = nCol;
    1985           0 :                         long nWidth = static_cast<long>(mpRowHeights->getValue(nRow) * nFactor);
    1986             :                         OSL_ENSURE(nWidth <= 0, "Wrong direction");
    1987           0 :                         while ( nWidth < 0 && nTouchedCol > 0 )
    1988             :                         {
    1989           0 :                             --nTouchedCol;
    1990           0 :                             nWidth += GetColWidth( nTouchedCol );
    1991             :                         }
    1992           0 :                         if ( nTouchedCol > nX2 )
    1993           0 :                             bHitOne = false;
    1994             :                     }
    1995             : 
    1996        5274 :                     if (bHitOne)
    1997             :                     {
    1998       14559 :                         while ( nArrY<nArrCount && pRowInfo[nArrY].nRowNo < nRow )
    1999        4011 :                             ++nArrY;
    2000        5274 :                         if ( nArrY<nArrCount && pRowInfo[nArrY].nRowNo == nRow )
    2001        5274 :                             pRowInfo[nArrY].nRotMaxCol = nCol;
    2002             :                     }
    2003             :                 }
    2004             :             }
    2005             :         }
    2006             :     }
    2007             : 
    2008      417047 :     return nArrY;
    2009             : }
    2010             : 
    2011         400 : void ScTable::FindMaxRotCol( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2 )
    2012             : {
    2013         400 :     if ( !pColWidth || !mpRowHeights || !pColFlags || !pRowFlags )
    2014             :     {
    2015             :         OSL_FAIL( "Row/column info missing" );
    2016         400 :         return;
    2017             :     }
    2018             : 
    2019             :     //  nRotMaxCol is initalized to SC_ROTMAX_NONE, nRowNo is already set
    2020             : 
    2021         400 :     SCROW nY1 = pRowInfo[0].nRowNo;
    2022         400 :     SCROW nY2 = pRowInfo[nArrCount-1].nRowNo;
    2023             : 
    2024      410000 :     for (SCCOL nCol=0; nCol<=MAXCOL; nCol++)
    2025             :     {
    2026      409600 :         if (!ColHidden(nCol))
    2027             :         {
    2028      409600 :             SCSIZE nArrY = 0;
    2029      409600 :             ScDocAttrIterator aIter( pDocument, nTab, nCol, nY1, nCol, nY2 );
    2030             :             SCCOL nAttrCol;
    2031             :             SCROW nAttrRow1, nAttrRow2;
    2032      409600 :             const ScPatternAttr* pPattern = aIter.GetNext( nAttrCol, nAttrRow1, nAttrRow2 );
    2033     1229816 :             while ( pPattern )
    2034             :             {
    2035             :                 const SfxPoolItem* pCondItem;
    2036      410616 :                 if ( pPattern->GetItemSet().GetItemState( ATTR_CONDITIONAL, true, &pCondItem )
    2037             :                         == SfxItemState::SET )
    2038             :                 {
    2039             :                     //  Run through all formats, so that each cell does not have to be
    2040             :                     //  handled individually
    2041             : 
    2042        6428 :                     const std::vector<sal_uInt32>& rCondFormatData = static_cast<const ScCondFormatItem*>(pCondItem)->GetCondFormatData();
    2043        6428 :                     ScStyleSheetPool* pStylePool = pDocument->GetStyleSheetPool();
    2044        6428 :                     if (mpCondFormatList && pStylePool && !rCondFormatData.empty())
    2045             :                     {
    2046       12854 :                         for(std::vector<sal_uInt32>::const_iterator itr = rCondFormatData.begin(), itrEnd = rCondFormatData.end();
    2047             :                                 itr != itrEnd; ++itr)
    2048             :                         {
    2049        6427 :                             const ScConditionalFormat* pFormat = mpCondFormatList->GetFormat(*itr);
    2050        6427 :                             if ( pFormat )
    2051             :                             {
    2052        6427 :                                 size_t nEntryCount = pFormat->size();
    2053       12858 :                                 for (size_t nEntry=0; nEntry<nEntryCount; nEntry++)
    2054             :                                 {
    2055        6431 :                                     const ScFormatEntry* pEntry = pFormat->GetEntry(nEntry);
    2056        6431 :                                     if(pEntry->GetType() != condformat::CONDITION)
    2057           0 :                                         continue;
    2058             : 
    2059        6431 :                                     OUString  aStyleName = static_cast<const ScCondFormatEntry*>(pEntry)->GetStyle();
    2060        6431 :                                     if (!aStyleName.isEmpty())
    2061             :                                     {
    2062             :                                         SfxStyleSheetBase* pStyleSheet =
    2063        6431 :                                             pStylePool->Find( aStyleName, SFX_STYLE_FAMILY_PARA );
    2064        6431 :                                         if ( pStyleSheet )
    2065             :                                         {
    2066             :                                             FillMaxRot( pRowInfo, nArrCount, nX1, nX2,
    2067             :                                                     nCol, nAttrRow1, nAttrRow2,
    2068        6431 :                                                     nArrY, pPattern, &pStyleSheet->GetItemSet() );
    2069             :                                             //  not changing nArrY
    2070             :                                         }
    2071             :                                     }
    2072        6431 :                                 }
    2073             :                             }
    2074             :                         }
    2075             :                     }
    2076             :                 }
    2077             : 
    2078             :                 nArrY = FillMaxRot( pRowInfo, nArrCount, nX1, nX2,
    2079             :                                     nCol, nAttrRow1, nAttrRow2,
    2080      410616 :                                     nArrY, pPattern, NULL );
    2081             : 
    2082      410616 :                 pPattern = aIter.GetNext( nAttrCol, nAttrRow1, nAttrRow2 );
    2083      409600 :             }
    2084             :         }
    2085             :     }
    2086             : }
    2087             : 
    2088        4414 : bool ScTable::HasBlockMatrixFragment( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const
    2089             : {
    2090             :     using namespace sc;
    2091             : 
    2092        4414 :     sal_uInt16 nEdges = 0;
    2093             : 
    2094        4414 :     if ( nCol1 == nCol2 )
    2095             :     {   // left and right column
    2096        3943 :         const sal_uInt16 n = MatrixEdgeLeft | MatrixEdgeRight;
    2097        3943 :         nEdges = aCol[nCol1].GetBlockMatrixEdges( nRow1, nRow2, n );
    2098             :         // not (4 and 16) or 1 or 32
    2099        3943 :         if (nEdges && (((nEdges & n) != n) || (nEdges & (MatrixEdgeInside|MatrixEdgeOpen))))
    2100           0 :             return true;        // left or right edge is missing or open
    2101             :     }
    2102             :     else
    2103             :     {   // left column
    2104         471 :         nEdges = aCol[nCol1].GetBlockMatrixEdges(nRow1, nRow2, MatrixEdgeLeft);
    2105             :         // not 4 or 1 or 32
    2106         471 :         if (nEdges && (((nEdges & MatrixEdgeLeft) != MatrixEdgeLeft) || (nEdges & (MatrixEdgeInside|MatrixEdgeOpen))))
    2107           0 :             return true;        // left edge missing or open
    2108             :         // right column
    2109         471 :         nEdges = aCol[nCol2].GetBlockMatrixEdges(nRow1, nRow2, MatrixEdgeRight);
    2110             :         // not 16 or 1 or 32
    2111         471 :         if (nEdges && (((nEdges & MatrixEdgeRight) != MatrixEdgeRight) || (nEdges & (MatrixEdgeInside|MatrixEdgeOpen))))
    2112           0 :             return true;        // right edge is missing or open
    2113             :     }
    2114             : 
    2115        4414 :     if ( nRow1 == nRow2 )
    2116             :     {   // Row on top and on bottom
    2117        3876 :         bool bOpen = false;
    2118        3876 :         const sal_uInt16 n = MatrixEdgeBottom | MatrixEdgeTop;
    2119        7784 :         for ( SCCOL i=nCol1; i<=nCol2; i++)
    2120             :         {
    2121        3908 :             nEdges = aCol[i].GetBlockMatrixEdges( nRow1, nRow1, n );
    2122        3908 :             if ( nEdges )
    2123             :             {
    2124           0 :                 if ( (nEdges & n) != n )
    2125           0 :                     return true;        // Top or bottom edge missing
    2126           0 :                 if (nEdges & MatrixEdgeLeft)
    2127           0 :                     bOpen = true;       // left edge open, continue
    2128           0 :                 else if ( !bOpen )
    2129           0 :                     return true;        // Something exist that has not been opened
    2130           0 :                 if (nEdges & MatrixEdgeRight)
    2131           0 :                     bOpen = false;      // Close right edge
    2132             :             }
    2133             :         }
    2134        3876 :         if ( bOpen )
    2135           0 :             return true;                // continue
    2136             :     }
    2137             :     else
    2138             :     {
    2139             :         sal_uInt16 j, n;
    2140             :         SCROW nR;
    2141             :         // first rop row, then bottom row
    2142        1614 :         for ( j=0, nR=nRow1, n=8; j<2; j++, nR=nRow2, n=2 )
    2143             :         {
    2144        1076 :             bool bOpen = false;
    2145      113788 :             for ( SCCOL i=nCol1; i<=nCol2; i++)
    2146             :             {
    2147      112712 :                 nEdges = aCol[i].GetBlockMatrixEdges( nR, nR, n );
    2148      112712 :                 if ( nEdges )
    2149             :                 {
    2150             :                     // in top row no top edge respectively
    2151             :                     // in bottom row no bottom edge
    2152           2 :                     if ( (nEdges & n) != n )
    2153           0 :                         return true;
    2154           2 :                     if (nEdges & MatrixEdgeLeft)
    2155           2 :                         bOpen = true;       // open left edge, continue
    2156           0 :                     else if ( !bOpen )
    2157           0 :                         return true;        // Something exist that has not been opened
    2158           2 :                     if (nEdges & MatrixEdgeRight)
    2159           2 :                         bOpen = false;      // Close right edge
    2160             :                 }
    2161             :             }
    2162        1076 :             if ( bOpen )
    2163           0 :                 return true;                // continue
    2164             :         }
    2165             :     }
    2166        4414 :     return false;
    2167             : }
    2168             : 
    2169          61 : bool ScTable::HasSelectionMatrixFragment( const ScMarkData& rMark ) const
    2170             : {
    2171          61 :     std::vector<sc::ColRowSpan> aSpans = rMark.GetMarkedColSpans();
    2172             : 
    2173         122 :     for ( size_t i=0; i<aSpans.size(); i++ )
    2174             :     {
    2175         435 :         for ( SCCOLROW j=aSpans[i].mnStart; j<aSpans[i].mnEnd; j++ )
    2176             :         {
    2177         374 :             if ( aCol[j].HasSelectionMatrixFragment(rMark) )
    2178           0 :                 return true;
    2179             :         }
    2180             :     }
    2181          61 :     return false;
    2182             : }
    2183             : 
    2184        4400 : bool ScTable::IsBlockEditable( SCCOL nCol1, SCROW nRow1, SCCOL nCol2,
    2185             :             SCROW nRow2, bool* pOnlyNotBecauseOfMatrix /* = NULL */ ) const
    2186             : {
    2187        4400 :     if ( !ValidColRow( nCol2, nRow2 ) )
    2188             :     {
    2189             :         OSL_FAIL("IsBlockEditable: invalid column or row");
    2190           0 :         if (pOnlyNotBecauseOfMatrix)
    2191           0 :             *pOnlyNotBecauseOfMatrix = false;
    2192           0 :         return false;
    2193             :     }
    2194             : 
    2195        4400 :     bool bIsEditable = true;
    2196        4400 :     if ( nLockCount )
    2197           0 :         bIsEditable = false;
    2198        4400 :     else if ( IsProtected() && !pDocument->IsScenario(nTab) )
    2199             :     {
    2200           0 :         bIsEditable = !HasAttrib( nCol1, nRow1, nCol2, nRow2, HASATTR_PROTECTED );
    2201           0 :         if (!bIsEditable)
    2202             :         {
    2203             :             // An enhanced protection permission may override the attribute.
    2204           0 :             if (pTabProtection)
    2205           0 :                 bIsEditable = pTabProtection->isBlockEditable( ScRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab));
    2206             :         }
    2207           0 :         if (bIsEditable)
    2208             :         {
    2209             :             // If Sheet is protected and cells are not protected then
    2210             :             // check the active scenario protect flag if this range is
    2211             :             // on the active scenario range. Note the 'copy back' must also
    2212             :             // be set to apply protection.
    2213           0 :             sal_uInt16 nScenTab = nTab+1;
    2214           0 :             while(pDocument->IsScenario(nScenTab))
    2215             :             {
    2216           0 :                 ScRange aEditRange(nCol1, nRow1, nScenTab, nCol2, nRow2, nScenTab);
    2217           0 :                 if(pDocument->IsActiveScenario(nScenTab) && pDocument->HasScenarioRange(nScenTab, aEditRange))
    2218             :                 {
    2219             :                     sal_uInt16 nFlags;
    2220           0 :                     pDocument->GetScenarioFlags(nScenTab,nFlags);
    2221           0 :                     bIsEditable = !((nFlags & SC_SCENARIO_PROTECT) && (nFlags & SC_SCENARIO_TWOWAY));
    2222           0 :                     break;
    2223             :                 }
    2224           0 :                 nScenTab++;
    2225             :             }
    2226             :         }
    2227             :     }
    2228        4400 :     else if (pDocument->IsScenario(nTab))
    2229             :     {
    2230             :         // Determine if the preceding sheet is protected
    2231           0 :         SCTAB nActualTab = nTab;
    2232           0 :         do
    2233             :         {
    2234           0 :             nActualTab--;
    2235             :         }
    2236           0 :         while(pDocument->IsScenario(nActualTab));
    2237             : 
    2238           0 :         if(pDocument->IsTabProtected(nActualTab))
    2239             :         {
    2240           0 :             ScRange aEditRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab);
    2241           0 :             if(pDocument->HasScenarioRange(nTab, aEditRange))
    2242             :             {
    2243             :                 sal_uInt16 nFlags;
    2244           0 :                 pDocument->GetScenarioFlags(nTab,nFlags);
    2245           0 :                 bIsEditable = !(nFlags & SC_SCENARIO_PROTECT);
    2246             :             }
    2247             :         }
    2248             :     }
    2249        4400 :     if ( bIsEditable )
    2250             :     {
    2251        4400 :         if ( HasBlockMatrixFragment( nCol1, nRow1, nCol2, nRow2 ) )
    2252             :         {
    2253           0 :             bIsEditable = false;
    2254           0 :             if ( pOnlyNotBecauseOfMatrix )
    2255           0 :                 *pOnlyNotBecauseOfMatrix = true;
    2256             :         }
    2257        4400 :         else if ( pOnlyNotBecauseOfMatrix )
    2258        3735 :             *pOnlyNotBecauseOfMatrix = false;
    2259             :     }
    2260           0 :     else if ( pOnlyNotBecauseOfMatrix )
    2261           0 :         *pOnlyNotBecauseOfMatrix = false;
    2262        4400 :     return bIsEditable;
    2263             : }
    2264             : 
    2265          61 : bool ScTable::IsSelectionEditable( const ScMarkData& rMark,
    2266             :             bool* pOnlyNotBecauseOfMatrix /* = NULL */ ) const
    2267             : {
    2268          61 :     bool bIsEditable = true;
    2269          61 :     if ( nLockCount )
    2270           0 :         bIsEditable = false;
    2271          61 :     else if ( IsProtected() && !pDocument->IsScenario(nTab) )
    2272             :     {
    2273           0 :         ScRangeList aRanges;
    2274           0 :         rMark.FillRangeListWithMarks( &aRanges, false );
    2275           0 :         bIsEditable = !HasAttribSelection( rMark, HASATTR_PROTECTED );
    2276           0 :         if (!bIsEditable)
    2277             :         {
    2278             :             // An enhanced protection permission may override the attribute.
    2279           0 :             if (pTabProtection)
    2280           0 :                 bIsEditable = pTabProtection->isSelectionEditable( aRanges);
    2281             :         }
    2282           0 :         if (bIsEditable)
    2283             :         {
    2284             :             // If Sheet is protected and cells are not protected then
    2285             :             // check the active scenario protect flag if this area is
    2286             :             // in the active scenario range.
    2287           0 :             SCTAB nScenTab = nTab+1;
    2288           0 :             while(pDocument->IsScenario(nScenTab) && bIsEditable)
    2289             :             {
    2290           0 :                 if(pDocument->IsActiveScenario(nScenTab))
    2291             :                 {
    2292           0 :                     for (size_t i=0, nRange = aRanges.size(); (i < nRange) && bIsEditable; i++ )
    2293             :                     {
    2294           0 :                         ScRange aRange = *aRanges[ i ];
    2295           0 :                         if(pDocument->HasScenarioRange(nScenTab, aRange))
    2296             :                         {
    2297             :                             sal_uInt16 nFlags;
    2298           0 :                             pDocument->GetScenarioFlags(nScenTab,nFlags);
    2299           0 :                             bIsEditable = !((nFlags & SC_SCENARIO_PROTECT) && (nFlags & SC_SCENARIO_TWOWAY));
    2300             :                         }
    2301             :                     }
    2302             :                 }
    2303           0 :                 nScenTab++;
    2304             :             }
    2305           0 :         }
    2306             :     }
    2307          61 :     else if (pDocument->IsScenario(nTab))
    2308             :     {
    2309             :         // Determine if the preceding sheet is protected
    2310           0 :         SCTAB nActualTab = nTab;
    2311           0 :         do
    2312             :         {
    2313           0 :             nActualTab--;
    2314             :         }
    2315           0 :         while(pDocument->IsScenario(nActualTab));
    2316             : 
    2317           0 :         if(pDocument->IsTabProtected(nActualTab))
    2318             :         {
    2319           0 :             ScRangeList aRanges;
    2320           0 :             rMark.FillRangeListWithMarks( &aRanges, false );
    2321           0 :             for (size_t i = 0, nRange = aRanges.size(); (i < nRange) && bIsEditable; i++)
    2322             :             {
    2323           0 :                 ScRange aRange = *aRanges[ i ];
    2324           0 :                 if(pDocument->HasScenarioRange(nTab, aRange))
    2325             :                 {
    2326             :                     sal_uInt16 nFlags;
    2327           0 :                     pDocument->GetScenarioFlags(nTab,nFlags);
    2328           0 :                     bIsEditable = !(nFlags & SC_SCENARIO_PROTECT);
    2329             :                 }
    2330           0 :             }
    2331             :         }
    2332             :     }
    2333          61 :     if ( bIsEditable )
    2334             :     {
    2335          61 :         if ( HasSelectionMatrixFragment( rMark ) )
    2336             :         {
    2337           0 :             bIsEditable = false;
    2338           0 :             if ( pOnlyNotBecauseOfMatrix )
    2339           0 :                 *pOnlyNotBecauseOfMatrix = true;
    2340             :         }
    2341          61 :         else if ( pOnlyNotBecauseOfMatrix )
    2342          61 :             *pOnlyNotBecauseOfMatrix = false;
    2343             :     }
    2344           0 :     else if ( pOnlyNotBecauseOfMatrix )
    2345           0 :         *pOnlyNotBecauseOfMatrix = false;
    2346          61 :     return bIsEditable;
    2347             : }
    2348             : 
    2349           0 : void ScTable::LockTable()
    2350             : {
    2351           0 :     ++nLockCount;
    2352           0 : }
    2353             : 
    2354           0 : void ScTable::UnlockTable()
    2355             : {
    2356           0 :     if (nLockCount)
    2357           0 :         --nLockCount;
    2358             :     else
    2359             :     {
    2360             :         OSL_FAIL("UnlockTable without LockTable");
    2361             :     }
    2362           0 : }
    2363             : 
    2364         296 : void ScTable::MergeSelectionPattern( ScMergePatternState& rState, const ScMarkData& rMark, bool bDeep ) const
    2365             : {
    2366      303400 :     for (SCCOL i=0; i<=MAXCOL; i++)
    2367      303104 :         aCol[i].MergeSelectionPattern( rState, rMark, bDeep );
    2368         296 : }
    2369             : 
    2370       16764 : void ScTable::MergePatternArea( ScMergePatternState& rState, SCCOL nCol1, SCROW nRow1,
    2371             :                                                     SCCOL nCol2, SCROW nRow2, bool bDeep ) const
    2372             : {
    2373       89136 :     for (SCCOL i=nCol1; i<=nCol2; i++)
    2374       72372 :         aCol[i].MergePatternArea( rState, nRow1, nRow2, bDeep );
    2375       16764 : }
    2376             : 
    2377          60 : void ScTable::MergeBlockFrame( SvxBoxItem* pLineOuter, SvxBoxInfoItem* pLineInner, ScLineFlags& rFlags,
    2378             :                     SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow ) const
    2379             : {
    2380          60 :     if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
    2381             :     {
    2382          60 :         PutInOrder(nStartCol, nEndCol);
    2383          60 :         PutInOrder(nStartRow, nEndRow);
    2384         266 :         for (SCCOL i=nStartCol; i<=nEndCol; i++)
    2385         206 :             aCol[i].MergeBlockFrame( pLineOuter, pLineInner, rFlags,
    2386         412 :                                     nStartRow, nEndRow, (i==nStartCol), nEndCol-i );
    2387             :     }
    2388          60 : }
    2389             : 
    2390         974 : void ScTable::ApplyBlockFrame( const SvxBoxItem* pLineOuter, const SvxBoxInfoItem* pLineInner,
    2391             :                     SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
    2392             : {
    2393         974 :     if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
    2394             :     {
    2395         974 :         PutInOrder(nStartCol, nEndCol);
    2396         974 :         PutInOrder(nStartRow, nEndRow);
    2397        2882 :         for (SCCOL i=nStartCol; i<=nEndCol; i++)
    2398        1908 :             aCol[i].ApplyBlockFrame( pLineOuter, pLineInner,
    2399        3816 :                                     nStartRow, nEndRow, (i==nStartCol), nEndCol-i );
    2400             :     }
    2401         974 : }
    2402             : 
    2403          12 : void ScTable::ApplyPattern( SCCOL nCol, SCROW nRow, const ScPatternAttr& rAttr )
    2404             : {
    2405          12 :     if (ValidColRow(nCol,nRow))
    2406          12 :         aCol[nCol].ApplyPattern( nRow, rAttr );
    2407          12 : }
    2408             : 
    2409        2028 : void ScTable::ApplyPatternArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
    2410             :                                      const ScPatternAttr& rAttr, ScEditDataArray* pDataArray )
    2411             : {
    2412        2028 :     if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
    2413             :     {
    2414        2028 :         PutInOrder(nStartCol, nEndCol);
    2415        2028 :         PutInOrder(nStartRow, nEndRow);
    2416      115643 :         for (SCCOL i = nStartCol; i <= nEndCol; i++)
    2417      113615 :             aCol[i].ApplyPatternArea(nStartRow, nEndRow, rAttr, pDataArray);
    2418             :     }
    2419        2028 : }
    2420             : 
    2421           0 : void ScTable::ApplyPatternIfNumberformatIncompatible( const ScRange& rRange,
    2422             :         const ScPatternAttr& rPattern, short nNewType )
    2423             : {
    2424           0 :     SCCOL nEndCol = rRange.aEnd.Col();
    2425           0 :     for ( SCCOL nCol = rRange.aStart.Col(); nCol <= nEndCol; nCol++ )
    2426             :     {
    2427           0 :         aCol[nCol].ApplyPatternIfNumberformatIncompatible( rRange, rPattern, nNewType );
    2428             :     }
    2429           0 : }
    2430             : 
    2431         182 : void ScTable::AddCondFormatData( const ScRangeList& rRange, sal_uInt32 nIndex )
    2432             : {
    2433         182 :     size_t n = rRange.size();
    2434         368 :     for(size_t i = 0; i < n; ++i)
    2435             :     {
    2436         186 :         const ScRange* pRange = rRange[i];
    2437         186 :         SCCOL nColStart = pRange->aStart.Col();
    2438         186 :         SCCOL nColEnd = pRange->aEnd.Col();
    2439         186 :         SCROW nRowStart = pRange->aStart.Row();
    2440         186 :         SCROW nRowEnd = pRange->aEnd.Row();
    2441        4529 :         for(SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol)
    2442             :         {
    2443        4343 :             aCol[nCol].AddCondFormat(nRowStart, nRowEnd, nIndex);
    2444             :         }
    2445             :     }
    2446         182 : }
    2447             : 
    2448          10 : void ScTable::RemoveCondFormatData( const ScRangeList& rRange, sal_uInt32 nIndex )
    2449             : {
    2450          10 :     size_t n = rRange.size();
    2451          20 :     for(size_t i = 0; i < n; ++i)
    2452             :     {
    2453          10 :         const ScRange* pRange = rRange[i];
    2454          10 :         SCCOL nColStart = pRange->aStart.Col();
    2455          10 :         SCCOL nColEnd = pRange->aEnd.Col();
    2456          10 :         SCROW nRowStart = pRange->aStart.Row();
    2457          10 :         SCROW nRowEnd = pRange->aEnd.Row();
    2458        2075 :         for(SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol)
    2459             :         {
    2460        2065 :             aCol[nCol].RemoveCondFormat(nRowStart, nRowEnd, nIndex);
    2461             :         }
    2462             :     }
    2463          10 : }
    2464             : 
    2465           2 : void ScTable::ApplyStyle( SCCOL nCol, SCROW nRow, const ScStyleSheet& rStyle )
    2466             : {
    2467           2 :     if (ValidColRow(nCol,nRow))
    2468           2 :         aCol[nCol].ApplyStyle( nRow, rStyle );
    2469           2 : }
    2470             : 
    2471        2443 : void ScTable::ApplyStyleArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, const ScStyleSheet& rStyle )
    2472             : {
    2473        2443 :     if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
    2474             :     {
    2475        2443 :         PutInOrder(nStartCol, nEndCol);
    2476        2443 :         PutInOrder(nStartRow, nEndRow);
    2477      395458 :         for (SCCOL i = nStartCol; i <= nEndCol; i++)
    2478      393015 :             aCol[i].ApplyStyleArea(nStartRow, nEndRow, rStyle);
    2479             :     }
    2480        2443 : }
    2481             : 
    2482         287 : void ScTable::ApplySelectionStyle(const ScStyleSheet& rStyle, const ScMarkData& rMark)
    2483             : {
    2484      294175 :     for (SCCOL i=0; i<=MAXCOL; i++)
    2485      293888 :         aCol[i].ApplySelectionStyle( rStyle, rMark );
    2486         287 : }
    2487             : 
    2488           0 : void ScTable::ApplySelectionLineStyle( const ScMarkData& rMark,
    2489             :                             const ::editeng::SvxBorderLine* pLine, bool bColorOnly )
    2490             : {
    2491           0 :     if ( bColorOnly && !pLine )
    2492           0 :         return;
    2493             : 
    2494           0 :     for (SCCOL i=0; i<=MAXCOL; i++)
    2495           0 :         aCol[i].ApplySelectionLineStyle( rMark, pLine, bColorOnly );
    2496             : }
    2497             : 
    2498          92 : const ScStyleSheet* ScTable::GetStyle( SCCOL nCol, SCROW nRow ) const
    2499             : {
    2500          92 :     if (ValidColRow(nCol, nRow))
    2501          92 :         return aCol[nCol].GetStyle(nRow);
    2502             :     else
    2503           0 :         return NULL;
    2504             : }
    2505             : 
    2506          22 : const ScStyleSheet* ScTable::GetSelectionStyle( const ScMarkData& rMark, bool& rFound ) const
    2507             : {
    2508          22 :     rFound = false;
    2509             : 
    2510          22 :     bool    bEqual = true;
    2511             :     bool    bColFound;
    2512             : 
    2513          22 :     const ScStyleSheet* pStyle = NULL;
    2514             :     const ScStyleSheet* pNewStyle;
    2515             : 
    2516       22550 :     for (SCCOL i=0; i<=MAXCOL && bEqual; i++)
    2517       22528 :         if (rMark.HasMultiMarks(i))
    2518             :         {
    2519       22528 :             pNewStyle = aCol[i].GetSelectionStyle( rMark, bColFound );
    2520       22528 :             if (bColFound)
    2521             :             {
    2522       22528 :                 rFound = true;
    2523       22528 :                 if ( !pNewStyle || ( pStyle && pNewStyle != pStyle ) )
    2524           0 :                     bEqual = false;
    2525       22528 :                 pStyle = pNewStyle;
    2526             :             }
    2527             :         }
    2528             : 
    2529          22 :     return bEqual ? pStyle : NULL;
    2530             : }
    2531             : 
    2532         194 : const ScStyleSheet* ScTable::GetAreaStyle( bool& rFound, SCCOL nCol1, SCROW nRow1,
    2533             :                                            SCCOL nCol2, SCROW nRow2 ) const
    2534             : {
    2535         194 :     rFound = false;
    2536             : 
    2537         194 :     bool    bEqual = true;
    2538             :     bool    bColFound;
    2539             : 
    2540         194 :     const ScStyleSheet* pStyle = NULL;
    2541             :     const ScStyleSheet* pNewStyle;
    2542             : 
    2543       45534 :     for (SCCOL i=nCol1; i<=nCol2 && bEqual; i++)
    2544             :     {
    2545       45340 :         pNewStyle = aCol[i].GetAreaStyle(bColFound, nRow1, nRow2);
    2546       45340 :         if (bColFound)
    2547             :         {
    2548       45340 :             rFound = true;
    2549       45340 :             if ( !pNewStyle || ( pStyle && pNewStyle != pStyle ) )
    2550           0 :                 bEqual = false;
    2551       45340 :             pStyle = pNewStyle;
    2552             :         }
    2553             :     }
    2554             : 
    2555         194 :     return bEqual ? pStyle : NULL;
    2556             : }
    2557             : 
    2558           0 : bool ScTable::IsStyleSheetUsed( const ScStyleSheet& rStyle, bool bGatherAllStyles ) const
    2559             : {
    2560           0 :     bool bIsUsed = false;
    2561             : 
    2562           0 :     for ( SCCOL i=0; i<=MAXCOL; i++ )
    2563             :     {
    2564           0 :         if ( aCol[i].IsStyleSheetUsed( rStyle, bGatherAllStyles ) )
    2565             :         {
    2566           0 :             if ( !bGatherAllStyles )
    2567           0 :                 return true;
    2568           0 :             bIsUsed = true;
    2569             :         }
    2570             :     }
    2571             : 
    2572           0 :     return bIsUsed;
    2573             : }
    2574             : 
    2575        6780 : void ScTable::StyleSheetChanged( const SfxStyleSheetBase* pStyleSheet, bool bRemoved,
    2576             :                                 OutputDevice* pDev,
    2577             :                                 double nPPTX, double nPPTY,
    2578             :                                 const Fraction& rZoomX, const Fraction& rZoomY )
    2579             : {
    2580        6780 :     ScFlatBoolRowSegments aUsedRows;
    2581     6949500 :     for (SCCOL i = 0; i <= MAXCOL; ++i)
    2582     6942720 :         aCol[i].FindStyleSheet(pStyleSheet, aUsedRows, bRemoved);
    2583             : 
    2584       13560 :     sc::RowHeightContext aCxt(nPPTX, nPPTY, rZoomX, rZoomY, pDev);
    2585        6780 :     SCROW nRow = 0;
    2586       20340 :     while (nRow <= MAXROW)
    2587             :     {
    2588             :         ScFlatBoolRowSegments::RangeData aData;
    2589        6780 :         if (!aUsedRows.getRangeData(nRow, aData))
    2590             :             // search failed!
    2591        6780 :             return;
    2592             : 
    2593        6780 :         SCROW nEndRow = aData.mnRow2;
    2594        6780 :         if (aData.mbValue)
    2595        2309 :             SetOptimalHeight(aCxt, nRow, nEndRow);
    2596             : 
    2597        6780 :         nRow = nEndRow + 1;
    2598        6780 :     }
    2599             : }
    2600             : 
    2601        1218 : bool ScTable::ApplyFlags( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
    2602             :                           sal_Int16 nFlags )
    2603             : {
    2604        1218 :     bool bChanged = false;
    2605        1218 :     if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
    2606        6704 :         for (SCCOL i = nStartCol; i <= nEndCol; i++)
    2607        5486 :             bChanged |= aCol[i].ApplyFlags(nStartRow, nEndRow, nFlags);
    2608        1218 :     return bChanged;
    2609             : }
    2610             : 
    2611         353 : bool ScTable::RemoveFlags( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
    2612             :                            sal_Int16 nFlags )
    2613             : {
    2614         353 :     bool bChanged = false;
    2615         353 :     if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
    2616       18538 :         for (SCCOL i = nStartCol; i <= nEndCol; i++)
    2617       18185 :             bChanged |= aCol[i].RemoveFlags(nStartRow, nEndRow, nFlags);
    2618         353 :     return bChanged;
    2619             : }
    2620             : 
    2621           6 : void ScTable::SetPattern( SCCOL nCol, SCROW nRow, const ScPatternAttr& rAttr, bool bPutToPool )
    2622             : {
    2623           6 :     if (ValidColRow(nCol,nRow))
    2624           6 :         aCol[nCol].SetPattern( nRow, rAttr, bPutToPool );
    2625           6 : }
    2626             : 
    2627        2874 : void ScTable::ApplyAttr( SCCOL nCol, SCROW nRow, const SfxPoolItem& rAttr )
    2628             : {
    2629        2874 :     if (ValidColRow(nCol,nRow))
    2630        2874 :         aCol[nCol].ApplyAttr( nRow, rAttr );
    2631        2874 : }
    2632             : 
    2633         206 : void ScTable::ApplySelectionCache( SfxItemPoolCache* pCache, const ScMarkData& rMark,
    2634             :                                    ScEditDataArray* pDataArray )
    2635             : {
    2636      211150 :     for (SCCOL i=0; i<=MAXCOL; i++)
    2637      210944 :         aCol[i].ApplySelectionCache( pCache, rMark, pDataArray );
    2638         206 : }
    2639             : 
    2640           6 : void ScTable::ChangeSelectionIndent( bool bIncrement, const ScMarkData& rMark )
    2641             : {
    2642        6150 :     for (SCCOL i=0; i<=MAXCOL; i++)
    2643        6144 :         aCol[i].ChangeSelectionIndent( bIncrement, rMark );
    2644           6 : }
    2645             : 
    2646           0 : void ScTable::ClearSelectionItems( const sal_uInt16* pWhich, const ScMarkData& rMark )
    2647             : {
    2648           0 :     for (SCCOL i=0; i<=MAXCOL; i++)
    2649           0 :         aCol[i].ClearSelectionItems( pWhich, rMark );
    2650           0 : }
    2651             : 
    2652             : //  Column widths / Row heights
    2653             : 
    2654       17656 : void ScTable::SetColWidth( SCCOL nCol, sal_uInt16 nNewWidth )
    2655             : {
    2656       17656 :     if (ValidCol(nCol) && pColWidth)
    2657             :     {
    2658       17656 :         if (!nNewWidth)
    2659             :         {
    2660           0 :             nNewWidth = STD_COL_WIDTH;
    2661             :         }
    2662             : 
    2663       17656 :         if ( nNewWidth != pColWidth[nCol] )
    2664             :         {
    2665       11872 :             pColWidth[nCol] = nNewWidth;
    2666       11872 :             InvalidatePageBreaks();
    2667             :         }
    2668             :     }
    2669             :     else
    2670             :     {
    2671             :         OSL_FAIL("Invalid column number or no widths");
    2672             :     }
    2673       17656 : }
    2674             : 
    2675      504832 : void ScTable::SetColWidthOnly( SCCOL nCol, sal_uInt16 nNewWidth )
    2676             : {
    2677      504832 :     if (!ValidCol(nCol) || !pColWidth)
    2678      504832 :         return;
    2679             : 
    2680      504832 :     if (!nNewWidth)
    2681           0 :         nNewWidth = STD_COL_WIDTH;
    2682             : 
    2683      504832 :     if (nNewWidth != pColWidth[nCol])
    2684      486405 :         pColWidth[nCol] = nNewWidth;
    2685             : }
    2686             : 
    2687           1 : void ScTable::SetRowHeight( SCROW nRow, sal_uInt16 nNewHeight )
    2688             : {
    2689           1 :     if (ValidRow(nRow) && mpRowHeights)
    2690             :     {
    2691           1 :         if (!nNewHeight)
    2692             :         {
    2693             :             OSL_FAIL("SetRowHeight: Row height zero");
    2694           0 :             nNewHeight = ScGlobal::nStdRowHeight;
    2695             :         }
    2696             : 
    2697           1 :         sal_uInt16 nOldHeight = mpRowHeights->getValue(nRow);
    2698           1 :         if ( nNewHeight != nOldHeight )
    2699             :         {
    2700           1 :             mpRowHeights->setValue(nRow, nRow, nNewHeight);
    2701           1 :             InvalidatePageBreaks();
    2702             :         }
    2703             :     }
    2704             :     else
    2705             :     {
    2706             :         OSL_FAIL("Invalid row number or no heights");
    2707             :     }
    2708           1 : }
    2709             : 
    2710             : namespace {
    2711             : 
    2712             : /**
    2713             :  * Check if the new pixel size is different from the old size between
    2714             :  * specified ranges.
    2715             :  */
    2716         932 : bool lcl_pixelSizeChanged(
    2717             :     ScFlatUInt16RowSegments& rRowHeights, SCROW nStartRow, SCROW nEndRow,
    2718             :     sal_uInt16 nNewHeight, double nPPTY)
    2719             : {
    2720         932 :     long nNewPix = static_cast<long>(nNewHeight * nPPTY);
    2721             : 
    2722         932 :     ScFlatUInt16RowSegments::ForwardIterator aFwdIter(rRowHeights);
    2723        1762 :     for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
    2724             :     {
    2725             :         sal_uInt16 nHeight;
    2726         936 :         if (!aFwdIter.getValue(nRow, nHeight))
    2727           0 :             break;
    2728             : 
    2729         936 :         if (nHeight != nNewHeight)
    2730             :         {
    2731         114 :             bool bChanged = (nNewPix != static_cast<long>(nHeight * nPPTY));
    2732         114 :             if (bChanged)
    2733         106 :                 return true;
    2734             :         }
    2735             : 
    2736             :         // Skip ahead to the last position of the current range.
    2737         830 :         nRow = aFwdIter.getLastPos();
    2738             :     }
    2739         826 :     return false;
    2740             : }
    2741             : 
    2742             : }
    2743             : 
    2744         932 : bool ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, sal_uInt16 nNewHeight,
    2745             :                                     double /* nPPTX */, double nPPTY )
    2746             : {
    2747         932 :     bool bChanged = false;
    2748         932 :     if (ValidRow(nStartRow) && ValidRow(nEndRow) && mpRowHeights)
    2749             :     {
    2750         932 :         if (!nNewHeight)
    2751             :         {
    2752             :             OSL_FAIL("SetRowHeight: Row height zero");
    2753           0 :             nNewHeight = ScGlobal::nStdRowHeight;
    2754             :         }
    2755             : 
    2756         932 :         bool bSingle = false;   // true = process every row for its own
    2757         932 :         ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
    2758         932 :         if (pDrawLayer)
    2759         811 :             if (pDrawLayer->HasObjectsInRows( nTab, nStartRow, nEndRow ))
    2760          13 :                 bSingle = true;
    2761             : 
    2762         932 :         if (bSingle)
    2763             :         {
    2764             :             ScFlatUInt16RowSegments::RangeData aData;
    2765          39 :             if (mpRowHeights->getRangeData(nStartRow, aData) &&
    2766          22 :                 nNewHeight == aData.mnValue && nEndRow <= aData.mnRow2)
    2767             :             {
    2768           8 :                 bSingle = false;    // no difference in this range
    2769             :             }
    2770             :         }
    2771         932 :         if (bSingle)
    2772             :         {
    2773           5 :             if (nEndRow-nStartRow < 20)
    2774             :             {
    2775           5 :                 if (!bChanged)
    2776           5 :                     bChanged = lcl_pixelSizeChanged(*mpRowHeights, nStartRow, nEndRow, nNewHeight, nPPTY);
    2777             : 
    2778           5 :                 mpRowHeights->setValue(nStartRow, nEndRow, nNewHeight);
    2779             :             }
    2780             :             else
    2781             :             {
    2782           0 :                 SCROW nMid = (nStartRow+nEndRow) / 2;
    2783           0 :                 if (SetRowHeightRange( nStartRow, nMid, nNewHeight, 1.0, 1.0 ))
    2784           0 :                     bChanged = true;
    2785           0 :                 if (SetRowHeightRange( nMid+1, nEndRow, nNewHeight, 1.0, 1.0 ))
    2786           0 :                     bChanged = true;
    2787             :             }
    2788             :         }
    2789             :         else
    2790             :         {
    2791         927 :             if (!bChanged)
    2792         927 :                 bChanged = lcl_pixelSizeChanged(*mpRowHeights, nStartRow, nEndRow, nNewHeight, nPPTY);
    2793             : 
    2794         927 :             mpRowHeights->setValue(nStartRow, nEndRow, nNewHeight);
    2795             :         }
    2796             : 
    2797         932 :         if (bChanged)
    2798         106 :             InvalidatePageBreaks();
    2799             :     }
    2800             :     else
    2801             :     {
    2802             :         OSL_FAIL("Invalid row number or no heights");
    2803             :     }
    2804             : 
    2805         932 :     return bChanged;
    2806             : }
    2807             : 
    2808        5903 : void ScTable::SetRowHeightOnly( SCROW nStartRow, SCROW nEndRow, sal_uInt16 nNewHeight )
    2809             : {
    2810        5903 :     if (!ValidRow(nStartRow) || !ValidRow(nEndRow) || !mpRowHeights)
    2811        5903 :         return;
    2812             : 
    2813        5903 :     if (!nNewHeight)
    2814           0 :         nNewHeight = ScGlobal::nStdRowHeight;
    2815             : 
    2816        5903 :     mpRowHeights->setValue(nStartRow, nEndRow, nNewHeight);
    2817             : }
    2818             : 
    2819         405 : void ScTable::SetManualHeight( SCROW nStartRow, SCROW nEndRow, bool bManual )
    2820             : {
    2821         405 :     if (ValidRow(nStartRow) && ValidRow(nEndRow) && pRowFlags)
    2822             :     {
    2823         405 :         if (bManual)
    2824         405 :             pRowFlags->OrValue( nStartRow, nEndRow, CR_MANUALSIZE);
    2825             :         else
    2826           0 :             pRowFlags->AndValue( nStartRow, nEndRow, sal::static_int_cast<sal_uInt8>(~CR_MANUALSIZE));
    2827             :     }
    2828             :     else
    2829             :     {
    2830             :         OSL_FAIL("Invalid row number or no column flags");
    2831             :     }
    2832         405 : }
    2833             : 
    2834     1089595 : sal_uInt16 ScTable::GetColWidth( SCCOL nCol, bool bHiddenAsZero ) const
    2835             : {
    2836             :     OSL_ENSURE(ValidCol(nCol),"wrong column number");
    2837             : 
    2838     1089595 :     if (ValidCol(nCol) && pColFlags && pColWidth)
    2839             :     {
    2840     1089595 :         if (bHiddenAsZero && ColHidden(nCol))
    2841        1447 :             return 0;
    2842             :         else
    2843     1088148 :             return pColWidth[nCol];
    2844             :     }
    2845             :     else
    2846           0 :         return (sal_uInt16) STD_COL_WIDTH;
    2847             : }
    2848             : 
    2849           0 : sal_uLong ScTable::GetColWidth( SCCOL nStartCol, SCCOL nEndCol, bool bHiddenAsZero ) const
    2850             : {
    2851           0 :     if (!ValidCol(nStartCol) || !ValidCol(nEndCol) || nStartCol > nEndCol)
    2852           0 :         return 0;
    2853             : 
    2854           0 :     sal_uLong nW = 0;
    2855           0 :     bool bHidden = false;
    2856           0 :     SCCOL nLastHiddenCol = -1;
    2857           0 :     for (SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol)
    2858             :     {
    2859           0 :         if (bHiddenAsZero && nCol > nLastHiddenCol)
    2860           0 :             bHidden = ColHidden(nCol, NULL, &nLastHiddenCol);
    2861             : 
    2862           0 :         if (bHidden)
    2863           0 :             continue;
    2864             : 
    2865           0 :         nW += pColWidth[nCol];
    2866             :     }
    2867           0 :     return nW;
    2868             : }
    2869             : 
    2870       34584 : sal_uInt16 ScTable::GetOriginalWidth( SCCOL nCol ) const        // always the set value
    2871             : {
    2872             :     OSL_ENSURE(ValidCol(nCol),"wrong column number");
    2873             : 
    2874       34584 :     if (ValidCol(nCol) && pColWidth)
    2875       34584 :         return pColWidth[nCol];
    2876             :     else
    2877           0 :         return (sal_uInt16) STD_COL_WIDTH;
    2878             : }
    2879             : 
    2880           0 : sal_uInt16 ScTable::GetCommonWidth( SCCOL nEndCol ) const
    2881             : {
    2882             :     //  get the width that is used in the largest continuous column range (up to nEndCol)
    2883             : 
    2884           0 :     if ( !ValidCol(nEndCol) )
    2885             :     {
    2886             :         OSL_FAIL("wrong column");
    2887           0 :         nEndCol = MAXCOL;
    2888             :     }
    2889             : 
    2890           0 :     sal_uInt16 nMaxWidth = 0;
    2891           0 :     sal_uInt16 nMaxCount = 0;
    2892           0 :     SCCOL nRangeStart = 0;
    2893           0 :     while ( nRangeStart <= nEndCol )
    2894             :     {
    2895             :         //  skip hidden columns
    2896           0 :         while ( nRangeStart <= nEndCol && ColHidden(nRangeStart) )
    2897           0 :             ++nRangeStart;
    2898           0 :         if ( nRangeStart <= nEndCol )
    2899             :         {
    2900           0 :             sal_uInt16 nThisCount = 0;
    2901           0 :             sal_uInt16 nThisWidth = pColWidth[nRangeStart];
    2902           0 :             SCCOL nRangeEnd = nRangeStart;
    2903           0 :             while ( nRangeEnd <= nEndCol && pColWidth[nRangeEnd] == nThisWidth )
    2904             :             {
    2905           0 :                 ++nThisCount;
    2906           0 :                 ++nRangeEnd;
    2907             : 
    2908             :                 //  skip hidden columns
    2909           0 :                 while ( nRangeEnd <= nEndCol && ColHidden(nRangeEnd) )
    2910           0 :                     ++nRangeEnd;
    2911             :             }
    2912             : 
    2913           0 :             if ( nThisCount > nMaxCount )
    2914             :             {
    2915           0 :                 nMaxCount = nThisCount;
    2916           0 :                 nMaxWidth = nThisWidth;
    2917             :             }
    2918             : 
    2919           0 :             nRangeStart = nRangeEnd;        // next range
    2920             :         }
    2921             :     }
    2922             : 
    2923           0 :     return nMaxWidth;
    2924             : }
    2925             : 
    2926   234515803 : sal_uInt16 ScTable::GetRowHeight( SCROW nRow, SCROW* pStartRow, SCROW* pEndRow, bool bHiddenAsZero ) const
    2927             : {
    2928             :     OSL_ENSURE(ValidRow(nRow),"Invalid row number");
    2929             : 
    2930   234515803 :     if (ValidRow(nRow) && mpRowHeights)
    2931             :     {
    2932   234515803 :         if (bHiddenAsZero && RowHidden( nRow, pStartRow, pEndRow))
    2933        1089 :             return 0;
    2934             :         else
    2935             :         {
    2936             :             ScFlatUInt16RowSegments::RangeData aData;
    2937   234514714 :             if (!mpRowHeights->getRangeData(nRow, aData))
    2938             :             {
    2939           0 :                 if (pStartRow)
    2940           0 :                     *pStartRow = nRow;
    2941           0 :                 if (pEndRow)
    2942           0 :                     *pEndRow = nRow;
    2943             :                 // TODO: What should we return in case the search fails?
    2944           0 :                 return 0;
    2945             :             }
    2946             : 
    2947             :             // If bHiddenAsZero, pStartRow and pEndRow were initialized to
    2948             :             // boundaries of a non-hidden segment. Assume that the previous and
    2949             :             // next segment are hidden then and limit the current height
    2950             :             // segment.
    2951   234514714 :             if (pStartRow)
    2952          75 :                 *pStartRow = (bHiddenAsZero ? std::max( *pStartRow, aData.mnRow1) : aData.mnRow1);
    2953   234514714 :             if (pEndRow)
    2954       79307 :                 *pEndRow = (bHiddenAsZero ? std::min( *pEndRow, aData.mnRow2) : aData.mnRow2);
    2955   234514714 :             return aData.mnValue;
    2956             :         }
    2957             :     }
    2958             :     else
    2959             :     {
    2960           0 :         if (pStartRow)
    2961           0 :             *pStartRow = nRow;
    2962           0 :         if (pEndRow)
    2963           0 :             *pEndRow = nRow;
    2964           0 :         return (sal_uInt16) ScGlobal::nStdRowHeight;
    2965             :     }
    2966             : }
    2967             : 
    2968        5654 : sal_uLong ScTable::GetRowHeight( SCROW nStartRow, SCROW nEndRow, bool bHiddenAsZero ) const
    2969             : {
    2970             :     OSL_ENSURE(ValidRow(nStartRow) && ValidRow(nEndRow),"wrong row number");
    2971             : 
    2972        5654 :     if (ValidRow(nStartRow) && ValidRow(nEndRow) && mpRowHeights)
    2973             :     {
    2974        5654 :         sal_uLong nHeight = 0;
    2975        5654 :         SCROW nRow = nStartRow;
    2976       17487 :         while (nRow <= nEndRow)
    2977             :         {
    2978        6179 :             SCROW nLastRow = -1;
    2979        6179 :             if (!( ( RowHidden(nRow, NULL, &nLastRow) ) && bHiddenAsZero ) )
    2980             :             {
    2981        5899 :                 if (nLastRow > nEndRow)
    2982        5227 :                     nLastRow = nEndRow;
    2983        5899 :                 nHeight += mpRowHeights->getSumValue(nRow, nLastRow);
    2984             :             }
    2985        6179 :             nRow = nLastRow + 1;
    2986             :         }
    2987        5654 :         return nHeight;
    2988             :     }
    2989             :     else
    2990           0 :         return (nEndRow - nStartRow + 1) * (sal_uLong)ScGlobal::nStdRowHeight;
    2991             : }
    2992             : 
    2993           3 : sal_uLong ScTable::GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, double fScale ) const
    2994             : {
    2995             :     OSL_ENSURE(ValidRow(nStartRow) && ValidRow(nEndRow),"wrong row number");
    2996             : 
    2997           3 :     if (ValidRow(nStartRow) && ValidRow(nEndRow) && mpRowHeights)
    2998             :     {
    2999           3 :         sal_uLong nHeight = 0;
    3000           3 :         SCROW nRow = nStartRow;
    3001           9 :         while (nRow <= nEndRow)
    3002             :         {
    3003           3 :             SCROW nLastRow = -1;
    3004           3 :             if (!RowHidden(nRow, NULL, &nLastRow))
    3005             :             {
    3006           3 :                 if (nLastRow > nEndRow)
    3007           3 :                     nLastRow = nEndRow;
    3008             : 
    3009             :                 // #i117315# can't use getSumValue, because individual values must be rounded
    3010           9 :                 while (nRow <= nLastRow)
    3011             :                 {
    3012             :                     ScFlatUInt16RowSegments::RangeData aData;
    3013           3 :                     if (!mpRowHeights->getRangeData(nRow, aData))
    3014           0 :                         return nHeight;   // shouldn't happen
    3015             : 
    3016           3 :                     SCROW nSegmentEnd = std::min( nLastRow, aData.mnRow2 );
    3017             : 
    3018             :                     // round-down a single height value, multiply resulting (pixel) values
    3019           3 :                     sal_uLong nOneHeight = static_cast<sal_uLong>( aData.mnValue * fScale );
    3020           3 :                     nHeight += nOneHeight * ( nSegmentEnd + 1 - nRow );
    3021             : 
    3022           3 :                     nRow = nSegmentEnd + 1;
    3023             :                 }
    3024             :             }
    3025           3 :             nRow = nLastRow + 1;
    3026             :         }
    3027           3 :         return nHeight;
    3028             :     }
    3029             :     else
    3030           0 :         return (sal_uLong) ((nEndRow - nStartRow + 1) * ScGlobal::nStdRowHeight * fScale);
    3031             : }
    3032             : 
    3033       70029 : sal_uInt16 ScTable::GetOriginalHeight( SCROW nRow ) const       // non-0 even if hidden
    3034             : {
    3035             :     OSL_ENSURE(ValidRow(nRow),"wrong row number");
    3036             : 
    3037       70029 :     if (ValidRow(nRow) && mpRowHeights)
    3038       70029 :         return mpRowHeights->getValue(nRow);
    3039             :     else
    3040           0 :         return (sal_uInt16) ScGlobal::nStdRowHeight;
    3041             : }
    3042             : 
    3043             : //  Column/Row -Flags
    3044             : 
    3045          70 : SCROW ScTable::GetHiddenRowCount( SCROW nRow ) const
    3046             : {
    3047          70 :     if (!ValidRow(nRow))
    3048           0 :         return 0;
    3049             : 
    3050          70 :     SCROW nLastRow = -1;
    3051          70 :     if (!RowHidden(nRow, NULL, &nLastRow) || !ValidRow(nLastRow))
    3052           0 :         return 0;
    3053             : 
    3054          70 :     return nLastRow - nRow + 1;
    3055             : }
    3056             : 
    3057             : //TODO: combine ShowRows / DBShowRows
    3058             : 
    3059       15973 : void ScTable::ShowCol(SCCOL nCol, bool bShow)
    3060             : {
    3061       15973 :     if (ValidCol(nCol))
    3062             :     {
    3063       15973 :         bool bWasVis = !ColHidden(nCol);
    3064       15973 :         if (bWasVis != bShow)
    3065             :         {
    3066         204 :             SetColHidden(nCol, nCol, !bShow);
    3067             : 
    3068         204 :             ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
    3069         204 :             if ( pCharts )
    3070         204 :                 pCharts->SetRangeDirty(ScRange( nCol, 0, nTab, nCol, MAXROW, nTab ));
    3071             :         }
    3072             :     }
    3073             :     else
    3074             :     {
    3075             :         OSL_FAIL("Invalid column number or no flags");
    3076             :     }
    3077       15973 : }
    3078             : 
    3079           0 : void ScTable::ShowRow(SCROW nRow, bool bShow)
    3080             : {
    3081           0 :     if (ValidRow(nRow) && pRowFlags)
    3082             :     {
    3083           0 :         bool bWasVis = !RowHidden(nRow);
    3084           0 :         if (bWasVis != bShow)
    3085             :         {
    3086           0 :             SetRowHidden(nRow, nRow, !bShow);
    3087           0 :             if (bShow)
    3088           0 :                 SetRowFiltered(nRow, nRow, false);
    3089           0 :             ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
    3090           0 :             if ( pCharts )
    3091           0 :                 pCharts->SetRangeDirty(ScRange( 0, nRow, nTab, MAXCOL, nRow, nTab ));
    3092             : 
    3093           0 :             InvalidatePageBreaks();
    3094             :         }
    3095             :     }
    3096             :     else
    3097             :     {
    3098             :         OSL_FAIL("Invalid row number or no flags");
    3099             :     }
    3100           0 : }
    3101             : 
    3102           2 : void ScTable::DBShowRow(SCROW nRow, bool bShow)
    3103             : {
    3104           2 :     if (ValidRow(nRow) && pRowFlags)
    3105             :     {
    3106             :         //  Always set Filter-Flag, also unchanged when Hidden
    3107           2 :         bool bChanged = SetRowHidden(nRow, nRow, !bShow);
    3108           2 :         SetRowFiltered(nRow, nRow, !bShow);
    3109             : 
    3110           2 :         if (bChanged)
    3111             :         {
    3112           0 :             ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
    3113           0 :             if ( pCharts )
    3114           0 :                 pCharts->SetRangeDirty(ScRange( 0, nRow, nTab, MAXCOL, nRow, nTab ));
    3115             : 
    3116           0 :             if (pOutlineTable)
    3117           0 :                 UpdateOutlineRow( nRow, nRow, bShow );
    3118             : 
    3119           0 :             InvalidatePageBreaks();
    3120             :         }
    3121             :     }
    3122             :     else
    3123             :     {
    3124             :         OSL_FAIL("Invalid row number or no flags");
    3125             :     }
    3126           2 : }
    3127             : 
    3128          46 : void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, bool bShow)
    3129             : {
    3130          46 :     SCROW nStartRow = nRow1;
    3131         151 :     while (nStartRow <= nRow2)
    3132             :     {
    3133          59 :         SCROW nEndRow = -1;
    3134          59 :         bool bWasVis = !RowHiddenLeaf(nStartRow, NULL, &nEndRow);
    3135          59 :         if (nEndRow > nRow2)
    3136          31 :             nEndRow = nRow2;
    3137             : 
    3138          59 :         bool bChanged = ( bWasVis != bShow );
    3139             : 
    3140          59 :         SetRowHidden(nStartRow, nEndRow, !bShow);
    3141          59 :         SetRowFiltered(nStartRow, nEndRow, !bShow);
    3142             : 
    3143          59 :         if ( bChanged )
    3144             :         {
    3145          31 :             ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
    3146          31 :             if ( pCharts )
    3147          31 :                 pCharts->SetRangeDirty(ScRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab ));
    3148             :         }
    3149             : 
    3150          59 :         nStartRow = nEndRow + 1;
    3151             :     }
    3152             : 
    3153             :     //  #i12341# For Show/Hide rows, the outlines are updated separately from the outside.
    3154             :     //  For filtering, the changes aren't visible to the caller, so UpdateOutlineRow has
    3155             :     //  to be done here.
    3156          46 :     if (pOutlineTable)
    3157          31 :         UpdateOutlineRow( nRow1, nRow2, bShow );
    3158          46 : }
    3159             : 
    3160          51 : void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, bool bShow)
    3161             : {
    3162          51 :     SCROW nStartRow = nRow1;
    3163             : 
    3164             :     // #i116164# if there are no drawing objects within the row range, a single HeightChanged call is enough
    3165          51 :     ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
    3166          51 :     bool bHasObjects = pDrawLayer && pDrawLayer->HasObjectsInRows( nTab, nRow1, nRow2 );
    3167             : 
    3168         156 :     while (nStartRow <= nRow2)
    3169             :     {
    3170          54 :         SCROW nEndRow = -1;
    3171          54 :         bool bWasVis = !RowHiddenLeaf(nStartRow, NULL, &nEndRow);
    3172          54 :         if (nEndRow > nRow2)
    3173          42 :             nEndRow = nRow2;
    3174             : 
    3175          54 :         bool bChanged = ( bWasVis != bShow );
    3176             : 
    3177          54 :         SetRowHidden(nStartRow, nEndRow, !bShow);
    3178          54 :         if (bShow)
    3179          26 :             SetRowFiltered(nStartRow, nEndRow, false);
    3180             : 
    3181          54 :         if ( bChanged )
    3182             :         {
    3183          39 :             ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
    3184          39 :             if ( pCharts )
    3185          39 :                 pCharts->SetRangeDirty(ScRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab ));
    3186             : 
    3187          39 :             InvalidatePageBreaks();
    3188             :         }
    3189             : 
    3190          54 :         nStartRow = nEndRow + 1;
    3191             :     }
    3192             : 
    3193          51 :     if ( !bHasObjects )
    3194             :     {
    3195             :         // #i116164# set the flags for the whole range at once
    3196          46 :         SetRowHidden(nRow1, nRow2, !bShow);
    3197          46 :         if (bShow)
    3198          21 :             SetRowFiltered(nRow1, nRow2, false);
    3199             :     }
    3200          51 : }
    3201             : 
    3202          24 : bool ScTable::IsDataFiltered(SCCOL nColStart, SCROW nRowStart, SCCOL nColEnd, SCROW nRowEnd) const
    3203             : {
    3204         115 :     for (SCROW i = nRowStart; i <= nRowEnd; ++i)
    3205             :     {
    3206          93 :         if (RowHidden(i))
    3207           2 :             return true;
    3208             :     }
    3209          74 :     for (SCCOL i = nColStart; i <= nColEnd; ++i)
    3210             :     {
    3211          52 :         if (ColHidden(i))
    3212           0 :             return true;
    3213             :     }
    3214          22 :     return false;
    3215             : }
    3216             : 
    3217          24 : bool ScTable::IsDataFiltered(const ScRange& rRange) const
    3218             : {
    3219          24 :     return IsDataFiltered(rRange.aStart.Col(), rRange.aStart.Row(),
    3220          48 :                 rRange.aEnd.Col(), rRange.aEnd.Row());
    3221             : }
    3222             : 
    3223           0 : void ScTable::SetRowFlags( SCROW nRow, sal_uInt8 nNewFlags )
    3224             : {
    3225           0 :     if (ValidRow(nRow) && pRowFlags)
    3226           0 :         pRowFlags->SetValue( nRow, nNewFlags);
    3227             :     else
    3228             :     {
    3229             :         OSL_FAIL("Invalid row number or no flags");
    3230             :     }
    3231           0 : }
    3232             : 
    3233          11 : void ScTable::SetRowFlags( SCROW nStartRow, SCROW nEndRow, sal_uInt8 nNewFlags )
    3234             : {
    3235          11 :     if (ValidRow(nStartRow) && ValidRow(nEndRow) && pRowFlags)
    3236          11 :         pRowFlags->SetValue( nStartRow, nEndRow, nNewFlags);
    3237             :     else
    3238             :     {
    3239             :         OSL_FAIL("Invalid row number(s) or no flags");
    3240             :     }
    3241          11 : }
    3242             : 
    3243       67551 : sal_uInt8 ScTable::GetColFlags( SCCOL nCol ) const
    3244             : {
    3245       67551 :     if (ValidCol(nCol) && pColFlags)
    3246       67551 :         return pColFlags[nCol];
    3247             :     else
    3248           0 :         return 0;
    3249             : }
    3250             : 
    3251        2529 : sal_uInt8 ScTable::GetRowFlags( SCROW nRow ) const
    3252             : {
    3253        2529 :     if (ValidRow(nRow) && pRowFlags)
    3254        2529 :         return pRowFlags->GetValue(nRow);
    3255             :     else
    3256           0 :         return 0;
    3257             : }
    3258             : 
    3259         162 : SCROW ScTable::GetLastFlaggedRow() const
    3260             : {
    3261         162 :     SCROW nLastFound = 0;
    3262         162 :     if (pRowFlags)
    3263             :     {
    3264         162 :         SCROW nRow = pRowFlags->GetLastAnyBitAccess( 0, sal::static_int_cast<sal_uInt8>(CR_ALL) );
    3265         162 :         if (ValidRow(nRow))
    3266           8 :             nLastFound = nRow;
    3267             :     }
    3268             : 
    3269         162 :     if (!maRowManualBreaks.empty())
    3270           0 :         nLastFound = ::std::max(nLastFound, *maRowManualBreaks.rbegin());
    3271             : 
    3272         162 :     if (mpHiddenRows)
    3273             :     {
    3274         162 :         SCROW nRow = mpHiddenRows->findLastNotOf(false);
    3275         162 :         if (ValidRow(nRow))
    3276           3 :             nLastFound = ::std::max(nLastFound, nRow);
    3277             :     }
    3278             : 
    3279         162 :     if (mpFilteredRows)
    3280             :     {
    3281         162 :         SCROW nRow = mpFilteredRows->findLastNotOf(false);
    3282         162 :         if (ValidRow(nRow))
    3283           0 :             nLastFound = ::std::max(nLastFound, nRow);
    3284             :     }
    3285             : 
    3286         162 :     return nLastFound;
    3287             : }
    3288             : 
    3289          33 : SCCOL ScTable::GetLastChangedCol() const
    3290             : {
    3291          33 :     if ( !pColFlags )
    3292           0 :         return 0;
    3293             : 
    3294          33 :     SCCOL nLastFound = 0;
    3295       33792 :     for (SCCOL nCol = 1; nCol <= MAXCOL; nCol++)
    3296       33759 :         if ((pColFlags[nCol] & CR_ALL) || (pColWidth[nCol] != STD_COL_WIDTH))
    3297        4101 :             nLastFound = nCol;
    3298             : 
    3299          33 :     return nLastFound;
    3300             : }
    3301             : 
    3302          33 : SCROW ScTable::GetLastChangedRow() const
    3303             : {
    3304          33 :     if ( !pRowFlags )
    3305           0 :         return 0;
    3306             : 
    3307          33 :     SCROW nLastFlags = GetLastFlaggedRow();
    3308             : 
    3309             :     // Find the last row position where the height is NOT the standard row
    3310             :     // height.
    3311             :     // KOHEI: Test this to make sure it does what it's supposed to.
    3312          33 :     SCROW nLastHeight = mpRowHeights->findLastNotOf(ScGlobal::nStdRowHeight);
    3313          33 :     if (!ValidRow(nLastHeight))
    3314          21 :         nLastHeight = 0;
    3315             : 
    3316          33 :     return std::max( nLastFlags, nLastHeight);
    3317             : }
    3318             : 
    3319        1326 : bool ScTable::UpdateOutlineCol( SCCOL nStartCol, SCCOL nEndCol, bool bShow )
    3320             : {
    3321        1326 :     if (pOutlineTable && pColFlags)
    3322             :     {
    3323          20 :         ScBitMaskCompressedArray< SCCOLROW, sal_uInt8> aArray( MAXCOL, pColFlags, MAXCOLCOUNT);
    3324          20 :         return pOutlineTable->GetColArray().ManualAction( nStartCol, nEndCol, bShow, *this, true );
    3325             :     }
    3326             :     else
    3327        1306 :         return false;
    3328             : }
    3329             : 
    3330          60 : bool ScTable::UpdateOutlineRow( SCROW nStartRow, SCROW nEndRow, bool bShow )
    3331             : {
    3332          60 :     if (pOutlineTable && pRowFlags)
    3333          41 :         return pOutlineTable->GetRowArray().ManualAction( nStartRow, nEndRow, bShow, *this, false );
    3334             :     else
    3335          19 :         return false;
    3336             : }
    3337             : 
    3338       10628 : void ScTable::ExtendHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 )
    3339             : {
    3340             :     // Column-wise expansion
    3341             : 
    3342       21302 :     while (rX1 > 0 && ColHidden(rX1-1))
    3343          46 :         --rX1;
    3344             : 
    3345       21256 :     while (rX2 < MAXCOL && ColHidden(rX2+1))
    3346           0 :         ++rX2;
    3347             : 
    3348             :     // Row-wise expansion
    3349             : 
    3350       10628 :     if (rY1 > 0)
    3351             :     {
    3352             :         ScFlatBoolRowSegments::RangeData aData;
    3353        1983 :         if (mpHiddenRows->getRangeData(rY1-1, aData) && aData.mbValue)
    3354             :         {
    3355          30 :             SCROW nStartRow = aData.mnRow1;
    3356          30 :             if (ValidRow(nStartRow))
    3357          30 :                 rY1 = nStartRow;
    3358             :         }
    3359             :     }
    3360       10628 :     if (rY2 < MAXROW)
    3361             :     {
    3362       10620 :         SCROW nEndRow = -1;
    3363       10620 :         if (RowHidden(rY2+1, NULL, &nEndRow) && ValidRow(nEndRow))
    3364          22 :             rY2 = nEndRow;
    3365             :     }
    3366       10628 : }
    3367             : 
    3368       10483 : void ScTable::StripHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 )
    3369             : {
    3370       20966 :     while ( rX2>rX1 && ColHidden(rX2) )
    3371           0 :         --rX2;
    3372       21606 :     while ( rX2>rX1 && ColHidden(rX1) )
    3373         640 :         ++rX1;
    3374             : 
    3375       10483 :     if (rY1 < rY2)
    3376             :     {
    3377             :         ScFlatBoolRowSegments::RangeData aData;
    3378       10165 :         if (mpHiddenRows->getRangeData(rY2, aData) && aData.mbValue)
    3379             :         {
    3380          22 :             SCROW nStartRow = aData.mnRow1;
    3381          22 :             if (ValidRow(nStartRow) && nStartRow >= rY1)
    3382          22 :                 rY2 = nStartRow;
    3383             :         }
    3384             :     }
    3385             : 
    3386       10483 :     if (rY1 < rY2)
    3387             :     {
    3388       10165 :         SCROW nEndRow = -1;
    3389       10165 :         if (RowHidden(rY1, NULL, &nEndRow) && ValidRow(nEndRow) && nEndRow <= rY2)
    3390          59 :             rY1 = nEndRow;
    3391             :     }
    3392       10483 : }
    3393             : 
    3394             : //  Auto-Outline
    3395             : 
    3396             : template< typename T >
    3397           8 : short DiffSign( T a, T b )
    3398             : {
    3399             :     return (a<b) ? -1 :
    3400           8 :             (a>b) ? 1 : 0;
    3401             : }
    3402             : 
    3403             : namespace {
    3404             : 
    3405             : class OutlineArrayFinder
    3406             : {
    3407             :     ScRange maRef;
    3408             :     SCCOL mnCol;
    3409             :     SCTAB mnTab;
    3410             :     ScOutlineArray* mpArray;
    3411             :     bool mbSizeChanged;
    3412             : 
    3413             : public:
    3414           8 :     OutlineArrayFinder(const ScRange& rRef, SCCOL nCol, SCTAB nTab, ScOutlineArray* pArray, bool bSizeChanged) :
    3415             :         maRef(rRef), mnCol(nCol), mnTab(nTab), mpArray(pArray),
    3416           8 :         mbSizeChanged(bSizeChanged) {}
    3417             : 
    3418           4 :     bool operator() (size_t nRow, const ScFormulaCell* pCell)
    3419             :     {
    3420           4 :         SCROW nRow2 = static_cast<SCROW>(nRow);
    3421             : 
    3422           4 :         if (!pCell->HasRefListExpressibleAsOneReference(maRef))
    3423           0 :             return false;
    3424             : 
    3425           8 :         if (maRef.aStart.Row() != nRow2 || maRef.aEnd.Row() != nRow2 ||
    3426           4 :             maRef.aStart.Tab() != mnTab || maRef.aEnd.Tab() != mnTab)
    3427           4 :             return false;
    3428             : 
    3429           0 :         if (DiffSign(maRef.aStart.Col(), mnCol) != DiffSign(maRef.aEnd.Col(), mnCol))
    3430           0 :             return false;
    3431             : 
    3432           0 :         return mpArray->Insert(maRef.aStart.Col(), maRef.aEnd.Col(), mbSizeChanged);
    3433             :     }
    3434             : };
    3435             : 
    3436             : }
    3437             : 
    3438           2 : void ScTable::DoAutoOutline( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
    3439             : {
    3440             :     typedef mdds::flat_segment_tree<SCROW, bool> UsedRowsType;
    3441             : 
    3442           2 :     bool bSizeChanged = false;
    3443             : 
    3444             :     SCCOL nCol;
    3445             :     SCROW nRow;
    3446             :     bool bFound;
    3447           2 :     ScRange aRef;
    3448             : 
    3449           2 :     StartOutlineTable();
    3450             : 
    3451             :                             // Rows
    3452             : 
    3453           2 :     UsedRowsType aUsed(0, MAXROW+1, false);
    3454          12 :     for (nCol=nStartCol; nCol<=nEndCol; nCol++)
    3455          10 :         aCol[nCol].FindUsed(nStartRow, nEndRow, aUsed);
    3456           2 :     aUsed.build_tree();
    3457             : 
    3458           2 :     ScOutlineArray& rRowArray = pOutlineTable->GetRowArray();
    3459          14 :     for (nRow=nStartRow; nRow<=nEndRow; nRow++)
    3460             :     {
    3461          12 :         bool bUsed = false;
    3462          12 :         SCROW nLastRow = nRow;
    3463          12 :         aUsed.search_tree(nRow, bUsed, NULL, &nLastRow);
    3464          12 :         if (!bUsed)
    3465             :         {
    3466           0 :             nRow = nLastRow;
    3467           0 :             continue;
    3468             :         }
    3469             : 
    3470          12 :         bFound = false;
    3471          70 :         for (nCol=nStartCol; nCol<=nEndCol && !bFound; nCol++)
    3472             :         {
    3473          58 :             ScRefCellValue aCell = aCol[nCol].GetCellValue(nRow);
    3474             : 
    3475          58 :             if (aCell.meType != CELLTYPE_FORMULA)
    3476          54 :                 continue;
    3477             : 
    3478           4 :             if (!aCell.mpFormula->HasRefListExpressibleAsOneReference(aRef))
    3479           0 :                 continue;
    3480             : 
    3481          16 :             if ( aRef.aStart.Col() == nCol && aRef.aEnd.Col() == nCol &&
    3482          16 :                  aRef.aStart.Tab() == nTab && aRef.aEnd.Tab() == nTab &&
    3483           4 :                  DiffSign( aRef.aStart.Row(), nRow ) ==
    3484           4 :                     DiffSign( aRef.aEnd.Row(), nRow ) )
    3485             :             {
    3486           4 :                 if (rRowArray.Insert( aRef.aStart.Row(), aRef.aEnd.Row(), bSizeChanged ))
    3487             :                 {
    3488           4 :                     bFound = true;
    3489             :                 }
    3490             :             }
    3491           4 :         }
    3492             :     }
    3493             : 
    3494             :     // Column
    3495           2 :     ScOutlineArray& rColArray = pOutlineTable->GetColArray();
    3496          12 :     for (nCol=nStartCol; nCol<=nEndCol; nCol++)
    3497             :     {
    3498          10 :         if (aCol[nCol].IsEmptyData())
    3499           2 :             continue;
    3500             : 
    3501           8 :         OutlineArrayFinder aFunc(aRef, nCol, nTab, &rColArray, bSizeChanged);
    3502           8 :         sc::FindFormula(aCol[nCol].maCells, nStartRow, nEndRow, aFunc);
    3503           2 :     }
    3504           2 : }
    3505             : 
    3506             :                                     //  CopyData - for Query in other range
    3507             : 
    3508           0 : void ScTable::CopyData( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
    3509             :                             SCCOL nDestCol, SCROW nDestRow, SCTAB nDestTab )
    3510             : {
    3511             :     //TODO: if used for multipe rows, optimize after columns!
    3512             : 
    3513           0 :     ScAddress aSrc( nStartCol, nStartRow, nTab );
    3514           0 :     ScAddress aDest( nDestCol, nDestRow, nDestTab );
    3515           0 :     ScRange aRange( aSrc, aDest );
    3516           0 :     bool bThisTab = ( nDestTab == nTab );
    3517           0 :     SCROW nDestY = nDestRow;
    3518           0 :     for (SCROW nRow=nStartRow; nRow<=nEndRow; nRow++)
    3519             :     {
    3520           0 :         aSrc.SetRow( nRow );
    3521           0 :         aDest.SetRow( nDestY );
    3522           0 :         SCCOL nDestX = nDestCol;
    3523           0 :         for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++)
    3524             :         {
    3525           0 :             aSrc.SetCol( nCol );
    3526           0 :             aDest.SetCol( nDestX );
    3527           0 :             ScCellValue aCell;
    3528           0 :             aCell.assign(*pDocument, ScAddress(nCol, nRow, nTab));
    3529             : 
    3530           0 :             if (aCell.meType == CELLTYPE_FORMULA)
    3531             :             {
    3532           0 :                 sc::RefUpdateContext aCxt(*pDocument);
    3533           0 :                 aCxt.meMode = URM_COPY;
    3534           0 :                 aCxt.maRange = aRange;
    3535           0 :                 aCxt.mnColDelta = nDestCol - nStartCol;
    3536           0 :                 aCxt.mnRowDelta = nDestRow - nStartRow;
    3537           0 :                 aCxt.mnTabDelta = nDestTab - nTab;
    3538           0 :                 aCell.mpFormula->UpdateReference(aCxt);
    3539           0 :                 aCell.mpFormula->aPos = aDest;
    3540             :             }
    3541             : 
    3542           0 :             if (bThisTab)
    3543             :             {
    3544           0 :                 aCell.release(aCol[nDestX], nDestY);
    3545           0 :                 SetPattern( nDestX, nDestY, *GetPattern( nCol, nRow ), true );
    3546             :             }
    3547             :             else
    3548             :             {
    3549           0 :                 aCell.release(*pDocument, aDest);
    3550           0 :                 pDocument->SetPattern( aDest, *GetPattern( nCol, nRow ), true );
    3551             :             }
    3552             : 
    3553           0 :             ++nDestX;
    3554           0 :         }
    3555           0 :         ++nDestY;
    3556             :     }
    3557           0 : }
    3558             : 
    3559           0 : bool ScTable::RefVisible(ScFormulaCell* pCell)
    3560             : {
    3561           0 :     ScRange aRef;
    3562             : 
    3563           0 :     if (pCell->HasOneReference(aRef))
    3564             :     {
    3565           0 :         if (aRef.aStart.Col()==aRef.aEnd.Col() && aRef.aStart.Tab()==aRef.aEnd.Tab())
    3566             :         {
    3567             :             SCROW nEndRow;
    3568           0 :             if (!RowFiltered(aRef.aStart.Row(), NULL, &nEndRow))
    3569             :                 // row not filtered.
    3570           0 :                 nEndRow = ::std::numeric_limits<SCROW>::max();
    3571             : 
    3572           0 :             if (!ValidRow(nEndRow) || nEndRow < aRef.aEnd.Row())
    3573           0 :                 return true;    // at least partly visible
    3574           0 :             return false;       // completely invisible
    3575             :         }
    3576             :     }
    3577             : 
    3578           0 :     return true;                        // somehow different
    3579             : }
    3580             : 
    3581          12 : void ScTable::GetUpperCellString(SCCOL nCol, SCROW nRow, OUString& rStr)
    3582             : {
    3583          12 :     GetInputString(nCol, nRow, rStr);
    3584          12 :     rStr = ScGlobal::pCharClass->uppercase(rStr.trim());
    3585          12 : }
    3586             : 
    3587             : // Calculate the size of the sheet and set the size on DrawPage
    3588             : 
    3589        4061 : void ScTable::SetDrawPageSize(bool bResetStreamValid, bool bUpdateNoteCaptionPos)
    3590             : {
    3591        4061 :     ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
    3592        4061 :     if( pDrawLayer )
    3593             :     {
    3594        3003 :         double fValX = GetColOffset( MAXCOL + 1 ) * HMM_PER_TWIPS;
    3595        3003 :         double fValY = GetRowOffset( MAXROW + 1 ) * HMM_PER_TWIPS;
    3596        3003 :         const long nMax = ::std::numeric_limits<long>::max();
    3597             :         // #i113884# Avoid int32 overflow with possible negative results than can cause bad effects.
    3598             :         // If the draw page size is smaller than all rows, only the bottom of the sheet is affected.
    3599        3003 :         long x = ( fValX > (double)nMax ) ? nMax : (long) fValX;
    3600        3003 :         long y = ( fValY > (double)nMax ) ? nMax : (long) fValY;
    3601             : 
    3602        3003 :         if ( IsLayoutRTL() )        // IsNegativePage
    3603           2 :             x = -x;
    3604             : 
    3605        3003 :         pDrawLayer->SetPageSize( static_cast<sal_uInt16>(nTab), Size( x, y ), bUpdateNoteCaptionPos );
    3606             :     }
    3607             : 
    3608             :     // #i102616# actions that modify the draw page size count as sheet modification
    3609             :     // (exception: InitDrawLayer)
    3610        4061 :     if (bResetStreamValid && IsStreamValid())
    3611           0 :         SetStreamValid(false);
    3612        4061 : }
    3613             : 
    3614           1 : void ScTable::SetRangeName(ScRangeName* pNew)
    3615             : {
    3616           1 :     delete mpRangeName;
    3617           1 :     mpRangeName = pNew;
    3618             : 
    3619             :     //fdo#39792: mark stream as invalid, otherwise new ScRangeName will not be written to file
    3620           1 :     if (IsStreamValid())
    3621           0 :         SetStreamValid(false);
    3622           1 : }
    3623             : 
    3624        2365 : ScRangeName* ScTable::GetRangeName() const
    3625             : {
    3626        2365 :     if (!mpRangeName)
    3627         598 :         mpRangeName = new ScRangeName;
    3628        2365 :     return mpRangeName;
    3629             : }
    3630             : 
    3631        4656 : sal_uLong ScTable::GetRowOffset( SCROW nRow, bool bHiddenAsZero ) const
    3632             : {
    3633        4656 :     sal_uLong n = 0;
    3634        4656 :     if ( mpHiddenRows && mpRowHeights )
    3635             :     {
    3636        4656 :         if (nRow == 0)
    3637         185 :             return 0;
    3638        4471 :         else if (nRow == 1)
    3639         116 :             return GetRowHeight(0, NULL, NULL, bHiddenAsZero );
    3640             : 
    3641        4355 :         n = GetTotalRowHeight(0, nRow-1, bHiddenAsZero);
    3642             : #if OSL_DEBUG_LEVEL > 0
    3643             :         if (n == ::std::numeric_limits<unsigned long>::max())
    3644             :             OSL_FAIL("ScTable::GetRowOffset: row heights overflow");
    3645             : #endif
    3646             :     }
    3647             :     else
    3648             :     {
    3649             :         OSL_FAIL("GetRowOffset: Data missing");
    3650             :     }
    3651        4355 :     return n;
    3652             : }
    3653             : 
    3654        3560 : SCROW ScTable::GetRowForHeight(sal_uLong nHeight) const
    3655             : {
    3656        3560 :     sal_uInt32 nSum = 0;
    3657             : 
    3658             :     ScFlatBoolRowSegments::RangeData aData;
    3659     6339956 :     for (SCROW nRow = 0; nRow <= MAXROW; ++nRow)
    3660             :     {
    3661     6339950 :         if (!mpHiddenRows->getRangeData(nRow, aData))
    3662           0 :             break;
    3663             : 
    3664     6339950 :         if (aData.mbValue)
    3665             :         {
    3666          84 :             nRow = aData.mnRow2;
    3667          84 :             continue;
    3668             :         }
    3669             : 
    3670     6339866 :         sal_uInt32 nNew = mpRowHeights->getValue(nRow);
    3671     6339866 :         nSum += nNew;
    3672     6339866 :         if (nSum > nHeight)
    3673             :         {
    3674        3554 :             return nRow < MAXROW ? nRow + 1 : MAXROW;
    3675             :         }
    3676             :     }
    3677           6 :     return -1;
    3678             : }
    3679             : 
    3680        4656 : sal_uLong ScTable::GetColOffset( SCCOL nCol, bool bHiddenAsZero ) const
    3681             : {
    3682        4656 :     sal_uLong n = 0;
    3683        4656 :     if ( pColWidth )
    3684             :     {
    3685             :         SCCOL i;
    3686     3086794 :         for( i = 0; i < nCol; i++ )
    3687     3082138 :             if (!( bHiddenAsZero && ColHidden(i) ))
    3688     3081233 :                 n += pColWidth[i];
    3689             :     }
    3690             :     else
    3691             :     {
    3692             :         OSL_FAIL("GetColumnOffset: Data missing");
    3693             :     }
    3694        4656 :     return n;
    3695         156 : }
    3696             : 
    3697             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11