LCOV - code coverage report
Current view: top level - sc/source/core/data - table2.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 1325 1872 70.8 %
Date: 2014-04-11 Functions: 167 197 84.8 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10