LCOV - code coverage report
Current view: top level - sc/source/core/data - table2.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1330 1880 70.7 %
Date: 2014-11-03 Functions: 167 199 83.9 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10