LCOV - code coverage report
Current view: top level - libreoffice/sc/source/core/data - table2.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 901 1717 52.5 %
Date: 2012-12-27 Functions: 103 154 66.9 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10