LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sc/source/core/data - table2.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 1245 1846 67.4 %
Date: 2013-07-09 Functions: 143 185 77.3 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10