LCOV - code coverage report
Current view: top level - sc/source/core/data - table1.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 829 1174 70.6 %
Date: 2014-11-03 Functions: 83 101 82.2 %
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 "scitems.hxx"
      21             : #include <svx/algitem.hxx>
      22             : #include <editeng/justifyitem.hxx>
      23             : #include <unotools/textsearch.hxx>
      24             : #include <sfx2/objsh.hxx>
      25             : 
      26             : #include "attrib.hxx"
      27             : #include "patattr.hxx"
      28             : #include "formulacell.hxx"
      29             : #include "table.hxx"
      30             : #include "document.hxx"
      31             : #include "drwlayer.hxx"
      32             : #include "olinetab.hxx"
      33             : #include "stlsheet.hxx"
      34             : #include "global.hxx"
      35             : #include "globstr.hrc"
      36             : #include "refupdat.hxx"
      37             : #include "markdata.hxx"
      38             : #include "progress.hxx"
      39             : #include "hints.hxx"
      40             : #include "prnsave.hxx"
      41             : #include "tabprotection.hxx"
      42             : #include "sheetevents.hxx"
      43             : #include "segmenttree.hxx"
      44             : #include "dbdata.hxx"
      45             : #include "colorscale.hxx"
      46             : #include "conditio.hxx"
      47             : #include "globalnames.hxx"
      48             : #include "cellvalue.hxx"
      49             : #include "scmatrix.hxx"
      50             : #include "refupdatecontext.hxx"
      51             : #include <rowheightcontext.hxx>
      52             : 
      53             : #include <formula/vectortoken.hxx>
      54             : 
      55             : #include <vector>
      56             : #include <boost/scoped_array.hpp>
      57             : 
      58             : using ::std::vector;
      59             : 
      60             : namespace {
      61             : 
      62        2710 : ScProgress* GetProgressBar(
      63             :     SCSIZE nCount, SCSIZE nTotalCount, ScProgress* pOuterProgress, ScDocument* pDoc)
      64             : {
      65        2710 :     if (nTotalCount < 1000)
      66             :     {
      67             :         // if the total number of rows is less than 1000, don't even bother
      68             :         // with the progress bar because drawing progress bar can be very
      69             :         // expensive especially in GTK.
      70        2710 :         return NULL;
      71             :     }
      72             : 
      73           0 :     if (pOuterProgress)
      74           0 :         return pOuterProgress;
      75             : 
      76           0 :     if (nCount > 1)
      77             :         return new ScProgress(
      78           0 :             pDoc->GetDocumentShell(), ScGlobal::GetRscString(STR_PROGRESS_HEIGHTING), nTotalCount);
      79             : 
      80           0 :     return NULL;
      81             : }
      82             : 
      83        2710 : void GetOptimalHeightsInColumn(
      84             :     sc::RowHeightContext& rCxt, ScColumn* pCol, SCROW nStartRow, SCROW nEndRow,
      85             :     ScProgress* pProgress, sal_uInt32 nProgressStart )
      86             : {
      87        2710 :     SCSIZE nCount = static_cast<SCSIZE>(nEndRow-nStartRow+1);
      88             : 
      89             :     //  zuerst einmal ueber den ganzen Bereich
      90             :     //  (mit der letzten Spalte in der Hoffnung, dass die am ehesten noch auf
      91             :     //   Standard formatiert ist)
      92             : 
      93        2710 :     std::vector<sal_uInt16>& rHeights = rCxt.getHeightArray();
      94             : 
      95        2710 :     pCol[MAXCOL].GetOptimalHeight(rCxt, nStartRow, nEndRow, 0, 0);
      96             : 
      97             :     //  daraus Standardhoehe suchen, die im unteren Bereich gilt
      98             : 
      99        2710 :     sal_uInt16 nMinHeight = rHeights[nCount-1];
     100        2710 :     SCSIZE nPos = nCount-1;
     101   163587838 :     while ( nPos && rHeights[nPos-1] >= nMinHeight )
     102   163582418 :         --nPos;
     103        2710 :     SCROW nMinStart = nStartRow + nPos;
     104             : 
     105        2710 :     sal_uLong nWeightedCount = 0;
     106     2775040 :     for (SCCOL nCol=0; nCol<MAXCOL; nCol++)     // MAXCOL schon oben
     107             :     {
     108     2772330 :         pCol[nCol].GetOptimalHeight(rCxt, nStartRow, nEndRow, nMinHeight, nMinStart);
     109             : 
     110     2772330 :         if (pProgress)
     111             :         {
     112           0 :             sal_uLong nWeight = pCol[nCol].GetWeightedCount();
     113           0 :             if (nWeight)        // nochmal denselben Status muss auch nicht sein
     114             :             {
     115           0 :                 nWeightedCount += nWeight;
     116           0 :                 pProgress->SetState( nWeightedCount + nProgressStart );
     117             :             }
     118             :         }
     119             :     }
     120        2710 : }
     121             : 
     122        2710 : struct OptimalHeightsFuncObjBase
     123             : {
     124        2710 :     virtual ~OptimalHeightsFuncObjBase() {}
     125             :     virtual bool operator() (SCROW nStartRow, SCROW nEndRow, sal_uInt16 nHeight) = 0;
     126             : };
     127             : 
     128           8 : struct SetRowHeightOnlyFunc : public OptimalHeightsFuncObjBase
     129             : {
     130             :     ScTable* mpTab;
     131           8 :     SetRowHeightOnlyFunc(ScTable* pTab) :
     132           8 :         mpTab(pTab)
     133           8 :     {}
     134             : 
     135           8 :     virtual bool operator() (SCROW nStartRow, SCROW nEndRow, sal_uInt16 nHeight) SAL_OVERRIDE
     136             :     {
     137           8 :         mpTab->SetRowHeightOnly(nStartRow, nEndRow, nHeight);
     138           8 :         return false;
     139             :     }
     140             : };
     141             : 
     142        2702 : struct SetRowHeightRangeFunc : public OptimalHeightsFuncObjBase
     143             : {
     144             :     ScTable* mpTab;
     145             :     double mnPPTX;
     146             :     double mnPPTY;
     147             : 
     148        2702 :     SetRowHeightRangeFunc(ScTable* pTab, double nPPTX, double nPPTY) :
     149             :         mpTab(pTab),
     150             :         mnPPTX(nPPTX),
     151        2702 :         mnPPTY(nPPTY)
     152        2702 :     {}
     153             : 
     154        2756 :     virtual bool operator() (SCROW nStartRow, SCROW nEndRow, sal_uInt16 nHeight) SAL_OVERRIDE
     155             :     {
     156        2756 :         return mpTab->SetRowHeightRange(nStartRow, nEndRow, nHeight, mnPPTX, mnPPTY);
     157             :     }
     158             : };
     159             : 
     160        2710 : bool SetOptimalHeightsToRows(
     161             :     sc::RowHeightContext& rCxt,
     162             :     OptimalHeightsFuncObjBase& rFuncObj,
     163             :     ScBitMaskCompressedArray<SCROW, sal_uInt8>* pRowFlags, SCROW nStartRow, SCROW nEndRow )
     164             : {
     165        2710 :     SCSIZE nCount = static_cast<SCSIZE>(nEndRow-nStartRow+1);
     166        2710 :     bool bChanged = false;
     167        2710 :     SCROW nRngStart = 0;
     168        2710 :     SCROW nRngEnd = 0;
     169        2710 :     sal_uInt16 nLast = 0;
     170        5448 :     for (SCSIZE i=0; i<nCount; i++)
     171             :     {
     172             :         size_t nIndex;
     173             :         SCROW nRegionEndRow;
     174        2738 :         sal_uInt8 nRowFlag = pRowFlags->GetValue( nStartRow+i, nIndex, nRegionEndRow );
     175        2738 :         if ( nRegionEndRow > nEndRow )
     176        2486 :             nRegionEndRow = nEndRow;
     177        2738 :         SCSIZE nMoreRows = nRegionEndRow - ( nStartRow+i );     // additional equal rows after first
     178             : 
     179        2738 :         bool bAutoSize = ((nRowFlag & CR_MANUALSIZE) == 0);
     180        2738 :         if (bAutoSize || rCxt.isForceAutoSize())
     181             :         {
     182        2488 :             if (rCxt.getExtraHeight())
     183             :             {
     184           0 :                 if (bAutoSize)
     185           0 :                     pRowFlags->SetValue( nStartRow+i, nRegionEndRow, nRowFlag | CR_MANUALSIZE);
     186             :             }
     187        2488 :             else if (!bAutoSize)
     188           2 :                 pRowFlags->SetValue( nStartRow+i, nRegionEndRow, nRowFlag & ~CR_MANUALSIZE);
     189             : 
     190   163586688 :             for (SCSIZE nInner = i; nInner <= i + nMoreRows; ++nInner)
     191             :             {
     192   163584200 :                 if (nLast)
     193             :                 {
     194   163581712 :                     if (rCxt.getHeightArray()[nInner] + rCxt.getExtraHeight() == nLast)
     195   163581436 :                         nRngEnd = nStartRow+nInner;
     196             :                     else
     197             :                     {
     198         276 :                         bChanged |= rFuncObj(nRngStart, nRngEnd, nLast);
     199         276 :                         nLast = 0;
     200             :                     }
     201             :                 }
     202   163584200 :                 if (!nLast)
     203             :                 {
     204        2764 :                     nLast = rCxt.getHeightArray()[nInner] + rCxt.getExtraHeight();
     205        2764 :                     nRngStart = nStartRow+nInner;
     206        2764 :                     nRngEnd = nStartRow+nInner;
     207             :                 }
     208             :             }
     209             :         }
     210             :         else
     211             :         {
     212         250 :             if (nLast)
     213          12 :                 bChanged |= rFuncObj(nRngStart, nRngEnd, nLast);
     214         250 :             nLast = 0;
     215             :         }
     216        2738 :         i += nMoreRows;     // already handled - skip
     217             :     }
     218        2710 :     if (nLast)
     219        2476 :         bChanged |= rFuncObj(nRngStart, nRngEnd, nLast);
     220             : 
     221        2710 :     return bChanged;
     222             : }
     223             : 
     224             : }
     225             : 
     226        4322 : ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const OUString& rNewName,
     227             :                     bool bColInfo, bool bRowInfo ) :
     228             :     aName( rNewName ),
     229             :     aCodeName( rNewName ),
     230             :     nLinkRefreshDelay( 0 ),
     231             :     nLinkMode( 0 ),
     232        4322 :     aPageStyle( ScGlobal::GetRscString(STR_STYLENAME_STANDARD) ),
     233             :     nRepeatStartX( SCCOL_REPEAT_NONE ),
     234             :     nRepeatEndX( SCCOL_REPEAT_NONE ),
     235             :     nRepeatStartY( SCROW_REPEAT_NONE ),
     236             :     nRepeatEndY( SCROW_REPEAT_NONE ),
     237             :     pTabProtection( NULL ),
     238             :     pColWidth( NULL ),
     239             :     mpRowHeights( static_cast<ScFlatUInt16RowSegments*>(NULL) ),
     240             :     pColFlags( NULL ),
     241             :     pRowFlags( NULL ),
     242        4322 :     mpHiddenCols(new ScFlatBoolColSegments),
     243        4322 :     mpHiddenRows(new ScFlatBoolRowSegments),
     244        4322 :     mpFilteredCols(new ScFlatBoolColSegments),
     245        4322 :     mpFilteredRows(new ScFlatBoolRowSegments),
     246             :     pOutlineTable( NULL ),
     247             :     pSheetEvents( NULL ),
     248             :     nTableAreaX( 0 ),
     249             :     nTableAreaY( 0 ),
     250             :     nTab( nNewTab ),
     251             :     pDocument( pDoc ),
     252             :     pSearchText ( NULL ),
     253             :     pSortCollator( NULL ),
     254             :     pRepeatColRange( NULL ),
     255             :     pRepeatRowRange( NULL ),
     256             :     nLockCount( 0 ),
     257             :     pScenarioRanges( NULL ),
     258             :     aScenarioColor( COL_LIGHTGRAY ),
     259             :     aTabBgColor( COL_AUTO ),
     260             :     nScenarioFlags( 0 ),
     261             :     pDBDataNoName(NULL),
     262             :     mpRangeName(NULL),
     263           0 :     mpCondFormatList( new ScConditionalFormatList() ),
     264             :     bScenario(false),
     265             :     bLayoutRTL(false),
     266             :     bLoadingRTL(false),
     267             :     bPageSizeValid(false),
     268             :     bTableAreaValid(false),
     269             :     bVisible(true),
     270             :     bStreamValid(false),
     271             :     bPendingRowHeights(false),
     272             :     bCalcNotification(false),
     273             :     bGlobalKeepQuery(false),
     274             :     bPrintEntireSheet(true),
     275             :     bActiveScenario(false),
     276             :     mbPageBreaksValid(false),
     277       25932 :     mbForceBreaks(false)
     278             : {
     279             : 
     280        4322 :     if (bColInfo)
     281             :     {
     282        2538 :         pColWidth  = new sal_uInt16[ MAXCOL+1 ];
     283        2538 :         pColFlags  = new sal_uInt8[ MAXCOL+1 ];
     284             : 
     285     2601450 :         for (SCCOL i=0; i<=MAXCOL; i++)
     286             :         {
     287     2598912 :             pColWidth[i] = STD_COL_WIDTH;
     288     2598912 :             pColFlags[i] = 0;
     289             :         }
     290             :     }
     291             : 
     292        4322 :     if (bRowInfo)
     293             :     {
     294        2544 :         mpRowHeights.reset(new ScFlatUInt16RowSegments(ScGlobal::nStdRowHeight));
     295        2544 :         pRowFlags  = new ScBitMaskCompressedArray< SCROW, sal_uInt8>( MAXROW, 0);
     296             :     }
     297             : 
     298        4322 :     if ( pDocument->IsDocVisible() )
     299             :     {
     300             :         //  when a sheet is added to a visible document,
     301             :         //  initialize its RTL flag from the system locale
     302          94 :         bLayoutRTL = ScGlobal::IsSystemRTL();
     303             :     }
     304             : 
     305        4322 :     ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
     306        4322 :     if (pDrawLayer)
     307             :     {
     308         472 :         if ( pDrawLayer->ScAddPage( nTab ) )    // sal_False (not inserted) during Undo
     309             :         {
     310         472 :             pDrawLayer->ScRenamePage( nTab, aName );
     311         472 :             sal_uLong nx = (sal_uLong) ((double) (MAXCOL+1) * STD_COL_WIDTH           * HMM_PER_TWIPS );
     312         472 :             sal_uLong ny = (sal_uLong) ((double) (MAXROW+1) * ScGlobal::nStdRowHeight * HMM_PER_TWIPS );
     313         472 :             pDrawLayer->SetPageSize( static_cast<sal_uInt16>(nTab), Size( nx, ny ), false );
     314             :         }
     315             :     }
     316             : 
     317     4430050 :     for (SCCOL k=0; k<=MAXCOL; k++)
     318     4425728 :         aCol[k].Init( k, nTab, pDocument );
     319        4322 : }
     320             : 
     321        8636 : ScTable::~ScTable()
     322             : {
     323        4318 :     if (!pDocument->IsInDtorClear())
     324             :     {
     325             :         //  nicht im dtor die Pages in der falschen Reihenfolge loeschen
     326             :         //  (nTab stimmt dann als Page-Number nicht!)
     327             :         //  In ScDocument::Clear wird hinterher per Clear am Draw Layer alles geloescht.
     328             : 
     329         188 :         ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
     330         188 :         if (pDrawLayer)
     331          42 :             pDrawLayer->ScRemovePage( nTab );
     332             :     }
     333             : 
     334        4318 :     delete[] pColWidth;
     335        4318 :     delete[] pColFlags;
     336        4318 :     delete pRowFlags;
     337        4318 :     delete pSheetEvents;
     338        4318 :     delete pOutlineTable;
     339        4318 :     delete pSearchText;
     340        4318 :     delete pRepeatColRange;
     341        4318 :     delete pRepeatRowRange;
     342        4318 :     delete pScenarioRanges;
     343        4318 :     delete mpRangeName;
     344        4318 :     delete pDBDataNoName;
     345        4318 :     DestroySortCollator();
     346             : 
     347     4425950 :     for (SCCOL k=0; k<=MAXCOL; k++)
     348     4421632 :         aCol[k].PrepareBroadcastersForDestruction();
     349        4318 : }
     350             : 
     351       73210 : void ScTable::GetName( OUString& rName ) const
     352             : {
     353       73210 :     rName = aName;
     354       73210 : }
     355             : 
     356         826 : void ScTable::SetName( const OUString& rNewName )
     357             : {
     358         826 :     aName = rNewName;
     359         826 :     aUpperName = OUString(); // invalidated if the name is changed
     360             : 
     361             :     // SetStreamValid is handled in ScDocument::RenameTab
     362         826 : }
     363             : 
     364       18584 : const OUString& ScTable::GetUpperName() const
     365             : {
     366       18584 :     if (aUpperName.isEmpty() && !aName.isEmpty())
     367        1348 :         aUpperName = ScGlobal::pCharClass->uppercase(aName);
     368       18584 :     return aUpperName;
     369             : }
     370             : 
     371          68 : void ScTable::SetVisible( bool bVis )
     372             : {
     373          68 :     if (bVisible != bVis && IsStreamValid())
     374           0 :         SetStreamValid(false);
     375             : 
     376          68 :     bVisible = bVis;
     377          68 : }
     378             : 
     379         698 : void ScTable::SetStreamValid( bool bSet, bool bIgnoreLock )
     380             : {
     381         698 :     if ( bIgnoreLock || !pDocument->IsStreamValidLocked() )
     382         698 :         bStreamValid = bSet;
     383         698 : }
     384             : 
     385          38 : void ScTable::SetPendingRowHeights( bool bSet )
     386             : {
     387          38 :     bPendingRowHeights = bSet;
     388          38 : }
     389             : 
     390         554 : void ScTable::SetLayoutRTL( bool bSet )
     391             : {
     392         554 :     bLayoutRTL = bSet;
     393         554 : }
     394             : 
     395          34 : void ScTable::SetLoadingRTL( bool bSet )
     396             : {
     397          34 :     bLoadingRTL = bSet;
     398          34 : }
     399             : 
     400         136 : void ScTable::SetTabBgColor(const Color& rColor)
     401             : {
     402         136 :     if (aTabBgColor != rColor)
     403             :     {
     404             :         // The tab color has changed.  Set this table 'modified'.
     405          50 :         aTabBgColor = rColor;
     406          50 :         if (IsStreamValid())
     407           0 :             SetStreamValid(false);
     408             :     }
     409         136 : }
     410             : 
     411           2 : void ScTable::SetScenario( bool bFlag )
     412             : {
     413           2 :     bScenario = bFlag;
     414           2 : }
     415             : 
     416           8 : void ScTable::SetLink( sal_uInt8 nMode,
     417             :                         const OUString& rDoc, const OUString& rFlt, const OUString& rOpt,
     418             :                         const OUString& rTab, sal_uLong nRefreshDelay )
     419             : {
     420           8 :     nLinkMode = nMode;
     421           8 :     aLinkDoc = rDoc;        // Datei
     422           8 :     aLinkFlt = rFlt;        // Filter
     423           8 :     aLinkOpt = rOpt;        // Filter-Optionen
     424           8 :     aLinkTab = rTab;        // Tabellenname in Quelldatei
     425           8 :     nLinkRefreshDelay = nRefreshDelay;  // refresh delay in seconds, 0==off
     426             : 
     427           8 :     if (IsStreamValid())
     428           0 :         SetStreamValid(false);
     429           8 : }
     430             : 
     431         196 : sal_uInt16 ScTable::GetOptimalColWidth( SCCOL nCol, OutputDevice* pDev,
     432             :                                     double nPPTX, double nPPTY,
     433             :                                     const Fraction& rZoomX, const Fraction& rZoomY,
     434             :                                     bool bFormula, const ScMarkData* pMarkData,
     435             :                                     const ScColWidthParam* pParam )
     436             : {
     437         196 :     return aCol[nCol].GetOptimalColWidth( pDev, nPPTX, nPPTY, rZoomX, rZoomY,
     438         392 :         bFormula, STD_COL_WIDTH - STD_EXTRA_WIDTH, pMarkData, pParam );
     439             : }
     440             : 
     441           0 : long ScTable::GetNeededSize( SCCOL nCol, SCROW nRow,
     442             :                                 OutputDevice* pDev,
     443             :                                 double nPPTX, double nPPTY,
     444             :                                 const Fraction& rZoomX, const Fraction& rZoomY,
     445             :                                 bool bWidth, bool bTotalSize )
     446             : {
     447           0 :     ScNeededSizeOptions aOptions;
     448           0 :     aOptions.bSkipMerged = false;       // zusammengefasste mitzaehlen
     449           0 :     aOptions.bTotalSize  = bTotalSize;
     450             : 
     451           0 :     return aCol[nCol].GetNeededSize
     452           0 :         ( nRow, pDev, nPPTX, nPPTY, rZoomX, rZoomY, bWidth, aOptions, NULL );
     453             : }
     454             : 
     455        6024 : bool ScTable::SetOptimalHeight(
     456             :     sc::RowHeightContext& rCxt, SCROW nStartRow, SCROW nEndRow,
     457             :     ScProgress* pOuterProgress, sal_uLong nProgressStart )
     458             : {
     459             :     OSL_ENSURE( rCxt.getExtraHeight() == 0 || rCxt.isForceAutoSize(),
     460             :         "automatic OptimalHeight with Extra" );
     461             : 
     462        6024 :     if ( !pDocument->IsAdjustHeightEnabled() )
     463             :     {
     464        3322 :         return false;
     465             :     }
     466             : 
     467        2702 :     SCSIZE  nCount = static_cast<SCSIZE>(nEndRow-nStartRow+1);
     468             : 
     469        2702 :     ScProgress* pProgress = GetProgressBar(nCount, GetWeightedCount(), pOuterProgress, pDocument);
     470             : 
     471        2702 :     rCxt.getHeightArray().resize(nCount, 0);
     472             : 
     473        2702 :     GetOptimalHeightsInColumn(rCxt, aCol, nStartRow, nEndRow, pProgress, nProgressStart);
     474             : 
     475        2702 :     SetRowHeightRangeFunc aFunc(this, rCxt.getPPTX(), rCxt.getPPTY());
     476        2702 :     bool bChanged = SetOptimalHeightsToRows(rCxt, aFunc, pRowFlags, nStartRow, nEndRow);
     477             : 
     478        2702 :     if ( pProgress != pOuterProgress )
     479          20 :         delete pProgress;
     480             : 
     481        2702 :     return bChanged;
     482             : }
     483             : 
     484           8 : void ScTable::SetOptimalHeightOnly(
     485             :     sc::RowHeightContext& rCxt, SCROW nStartRow, SCROW nEndRow,
     486             :     ScProgress* pOuterProgress, sal_uLong nProgressStart )
     487             : {
     488             :     OSL_ENSURE( rCxt.getExtraHeight() == 0 || rCxt.isForceAutoSize(),
     489             :         "automatic OptimalHeight with Extra" );
     490             : 
     491           8 :     if ( !pDocument->IsAdjustHeightEnabled() )
     492           8 :         return;
     493             : 
     494           8 :     SCSIZE  nCount = static_cast<SCSIZE>(nEndRow-nStartRow+1);
     495             : 
     496           8 :     ScProgress* pProgress = GetProgressBar(nCount, GetWeightedCount(), pOuterProgress, pDocument);
     497             : 
     498           8 :     rCxt.getHeightArray().resize(nCount, 0);
     499             : 
     500           8 :     GetOptimalHeightsInColumn(rCxt, aCol, nStartRow, nEndRow, pProgress, nProgressStart);
     501             : 
     502           8 :     SetRowHeightOnlyFunc aFunc(this);
     503           8 :     SetOptimalHeightsToRows(rCxt, aFunc, pRowFlags, nStartRow, nEndRow);
     504             : 
     505           8 :     if ( pProgress != pOuterProgress )
     506           8 :         delete pProgress;
     507             : }
     508             : 
     509          62 : bool ScTable::GetCellArea( SCCOL& rEndCol, SCROW& rEndRow ) const
     510             : {
     511          62 :     bool bFound = false;
     512          62 :     SCCOL nMaxX = 0;
     513          62 :     SCROW nMaxY = 0;
     514       63550 :     for (SCCOL i=0; i<=MAXCOL; i++)
     515             :         {
     516       63488 :             if (!aCol[i].IsEmptyData())
     517             :             {
     518         318 :                 bFound = true;
     519         318 :                 nMaxX = i;
     520         318 :                 SCROW nRow = aCol[i].GetLastDataPos();
     521         318 :                 if (nRow > nMaxY)
     522          60 :                     nMaxY = nRow;
     523             :             }
     524       63488 :             if ( aCol[i].HasCellNotes() )
     525             :             {
     526          10 :                 SCROW maxNoteRow = aCol[i].GetCellNotesMaxRow();
     527          10 :                 if (maxNoteRow >= nMaxY)
     528             :                 {
     529           4 :                     bFound = true;
     530           4 :                     nMaxY = maxNoteRow;
     531             :                 }
     532          10 :                 if (i>nMaxX)
     533             :                 {
     534          10 :                     bFound = true;
     535          10 :                     nMaxX = i;
     536             :                 }
     537             :             }
     538             :         }
     539             : 
     540          62 :     rEndCol = nMaxX;
     541          62 :     rEndRow = nMaxY;
     542          62 :     return bFound;
     543             : }
     544             : 
     545        6884 : bool ScTable::GetTableArea( SCCOL& rEndCol, SCROW& rEndRow ) const
     546             : {
     547        6884 :     bool bRet = true;               //! merken?
     548        6884 :     if (!bTableAreaValid)
     549             :     {
     550        1062 :         bRet = GetPrintArea(nTableAreaX, nTableAreaY, true);
     551        1062 :         bTableAreaValid = true;
     552             :     }
     553        6884 :     rEndCol = nTableAreaX;
     554        6884 :     rEndRow = nTableAreaY;
     555        6884 :     return bRet;
     556             : }
     557             : 
     558             : const SCCOL SC_COLUMNS_STOP = 30;
     559             : 
     560        4634 : bool ScTable::GetPrintArea( SCCOL& rEndCol, SCROW& rEndRow, bool bNotes, bool bFullFormattedArea ) const
     561             : {
     562        4634 :     bool bFound = false;
     563        4634 :     SCCOL nMaxX = 0;
     564        4634 :     SCROW nMaxY = 0;
     565             :     SCCOL i;
     566             : 
     567     4749850 :     for (i=0; i<=MAXCOL; i++)               // Daten testen
     568             :         {
     569     4745216 :             if (!aCol[i].IsEmptyData())
     570             :             {
     571        8832 :                 bFound = true;
     572        8832 :                 if (i>nMaxX)
     573        7288 :                     nMaxX = i;
     574        8832 :                 SCROW nColY = aCol[i].GetLastDataPos();
     575        8832 :                 if (nColY > nMaxY)
     576        2490 :                     nMaxY = nColY;
     577             :             }
     578     4745216 :             if (bNotes)
     579             :             {
     580     4143104 :                 if ( aCol[i].HasCellNotes() )
     581             :                 {
     582          76 :                     SCROW maxNoteRow = aCol[i].GetCellNotesMaxRow();
     583          76 :                     if (maxNoteRow >= nMaxY)
     584             :                     {
     585          68 :                         bFound = true;
     586          68 :                         nMaxY = maxNoteRow;
     587             :                     }
     588          76 :                     if (i>nMaxX)
     589             :                     {
     590          58 :                         bFound = true;
     591          58 :                         nMaxX = i;
     592             :                     }
     593             :                 }
     594             :             }
     595             :         }
     596             : 
     597        4634 :     SCCOL nMaxDataX = nMaxX;
     598             : 
     599     4749850 :     for (i=0; i<=MAXCOL; i++)               // Attribute testen
     600             :     {
     601             :         SCROW nLastRow;
     602     4745216 :         if (aCol[i].GetLastVisibleAttr( nLastRow, bFullFormattedArea ))
     603             :         {
     604        2046 :             bFound = true;
     605        2046 :             nMaxX = i;
     606        2046 :             if (nLastRow > nMaxY)
     607          16 :                 nMaxY = nLastRow;
     608             :         }
     609             :     }
     610             : 
     611        4634 :     if (nMaxX == MAXCOL)                    // Attribute rechts weglassen
     612             :     {
     613           0 :         --nMaxX;
     614           0 :         while ( nMaxX>0 && aCol[nMaxX].IsVisibleAttrEqual(aCol[nMaxX+1]) )
     615           0 :             --nMaxX;
     616             :     }
     617             : 
     618        4634 :     if ( nMaxX < nMaxDataX )
     619             :     {
     620         210 :         nMaxX = nMaxDataX;
     621             :     }
     622        4424 :     else if ( nMaxX > nMaxDataX )
     623             :     {
     624         106 :         SCCOL nAttrStartX = nMaxDataX + 1;
     625         398 :         while ( nAttrStartX < MAXCOL )
     626             :         {
     627         292 :             SCCOL nAttrEndX = nAttrStartX;
     628       23960 :             while ( nAttrEndX < MAXCOL && aCol[nAttrStartX].IsVisibleAttrEqual(aCol[nAttrEndX+1]) )
     629       23376 :                 ++nAttrEndX;
     630         292 :             if ( nAttrEndX + 1 - nAttrStartX >= SC_COLUMNS_STOP )
     631             :             {
     632             :                 // found equally-formatted columns behind data -> stop before these columns
     633         106 :                 nMaxX = nAttrStartX - 1;
     634             : 
     635             :                 // also don't include default-formatted columns before that
     636             :                 SCROW nDummyRow;
     637         212 :                 while ( nMaxX > nMaxDataX && !aCol[nMaxX].GetLastVisibleAttr( nDummyRow ) )
     638           0 :                     --nMaxX;
     639         106 :                 break;
     640             :             }
     641         186 :             nAttrStartX = nAttrEndX + 1;
     642             :         }
     643             :     }
     644             : 
     645        4634 :     rEndCol = nMaxX;
     646        4634 :     rEndRow = nMaxY;
     647        4634 :     return bFound;
     648             : }
     649             : 
     650           0 : bool ScTable::GetPrintAreaHor( SCROW nStartRow, SCROW nEndRow,
     651             :                                 SCCOL& rEndCol, bool /* bNotes */ ) const
     652             : {
     653           0 :     bool bFound = false;
     654           0 :     SCCOL nMaxX = 0;
     655             :     SCCOL i;
     656             : 
     657           0 :     for (i=0; i<=MAXCOL; i++)               // Attribute testen
     658             :     {
     659           0 :         if (aCol[i].HasVisibleAttrIn( nStartRow, nEndRow ))
     660             :         {
     661           0 :             bFound = true;
     662           0 :             nMaxX = i;
     663             :         }
     664             :     }
     665             : 
     666           0 :     if (nMaxX == MAXCOL)                    // Attribute rechts weglassen
     667             :     {
     668           0 :         --nMaxX;
     669           0 :         while ( nMaxX>0 && aCol[nMaxX].IsVisibleAttrEqual(aCol[nMaxX+1], nStartRow, nEndRow) )
     670           0 :             --nMaxX;
     671             :     }
     672             : 
     673           0 :     for (i=0; i<=MAXCOL; i++)               // Daten testen
     674             :     {
     675           0 :         if (!aCol[i].IsEmptyBlock( nStartRow, nEndRow ))        //! bNotes ??????
     676             :         {
     677           0 :             bFound = true;
     678           0 :             if (i>nMaxX)
     679           0 :                 nMaxX = i;
     680             :         }
     681             :     }
     682             : 
     683           0 :     rEndCol = nMaxX;
     684           0 :     return bFound;
     685             : }
     686             : 
     687          80 : bool ScTable::GetPrintAreaVer( SCCOL nStartCol, SCCOL nEndCol,
     688             :                                 SCROW& rEndRow, bool bNotes ) const
     689             : {
     690          80 :     bool bFound = false;
     691          80 :     SCROW nMaxY = 0;
     692             :     SCCOL i;
     693             : 
     694         328 :     for (i=nStartCol; i<=nEndCol; i++)              // Attribute testen
     695             :     {
     696             :         SCROW nLastRow;
     697         248 :         if (aCol[i].GetLastVisibleAttr( nLastRow ))
     698             :         {
     699           0 :             bFound = true;
     700           0 :             if (nLastRow > nMaxY)
     701           0 :                 nMaxY = nLastRow;
     702             :         }
     703             :     }
     704             : 
     705         328 :     for (i=nStartCol; i<=nEndCol; i++)              // Daten testen
     706             :     {
     707         248 :         if (!aCol[i].IsEmptyData())
     708             :         {
     709          98 :             bFound = true;
     710          98 :             SCROW nColY = aCol[i].GetLastDataPos();
     711          98 :             if (nColY > nMaxY)
     712          26 :                 nMaxY = nColY;
     713             :         }
     714         248 :         if (bNotes)
     715             :         {
     716          16 :             if ( aCol[i].HasCellNotes() )
     717             :             {
     718           8 :                 SCROW maxNoteRow =aCol[i].GetCellNotesMaxRow();
     719           8 :                 if (maxNoteRow > nMaxY)
     720             :                 {
     721           8 :                     bFound = true;
     722           8 :                     nMaxY = maxNoteRow;
     723             :                 }
     724             :             }
     725             :         }
     726             :     }
     727             : 
     728          80 :     rEndRow = nMaxY;
     729          80 :     return bFound;
     730             : }
     731             : 
     732        2988 : bool ScTable::GetDataStart( SCCOL& rStartCol, SCROW& rStartRow ) const
     733             : {
     734        2988 :     bool bFound = false;
     735        2988 :     SCCOL nMinX = MAXCOL;
     736        2988 :     SCROW nMinY = MAXROW;
     737             :     SCCOL i;
     738             : 
     739     3062700 :     for (i=0; i<=MAXCOL; i++)                   // Attribute testen
     740             :     {
     741             :         SCROW nFirstRow;
     742     3059712 :         if (aCol[i].GetFirstVisibleAttr( nFirstRow ))
     743             :         {
     744        1700 :             if (!bFound)
     745         190 :                 nMinX = i;
     746        1700 :             bFound = true;
     747        1700 :             if (nFirstRow < nMinY)
     748         334 :                 nMinY = nFirstRow;
     749             :         }
     750             :     }
     751             : 
     752        2988 :     if (nMinX == 0)                                     // Attribute links weglassen
     753             :     {
     754         190 :         if ( aCol[0].IsVisibleAttrEqual(aCol[1]) )      // keine einzelnen
     755             :         {
     756          28 :             ++nMinX;
     757         224 :             while ( nMinX<MAXCOL && aCol[nMinX].IsVisibleAttrEqual(aCol[nMinX-1]) )
     758         168 :                 ++nMinX;
     759             :         }
     760             :     }
     761             : 
     762        2988 :     bool bDatFound = false;
     763     3062700 :     for (i=0; i<=MAXCOL; i++)                   // Daten testen
     764             :     {
     765     3059712 :         if (!aCol[i].IsEmptyData())
     766             :         {
     767        5540 :             if (!bDatFound && i<nMinX)
     768        1274 :                 nMinX = i;
     769        5540 :             bFound = bDatFound = true;
     770        5540 :             SCROW nRow = aCol[i].GetFirstDataPos();
     771        5540 :             if (nRow < nMinY)
     772        1482 :                 nMinY = nRow;
     773             :         }
     774     3059712 :         if ( aCol[i].HasCellNotes() )
     775             :         {
     776          62 :             SCROW minNoteRow = aCol[i].GetCellNotesMinRow();
     777          62 :             if (minNoteRow <= nMinY)
     778             :             {
     779          42 :                 bFound = true;
     780          42 :                 nMinY = minNoteRow;
     781             :             }
     782          62 :             if (i<nMinX)
     783             :             {
     784          34 :                 bFound = true;
     785          34 :                 nMinX = i;
     786             :             }
     787             :         }
     788             :     }
     789        2988 :     rStartCol = nMinX;
     790        2988 :     rStartRow = nMinY;
     791        2988 :     return bFound;
     792             : }
     793             : 
     794          78 : void ScTable::GetDataArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow,
     795             :                            bool bIncludeOld, bool bOnlyDown ) const
     796             : {
     797             :     // return the smallest area containing at least all contiguous cells having data. This area
     798             :     // is a square containing also empty cells. It may shrink or extend the area given as input
     799             :     // Flags as modifiers:
     800             :     //
     801             :     //     bIncludeOld = true ensure that the returned area contains at least the initial area,
     802             :     //                   independently of the emptniess of rows / columns (i.e. does not allow shrinking)
     803             :     //     bOnlyDown = true means extend / shrink the inputed area only down, i.e modifiy only rEndRow
     804             : 
     805          78 :     bool bLeft = false;
     806          78 :     bool bRight  = false;
     807          78 :     bool bTop = false;
     808          78 :     bool bBottom = false;
     809          78 :     bool bChanged = false;
     810             : 
     811         528 :     do
     812             :     {
     813         528 :         bChanged = false;
     814             : 
     815         528 :         if (!bOnlyDown)
     816             :         {
     817         526 :             SCROW nStart = rStartRow;
     818         526 :             SCROW nEnd = rEndRow;
     819         526 :             if (nStart>0) --nStart;
     820         526 :             if (nEnd<MAXROW) ++nEnd;
     821             : 
     822         526 :             if (rEndCol < MAXCOL)
     823         526 :                 if (!aCol[rEndCol+1].IsEmptyBlock(nStart,nEnd))
     824             :                 {
     825         280 :                     ++rEndCol;
     826         280 :                     bChanged = true;
     827         280 :                     bRight = true;
     828             :                 }
     829             : 
     830         526 :             if (rStartCol > 0)
     831         214 :                 if (!aCol[rStartCol-1].IsEmptyBlock(nStart,nEnd))
     832             :                 {
     833           0 :                     --rStartCol;
     834           0 :                     bChanged = true;
     835           0 :                     bLeft = true;
     836             :                 }
     837             : 
     838         526 :             if (rStartRow > 0)
     839             :             {
     840         214 :                 SCROW nTest = rStartRow-1;
     841         214 :                 bool needExtend = false;
     842         632 :                 for ( SCCOL i = rStartCol; i<=rEndCol && !needExtend; i++)
     843         418 :                     if (aCol[i].HasDataAt(nTest))
     844         132 :                         needExtend = true;
     845         214 :                 if (needExtend)
     846             :                 {
     847         132 :                     --rStartRow;
     848         132 :                     bChanged = true;
     849         132 :                     bTop = true;
     850             :                 }
     851             :             }
     852             :         }
     853             : 
     854         528 :         if (rEndRow < MAXROW)
     855             :         {
     856         528 :             SCROW nTest = rEndRow+1;
     857         528 :             bool needExtend = false;
     858        2456 :             for ( SCCOL i = rStartCol; i<=rEndCol && !needExtend; i++)
     859        1928 :                 if (aCol[i].HasDataAt(nTest))
     860         164 :                     needExtend = true;
     861         528 :             if (needExtend)
     862             :             {
     863         164 :                 ++rEndRow;
     864         164 :                 bChanged = true;
     865         164 :                 bBottom = true;
     866             :             }
     867             :         }
     868             :     }
     869             :     while( bChanged );
     870             : 
     871          78 :     if ( !bIncludeOld && !bOnlyDown )
     872             :     {
     873          32 :         if ( !bLeft )
     874          64 :             while ( aCol[rStartCol].IsEmptyBlock(rStartRow,rEndRow) && rStartCol < MAXCOL && rStartCol < rEndCol)
     875           0 :                 ++rStartCol;
     876             : 
     877          32 :         if ( !bRight )
     878           0 :             while ( aCol[rEndCol].IsEmptyBlock(rStartRow,rEndRow) && rEndCol > 0 && rStartCol < rEndCol)
     879           0 :                 --rEndCol;
     880             : 
     881          32 :         if ( !bTop && rStartRow < MAXROW && rStartRow < rEndRow )
     882             :         {
     883          32 :             bool bShrink = true;
     884          32 :             do
     885             :             {
     886          64 :                 for ( SCCOL i = rStartCol; i<=rEndCol && bShrink; i++)
     887          32 :                     if (aCol[i].HasDataAt(rStartRow))
     888          32 :                         bShrink = false;
     889          32 :                 if (bShrink)
     890           0 :                     ++rStartRow;
     891           0 :             } while (bShrink && rStartRow < MAXROW && rStartRow < rEndRow);
     892             :         }
     893             :     }
     894             : 
     895          78 :     if ( !bIncludeOld )
     896             :     {
     897          32 :         if ( !bBottom && rEndRow > 0 && rStartRow < rEndRow )
     898             :         {
     899           0 :             SCROW nLastDataRow = GetLastDataRow( rStartCol, rEndCol, rEndRow);
     900           0 :             if (nLastDataRow < rEndRow)
     901           0 :                 rEndRow = std::max( rStartRow, nLastDataRow);
     902             :         }
     903             :     }
     904          78 : }
     905             : 
     906          22 : bool ScTable::ShrinkToUsedDataArea( bool& o_bShrunk, SCCOL& rStartCol, SCROW& rStartRow,
     907             :         SCCOL& rEndCol, SCROW& rEndRow, bool bColumnsOnly ) const
     908             : {
     909          22 :     o_bShrunk = false;
     910             : 
     911          22 :     PutInOrder( rStartCol, rEndCol);
     912          22 :     PutInOrder( rStartRow, rEndRow);
     913          22 :     if (rStartCol < 0)
     914           0 :         rStartCol = 0, o_bShrunk = true;
     915          22 :     if (rStartRow < 0)
     916           0 :         rStartRow = 0, o_bShrunk = true;
     917          22 :     if (rEndCol > MAXCOL)
     918           0 :         rEndCol = MAXCOL, o_bShrunk = true;
     919          22 :     if (rEndRow > MAXROW)
     920           0 :         rEndRow = MAXROW, o_bShrunk = true;
     921             : 
     922             :     bool bChanged;
     923          28 :     do
     924             :     {
     925          28 :         bChanged = false;
     926             : 
     927          56 :         while (rStartCol < rEndCol)
     928             :         {
     929           4 :             if (aCol[rEndCol].IsEmptyBlock( rStartRow, rEndRow))
     930             :             {
     931           0 :                 --rEndCol;
     932           0 :                 bChanged = true;
     933             :             }
     934             :             else
     935           4 :                 break;  // while
     936             :         }
     937             : 
     938          56 :         while (rStartCol < rEndCol)
     939             :         {
     940           4 :             if (aCol[rStartCol].IsEmptyBlock( rStartRow, rEndRow))
     941             :             {
     942           0 :                 ++rStartCol;
     943           0 :                 bChanged = true;
     944             :             }
     945             :             else
     946           4 :                 break;  // while
     947             :         }
     948             : 
     949          28 :         if (!bColumnsOnly)
     950             :         {
     951          28 :             if (rStartRow < rEndRow)
     952             :             {
     953          26 :                 bool bFound = false;
     954          52 :                 for (SCCOL i=rStartCol; i<=rEndCol && !bFound; i++)
     955          26 :                     if (aCol[i].HasDataAt( rStartRow))
     956          20 :                         bFound = true;
     957          26 :                 if (!bFound)
     958             :                 {
     959           6 :                     ++rStartRow;
     960           6 :                     bChanged = true;
     961             :                 }
     962             :             }
     963             : 
     964          28 :             if (rStartRow < rEndRow)
     965             :             {
     966          26 :                 SCROW nLastDataRow = GetLastDataRow( rStartCol, rEndCol, rEndRow);
     967          26 :                 if (0 <= nLastDataRow && nLastDataRow < rEndRow)
     968             :                 {
     969           0 :                     rEndRow = std::max( rStartRow, nLastDataRow);
     970           0 :                     bChanged = true;
     971             :                 }
     972             :             }
     973             :         }
     974             : 
     975          28 :         if (bChanged)
     976           6 :             o_bShrunk = true;
     977             :     } while( bChanged );
     978             : 
     979          62 :     return rStartCol != rEndCol || (bColumnsOnly ?
     980           0 :             !aCol[rStartCol].IsEmptyBlock( rStartRow, rEndRow) :
     981          42 :             (rStartRow != rEndRow || aCol[rStartCol].HasDataAt( rStartRow)));
     982             : }
     983             : 
     984          26 : SCROW ScTable::GetLastDataRow( SCCOL nCol1, SCCOL nCol2, SCROW nLastRow ) const
     985             : {
     986          26 :     if (!ValidCol(nCol1) || !ValidCol(nCol2))
     987           0 :         return -1;
     988             : 
     989          26 :     SCROW nNewLastRow = 0;
     990          56 :     for (SCCOL i = nCol1; i <= nCol2; ++i)
     991             :     {
     992          30 :         SCROW nThis = aCol[i].GetLastDataPos(nLastRow);
     993          30 :         if (nNewLastRow < nThis)
     994          26 :             nNewLastRow = nThis;
     995             :     }
     996             : 
     997          26 :     return nNewLastRow;
     998             : }
     999             : 
    1000        3134 : SCSIZE ScTable::GetEmptyLinesInBlock( SCCOL nStartCol, SCROW nStartRow,
    1001             :                                         SCCOL nEndCol, SCROW nEndRow, ScDirection eDir ) const
    1002             : {
    1003        3134 :     SCSIZE nCount = 0;
    1004             :     SCCOL nCol;
    1005        3154 :     if ((eDir == DIR_BOTTOM) || (eDir == DIR_TOP))
    1006             :     {
    1007          20 :         nCount = static_cast<SCSIZE>(nEndRow - nStartRow + 1);
    1008          86 :         for (nCol = nStartCol; nCol <= nEndCol; nCol++)
    1009          66 :             nCount = std::min(nCount, aCol[nCol].GetEmptyLinesInBlock(nStartRow, nEndRow, eDir));
    1010             :     }
    1011        3114 :     else if (eDir == DIR_RIGHT)
    1012             :     {
    1013        3110 :         nCol = nEndCol;
    1014     6267336 :         while (((SCsCOL)nCol >= (SCsCOL)nStartCol) &&
    1015     3130770 :                  aCol[nCol].IsEmptyBlock(nStartRow, nEndRow))
    1016             :         {
    1017     3130346 :             nCount++;
    1018     3130346 :             nCol--;
    1019             :         }
    1020             :     }
    1021             :     else
    1022             :     {
    1023           4 :         nCol = nStartCol;
    1024           8 :         while ((nCol <= nEndCol) && aCol[nCol].IsEmptyBlock(nStartRow, nEndRow))
    1025             :         {
    1026           0 :             nCount++;
    1027           0 :             nCol++;
    1028             :         }
    1029             :     }
    1030        3134 :     return nCount;
    1031             : }
    1032             : 
    1033           0 : bool ScTable::IsEmptyLine( SCROW nRow, SCCOL nStartCol, SCCOL nEndCol ) const
    1034             : {
    1035           0 :     bool bFound = false;
    1036           0 :     for (SCCOL i=nStartCol; i<=nEndCol && !bFound; i++)
    1037           0 :         if (aCol[i].HasDataAt(nRow))
    1038           0 :             bFound = true;
    1039           0 :     return !bFound;
    1040             : }
    1041             : 
    1042           0 : void ScTable::LimitChartArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow ) const
    1043             : {
    1044           0 :     while ( rStartCol<rEndCol && aCol[rStartCol].IsEmptyBlock(rStartRow,rEndRow) )
    1045           0 :         ++rStartCol;
    1046             : 
    1047           0 :     while ( rStartCol<rEndCol && aCol[rEndCol].IsEmptyBlock(rStartRow,rEndRow) )
    1048           0 :         --rEndCol;
    1049             : 
    1050           0 :     while ( rStartRow<rEndRow && IsEmptyLine(rStartRow, rStartCol, rEndCol) )
    1051           0 :         ++rStartRow;
    1052             : 
    1053           0 :     while ( rStartRow<rEndRow && IsEmptyLine(rEndRow, rStartCol, rEndCol) )
    1054           0 :         --rEndRow;
    1055           0 : }
    1056             : 
    1057          32 : SCCOL ScTable::FindNextVisibleCol( SCCOL nCol, bool bRight ) const
    1058             : {
    1059          32 :     if(bRight)
    1060             :     {
    1061          26 :         nCol++;
    1062          26 :         SCCOL nEnd = 0;
    1063          26 :         bool bHidden = pDocument->ColHidden(nCol, nTab, NULL, &nEnd);
    1064          26 :         if(bHidden)
    1065           4 :             nCol = nEnd +1;
    1066             : 
    1067          26 :         return std::min<SCCOL>(MAXCOL, nCol);
    1068             :     }
    1069             :     else
    1070             :     {
    1071           6 :         nCol--;
    1072           6 :         SCCOL nStart = MAXCOL;
    1073           6 :         bool bHidden = pDocument->ColHidden(nCol, nTab, &nStart, NULL);
    1074           6 :         if(bHidden)
    1075           0 :             nCol = nStart - 1;
    1076             : 
    1077           6 :         return std::max<SCCOL>(0, nCol);
    1078             :     }
    1079             : }
    1080             : 
    1081          16 : SCCOL ScTable::FindNextVisibleColWithContent( SCCOL nCol, bool bRight, SCROW nRow ) const
    1082             : {
    1083          16 :     if(bRight)
    1084             :     {
    1085          12 :         if(nCol == MAXCOL)
    1086           0 :             return MAXCOL;
    1087             : 
    1088        4116 :         do
    1089             :         {
    1090        4124 :             nCol++;
    1091        4124 :             SCCOL nEndCol = 0;
    1092        4124 :             bool bHidden = pDocument->ColHidden( nCol, nTab, NULL, &nEndCol );
    1093        4124 :             if(bHidden)
    1094             :             {
    1095           4 :                 nCol = nEndCol +1;
    1096           4 :                 if(nEndCol >= MAXCOL)
    1097           8 :                     return MAXCOL;
    1098             :             }
    1099             : 
    1100        4124 :             if(aCol[nCol].HasVisibleDataAt(nRow))
    1101           8 :                 return nCol;
    1102             :         }
    1103             :         while(nCol < MAXCOL);
    1104             : 
    1105           4 :         return MAXCOL;
    1106             :     }
    1107             :     else
    1108             :     {
    1109           4 :         if(nCol == 0)
    1110           0 :             return 0;
    1111             : 
    1112          12 :         do
    1113             :         {
    1114          14 :             nCol--;
    1115          14 :             SCCOL nStartCol = MAXCOL;
    1116          14 :             bool bHidden = pDocument->ColHidden( nCol, nTab, &nStartCol, NULL );
    1117          14 :             if(bHidden)
    1118             :             {
    1119           0 :                 nCol = nStartCol -1;
    1120           0 :                 if(nCol <= 0)
    1121           2 :                     return 0;
    1122             :             }
    1123             : 
    1124          14 :             if(aCol[nCol].HasVisibleDataAt(nRow))
    1125           2 :                 return nCol;
    1126             :         }
    1127             :         while(nCol > 0);
    1128             : 
    1129           2 :         return 0;
    1130             :     }
    1131             : }
    1132             : 
    1133          52 : void ScTable::FindAreaPos( SCCOL& rCol, SCROW& rRow, ScMoveDirection eDirection ) const
    1134             : {
    1135          52 :     if (eDirection == SC_MOVE_LEFT || eDirection == SC_MOVE_RIGHT)
    1136             :     {
    1137          26 :         SCCOL nNewCol = rCol;
    1138          26 :         bool bThere = aCol[nNewCol].HasVisibleDataAt(rRow);
    1139          26 :         bool bRight = (eDirection == SC_MOVE_RIGHT);
    1140          26 :         if (bThere)
    1141             :         {
    1142          16 :             if(nNewCol >= MAXCOL && eDirection == SC_MOVE_RIGHT)
    1143           0 :                 return;
    1144          16 :             else if(nNewCol == 0 && eDirection == SC_MOVE_LEFT)
    1145           0 :                 return;
    1146             : 
    1147          16 :             SCCOL nNextCol = FindNextVisibleCol( nNewCol, bRight );
    1148             : 
    1149          16 :             if(aCol[nNextCol].HasVisibleDataAt(rRow))
    1150             :             {
    1151          10 :                 bool bFound = false;
    1152          10 :                 nNewCol = nNextCol;
    1153          16 :                 do
    1154             :                 {
    1155          16 :                     nNextCol = FindNextVisibleCol( nNewCol, bRight );
    1156          16 :                     if(aCol[nNextCol].HasVisibleDataAt(rRow))
    1157           6 :                         nNewCol = nNextCol;
    1158             :                     else
    1159          10 :                         bFound = true;
    1160             :                 }
    1161          22 :                 while(!bFound && nNextCol > 0 && nNextCol < MAXCOL);
    1162             :             }
    1163             :             else
    1164             :             {
    1165           6 :                 nNewCol = FindNextVisibleColWithContent(nNewCol, bRight, rRow);
    1166             :             }
    1167             :         }
    1168             :         else
    1169             :         {
    1170          10 :             nNewCol = FindNextVisibleColWithContent(nNewCol, bRight, rRow);
    1171             :         }
    1172             : 
    1173          26 :         if (nNewCol<0)
    1174           0 :             nNewCol=0;
    1175          26 :         if (nNewCol>MAXCOL)
    1176           0 :             nNewCol=MAXCOL;
    1177          26 :         rCol = nNewCol;
    1178             :     }
    1179             :     else
    1180             :     {
    1181          26 :         aCol[rCol].FindDataAreaPos(rRow,eDirection == SC_MOVE_DOWN);
    1182             :     }
    1183             : }
    1184             : 
    1185           0 : bool ScTable::ValidNextPos( SCCOL nCol, SCROW nRow, const ScMarkData& rMark,
    1186             :                                 bool bMarked, bool bUnprotected ) const
    1187             : {
    1188           0 :     if (!ValidCol(nCol) || !ValidRow(nRow))
    1189           0 :         return false;
    1190             : 
    1191           0 :     if (pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED))
    1192             :         // Skip an overlapped cell.
    1193           0 :         return false;
    1194             : 
    1195           0 :     if (bMarked && !rMark.IsCellMarked(nCol,nRow))
    1196           0 :         return false;
    1197             : 
    1198           0 :     if (bUnprotected && static_cast<const ScProtectionAttr*>(
    1199           0 :                         GetAttr(nCol,nRow,ATTR_PROTECTION))->GetProtection())
    1200           0 :         return false;
    1201             : 
    1202           0 :     if (bMarked || bUnprotected)        //! auch sonst ???
    1203             :     {
    1204             :         //  ausgeblendete muessen uebersprungen werden, weil der Cursor sonst
    1205             :         //  auf der naechsten Zelle landet, auch wenn die geschuetzt/nicht markiert ist.
    1206             :         //! per Extra-Parameter steuern, nur fuer Cursor-Bewegung ???
    1207             : 
    1208           0 :         if (RowHidden(nRow))
    1209           0 :             return false;
    1210             : 
    1211           0 :         if (ColHidden(nCol))
    1212           0 :             return false;
    1213             :     }
    1214             : 
    1215           0 :     return true;
    1216             : }
    1217             : 
    1218           0 : void ScTable::GetNextPos( SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY,
    1219             :                                 bool bMarked, bool bUnprotected, const ScMarkData& rMark ) const
    1220             : {
    1221           0 :     if (bUnprotected && !IsProtected())     // Tabelle ueberhaupt geschuetzt?
    1222           0 :         bUnprotected = false;
    1223             : 
    1224           0 :     sal_uInt16 nWrap = 0;
    1225           0 :     SCsCOL nCol = rCol;
    1226           0 :     SCsROW nRow = rRow;
    1227             : 
    1228           0 :     nCol = sal::static_int_cast<SCsCOL>( nCol + nMovX );
    1229           0 :     nRow = sal::static_int_cast<SCsROW>( nRow + nMovY );
    1230             : 
    1231             :     OSL_ENSURE( !nMovY || !bUnprotected,
    1232             :                 "GetNextPos mit bUnprotected horizontal nicht implementiert" );
    1233             : 
    1234           0 :     if ( nMovY && bMarked )
    1235             :     {
    1236           0 :         bool bUp = ( nMovY < 0 );
    1237           0 :         nRow = rMark.GetNextMarked( nCol, nRow, bUp );
    1238           0 :         while ( ValidRow(nRow) &&
    1239           0 :                 (RowHidden(nRow) || pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED)) )
    1240             :         {
    1241             :             //  ausgeblendete ueberspringen (s.o.)
    1242           0 :             nRow += nMovY;
    1243           0 :             nRow = rMark.GetNextMarked( nCol, nRow, bUp );
    1244             :         }
    1245             : 
    1246           0 :         while ( nRow < 0 || nRow > MAXROW )
    1247             :         {
    1248           0 :             nCol = sal::static_int_cast<SCsCOL>( nCol + static_cast<SCsCOL>(nMovY) );
    1249           0 :             while ( ValidCol(nCol) && ColHidden(nCol) )
    1250           0 :                 nCol = sal::static_int_cast<SCsCOL>( nCol + static_cast<SCsCOL>(nMovY) );   //  skip hidden rows (see above)
    1251           0 :             if (nCol < 0)
    1252             :             {
    1253           0 :                 nCol = MAXCOL;
    1254           0 :                 if (++nWrap >= 2)
    1255           0 :                     return;
    1256             :             }
    1257           0 :             else if (nCol > MAXCOL)
    1258             :             {
    1259           0 :                 nCol = 0;
    1260           0 :                 if (++nWrap >= 2)
    1261           0 :                     return;
    1262             :             }
    1263           0 :             if (nRow < 0)
    1264           0 :                 nRow = MAXROW;
    1265           0 :             else if (nRow > MAXROW)
    1266           0 :                 nRow = 0;
    1267           0 :             nRow = rMark.GetNextMarked( nCol, nRow, bUp );
    1268           0 :             while ( ValidRow(nRow) &&
    1269           0 :                     (RowHidden(nRow) || pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED)) )
    1270             :             {
    1271             :                 //  ausgeblendete ueberspringen (s.o.)
    1272           0 :                 nRow += nMovY;
    1273           0 :                 nRow = rMark.GetNextMarked( nCol, nRow, bUp );
    1274             :             }
    1275             :         }
    1276             :     }
    1277             : 
    1278           0 :     if ( nMovX && ( bMarked || bUnprotected ) )
    1279             :     {
    1280             :         // initiales Weiterzaehlen wrappen:
    1281           0 :         if (nCol<0)
    1282             :         {
    1283           0 :             nCol = MAXCOL;
    1284           0 :             --nRow;
    1285           0 :             if (nRow<0)
    1286           0 :                 nRow = MAXROW;
    1287             :         }
    1288           0 :         if (nCol>MAXCOL)
    1289             :         {
    1290           0 :             nCol = 0;
    1291           0 :             ++nRow;
    1292           0 :             if (nRow>MAXROW)
    1293           0 :                 nRow = 0;
    1294             :         }
    1295             : 
    1296           0 :         if ( !ValidNextPos(nCol, nRow, rMark, bMarked, bUnprotected) )
    1297             :         {
    1298           0 :             boost::scoped_array<SCsROW> pNextRows(new SCsROW[MAXCOL+1]);
    1299             :             SCCOL i;
    1300             : 
    1301           0 :             if ( nMovX > 0 )                            //  vorwaerts
    1302             :             {
    1303           0 :                 for (i=0; i<=MAXCOL; i++)
    1304           0 :                     pNextRows[i] = (i<nCol) ? (nRow+1) : nRow;
    1305           0 :                 do
    1306             :                 {
    1307           0 :                     SCsROW nNextRow = pNextRows[nCol] + 1;
    1308           0 :                     if ( bMarked )
    1309           0 :                         nNextRow = rMark.GetNextMarked( nCol, nNextRow, false );
    1310           0 :                     if ( bUnprotected )
    1311           0 :                         nNextRow = aCol[nCol].GetNextUnprotected( nNextRow, false );
    1312           0 :                     pNextRows[nCol] = nNextRow;
    1313             : 
    1314           0 :                     SCsROW nMinRow = MAXROW+1;
    1315           0 :                     for (i=0; i<=MAXCOL; i++)
    1316           0 :                         if (pNextRows[i] < nMinRow)     // bei gleichen den linken
    1317             :                         {
    1318           0 :                             nMinRow = pNextRows[i];
    1319           0 :                             nCol = i;
    1320             :                         }
    1321           0 :                     nRow = nMinRow;
    1322             : 
    1323           0 :                     if ( nRow > MAXROW )
    1324             :                     {
    1325           0 :                         if (++nWrap >= 2) break;        // ungueltigen Wert behalten
    1326           0 :                         nCol = 0;
    1327           0 :                         nRow = 0;
    1328           0 :                         for (i=0; i<=MAXCOL; i++)
    1329           0 :                             pNextRows[i] = 0;           // alles ganz von vorne
    1330             :                     }
    1331             :                 }
    1332           0 :                 while ( !ValidNextPos(nCol, nRow, rMark, bMarked, bUnprotected) );
    1333             :             }
    1334             :             else                                        //  rueckwaerts
    1335             :             {
    1336           0 :                 for (i=0; i<=MAXCOL; i++)
    1337           0 :                     pNextRows[i] = (i>nCol) ? (nRow-1) : nRow;
    1338           0 :                 do
    1339             :                 {
    1340           0 :                     SCsROW nNextRow = pNextRows[nCol] - 1;
    1341           0 :                     if ( bMarked )
    1342           0 :                         nNextRow = rMark.GetNextMarked( nCol, nNextRow, true );
    1343           0 :                     if ( bUnprotected )
    1344           0 :                         nNextRow = aCol[nCol].GetNextUnprotected( nNextRow, true );
    1345           0 :                     pNextRows[nCol] = nNextRow;
    1346             : 
    1347           0 :                     SCsROW nMaxRow = -1;
    1348           0 :                     for (i=0; i<=MAXCOL; i++)
    1349           0 :                         if (pNextRows[i] >= nMaxRow)    // bei gleichen den rechten
    1350             :                         {
    1351           0 :                             nMaxRow = pNextRows[i];
    1352           0 :                             nCol = i;
    1353             :                         }
    1354           0 :                     nRow = nMaxRow;
    1355             : 
    1356           0 :                     if ( nRow < 0 )
    1357             :                     {
    1358           0 :                         if (++nWrap >= 2) break;        // ungueltigen Wert behalten
    1359           0 :                         nCol = MAXCOL;
    1360           0 :                         nRow = MAXROW;
    1361           0 :                         for (i=0; i<=MAXCOL; i++)
    1362           0 :                             pNextRows[i] = MAXROW;      // alles ganz von vorne
    1363             :                     }
    1364             :                 }
    1365           0 :                 while ( !ValidNextPos(nCol, nRow, rMark, bMarked, bUnprotected) );
    1366           0 :             }
    1367             :         }
    1368             :     }
    1369             : 
    1370             :     //  ungueltige Werte kommen z.b. bei Tab heraus,
    1371             :     //  wenn nicht markiert und nicht geschuetzt ist (linker / rechter Rand),
    1372             :     //  dann Werte unveraendert lassen
    1373             : 
    1374           0 :     if (ValidColRow(nCol,nRow))
    1375             :     {
    1376           0 :         rCol = nCol;
    1377           0 :         rRow = nRow;
    1378             :     }
    1379             : }
    1380             : 
    1381          62 : bool ScTable::GetNextMarkedCell( SCCOL& rCol, SCROW& rRow, const ScMarkData& rMark ) const
    1382             : {
    1383          62 :     const ScMarkArray* pMarkArray = rMark.GetArray();
    1384             :     OSL_ENSURE(pMarkArray,"GetNextMarkedCell without MarkArray");
    1385          62 :     if ( !pMarkArray )
    1386           0 :         return false;
    1387             : 
    1388          62 :     ++rRow;                 // naechste Zelle ist gesucht
    1389             : 
    1390        4596 :     while ( rCol <= MAXCOL )
    1391             :     {
    1392        4530 :         const ScMarkArray& rArray = pMarkArray[rCol];
    1393       13532 :         while ( rRow <= MAXROW )
    1394             :         {
    1395        4530 :             SCROW nStart = (SCROW) rArray.GetNextMarked( (SCsROW) rRow, false );
    1396        4530 :             if ( nStart <= MAXROW )
    1397             :             {
    1398          58 :                 SCROW nEnd = rArray.GetMarkEnd( nStart, false );
    1399             : 
    1400          58 :                 const sc::CellStoreType& rCells = aCol[rCol].maCells;
    1401          58 :                 std::pair<sc::CellStoreType::const_iterator,size_t> aPos = rCells.position(nStart);
    1402          58 :                 sc::CellStoreType::const_iterator it = aPos.first;
    1403          58 :                 SCROW nTestRow = nStart;
    1404          58 :                 if (it->type == sc::element_type_empty)
    1405             :                 {
    1406             :                     // Skip the empty block.
    1407          48 :                     nTestRow += it->size - aPos.second;
    1408          48 :                     ++it;
    1409          48 :                     if (it == rCells.end())
    1410             :                     {
    1411             :                         // No more block.
    1412          48 :                         rRow = MAXROW + 1;
    1413         106 :                         return false;
    1414             :                     }
    1415             :                 }
    1416             : 
    1417          10 :                 if (nTestRow <= nEnd)
    1418             :                 {
    1419             :                     // Cell found.
    1420          10 :                     rRow = nTestRow;
    1421          10 :                     return true;
    1422             :                 }
    1423             : 
    1424           0 :                 rRow = nEnd + 1;                // naechsten markierten Bereich suchen
    1425             :             }
    1426             :             else
    1427        4472 :                 rRow = MAXROW + 1;              // Ende der Spalte
    1428             :         }
    1429        4472 :         rRow = 0;
    1430        4472 :         ++rCol;                                 // naechste Spalte testen
    1431             :     }
    1432             : 
    1433           4 :     return false;                               // alle Spalten durch
    1434             : }
    1435             : 
    1436         372 : void ScTable::UpdateDrawRef( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
    1437             :                                     SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
    1438             :                                     SCsCOL nDx, SCsROW nDy, SCsTAB nDz, bool bUpdateNoteCaptionPos )
    1439             : {
    1440         372 :     if ( nTab >= nTab1 && nTab <= nTab2 && nDz == 0 )       // only within the table
    1441             :     {
    1442         316 :         ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
    1443         316 :         if ( eUpdateRefMode != URM_COPY && pDrawLayer )
    1444             :         {
    1445          50 :             if ( eUpdateRefMode == URM_MOVE )
    1446             :             {                                               // source range
    1447           0 :                 nCol1 = sal::static_int_cast<SCCOL>( nCol1 - nDx );
    1448           0 :                 nRow1 = sal::static_int_cast<SCROW>( nRow1 - nDy );
    1449           0 :                 nCol2 = sal::static_int_cast<SCCOL>( nCol2 - nDx );
    1450           0 :                 nRow2 = sal::static_int_cast<SCROW>( nRow2 - nDy );
    1451             :             }
    1452             :             pDrawLayer->MoveArea( nTab, nCol1,nRow1, nCol2,nRow2, nDx,nDy,
    1453          50 :                                     (eUpdateRefMode == URM_INSDEL), bUpdateNoteCaptionPos );
    1454             :         }
    1455             :     }
    1456         372 : }
    1457             : 
    1458         494 : void ScTable::UpdateReference(
    1459             :     sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc, bool bIncludeDraw, bool bUpdateNoteCaptionPos )
    1460             : {
    1461         494 :     bool bUpdated = false;
    1462             :     SCCOL i;
    1463             :     SCCOL iMax;
    1464         494 :     if (rCxt.meMode == URM_COPY )
    1465             :     {
    1466         106 :         i = rCxt.maRange.aStart.Col();
    1467         106 :         iMax = rCxt.maRange.aEnd.Col();
    1468             :     }
    1469             :     else
    1470             :     {
    1471         388 :         i = 0;
    1472         388 :         iMax = MAXCOL;
    1473             :     }
    1474             : 
    1475         494 :     UpdateRefMode eUpdateRefMode = rCxt.meMode;
    1476         494 :     SCCOL nDx = rCxt.mnColDelta;
    1477         494 :     SCROW nDy = rCxt.mnRowDelta;
    1478         494 :     SCTAB nDz = rCxt.mnTabDelta;
    1479         494 :     SCCOL nCol1 = rCxt.maRange.aStart.Col(), nCol2 = rCxt.maRange.aEnd.Col();
    1480         494 :     SCROW nRow1 = rCxt.maRange.aStart.Row(), nRow2 = rCxt.maRange.aEnd.Row();
    1481         494 :     SCTAB nTab1 = rCxt.maRange.aStart.Tab(), nTab2 = rCxt.maRange.aEnd.Tab();
    1482             : 
    1483             :     // Named expressions need to be updated before formulas acessing them.
    1484         494 :     if (mpRangeName)
    1485         112 :         mpRangeName->UpdateReference(rCxt, nTab);
    1486             : 
    1487      432844 :     for ( ; i<=iMax; i++)
    1488      432350 :         bUpdated |= aCol[i].UpdateReference(rCxt, pUndoDoc);
    1489             : 
    1490         494 :     if ( bIncludeDraw )
    1491         274 :         UpdateDrawRef( eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz, bUpdateNoteCaptionPos );
    1492             : 
    1493         494 :     if ( nTab >= nTab1 && nTab <= nTab2 && nDz == 0 )       // print ranges: only within the table
    1494             :     {
    1495         404 :         SCTAB nSTab = nTab;
    1496         404 :         SCTAB nETab = nTab;
    1497         404 :         SCCOL nSCol = 0;
    1498         404 :         SCROW nSRow = 0;
    1499         404 :         SCCOL nECol = 0;
    1500         404 :         SCROW nERow = 0;
    1501         404 :         bool bRecalcPages = false;
    1502             : 
    1503         404 :         for ( ScRangeVec::iterator aIt = aPrintRanges.begin(), aEnd = aPrintRanges.end(); aIt != aEnd; ++aIt )
    1504             :         {
    1505           0 :             nSCol = aIt->aStart.Col();
    1506           0 :             nSRow = aIt->aStart.Row();
    1507           0 :             nECol = aIt->aEnd.Col();
    1508           0 :             nERow = aIt->aEnd.Row();
    1509             : 
    1510             :             // do not try to modify sheet index of print range
    1511           0 :             if ( ScRefUpdate::Update( pDocument, eUpdateRefMode,
    1512             :                                       nCol1,nRow1,nTab, nCol2,nRow2,nTab,
    1513             :                                       nDx,nDy,0,
    1514           0 :                                       nSCol,nSRow,nSTab, nECol,nERow,nETab ) )
    1515             :             {
    1516           0 :                 *aIt = ScRange( nSCol, nSRow, 0, nECol, nERow, 0 );
    1517           0 :                 bRecalcPages = true;
    1518             :             }
    1519             :         }
    1520             : 
    1521         404 :         if ( pRepeatColRange )
    1522             :         {
    1523           0 :             nSCol = pRepeatColRange->aStart.Col();
    1524           0 :             nSRow = pRepeatColRange->aStart.Row();
    1525           0 :             nECol = pRepeatColRange->aEnd.Col();
    1526           0 :             nERow = pRepeatColRange->aEnd.Row();
    1527             : 
    1528             :             // do not try to modify sheet index of repeat range
    1529           0 :             if ( ScRefUpdate::Update( pDocument, eUpdateRefMode,
    1530             :                                       nCol1,nRow1,nTab, nCol2,nRow2,nTab,
    1531             :                                       nDx,nDy,0,
    1532           0 :                                       nSCol,nSRow,nSTab, nECol,nERow,nETab ) )
    1533             :             {
    1534           0 :                 *pRepeatColRange = ScRange( nSCol, nSRow, 0, nECol, nERow, 0 );
    1535           0 :                 bRecalcPages = true;
    1536           0 :                 nRepeatStartX = nSCol;  // fuer UpdatePageBreaks
    1537           0 :                 nRepeatEndX = nECol;
    1538             :             }
    1539             :         }
    1540             : 
    1541         404 :         if ( pRepeatRowRange )
    1542             :         {
    1543           0 :             nSCol = pRepeatRowRange->aStart.Col();
    1544           0 :             nSRow = pRepeatRowRange->aStart.Row();
    1545           0 :             nECol = pRepeatRowRange->aEnd.Col();
    1546           0 :             nERow = pRepeatRowRange->aEnd.Row();
    1547             : 
    1548             :             // do not try to modify sheet index of repeat range
    1549           0 :             if ( ScRefUpdate::Update( pDocument, eUpdateRefMode,
    1550             :                                       nCol1,nRow1,nTab, nCol2,nRow2,nTab,
    1551             :                                       nDx,nDy,0,
    1552           0 :                                       nSCol,nSRow,nSTab, nECol,nERow,nETab ) )
    1553             :             {
    1554           0 :                 *pRepeatRowRange = ScRange( nSCol, nSRow, 0, nECol, nERow, 0 );
    1555           0 :                 bRecalcPages = true;
    1556           0 :                 nRepeatStartY = nSRow;  // fuer UpdatePageBreaks
    1557           0 :                 nRepeatEndY = nERow;
    1558             :             }
    1559             :         }
    1560             : 
    1561             :         //  updating print ranges is not necessary with multiple print ranges
    1562         404 :         if ( bRecalcPages && GetPrintRangeCount() <= 1 )
    1563             :         {
    1564           0 :             UpdatePageBreaks(NULL);
    1565             : 
    1566           0 :             pDocument->RepaintRange( ScRange(0,0,nTab,MAXCOL,MAXROW,nTab) );
    1567             :         }
    1568             :     }
    1569             : 
    1570         494 :     if (bUpdated && IsStreamValid())
    1571           4 :         SetStreamValid(false);
    1572             : 
    1573         494 :     if(mpCondFormatList)
    1574         494 :         mpCondFormatList->UpdateReference(rCxt);
    1575             : 
    1576         494 :     if (pTabProtection)
    1577           0 :         pTabProtection->updateReference( eUpdateRefMode, pDocument, rCxt.maRange, nDx, nDy, nDz);
    1578         494 : }
    1579             : 
    1580           0 : void ScTable::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
    1581             :                                     ScDocument* pUndoDoc )
    1582             : {
    1583           0 :     for ( SCCOL i=0; i<=MAXCOL; i++ )
    1584           0 :         aCol[i].UpdateTranspose( rSource, rDest, pUndoDoc );
    1585           0 : }
    1586             : 
    1587           0 : void ScTable::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
    1588             : {
    1589           0 :     for ( SCCOL i=0; i<=MAXCOL; i++ )
    1590           0 :         aCol[i].UpdateGrow( rArea, nGrowX, nGrowY );
    1591           0 : }
    1592             : 
    1593         268 : void ScTable::UpdateInsertTab( sc::RefUpdateInsertTabContext& rCxt )
    1594             : {
    1595             :     // Store the old tab number in sc::UpdatedRangeNames for
    1596             :     // ScTokenArray::AdjustReferenceOnInsertedTab() to check with
    1597             :     // isNameModified()
    1598         268 :     if (mpRangeName)
    1599         190 :         mpRangeName->UpdateInsertTab(rCxt, nTab);
    1600             : 
    1601         268 :     if (nTab >= rCxt.mnInsertPos)
    1602             :     {
    1603         248 :         nTab += rCxt.mnSheets;
    1604         248 :         if (pDBDataNoName)
    1605           0 :             pDBDataNoName->UpdateMoveTab(nTab - 1 ,nTab);
    1606             :     }
    1607             : 
    1608         268 :     if (mpCondFormatList)
    1609         268 :         mpCondFormatList->UpdateInsertTab(rCxt);
    1610             : 
    1611         268 :     if (pTabProtection)
    1612             :         pTabProtection->updateReference( URM_INSDEL, pDocument,
    1613             :                 ScRange( 0, 0, rCxt.mnInsertPos, MAXCOL, MAXROW, MAXTAB),
    1614           0 :                 0, 0, rCxt.mnSheets);
    1615             : 
    1616      274700 :     for (SCCOL i=0; i <= MAXCOL; i++)
    1617      274432 :         aCol[i].UpdateInsertTab(rCxt);
    1618             : 
    1619         268 :     if (IsStreamValid())
    1620           4 :         SetStreamValid(false);
    1621         268 : }
    1622             : 
    1623         428 : void ScTable::UpdateDeleteTab( sc::RefUpdateDeleteTabContext& rCxt )
    1624             : {
    1625             :     // Store the old tab number in sc::UpdatedRangeNames for
    1626             :     // ScTokenArray::AdjustReferenceOnDeletedTab() to check with
    1627             :     // isNameModified()
    1628         428 :     if (mpRangeName)
    1629          58 :         mpRangeName->UpdateDeleteTab(rCxt, nTab);
    1630             : 
    1631         428 :     if (nTab > rCxt.mnDeletePos)
    1632             :     {
    1633          84 :         nTab -= rCxt.mnSheets;
    1634          84 :         if (pDBDataNoName)
    1635           0 :             pDBDataNoName->UpdateMoveTab(nTab + 1,nTab);
    1636             :     }
    1637             : 
    1638         428 :     if (mpCondFormatList)
    1639         428 :         mpCondFormatList->UpdateDeleteTab(rCxt);
    1640             : 
    1641         428 :     if (pTabProtection)
    1642             :         pTabProtection->updateReference( URM_INSDEL, pDocument,
    1643             :                 ScRange( 0, 0, rCxt.mnDeletePos, MAXCOL, MAXROW, MAXTAB),
    1644           0 :                 0, 0, -rCxt.mnSheets);
    1645             : 
    1646      438700 :     for (SCCOL i = 0; i <= MAXCOL; ++i)
    1647      438272 :         aCol[i].UpdateDeleteTab(rCxt);
    1648             : 
    1649         428 :     if (IsStreamValid())
    1650          12 :         SetStreamValid(false);
    1651         428 : }
    1652             : 
    1653          78 : void ScTable::UpdateMoveTab(
    1654             :     sc::RefUpdateMoveTabContext& rCxt, SCTAB nTabNo, ScProgress* pProgress )
    1655             : {
    1656          78 :     nTab = nTabNo;
    1657          78 :     if (mpRangeName)
    1658           0 :         mpRangeName->UpdateMoveTab(rCxt, nTab);
    1659             : 
    1660          78 :     if (pDBDataNoName)
    1661           0 :         pDBDataNoName->UpdateMoveTab(rCxt.mnOldPos, rCxt.mnNewPos);
    1662             : 
    1663          78 :     if(mpCondFormatList)
    1664          78 :         mpCondFormatList->UpdateMoveTab(rCxt);
    1665             : 
    1666          78 :     if (pTabProtection)
    1667             :         pTabProtection->updateReference( URM_REORDER, pDocument,
    1668             :                 ScRange( 0, 0, rCxt.mnOldPos, MAXCOL, MAXROW, MAXTAB),
    1669           0 :                 0, 0, rCxt.mnNewPos - rCxt.mnOldPos);
    1670             : 
    1671       79950 :     for ( SCCOL i=0; i <= MAXCOL; i++ )
    1672             :     {
    1673       79872 :         aCol[i].UpdateMoveTab(rCxt, nTabNo);
    1674       79872 :         if (pProgress)
    1675           0 :             pProgress->SetState(pProgress->GetState() + aCol[i].GetCodeCount());
    1676             :     }
    1677             : 
    1678          78 :     if (IsStreamValid())
    1679           0 :         SetStreamValid(false);
    1680          78 : }
    1681             : 
    1682         724 : void ScTable::UpdateCompile( bool bForceIfNameInUse )
    1683             : {
    1684      742100 :     for (SCCOL i=0; i <= MAXCOL; i++)
    1685             :     {
    1686      741376 :         aCol[i].UpdateCompile( bForceIfNameInUse );
    1687             :     }
    1688         724 : }
    1689             : 
    1690          26 : void ScTable::SetTabNo(SCTAB nNewTab)
    1691             : {
    1692          26 :     nTab = nNewTab;
    1693          26 :     for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].SetTabNo(nNewTab);
    1694          26 : }
    1695             : 
    1696          12 : void ScTable::FindRangeNamesInUse(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
    1697             :                                std::set<sal_uInt16>& rIndexes) const
    1698             : {
    1699          34 :     for (SCCOL i = nCol1; i <= nCol2 && ValidCol(i); i++)
    1700          22 :         aCol[i].FindRangeNamesInUse(nRow1, nRow2, rIndexes);
    1701          12 : }
    1702             : 
    1703          60 : void ScTable::ExtendPrintArea( OutputDevice* pDev,
    1704             :                     SCCOL /* nStartCol */, SCROW nStartRow, SCCOL& rEndCol, SCROW nEndRow )
    1705             : {
    1706          60 :     if ( !pColFlags || !pRowFlags )
    1707             :     {
    1708             :         OSL_FAIL("ExtendPrintArea: No ColInfo or RowInfo");
    1709           0 :         return;
    1710             :     }
    1711             : 
    1712          60 :     Point aPix1000 = pDev->LogicToPixel( Point(1000,1000), MAP_TWIP );
    1713          60 :     double nPPTX = aPix1000.X() / 1000.0;
    1714          60 :     double nPPTY = aPix1000.Y() / 1000.0;
    1715             : 
    1716             :     // First, mark those columns that we need to skip i.e. hidden and empty columns.
    1717             : 
    1718          60 :     ScFlatBoolColSegments aSkipCols;
    1719          60 :     aSkipCols.setFalse(0, MAXCOL);
    1720         120 :     for (SCCOL i = 0; i <= MAXCOL; ++i)
    1721             :     {
    1722          60 :         SCCOL nLastCol = i;
    1723          60 :         if (ColHidden(i, NULL, &nLastCol))
    1724             :         {
    1725             :             // Columns are hidden in this range.
    1726           0 :             aSkipCols.setTrue(i, nLastCol);
    1727             :         }
    1728             :         else
    1729             :         {
    1730             :             // These columns are visible.  Check for empty columns.
    1731       61500 :             for (SCCOL j = i; j <= nLastCol; ++j)
    1732             :             {
    1733       61440 :                 if (aCol[j].GetCellCount() == 0)
    1734             :                     // empty
    1735       61364 :                     aSkipCols.setTrue(j,j);
    1736             :             }
    1737             :         }
    1738          60 :         i = nLastCol;
    1739             :     }
    1740             : 
    1741             :     ScFlatBoolColSegments::RangeData aColData;
    1742         136 :     for (SCCOL nCol = rEndCol; nCol >= 0; --nCol)
    1743             :     {
    1744          76 :         if (!aSkipCols.getRangeData(nCol, aColData))
    1745             :             // Failed to get the data.  This should never happen!
    1746           0 :             return;
    1747             : 
    1748          76 :         if (aColData.mbValue)
    1749             :         {
    1750             :             // Skip these columns.
    1751           8 :             nCol = aColData.mnCol1; // move toward 0.
    1752           8 :             continue;
    1753             :         }
    1754             : 
    1755             :         // These are visible and non-empty columns.
    1756         144 :         for (SCCOL nDataCol = nCol; 0 <= nDataCol && nDataCol >= aColData.mnCol1; --nDataCol)
    1757             :         {
    1758          76 :             SCCOL nPrintCol = nDataCol;
    1759          76 :             VisibleDataCellIterator aIter(*mpHiddenRows, aCol[nDataCol]);
    1760         152 :             ScRefCellValue aCell = aIter.reset(nStartRow);
    1761          76 :             if (aCell.isEmpty())
    1762             :                 // No visible cells found in this column.  Skip it.
    1763           0 :                 continue;
    1764             : 
    1765         248 :             while (!aCell.isEmpty())
    1766             :             {
    1767          96 :                 SCCOL nNewCol = nDataCol;
    1768          96 :                 SCROW nRow = aIter.getRow();
    1769          96 :                 if (nRow > nEndRow)
    1770             :                     // Went past the last row position.  Bail out.
    1771           0 :                     break;
    1772             : 
    1773          96 :                 MaybeAddExtraColumn(nNewCol, nRow, pDev, nPPTX, nPPTY);
    1774          96 :                 if (nNewCol > nPrintCol)
    1775          32 :                     nPrintCol = nNewCol;
    1776          96 :                 aCell = aIter.next();
    1777             :             }
    1778             : 
    1779          76 :             if (nPrintCol > rEndCol)
    1780             :                 // Make sure we don't shrink the print area.
    1781          20 :                 rEndCol = nPrintCol;
    1782          76 :         }
    1783          68 :         nCol = aColData.mnCol1; // move toward 0.
    1784          60 :     }
    1785             : }
    1786             : 
    1787          96 : void ScTable::MaybeAddExtraColumn(SCCOL& rCol, SCROW nRow, OutputDevice* pDev, double nPPTX, double nPPTY)
    1788             : {
    1789          96 :     ScRefCellValue aCell = aCol[rCol].GetCellValue(nRow);
    1790          96 :     if (!aCell.hasString())
    1791          96 :         return;
    1792             : 
    1793          96 :     bool bFormula = false;  //! ueberge
    1794          96 :     long nPixel = aCol[rCol].GetTextWidth(nRow);
    1795             : 
    1796             :     // Breite bereits im Idle-Handler berechnet?
    1797          96 :     if ( TEXTWIDTH_DIRTY == nPixel )
    1798             :     {
    1799          60 :         ScNeededSizeOptions aOptions;
    1800          60 :         aOptions.bTotalSize  = true;
    1801          60 :         aOptions.bFormula    = bFormula;
    1802          60 :         aOptions.bSkipMerged = false;
    1803             : 
    1804          60 :         Fraction aZoom(1,1);
    1805          60 :         nPixel = aCol[rCol].GetNeededSize(
    1806          60 :             nRow, pDev, nPPTX, nPPTY, aZoom, aZoom, true, aOptions, NULL );
    1807             : 
    1808          60 :         aCol[rCol].SetTextWidth(nRow, static_cast<sal_uInt16>(nPixel));
    1809             :     }
    1810             : 
    1811          96 :     long nTwips = (long) (nPixel / nPPTX);
    1812          96 :     long nDocW = GetColWidth( rCol );
    1813             : 
    1814          96 :     long nMissing = nTwips - nDocW;
    1815          96 :     if ( nMissing > 0 )
    1816             :     {
    1817             :         //  look at alignment
    1818             : 
    1819          36 :         const ScPatternAttr* pPattern = GetPattern( rCol, nRow );
    1820          36 :         const SfxItemSet* pCondSet = pDocument->GetCondResult( rCol, nRow, nTab );
    1821             : 
    1822             :         SvxCellHorJustify eHorJust = (SvxCellHorJustify)static_cast<const SvxHorJustifyItem&>(
    1823          36 :                         pPattern->GetItem( ATTR_HOR_JUSTIFY, pCondSet )).GetValue();
    1824          36 :         if ( eHorJust == SVX_HOR_JUSTIFY_CENTER )
    1825           0 :             nMissing /= 2;                          // distributed into both directions
    1826             :         else
    1827             :         {
    1828             :             // STANDARD is LEFT (only text is handled here)
    1829          36 :             bool bRight = ( eHorJust == SVX_HOR_JUSTIFY_RIGHT );
    1830          36 :             if ( IsLayoutRTL() )
    1831           0 :                 bRight = !bRight;
    1832          36 :             if ( bRight )
    1833           0 :                 nMissing = 0;       // extended only to the left (logical)
    1834             :         }
    1835             :     }
    1836             : 
    1837          96 :     SCCOL nNewCol = rCol;
    1838         228 :     while (nMissing > 0 && nNewCol < MAXCOL)
    1839             :     {
    1840          36 :         ScRefCellValue aNextCell = aCol[nNewCol+1].GetCellValue(nRow);
    1841          36 :         if (!aNextCell.isEmpty())
    1842             :             // Cell content in a next column ends display of this string.
    1843           0 :             nMissing = 0;
    1844             :         else
    1845          36 :             nMissing -= GetColWidth(++nNewCol);
    1846          36 :     }
    1847          96 :     rCol = nNewCol;
    1848             : }
    1849             : 
    1850             : namespace {
    1851             : 
    1852             : class SetTableIndex : public ::std::unary_function<ScRange, void>
    1853             : {
    1854             :     SCTAB mnTab;
    1855             : public:
    1856          12 :     SetTableIndex(SCTAB nTab) : mnTab(nTab) {}
    1857             : 
    1858           0 :     void operator() (ScRange& rRange) const
    1859             :     {
    1860           0 :         rRange.aStart.SetTab(mnTab);
    1861           0 :         rRange.aEnd.SetTab(mnTab);
    1862           0 :     }
    1863             : };
    1864             : 
    1865          28 : void setPrintRange(ScRange*& pRange1, const ScRange* pRange2)
    1866             : {
    1867          28 :     if (pRange2)
    1868             :     {
    1869          12 :         if (pRange1)
    1870           4 :             *pRange1 = *pRange2;
    1871             :         else
    1872           8 :             pRange1 = new ScRange(*pRange2);
    1873             :     }
    1874             :     else
    1875          16 :         DELETEZ(pRange1);
    1876          28 : }
    1877             : 
    1878             : }
    1879             : 
    1880          12 : void ScTable::CopyPrintRange(const ScTable& rTable)
    1881             : {
    1882             :     // The table index shouldn't be used when the print range is used, but
    1883             :     // just in case set the correct table index.
    1884             : 
    1885          12 :     aPrintRanges = rTable.aPrintRanges;
    1886          12 :     ::std::for_each(aPrintRanges.begin(), aPrintRanges.end(), SetTableIndex(nTab));
    1887             : 
    1888          12 :     bPrintEntireSheet = rTable.bPrintEntireSheet;
    1889             : 
    1890          12 :     delete pRepeatColRange;
    1891          12 :     pRepeatColRange = NULL;
    1892          12 :     if (rTable.pRepeatColRange)
    1893             :     {
    1894           0 :         pRepeatColRange = new ScRange(*rTable.pRepeatColRange);
    1895           0 :         pRepeatColRange->aStart.SetTab(nTab);
    1896           0 :         pRepeatColRange->aEnd.SetTab(nTab);
    1897             :     }
    1898             : 
    1899          12 :     delete pRepeatRowRange;
    1900          12 :     pRepeatRowRange = NULL;
    1901          12 :     if (rTable.pRepeatRowRange)
    1902             :     {
    1903           0 :         pRepeatRowRange = new ScRange(*rTable.pRepeatRowRange);
    1904           0 :         pRepeatRowRange->aStart.SetTab(nTab);
    1905           0 :         pRepeatRowRange->aEnd.SetTab(nTab);
    1906             :     }
    1907          12 : }
    1908             : 
    1909          10 : void ScTable::SetRepeatColRange( const ScRange* pNew )
    1910             : {
    1911          10 :     setPrintRange( pRepeatColRange, pNew );
    1912             : 
    1913          10 :     if (IsStreamValid())
    1914           2 :         SetStreamValid(false);
    1915             : 
    1916          10 :     InvalidatePageBreaks();
    1917          10 : }
    1918             : 
    1919          18 : void ScTable::SetRepeatRowRange( const ScRange* pNew )
    1920             : {
    1921          18 :     setPrintRange( pRepeatRowRange, pNew );
    1922             : 
    1923          18 :     if (IsStreamValid())
    1924           2 :         SetStreamValid(false);
    1925             : 
    1926          18 :     InvalidatePageBreaks();
    1927          18 : }
    1928             : 
    1929         104 : void ScTable::ClearPrintRanges()
    1930             : {
    1931         104 :     aPrintRanges.clear();
    1932         104 :     bPrintEntireSheet = false;
    1933             : 
    1934         104 :     if (IsStreamValid())
    1935           0 :         SetStreamValid(false);
    1936             : 
    1937         104 :     InvalidatePageBreaks();     // #i117952# forget page breaks for an old print range
    1938         104 : }
    1939             : 
    1940          16 : void ScTable::AddPrintRange( const ScRange& rNew )
    1941             : {
    1942          16 :     bPrintEntireSheet = false;
    1943          16 :     if( aPrintRanges.size() < 0xFFFF )
    1944          16 :         aPrintRanges.push_back( rNew );
    1945             : 
    1946          16 :     if (IsStreamValid())
    1947           0 :         SetStreamValid(false);
    1948             : 
    1949          16 :     InvalidatePageBreaks();
    1950          16 : }
    1951             : 
    1952          22 : void ScTable::SetPrintEntireSheet()
    1953             : {
    1954          22 :     if( !IsPrintEntireSheet() )
    1955             :     {
    1956           0 :         ClearPrintRanges();
    1957           0 :         bPrintEntireSheet = true;
    1958             :     }
    1959          22 : }
    1960             : 
    1961         704 : const ScRange* ScTable::GetPrintRange(sal_uInt16 nPos) const
    1962             : {
    1963         704 :     return (nPos < GetPrintRangeCount()) ? &aPrintRanges[ nPos ] : NULL;
    1964             : }
    1965             : 
    1966         388 : void ScTable::FillPrintSaver( ScPrintSaverTab& rSaveTab ) const
    1967             : {
    1968         388 :     rSaveTab.SetAreas( aPrintRanges, bPrintEntireSheet );
    1969         388 :     rSaveTab.SetRepeat( pRepeatColRange, pRepeatRowRange );
    1970         388 : }
    1971             : 
    1972           8 : void ScTable::RestorePrintRanges( const ScPrintSaverTab& rSaveTab )
    1973             : {
    1974           8 :     aPrintRanges = rSaveTab.GetPrintRanges();
    1975           8 :     bPrintEntireSheet = rSaveTab.IsEntireSheet();
    1976           8 :     SetRepeatColRange( rSaveTab.GetRepeatCol() );
    1977           8 :     SetRepeatRowRange( rSaveTab.GetRepeatRow() );
    1978             : 
    1979           8 :     InvalidatePageBreaks();     // #i117952# forget page breaks for an old print range
    1980           8 :     UpdatePageBreaks(NULL);
    1981           8 : }
    1982             : 
    1983             : SCROW ScTable::VisibleDataCellIterator::ROW_NOT_FOUND = -1;
    1984             : 
    1985          76 : ScTable::VisibleDataCellIterator::VisibleDataCellIterator(ScFlatBoolRowSegments& rRowSegs, ScColumn& rColumn) :
    1986             :     mrRowSegs(rRowSegs),
    1987             :     mrColumn(rColumn),
    1988             :     mnCurRow(ROW_NOT_FOUND),
    1989          76 :     mnUBound(ROW_NOT_FOUND)
    1990             : {
    1991          76 : }
    1992             : 
    1993          76 : ScTable::VisibleDataCellIterator::~VisibleDataCellIterator()
    1994             : {
    1995          76 : }
    1996             : 
    1997          76 : ScRefCellValue ScTable::VisibleDataCellIterator::reset(SCROW nRow)
    1998             : {
    1999          76 :     if (nRow > MAXROW)
    2000             :     {
    2001           0 :         mnCurRow = ROW_NOT_FOUND;
    2002           0 :         return ScRefCellValue();
    2003             :     }
    2004             : 
    2005             :     ScFlatBoolRowSegments::RangeData aData;
    2006          76 :     if (!mrRowSegs.getRangeData(nRow, aData))
    2007             :     {
    2008           0 :         mnCurRow = ROW_NOT_FOUND;
    2009           0 :         return ScRefCellValue();
    2010             :     }
    2011             : 
    2012          76 :     if (!aData.mbValue)
    2013             :     {
    2014             :         // specified row is visible.  Take it.
    2015          76 :         mnCurRow = nRow;
    2016          76 :         mnUBound = aData.mnRow2;
    2017             :     }
    2018             :     else
    2019             :     {
    2020             :         // specified row is not-visible.  The first visible row is the start of
    2021             :         // the next segment.
    2022           0 :         mnCurRow = aData.mnRow2 + 1;
    2023           0 :         mnUBound = mnCurRow; // get range data on the next iteration.
    2024           0 :         if (mnCurRow > MAXROW)
    2025             :         {
    2026             :             // Make sure the row doesn't exceed our current limit.
    2027           0 :             mnCurRow = ROW_NOT_FOUND;
    2028           0 :             return ScRefCellValue();
    2029             :         }
    2030             :     }
    2031             : 
    2032          76 :     maCell = mrColumn.GetCellValue(mnCurRow);
    2033          76 :     if (!maCell.isEmpty())
    2034             :         // First visible cell found.
    2035          60 :         return maCell;
    2036             : 
    2037             :     // Find a first visible cell below this row (if any).
    2038          16 :     return next();
    2039             : }
    2040             : 
    2041         112 : ScRefCellValue ScTable::VisibleDataCellIterator::next()
    2042             : {
    2043         112 :     if (mnCurRow == ROW_NOT_FOUND)
    2044           0 :         return ScRefCellValue();
    2045             : 
    2046         224 :     while (mrColumn.GetNextDataPos(mnCurRow))
    2047             :     {
    2048          36 :         if (mnCurRow > mnUBound)
    2049             :         {
    2050             :             // We don't know the visibility of this row range.  Query it.
    2051             :             ScFlatBoolRowSegments::RangeData aData;
    2052           0 :             if (!mrRowSegs.getRangeData(mnCurRow, aData))
    2053             :             {
    2054           0 :                 mnCurRow = ROW_NOT_FOUND;
    2055           0 :                 return ScRefCellValue();
    2056             :             }
    2057             : 
    2058           0 :             if (aData.mbValue)
    2059             :             {
    2060             :                 // This row is invisible.  Skip to the last invisible row and
    2061             :                 // try again.
    2062           0 :                 mnCurRow = mnUBound = aData.mnRow2;
    2063           0 :                 continue;
    2064             :             }
    2065             : 
    2066             :             // This row is visible.
    2067           0 :             mnUBound = aData.mnRow2;
    2068             :         }
    2069             : 
    2070          36 :         maCell = mrColumn.GetCellValue(mnCurRow);
    2071          36 :         if (!maCell.isEmpty())
    2072          36 :             return maCell;
    2073             :     }
    2074             : 
    2075          76 :     mnCurRow = ROW_NOT_FOUND;
    2076          76 :     return ScRefCellValue();
    2077             : }
    2078             : 
    2079         644 : void ScTable::SetAnonymousDBData(ScDBData* pDBData)
    2080             : {
    2081         644 :     delete pDBDataNoName;
    2082         644 :     pDBDataNoName = pDBData;
    2083         644 : }
    2084             : 
    2085         288 : sal_uLong ScTable::AddCondFormat( ScConditionalFormat* pNew )
    2086             : {
    2087         288 :     if(!mpCondFormatList)
    2088           0 :         mpCondFormatList.reset(new ScConditionalFormatList());
    2089             : 
    2090         288 :     sal_uLong nMax = 0;
    2091        2562 :     for(ScConditionalFormatList::const_iterator itr = mpCondFormatList->begin();
    2092        1708 :             itr != mpCondFormatList->end(); ++itr)
    2093             :     {
    2094         566 :         sal_uLong nKey = itr->GetKey();
    2095         566 :         if(nKey > nMax)
    2096         566 :             nMax = nKey;
    2097             :     }
    2098             : 
    2099         288 :     pNew->SetKey(nMax+1);
    2100         288 :     mpCondFormatList->InsertNew(pNew);
    2101             : 
    2102         288 :     return nMax + 1;
    2103             : }
    2104             : 
    2105       28583 : sal_uInt8 ScTable::GetScriptType( SCCOL nCol, SCROW nRow ) const
    2106             : {
    2107       28583 :     if (!ValidCol(nCol))
    2108           0 :         return 0;
    2109             : 
    2110       28583 :     return aCol[nCol].GetScriptType(nRow);
    2111             : }
    2112             : 
    2113        6019 : void ScTable::SetScriptType( SCCOL nCol, SCROW nRow, sal_uInt8 nType )
    2114             : {
    2115        6019 :     if (!ValidCol(nCol))
    2116        6019 :         return;
    2117             : 
    2118        6019 :     aCol[nCol].SetScriptType(nRow, nType);
    2119             : }
    2120             : 
    2121          92 : sal_uInt8 ScTable::GetRangeScriptType(
    2122             :     sc::ColumnBlockPosition& rBlockPos, SCCOL nCol, SCROW nRow1, SCROW nRow2 )
    2123             : {
    2124          92 :     if (!ValidCol(nCol))
    2125           0 :         return 0;
    2126             : 
    2127          92 :     sc::CellStoreType::iterator itr = aCol[nCol].maCells.begin();
    2128          92 :     return aCol[nCol].GetRangeScriptType(rBlockPos.miCellTextAttrPos, nRow1, nRow2, itr);
    2129             : }
    2130             : 
    2131          76 : size_t ScTable::GetFormulaHash( SCCOL nCol, SCROW nRow ) const
    2132             : {
    2133          76 :     if (!ValidCol(nCol))
    2134           0 :         return 0;
    2135             : 
    2136          76 :     return aCol[nCol].GetFormulaHash(nRow);
    2137             : }
    2138             : 
    2139          12 : ScFormulaVectorState ScTable::GetFormulaVectorState( SCCOL nCol, SCROW nRow ) const
    2140             : {
    2141          12 :     if (!ValidCol(nCol))
    2142           0 :         return FormulaVectorUnknown;
    2143             : 
    2144          12 :     return aCol[nCol].GetFormulaVectorState(nRow);
    2145             : }
    2146             : 
    2147           0 : formula::FormulaTokenRef ScTable::ResolveStaticReference( SCCOL nCol, SCROW nRow )
    2148             : {
    2149           0 :     if (!ValidCol(nCol) || !ValidRow(nRow))
    2150           0 :         return formula::FormulaTokenRef();
    2151             : 
    2152           0 :     return aCol[nCol].ResolveStaticReference(nRow);
    2153             : }
    2154             : 
    2155           0 : formula::FormulaTokenRef ScTable::ResolveStaticReference( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
    2156             : {
    2157           0 :     if (nCol2 < nCol1 || nRow2 < nRow1)
    2158           0 :         return formula::FormulaTokenRef();
    2159             : 
    2160           0 :     if (!ValidCol(nCol1) || !ValidCol(nCol2) || !ValidRow(nRow1) || !ValidRow(nRow2))
    2161           0 :         return formula::FormulaTokenRef();
    2162             : 
    2163           0 :     ScMatrixRef pMat(new ScMatrix(nCol2-nCol1+1, nRow2-nRow1+1, 0.0));
    2164           0 :     for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
    2165             :     {
    2166           0 :         if (!aCol[nCol].ResolveStaticReference(*pMat, nCol2-nCol1, nRow1, nRow2))
    2167             :             // Column contains non-static cell. Failed.
    2168           0 :             return formula::FormulaTokenRef();
    2169             :     }
    2170             : 
    2171           0 :     return formula::FormulaTokenRef(new ScMatrixToken(pMat));
    2172             : }
    2173             : 
    2174          40 : formula::VectorRefArray ScTable::FetchVectorRefArray( SCCOL nCol, SCROW nRow1, SCROW nRow2 )
    2175             : {
    2176          40 :     if (nRow2 < nRow1)
    2177           0 :         return formula::VectorRefArray();
    2178             : 
    2179          40 :     if (!ValidCol(nCol) || !ValidRow(nRow1) || !ValidRow(nRow2))
    2180           0 :         return formula::VectorRefArray();
    2181             : 
    2182          40 :     return aCol[nCol].FetchVectorRefArray(nRow1, nRow2);
    2183             : }
    2184             : 
    2185      147200 : ScRefCellValue ScTable::GetRefCellValue( SCCOL nCol, SCROW nRow )
    2186             : {
    2187      147200 :     if (!ValidColRow(nCol, nRow))
    2188           0 :         return ScRefCellValue();
    2189             : 
    2190      147200 :     return aCol[nCol].GetCellValue(nRow);
    2191             : }
    2192             : 
    2193      148120 : SvtBroadcaster* ScTable::GetBroadcaster( SCCOL nCol, SCROW nRow )
    2194             : {
    2195      148120 :     if (!ValidColRow(nCol, nRow))
    2196       33976 :         return NULL;
    2197             : 
    2198      114144 :     return aCol[nCol].GetBroadcaster(nRow);
    2199             : }
    2200             : 
    2201         164 : void ScTable::DeleteBroadcasters(
    2202             :     sc::ColumnBlockPosition& rBlockPos, SCCOL nCol, SCROW nRow1, SCROW nRow2 )
    2203             : {
    2204         164 :     if (!ValidCol(nCol))
    2205         164 :         return;
    2206             : 
    2207         164 :     aCol[nCol].DeleteBroadcasters(rBlockPos, nRow1, nRow2);
    2208             : }
    2209             : 
    2210           0 : bool ScTable::HasBroadcaster( SCCOL nCol ) const
    2211             : {
    2212           0 :     if (!ValidCol(nCol))
    2213           0 :         return false;
    2214             : 
    2215           0 :     return aCol[nCol].HasBroadcaster();
    2216             : }
    2217             : 
    2218         160 : void ScTable::FillMatrix( ScMatrix& rMat, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const
    2219             : {
    2220         160 :     size_t nMatCol = 0;
    2221         338 :     for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol, ++nMatCol)
    2222         178 :         aCol[nCol].FillMatrix(rMat, nMatCol, nRow1, nRow2);
    2223         160 : }
    2224             : 
    2225        4134 : void ScTable::InterpretDirtyCells( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
    2226             : {
    2227       31498 :     for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
    2228       27364 :         aCol[nCol].InterpretDirtyCells(nRow1, nRow2);
    2229        4134 : }
    2230             : 
    2231           0 : void ScTable::SetFormulaResults( SCCOL nCol, SCROW nRow, const double* pResults, size_t nLen )
    2232             : {
    2233           0 :     if (!ValidCol(nCol))
    2234           0 :         return;
    2235             : 
    2236           0 :     aCol[nCol].SetFormulaResults(nRow, pResults, nLen);
    2237             : }
    2238             : 
    2239           0 : void ScTable::SetFormulaResults(
    2240             :     SCCOL nCol, SCROW nRow, const formula::FormulaTokenRef* pResults, size_t nLen )
    2241             : {
    2242           0 :     if (!ValidCol(nCol))
    2243           0 :         return;
    2244             : 
    2245           0 :     aCol[nCol].SetFormulaResults(nRow, pResults, nLen);
    2246             : }
    2247             : 
    2248             : #if DEBUG_COLUMN_STORAGE
    2249             : void ScTable::DumpFormulaGroups( SCCOL nCol ) const
    2250             : {
    2251             :     if (!ValidCol(nCol))
    2252             :         return;
    2253             : 
    2254             :     aCol[nCol].DumpFormulaGroups();
    2255             : }
    2256             : #endif
    2257             : 
    2258          28 : const SvtBroadcaster* ScTable::GetBroadcaster( SCCOL nCol, SCROW nRow ) const
    2259             : {
    2260          28 :     if (!ValidColRow(nCol, nRow))
    2261           0 :         return NULL;
    2262             : 
    2263          28 :     return aCol[nCol].GetBroadcaster(nRow);
    2264             : }
    2265             : 
    2266           0 : void ScTable::DeleteConditionalFormat( sal_uLong nIndex )
    2267             : {
    2268           0 :     mpCondFormatList->erase(nIndex);
    2269           0 : }
    2270             : 
    2271          30 : void ScTable::SetCondFormList( ScConditionalFormatList* pNew )
    2272             : {
    2273          30 :     mpCondFormatList.reset( pNew );
    2274          30 : }
    2275             : 
    2276     1428619 : ScConditionalFormatList* ScTable::GetCondFormList()
    2277             : {
    2278     1428619 :     if(!mpCondFormatList)
    2279           0 :         mpCondFormatList.reset( new ScConditionalFormatList() );
    2280             : 
    2281     1428619 :     return mpCondFormatList.get();
    2282             : }
    2283             : 
    2284           0 : const ScConditionalFormatList* ScTable::GetCondFormList() const
    2285             : {
    2286           0 :     return mpCondFormatList.get();
    2287         228 : }
    2288             : 
    2289             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10