LCOV - code coverage report
Current view: top level - sc/source/core/data - table1.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 836 1175 71.1 %
Date: 2015-06-13 12:38:46 Functions: 83 102 81.4 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11