LCOV - code coverage report
Current view: top level - sc/source/core/data - table1.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 814 1180 69.0 %
Date: 2014-04-11 Functions: 82 105 78.1 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10