xref: /aoo41x/main/sc/source/core/data/table1.cxx (revision 557cb412)
1b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3b3f79822SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4b3f79822SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5b3f79822SAndrew Rist  * distributed with this work for additional information
6b3f79822SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7b3f79822SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8b3f79822SAndrew Rist  * "License"); you may not use this file except in compliance
9b3f79822SAndrew Rist  * with the License.  You may obtain a copy of the License at
10b3f79822SAndrew Rist  *
11b3f79822SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12b3f79822SAndrew Rist  *
13b3f79822SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14b3f79822SAndrew Rist  * software distributed under the License is distributed on an
15b3f79822SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16b3f79822SAndrew Rist  * KIND, either express or implied.  See the License for the
17b3f79822SAndrew Rist  * specific language governing permissions and limitations
18b3f79822SAndrew Rist  * under the License.
19b3f79822SAndrew Rist  *
20b3f79822SAndrew Rist  *************************************************************/
21b3f79822SAndrew Rist 
22b3f79822SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sc.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir // INCLUDE ---------------------------------------------------------------
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include "scitems.hxx"
30cdf0e10cSrcweir #include <svx/algitem.hxx>
31cdf0e10cSrcweir #include <unotools/textsearch.hxx>
32cdf0e10cSrcweir #include <sfx2/objsh.hxx>
33cdf0e10cSrcweir 
34cdf0e10cSrcweir #include "attrib.hxx"
35cdf0e10cSrcweir #include "patattr.hxx"
36cdf0e10cSrcweir #include "cell.hxx"
37cdf0e10cSrcweir #include "table.hxx"
38cdf0e10cSrcweir #include "document.hxx"
39cdf0e10cSrcweir #include "drwlayer.hxx"
40cdf0e10cSrcweir #include "olinetab.hxx"
41cdf0e10cSrcweir #include "stlsheet.hxx"
42cdf0e10cSrcweir #include "global.hxx"
43cdf0e10cSrcweir #include "globstr.hrc"
44cdf0e10cSrcweir #include "refupdat.hxx"
45cdf0e10cSrcweir #include "markdata.hxx"
46cdf0e10cSrcweir #include "progress.hxx"
47cdf0e10cSrcweir #include "hints.hxx"		// fuer Paint-Broadcast
48cdf0e10cSrcweir #include "prnsave.hxx"
49cdf0e10cSrcweir #include "tabprotection.hxx"
50cdf0e10cSrcweir #include "sheetevents.hxx"
51cdf0e10cSrcweir #include "segmenttree.hxx"
52cdf0e10cSrcweir 
53cdf0e10cSrcweir // -----------------------------------------------------------------------
54cdf0e10cSrcweir 
ScTable(ScDocument * pDoc,SCTAB nNewTab,const String & rNewName,sal_Bool bColInfo,sal_Bool bRowInfo)55cdf0e10cSrcweir ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const String& rNewName,
56cdf0e10cSrcweir 					sal_Bool bColInfo, sal_Bool bRowInfo ) :
57cdf0e10cSrcweir 	aName( rNewName ),
58cdf0e10cSrcweir 	aCodeName( rNewName ),
59cdf0e10cSrcweir 	bScenario( sal_False ),
60cdf0e10cSrcweir 	bLayoutRTL( sal_False ),
61cdf0e10cSrcweir     bLoadingRTL( sal_False ),
62cdf0e10cSrcweir 	nLinkMode( 0 ),
63cdf0e10cSrcweir 	aPageStyle( ScGlobal::GetRscString(STR_STYLENAME_STANDARD) ),
64cdf0e10cSrcweir 	bPageSizeValid( sal_False ),
65cdf0e10cSrcweir 	nRepeatStartX( SCCOL_REPEAT_NONE ),
66cdf0e10cSrcweir 	nRepeatStartY( SCROW_REPEAT_NONE ),
67cdf0e10cSrcweir     pTabProtection( NULL ),
68cdf0e10cSrcweir 	pColWidth( NULL ),
69cdf0e10cSrcweir     mpRowHeights( static_cast<ScFlatUInt16RowSegments*>(NULL) ),
70cdf0e10cSrcweir 	pColFlags( NULL ),
71cdf0e10cSrcweir 	pRowFlags( NULL ),
72cdf0e10cSrcweir     mpHiddenCols(new ScFlatBoolColSegments),
73cdf0e10cSrcweir     mpHiddenRows(new ScFlatBoolRowSegments),
74cdf0e10cSrcweir     mpFilteredCols(new ScFlatBoolColSegments),
75cdf0e10cSrcweir     mpFilteredRows(new ScFlatBoolRowSegments),
76cdf0e10cSrcweir 	pOutlineTable( NULL ),
77cdf0e10cSrcweir     pSheetEvents( NULL ),
78cdf0e10cSrcweir 	bTableAreaValid( sal_False ),
79cdf0e10cSrcweir 	bVisible( sal_True ),
80cdf0e10cSrcweir     bStreamValid( sal_False ),
81cdf0e10cSrcweir     bPendingRowHeights( sal_False ),
82cdf0e10cSrcweir     bCalcNotification( sal_False ),
83cdf0e10cSrcweir 	nTab( nNewTab ),
84cdf0e10cSrcweir 	nRecalcLvl( 0 ),
85cdf0e10cSrcweir 	pDocument( pDoc ),
86cdf0e10cSrcweir 	pSearchParam( NULL ),
87cdf0e10cSrcweir 	pSearchText ( NULL ),
88cdf0e10cSrcweir 	pSortCollator( NULL ),
89cdf0e10cSrcweir     bPrintEntireSheet( sal_False ),
90cdf0e10cSrcweir 	pRepeatColRange( NULL ),
91cdf0e10cSrcweir 	pRepeatRowRange( NULL ),
92cdf0e10cSrcweir 	nLockCount( 0 ),
93cdf0e10cSrcweir 	pScenarioRanges( NULL ),
94cdf0e10cSrcweir 	aScenarioColor( COL_LIGHTGRAY ),
95cdf0e10cSrcweir     aTabBgColor( COL_AUTO ),
96cdf0e10cSrcweir 	nScenarioFlags( 0 ),
97cdf0e10cSrcweir 	bActiveScenario( sal_False ),
98cdf0e10cSrcweir     mbPageBreaksValid(false)
99cdf0e10cSrcweir {
100cdf0e10cSrcweir 
101cdf0e10cSrcweir 	if (bColInfo)
102cdf0e10cSrcweir 	{
103cdf0e10cSrcweir 		pColWidth  = new sal_uInt16[ MAXCOL+1 ];
104cdf0e10cSrcweir 		pColFlags  = new sal_uInt8[ MAXCOL+1 ];
105cdf0e10cSrcweir 
106cdf0e10cSrcweir 		for (SCCOL i=0; i<=MAXCOL; i++)
107cdf0e10cSrcweir 		{
108cdf0e10cSrcweir 			pColWidth[i] = STD_COL_WIDTH;
109cdf0e10cSrcweir 			pColFlags[i] = 0;
110cdf0e10cSrcweir 		}
111cdf0e10cSrcweir 	}
112cdf0e10cSrcweir 
113cdf0e10cSrcweir 	if (bRowInfo)
114cdf0e10cSrcweir 	{
115cdf0e10cSrcweir         mpRowHeights.reset(new ScFlatUInt16RowSegments(ScGlobal::nStdRowHeight));
116cdf0e10cSrcweir         pRowFlags  = new ScBitMaskCompressedArray< SCROW, sal_uInt8>( MAXROW, 0);
117cdf0e10cSrcweir 	}
118cdf0e10cSrcweir 
119cdf0e10cSrcweir 	if ( pDocument->IsDocVisible() )
120cdf0e10cSrcweir 	{
121cdf0e10cSrcweir 		//	when a sheet is added to a visible document,
122cdf0e10cSrcweir 		//	initialize its RTL flag from the system locale
123cdf0e10cSrcweir 		bLayoutRTL = ScGlobal::IsSystemRTL();
124cdf0e10cSrcweir 	}
125cdf0e10cSrcweir 
126cdf0e10cSrcweir 	ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
127cdf0e10cSrcweir 	if (pDrawLayer)
128cdf0e10cSrcweir 	{
129cdf0e10cSrcweir         if ( pDrawLayer->ScAddPage( nTab ) )    // sal_False (not inserted) during Undo
130cdf0e10cSrcweir         {
131cdf0e10cSrcweir             pDrawLayer->ScRenamePage( nTab, aName );
132cdf0e10cSrcweir             sal_uLong nx = (sal_uLong) ((double) (MAXCOL+1) * STD_COL_WIDTH			  * HMM_PER_TWIPS );
133cdf0e10cSrcweir             sal_uLong ny = (sal_uLong) ((double) (MAXROW+1) * ScGlobal::nStdRowHeight * HMM_PER_TWIPS );
134cdf0e10cSrcweir             pDrawLayer->SetPageSize( static_cast<sal_uInt16>(nTab), Size( nx, ny ), false );
135cdf0e10cSrcweir         }
136cdf0e10cSrcweir 	}
137cdf0e10cSrcweir 
138cdf0e10cSrcweir 	for (SCCOL k=0; k<=MAXCOL; k++)
139cdf0e10cSrcweir 		aCol[k].Init( k, nTab, pDocument );
140cdf0e10cSrcweir }
141cdf0e10cSrcweir 
~ScTable()142cdf0e10cSrcweir ScTable::~ScTable()
143cdf0e10cSrcweir {
144cdf0e10cSrcweir 	if (!pDocument->IsInDtorClear())
145cdf0e10cSrcweir 	{
146cdf0e10cSrcweir 		//	nicht im dtor die Pages in der falschen Reihenfolge loeschen
147cdf0e10cSrcweir 		//	(nTab stimmt dann als Page-Number nicht!)
148cdf0e10cSrcweir 		//	In ScDocument::Clear wird hinterher per Clear am Draw Layer alles geloescht.
149cdf0e10cSrcweir 
150cdf0e10cSrcweir 		ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
151cdf0e10cSrcweir 		if (pDrawLayer)
152cdf0e10cSrcweir 			pDrawLayer->ScRemovePage( nTab );
153cdf0e10cSrcweir 	}
154cdf0e10cSrcweir 
155cdf0e10cSrcweir 	delete[] pColWidth;
156cdf0e10cSrcweir 	delete[] pColFlags;
157cdf0e10cSrcweir 	delete pRowFlags;
158cdf0e10cSrcweir     delete pSheetEvents;
159cdf0e10cSrcweir 	delete pOutlineTable;
160cdf0e10cSrcweir 	delete pSearchParam;
161cdf0e10cSrcweir 	delete pSearchText;
162cdf0e10cSrcweir 	delete pRepeatColRange;
163cdf0e10cSrcweir 	delete pRepeatRowRange;
164cdf0e10cSrcweir 	delete pScenarioRanges;
165cdf0e10cSrcweir 	DestroySortCollator();
166cdf0e10cSrcweir }
167cdf0e10cSrcweir 
GetName(String & rName) const168cdf0e10cSrcweir void ScTable::GetName( String& rName ) const
169cdf0e10cSrcweir {
170cdf0e10cSrcweir 	rName = aName;
171cdf0e10cSrcweir }
172cdf0e10cSrcweir 
SetName(const String & rNewName)173cdf0e10cSrcweir void ScTable::SetName( const String& rNewName )
174cdf0e10cSrcweir {
175cdf0e10cSrcweir 	aName = rNewName;
176cdf0e10cSrcweir     aUpperName.Erase();         // invalidated if the name is changed
177cdf0e10cSrcweir 
178cdf0e10cSrcweir     // SetStreamValid is handled in ScDocument::RenameTab
179cdf0e10cSrcweir }
180cdf0e10cSrcweir 
GetUpperName() const181cdf0e10cSrcweir const String& ScTable::GetUpperName() const
182cdf0e10cSrcweir {
183cdf0e10cSrcweir     if ( !aUpperName.Len() && aName.Len() )
184cdf0e10cSrcweir         aUpperName = ScGlobal::pCharClass->upper( aName );
185cdf0e10cSrcweir     return aUpperName;
186cdf0e10cSrcweir }
187cdf0e10cSrcweir 
SetVisible(sal_Bool bVis)188cdf0e10cSrcweir void ScTable::SetVisible( sal_Bool bVis )
189cdf0e10cSrcweir {
190cdf0e10cSrcweir     if (bVisible != bVis && IsStreamValid())
191cdf0e10cSrcweir         SetStreamValid(sal_False);
192cdf0e10cSrcweir 
193cdf0e10cSrcweir 	bVisible = bVis;
194cdf0e10cSrcweir }
195cdf0e10cSrcweir 
SetStreamValid(sal_Bool bSet,sal_Bool bIgnoreLock)196cdf0e10cSrcweir void ScTable::SetStreamValid( sal_Bool bSet, sal_Bool bIgnoreLock )
197cdf0e10cSrcweir {
198cdf0e10cSrcweir     if ( bIgnoreLock || !pDocument->IsStreamValidLocked() )
199cdf0e10cSrcweir         bStreamValid = bSet;
200cdf0e10cSrcweir }
201cdf0e10cSrcweir 
SetPendingRowHeights(sal_Bool bSet)202cdf0e10cSrcweir void ScTable::SetPendingRowHeights( sal_Bool bSet )
203cdf0e10cSrcweir {
204cdf0e10cSrcweir     bPendingRowHeights = bSet;
205cdf0e10cSrcweir }
206cdf0e10cSrcweir 
SetLayoutRTL(sal_Bool bSet)207cdf0e10cSrcweir void ScTable::SetLayoutRTL( sal_Bool bSet )
208cdf0e10cSrcweir {
209cdf0e10cSrcweir     bLayoutRTL = bSet;
210cdf0e10cSrcweir }
211cdf0e10cSrcweir 
SetLoadingRTL(sal_Bool bSet)212cdf0e10cSrcweir void ScTable::SetLoadingRTL( sal_Bool bSet )
213cdf0e10cSrcweir {
214cdf0e10cSrcweir     bLoadingRTL = bSet;
215cdf0e10cSrcweir }
216cdf0e10cSrcweir 
GetTabBgColor() const217cdf0e10cSrcweir const Color& ScTable::GetTabBgColor() const
218cdf0e10cSrcweir {
219cdf0e10cSrcweir     return aTabBgColor;
220cdf0e10cSrcweir }
221cdf0e10cSrcweir 
SetTabBgColor(const Color & rColor)222cdf0e10cSrcweir void ScTable::SetTabBgColor(const Color& rColor)
223cdf0e10cSrcweir {
224cdf0e10cSrcweir     if (aTabBgColor != rColor)
225cdf0e10cSrcweir     {
226cdf0e10cSrcweir         // The tab color has changed.  Set this table 'modified'.
227cdf0e10cSrcweir         aTabBgColor = rColor;
228cdf0e10cSrcweir         if (IsStreamValid())
229cdf0e10cSrcweir             SetStreamValid(false);
230cdf0e10cSrcweir     }
231cdf0e10cSrcweir }
232cdf0e10cSrcweir 
SetScenario(sal_Bool bFlag)233cdf0e10cSrcweir void ScTable::SetScenario( sal_Bool bFlag )
234cdf0e10cSrcweir {
235cdf0e10cSrcweir 	bScenario = bFlag;
236cdf0e10cSrcweir }
237cdf0e10cSrcweir 
SetLink(sal_uInt8 nMode,const String & rDoc,const String & rFlt,const String & rOpt,const String & rTab,sal_uLong nRefreshDelay)238cdf0e10cSrcweir void ScTable::SetLink( sal_uInt8 nMode,
239cdf0e10cSrcweir 						const String& rDoc, const String& rFlt, const String& rOpt,
240cdf0e10cSrcweir 						const String& rTab, sal_uLong nRefreshDelay )
241cdf0e10cSrcweir {
242cdf0e10cSrcweir 	nLinkMode = nMode;
243cdf0e10cSrcweir 	aLinkDoc = rDoc;		// Datei
244cdf0e10cSrcweir 	aLinkFlt = rFlt;		// Filter
245cdf0e10cSrcweir 	aLinkOpt = rOpt;		// Filter-Optionen
246cdf0e10cSrcweir 	aLinkTab = rTab;		// Tabellenname in Quelldatei
247cdf0e10cSrcweir 	nLinkRefreshDelay = nRefreshDelay;	// refresh delay in seconds, 0==off
248cdf0e10cSrcweir 
249cdf0e10cSrcweir     if (IsStreamValid())
250cdf0e10cSrcweir         SetStreamValid(sal_False);
251cdf0e10cSrcweir }
252cdf0e10cSrcweir 
GetOptimalColWidth(SCCOL nCol,OutputDevice * pDev,double nPPTX,double nPPTY,const Fraction & rZoomX,const Fraction & rZoomY,sal_Bool bFormula,const ScMarkData * pMarkData,sal_Bool bSimpleTextImport)253cdf0e10cSrcweir sal_uInt16 ScTable::GetOptimalColWidth( SCCOL nCol, OutputDevice* pDev,
254cdf0e10cSrcweir 									double nPPTX, double nPPTY,
255cdf0e10cSrcweir 									const Fraction& rZoomX, const Fraction& rZoomY,
256cdf0e10cSrcweir 									sal_Bool bFormula, const ScMarkData* pMarkData,
257cdf0e10cSrcweir 									sal_Bool bSimpleTextImport )
258cdf0e10cSrcweir {
259cdf0e10cSrcweir 	return aCol[nCol].GetOptimalColWidth( pDev, nPPTX, nPPTY, rZoomX, rZoomY,
260cdf0e10cSrcweir 		bFormula, STD_COL_WIDTH - STD_EXTRA_WIDTH, pMarkData, bSimpleTextImport );
261cdf0e10cSrcweir }
262cdf0e10cSrcweir 
GetNeededSize(SCCOL nCol,SCROW nRow,OutputDevice * pDev,double nPPTX,double nPPTY,const Fraction & rZoomX,const Fraction & rZoomY,sal_Bool bWidth,sal_Bool bTotalSize)263cdf0e10cSrcweir long ScTable::GetNeededSize( SCCOL nCol, SCROW nRow,
264cdf0e10cSrcweir 								OutputDevice* pDev,
265cdf0e10cSrcweir 								double nPPTX, double nPPTY,
266cdf0e10cSrcweir 								const Fraction& rZoomX, const Fraction& rZoomY,
267cdf0e10cSrcweir 								sal_Bool bWidth, sal_Bool bTotalSize )
268cdf0e10cSrcweir {
269cdf0e10cSrcweir 	ScNeededSizeOptions aOptions;
270cdf0e10cSrcweir 	aOptions.bSkipMerged = sal_False;		// zusammengefasste mitzaehlen
271cdf0e10cSrcweir 	aOptions.bTotalSize  = bTotalSize;
272cdf0e10cSrcweir 
273cdf0e10cSrcweir 	return aCol[nCol].GetNeededSize
274cdf0e10cSrcweir 		( nRow, pDev, nPPTX, nPPTY, rZoomX, rZoomY, bWidth, aOptions );
275cdf0e10cSrcweir }
276cdf0e10cSrcweir 
SetOptimalHeight(SCROW nStartRow,SCROW nEndRow,sal_uInt16 nExtra,OutputDevice * pDev,double nPPTX,double nPPTY,const Fraction & rZoomX,const Fraction & rZoomY,sal_Bool bForce,ScProgress * pOuterProgress,sal_uLong nProgressStart)277cdf0e10cSrcweir sal_Bool ScTable::SetOptimalHeight( SCROW nStartRow, SCROW nEndRow, sal_uInt16 nExtra,
278cdf0e10cSrcweir 								OutputDevice* pDev,
279cdf0e10cSrcweir 								double nPPTX, double nPPTY,
280cdf0e10cSrcweir 								const Fraction& rZoomX, const Fraction& rZoomY,
281cdf0e10cSrcweir                                 sal_Bool bForce, ScProgress* pOuterProgress, sal_uLong nProgressStart )
282cdf0e10cSrcweir {
283cdf0e10cSrcweir 	DBG_ASSERT( nExtra==0 || bForce, "autom. OptimalHeight mit Extra" );
284cdf0e10cSrcweir 
285cdf0e10cSrcweir     if ( !pDocument->IsAdjustHeightEnabled() )
286cdf0e10cSrcweir     {
287cdf0e10cSrcweir         return sal_False;
288cdf0e10cSrcweir     }
289cdf0e10cSrcweir 
290cdf0e10cSrcweir 	sal_Bool    bChanged = sal_False;
291cdf0e10cSrcweir 	SCSIZE  nCount = static_cast<SCSIZE>(nEndRow-nStartRow+1);
292cdf0e10cSrcweir 
293cdf0e10cSrcweir 	ScProgress* pProgress = NULL;
294cdf0e10cSrcweir     if ( pOuterProgress )
295cdf0e10cSrcweir         pProgress = pOuterProgress;
296cdf0e10cSrcweir     else if ( nCount > 1 )
297cdf0e10cSrcweir 		pProgress = new ScProgress( pDocument->GetDocumentShell(),
298cdf0e10cSrcweir 							ScGlobal::GetRscString(STR_PROGRESS_HEIGHTING), GetWeightedCount() );
299cdf0e10cSrcweir 
300cdf0e10cSrcweir 	sal_uInt16* pHeight = new sal_uInt16[nCount];                   // Twips !
301cdf0e10cSrcweir     memset( pHeight, 0, sizeof(sal_uInt16) * nCount );
302cdf0e10cSrcweir 
303cdf0e10cSrcweir 	//	zuerst einmal ueber den ganzen Bereich
304cdf0e10cSrcweir 	//	(mit der letzten Spalte in der Hoffnung, dass die am ehesten noch auf
305cdf0e10cSrcweir 	//	 Standard formatiert ist)
306cdf0e10cSrcweir 
307cdf0e10cSrcweir 	aCol[MAXCOL].GetOptimalHeight(
308cdf0e10cSrcweir 			nStartRow, nEndRow, pHeight, pDev, nPPTX, nPPTY, rZoomX, rZoomY, bForce, 0, 0 );
309cdf0e10cSrcweir 
310cdf0e10cSrcweir 	//	daraus Standardhoehe suchen, die im unteren Bereich gilt
311cdf0e10cSrcweir 
312cdf0e10cSrcweir 	sal_uInt16 nMinHeight = pHeight[nCount-1];
313cdf0e10cSrcweir 	SCSIZE nPos = nCount-1;
314cdf0e10cSrcweir 	while ( nPos && pHeight[nPos-1] >= nMinHeight )
315cdf0e10cSrcweir 		--nPos;
316cdf0e10cSrcweir 	SCROW nMinStart = nStartRow + nPos;
317cdf0e10cSrcweir 
318cdf0e10cSrcweir     sal_uLong nWeightedCount = 0;
319cdf0e10cSrcweir 	for (SCCOL nCol=0; nCol<MAXCOL; nCol++)		// MAXCOL schon oben
320cdf0e10cSrcweir 	{
321cdf0e10cSrcweir 		aCol[nCol].GetOptimalHeight(
322cdf0e10cSrcweir 			nStartRow, nEndRow, pHeight, pDev, nPPTX, nPPTY, rZoomX, rZoomY, bForce,
323cdf0e10cSrcweir 			nMinHeight, nMinStart );
324cdf0e10cSrcweir 
325cdf0e10cSrcweir 		if (pProgress)
326cdf0e10cSrcweir 		{
327cdf0e10cSrcweir             sal_uLong nWeight = aCol[nCol].GetWeightedCount();
328cdf0e10cSrcweir 			if (nWeight)		// nochmal denselben Status muss auch nicht sein
329cdf0e10cSrcweir 			{
330cdf0e10cSrcweir 				nWeightedCount += nWeight;
331cdf0e10cSrcweir                 pProgress->SetState( nWeightedCount + nProgressStart );
332cdf0e10cSrcweir 			}
333cdf0e10cSrcweir 		}
334cdf0e10cSrcweir 	}
335cdf0e10cSrcweir 
336cdf0e10cSrcweir     IncRecalcLevel();       // #i116460# avoid problems with Excel files
337cdf0e10cSrcweir 
338cdf0e10cSrcweir     SCROW nRngStart = 0;
339cdf0e10cSrcweir     SCROW nRngEnd = 0;
340cdf0e10cSrcweir 	sal_uInt16 nLast = 0;
341cdf0e10cSrcweir 	for (SCSIZE i=0; i<nCount; i++)
342cdf0e10cSrcweir 	{
343cdf0e10cSrcweir         size_t nIndex;
344cdf0e10cSrcweir         SCROW nRegionEndRow;
345cdf0e10cSrcweir         sal_uInt8 nRowFlag = pRowFlags->GetValue( nStartRow+i, nIndex, nRegionEndRow );
346cdf0e10cSrcweir         if ( nRegionEndRow > nEndRow )
347cdf0e10cSrcweir             nRegionEndRow = nEndRow;
348cdf0e10cSrcweir         SCSIZE nMoreRows = nRegionEndRow - ( nStartRow+i );     // additional equal rows after first
349cdf0e10cSrcweir 
350cdf0e10cSrcweir         bool bAutoSize = ((nRowFlag & CR_MANUALSIZE) == 0);
351cdf0e10cSrcweir 		if ( bAutoSize || bForce )
352cdf0e10cSrcweir 		{
353cdf0e10cSrcweir 			if (nExtra)
354cdf0e10cSrcweir             {
355cdf0e10cSrcweir                 if (bAutoSize)
356cdf0e10cSrcweir                     pRowFlags->SetValue( nStartRow+i, nRegionEndRow, nRowFlag | CR_MANUALSIZE);
357cdf0e10cSrcweir             }
358cdf0e10cSrcweir 			else if (!bAutoSize)
359cdf0e10cSrcweir                 pRowFlags->SetValue( nStartRow+i, nRegionEndRow, nRowFlag & ~CR_MANUALSIZE);
360cdf0e10cSrcweir 
361cdf0e10cSrcweir             for (SCSIZE nInner = i; nInner <= i + nMoreRows; ++nInner)
362cdf0e10cSrcweir             {
363cdf0e10cSrcweir                 if (nLast)
364cdf0e10cSrcweir                 {
365cdf0e10cSrcweir                     if (pHeight[nInner]+nExtra == nLast)
366cdf0e10cSrcweir                         nRngEnd = nStartRow+nInner;
367cdf0e10cSrcweir                     else
368cdf0e10cSrcweir                     {
369cdf0e10cSrcweir                         bChanged |= SetRowHeightRange( nRngStart, nRngEnd, nLast, nPPTX, nPPTY );
370cdf0e10cSrcweir                         nLast = 0;
371cdf0e10cSrcweir                     }
372cdf0e10cSrcweir                 }
373cdf0e10cSrcweir                 if (!nLast)
374cdf0e10cSrcweir                 {
375cdf0e10cSrcweir                     nLast = pHeight[nInner]+nExtra;
376cdf0e10cSrcweir                     nRngStart = nStartRow+nInner;
377cdf0e10cSrcweir                     nRngEnd = nStartRow+nInner;
378cdf0e10cSrcweir                 }
379cdf0e10cSrcweir             }
380cdf0e10cSrcweir 		}
381cdf0e10cSrcweir 		else
382cdf0e10cSrcweir 		{
383cdf0e10cSrcweir 			if (nLast)
384cdf0e10cSrcweir 				bChanged |= SetRowHeightRange( nRngStart, nRngEnd, nLast, nPPTX, nPPTY );
385cdf0e10cSrcweir 			nLast = 0;
386cdf0e10cSrcweir 		}
387cdf0e10cSrcweir         i += nMoreRows;     // already handled - skip
388cdf0e10cSrcweir 	}
389cdf0e10cSrcweir 	if (nLast)
390cdf0e10cSrcweir 		bChanged |= SetRowHeightRange( nRngStart, nRngEnd, nLast, nPPTX, nPPTY );
391cdf0e10cSrcweir 
392cdf0e10cSrcweir     DecRecalcLevel();       // #i116460# avoid problems with Excel files
393cdf0e10cSrcweir 
394cdf0e10cSrcweir 	delete[] pHeight;
395cdf0e10cSrcweir     if ( pProgress != pOuterProgress )
396cdf0e10cSrcweir         delete pProgress;
397cdf0e10cSrcweir 
398cdf0e10cSrcweir 	return bChanged;
399cdf0e10cSrcweir }
400cdf0e10cSrcweir 
GetCellArea(SCCOL & rEndCol,SCROW & rEndRow) const401cdf0e10cSrcweir sal_Bool ScTable::GetCellArea( SCCOL& rEndCol, SCROW& rEndRow ) const
402cdf0e10cSrcweir {
403cdf0e10cSrcweir 	sal_Bool bFound = sal_False;
404cdf0e10cSrcweir 	SCCOL nMaxX = 0;
405cdf0e10cSrcweir 	SCROW nMaxY = 0;
406cdf0e10cSrcweir 	for (SCCOL i=0; i<=MAXCOL; i++)
407cdf0e10cSrcweir 		if (!aCol[i].IsEmptyVisData(sal_True))		// sal_True = Notizen zaehlen auch
408cdf0e10cSrcweir 		{
409cdf0e10cSrcweir 			bFound = sal_True;
410cdf0e10cSrcweir 			nMaxX = i;
411cdf0e10cSrcweir 			SCROW nColY = aCol[i].GetLastVisDataPos(sal_True);
412cdf0e10cSrcweir 			if (nColY > nMaxY)
413cdf0e10cSrcweir 				nMaxY = nColY;
414cdf0e10cSrcweir 		}
415cdf0e10cSrcweir 
416cdf0e10cSrcweir 	rEndCol = nMaxX;
417cdf0e10cSrcweir 	rEndRow = nMaxY;
418cdf0e10cSrcweir 	return bFound;
419cdf0e10cSrcweir }
420cdf0e10cSrcweir 
GetTableArea(SCCOL & rEndCol,SCROW & rEndRow) const421cdf0e10cSrcweir sal_Bool ScTable::GetTableArea( SCCOL& rEndCol, SCROW& rEndRow ) const
422cdf0e10cSrcweir {
423cdf0e10cSrcweir 	sal_Bool bRet = sal_True;				//! merken?
424cdf0e10cSrcweir 	if (!bTableAreaValid)
425cdf0e10cSrcweir 	{
426cdf0e10cSrcweir 		bRet = GetPrintArea( ((ScTable*)this)->nTableAreaX,
427cdf0e10cSrcweir 								((ScTable*)this)->nTableAreaY, sal_True );
428cdf0e10cSrcweir 		((ScTable*)this)->bTableAreaValid = sal_True;
429cdf0e10cSrcweir 	}
430cdf0e10cSrcweir 	rEndCol = nTableAreaX;
431cdf0e10cSrcweir 	rEndRow = nTableAreaY;
432cdf0e10cSrcweir 	return bRet;
433cdf0e10cSrcweir }
434cdf0e10cSrcweir 
GetLastAttrCell(SCCOL & rEndCol,SCROW & rEndRow) const435*557cb412SWang Lei void ScTable::GetLastAttrCell( SCCOL& rEndCol, SCROW& rEndRow ) const
436*557cb412SWang Lei {
437*557cb412SWang Lei 	SCCOL nMaxX = 0;
438*557cb412SWang Lei 	SCROW nMaxY = 0;
439*557cb412SWang Lei 	SCCOL i;
440*557cb412SWang Lei 	for ( i = 0; i <= MAXCOL; i++ )
441*557cb412SWang Lei 	{
442*557cb412SWang Lei 		SCROW nLastRow;
443*557cb412SWang Lei 		aCol[i].GetLastAttr( nLastRow );
444*557cb412SWang Lei 		if ( nLastRow > nMaxY && nLastRow > 0 && nLastRow <= MAXROW )
445*557cb412SWang Lei 		{
446*557cb412SWang Lei 			nMaxY = nLastRow;
447*557cb412SWang Lei 			nMaxX = i;
448*557cb412SWang Lei 		}
449*557cb412SWang Lei 	}
450*557cb412SWang Lei 	rEndCol = nMaxX;
451*557cb412SWang Lei 	rEndRow = nMaxY;
452*557cb412SWang Lei }
453cdf0e10cSrcweir /*		vorher:
454cdf0e10cSrcweir 
455cdf0e10cSrcweir 	sal_Bool bFound = sal_False;
456cdf0e10cSrcweir 	SCCOL nMaxX = 0;
457cdf0e10cSrcweir 	SCROW nMaxY = 0;
458cdf0e10cSrcweir 	for (SCCOL i=0; i<=MAXCOL; i++)
459cdf0e10cSrcweir 		if (!aCol[i].IsEmpty())
460cdf0e10cSrcweir 		{
461cdf0e10cSrcweir 			bFound = sal_True;
462cdf0e10cSrcweir 			nMaxX = i;
463cdf0e10cSrcweir 			SCCOL nColY = aCol[i].GetLastEntryPos();
464cdf0e10cSrcweir 			if (nColY > nMaxY)
465cdf0e10cSrcweir 				nMaxY = nColY;
466cdf0e10cSrcweir 		}
467cdf0e10cSrcweir 
468cdf0e10cSrcweir 	rEndCol = nMaxX;
469cdf0e10cSrcweir 	rEndRow = nMaxY;
470cdf0e10cSrcweir 	return bFound;
471cdf0e10cSrcweir */
472cdf0e10cSrcweir 
473cdf0e10cSrcweir const SCCOL SC_COLUMNS_STOP = 30;
474cdf0e10cSrcweir 
GetPrintArea(SCCOL & rEndCol,SCROW & rEndRow,sal_Bool bNotes) const475cdf0e10cSrcweir sal_Bool ScTable::GetPrintArea( SCCOL& rEndCol, SCROW& rEndRow, sal_Bool bNotes ) const
476cdf0e10cSrcweir {
477cdf0e10cSrcweir 	sal_Bool bFound = sal_False;
478cdf0e10cSrcweir 	SCCOL nMaxX = 0;
479cdf0e10cSrcweir 	SCROW nMaxY = 0;
480cdf0e10cSrcweir 	SCCOL i;
481cdf0e10cSrcweir 
482cdf0e10cSrcweir 	for (i=0; i<=MAXCOL; i++)				// Daten testen
483cdf0e10cSrcweir 		if (!aCol[i].IsEmptyVisData(bNotes))
484cdf0e10cSrcweir 		{
485cdf0e10cSrcweir 			bFound = sal_True;
486cdf0e10cSrcweir 			if (i>nMaxX)
487cdf0e10cSrcweir 				nMaxX = i;
488cdf0e10cSrcweir 			SCROW nColY = aCol[i].GetLastVisDataPos(bNotes);
489cdf0e10cSrcweir 			if (nColY > nMaxY)
490cdf0e10cSrcweir 				nMaxY = nColY;
491cdf0e10cSrcweir 		}
492cdf0e10cSrcweir 
493cdf0e10cSrcweir     SCCOL nMaxDataX = nMaxX;
494cdf0e10cSrcweir 
495cdf0e10cSrcweir 	for (i=0; i<=MAXCOL; i++)				// Attribute testen
496cdf0e10cSrcweir 	{
497cdf0e10cSrcweir 		SCROW nLastRow;
498cdf0e10cSrcweir 		if (aCol[i].GetLastVisibleAttr( nLastRow ))
499cdf0e10cSrcweir 		{
500cdf0e10cSrcweir 			bFound = sal_True;
501cdf0e10cSrcweir 			nMaxX = i;
502cdf0e10cSrcweir 			if (nLastRow > nMaxY)
503cdf0e10cSrcweir 				nMaxY = nLastRow;
504cdf0e10cSrcweir 		}
505cdf0e10cSrcweir 	}
506cdf0e10cSrcweir 
507cdf0e10cSrcweir 	if (nMaxX == MAXCOL)					// Attribute rechts weglassen
508cdf0e10cSrcweir 	{
509cdf0e10cSrcweir 		--nMaxX;
510cdf0e10cSrcweir 		while ( nMaxX>0 && aCol[nMaxX].IsVisibleAttrEqual(aCol[nMaxX+1]) )
511cdf0e10cSrcweir 			--nMaxX;
512cdf0e10cSrcweir 	}
513cdf0e10cSrcweir 
514cdf0e10cSrcweir     if ( nMaxX < nMaxDataX )
515cdf0e10cSrcweir     {
516cdf0e10cSrcweir         nMaxX = nMaxDataX;
517cdf0e10cSrcweir     }
518cdf0e10cSrcweir     else if ( nMaxX > nMaxDataX )
519cdf0e10cSrcweir     {
520cdf0e10cSrcweir         SCCOL nAttrStartX = nMaxDataX + 1;
521cdf0e10cSrcweir         while ( nAttrStartX < MAXCOL )
522cdf0e10cSrcweir         {
523cdf0e10cSrcweir             SCCOL nAttrEndX = nAttrStartX;
524cdf0e10cSrcweir             while ( nAttrEndX < MAXCOL && aCol[nAttrStartX].IsVisibleAttrEqual(aCol[nAttrEndX+1]) )
525cdf0e10cSrcweir                 ++nAttrEndX;
526cdf0e10cSrcweir             if ( nAttrEndX + 1 - nAttrStartX >= SC_COLUMNS_STOP )
527cdf0e10cSrcweir             {
528cdf0e10cSrcweir                 // found equally-formatted columns behind data -> stop before these columns
529cdf0e10cSrcweir                 nMaxX = nAttrStartX - 1;
530cdf0e10cSrcweir 
531cdf0e10cSrcweir                 // also don't include default-formatted columns before that
532cdf0e10cSrcweir                 SCROW nDummyRow;
533cdf0e10cSrcweir                 while ( nMaxX > nMaxDataX && !aCol[nMaxX].GetLastVisibleAttr( nDummyRow ) )
534cdf0e10cSrcweir                     --nMaxX;
535cdf0e10cSrcweir                 break;
536cdf0e10cSrcweir             }
537cdf0e10cSrcweir             nAttrStartX = nAttrEndX + 1;
538cdf0e10cSrcweir         }
539cdf0e10cSrcweir     }
540cdf0e10cSrcweir 
541cdf0e10cSrcweir 	rEndCol = nMaxX;
542cdf0e10cSrcweir 	rEndRow = nMaxY;
543cdf0e10cSrcweir 	return bFound;
544cdf0e10cSrcweir }
545cdf0e10cSrcweir 
GetPrintAreaHor(SCROW nStartRow,SCROW nEndRow,SCCOL & rEndCol,sal_Bool) const546cdf0e10cSrcweir sal_Bool ScTable::GetPrintAreaHor( SCROW nStartRow, SCROW nEndRow,
547cdf0e10cSrcweir                                 SCCOL& rEndCol, sal_Bool /* bNotes */ ) const
548cdf0e10cSrcweir {
549cdf0e10cSrcweir 	sal_Bool bFound = sal_False;
550cdf0e10cSrcweir 	SCCOL nMaxX = 0;
551cdf0e10cSrcweir 	SCCOL i;
552cdf0e10cSrcweir 
553cdf0e10cSrcweir 	for (i=0; i<=MAXCOL; i++)				// Attribute testen
554cdf0e10cSrcweir 	{
555cdf0e10cSrcweir 		if (aCol[i].HasVisibleAttrIn( nStartRow, nEndRow ))
556cdf0e10cSrcweir 		{
557cdf0e10cSrcweir 			bFound = sal_True;
558cdf0e10cSrcweir 			nMaxX = i;
559cdf0e10cSrcweir 		}
560cdf0e10cSrcweir 	}
561cdf0e10cSrcweir 
562cdf0e10cSrcweir 	if (nMaxX == MAXCOL)					// Attribute rechts weglassen
563cdf0e10cSrcweir 	{
564cdf0e10cSrcweir 		--nMaxX;
565cdf0e10cSrcweir 		while ( nMaxX>0 && aCol[nMaxX].IsVisibleAttrEqual(aCol[nMaxX+1], nStartRow, nEndRow) )
566cdf0e10cSrcweir 			--nMaxX;
567cdf0e10cSrcweir 	}
568cdf0e10cSrcweir 
569cdf0e10cSrcweir 	for (i=0; i<=MAXCOL; i++)				// Daten testen
570cdf0e10cSrcweir 	{
571cdf0e10cSrcweir 		if (!aCol[i].IsEmptyBlock( nStartRow, nEndRow ))		//! bNotes ??????
572cdf0e10cSrcweir 		{
573cdf0e10cSrcweir 			bFound = sal_True;
574cdf0e10cSrcweir 			if (i>nMaxX)
575cdf0e10cSrcweir 				nMaxX = i;
576cdf0e10cSrcweir 		}
577cdf0e10cSrcweir 	}
578cdf0e10cSrcweir 
579cdf0e10cSrcweir 	rEndCol = nMaxX;
580cdf0e10cSrcweir 	return bFound;
581cdf0e10cSrcweir }
582cdf0e10cSrcweir 
GetPrintAreaVer(SCCOL nStartCol,SCCOL nEndCol,SCROW & rEndRow,sal_Bool bNotes) const583cdf0e10cSrcweir sal_Bool ScTable::GetPrintAreaVer( SCCOL nStartCol, SCCOL nEndCol,
584cdf0e10cSrcweir 								SCROW& rEndRow, sal_Bool bNotes ) const
585cdf0e10cSrcweir {
586cdf0e10cSrcweir 	sal_Bool bFound = sal_False;
587cdf0e10cSrcweir 	SCROW nMaxY = 0;
588cdf0e10cSrcweir 	SCCOL i;
589cdf0e10cSrcweir 
590cdf0e10cSrcweir 	for (i=nStartCol; i<=nEndCol; i++)				// Attribute testen
591cdf0e10cSrcweir 	{
592cdf0e10cSrcweir 		SCROW nLastRow;
593cdf0e10cSrcweir 		if (aCol[i].GetLastVisibleAttr( nLastRow ))
594cdf0e10cSrcweir 		{
595cdf0e10cSrcweir 			bFound = sal_True;
596cdf0e10cSrcweir 			if (nLastRow > nMaxY)
597cdf0e10cSrcweir 				nMaxY = nLastRow;
598cdf0e10cSrcweir 		}
599cdf0e10cSrcweir 	}
600cdf0e10cSrcweir 
601cdf0e10cSrcweir 	for (i=nStartCol; i<=nEndCol; i++)				// Daten testen
602cdf0e10cSrcweir 		if (!aCol[i].IsEmptyVisData(bNotes))
603cdf0e10cSrcweir 		{
604cdf0e10cSrcweir 			bFound = sal_True;
605cdf0e10cSrcweir 			SCROW nColY = aCol[i].GetLastVisDataPos(bNotes);
606cdf0e10cSrcweir 			if (nColY > nMaxY)
607cdf0e10cSrcweir 				nMaxY = nColY;
608cdf0e10cSrcweir 		}
609cdf0e10cSrcweir 
610cdf0e10cSrcweir 	rEndRow = nMaxY;
611cdf0e10cSrcweir 	return bFound;
612cdf0e10cSrcweir }
613cdf0e10cSrcweir 
GetDataStart(SCCOL & rStartCol,SCROW & rStartRow) const614cdf0e10cSrcweir sal_Bool ScTable::GetDataStart( SCCOL& rStartCol, SCROW& rStartRow ) const
615cdf0e10cSrcweir {
616cdf0e10cSrcweir 	sal_Bool bFound = sal_False;
617cdf0e10cSrcweir 	SCCOL nMinX = MAXCOL;
618cdf0e10cSrcweir 	SCROW nMinY = MAXROW;
619cdf0e10cSrcweir 	SCCOL i;
620cdf0e10cSrcweir 
621cdf0e10cSrcweir 	for (i=0; i<=MAXCOL; i++)					// Attribute testen
622cdf0e10cSrcweir 	{
623cdf0e10cSrcweir 		SCROW nFirstRow;
624cdf0e10cSrcweir 		if (aCol[i].GetFirstVisibleAttr( nFirstRow ))
625cdf0e10cSrcweir 		{
626cdf0e10cSrcweir 			if (!bFound)
627cdf0e10cSrcweir 				nMinX = i;
628cdf0e10cSrcweir 			bFound = sal_True;
629cdf0e10cSrcweir 			if (nFirstRow < nMinY)
630cdf0e10cSrcweir 				nMinY = nFirstRow;
631cdf0e10cSrcweir 		}
632cdf0e10cSrcweir 	}
633cdf0e10cSrcweir 
634cdf0e10cSrcweir 	if (nMinX == 0)										// Attribute links weglassen
635cdf0e10cSrcweir 	{
636cdf0e10cSrcweir 		if ( aCol[0].IsVisibleAttrEqual(aCol[1]) )		// keine einzelnen
637cdf0e10cSrcweir 		{
638cdf0e10cSrcweir 			++nMinX;
639cdf0e10cSrcweir 			while ( nMinX<MAXCOL && aCol[nMinX].IsVisibleAttrEqual(aCol[nMinX-1]) )
640cdf0e10cSrcweir 				++nMinX;
641cdf0e10cSrcweir 		}
642cdf0e10cSrcweir 	}
643cdf0e10cSrcweir 
644cdf0e10cSrcweir 	sal_Bool bDatFound = sal_False;
645cdf0e10cSrcweir 	for (i=0; i<=MAXCOL; i++)					// Daten testen
646cdf0e10cSrcweir 		if (!aCol[i].IsEmptyVisData(sal_True))
647cdf0e10cSrcweir 		{
648cdf0e10cSrcweir 			if (!bDatFound && i<nMinX)
649cdf0e10cSrcweir 				nMinX = i;
650cdf0e10cSrcweir 			bFound = bDatFound = sal_True;
651cdf0e10cSrcweir 			SCROW nColY = aCol[i].GetFirstVisDataPos(sal_True);
652cdf0e10cSrcweir 			if (nColY < nMinY)
653cdf0e10cSrcweir 				nMinY = nColY;
654cdf0e10cSrcweir 		}
655cdf0e10cSrcweir 
656cdf0e10cSrcweir 	rStartCol = nMinX;
657cdf0e10cSrcweir 	rStartRow = nMinY;
658cdf0e10cSrcweir 	return bFound;
659cdf0e10cSrcweir }
660cdf0e10cSrcweir 
GetDataArea(SCCOL & rStartCol,SCROW & rStartRow,SCCOL & rEndCol,SCROW & rEndRow,sal_Bool bIncludeOld,bool bOnlyDown) const661cdf0e10cSrcweir void ScTable::GetDataArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow,
662cdf0e10cSrcweir                            sal_Bool bIncludeOld, bool bOnlyDown ) const
663cdf0e10cSrcweir {
664cdf0e10cSrcweir 	sal_Bool bLeft       = sal_False;
665cdf0e10cSrcweir 	sal_Bool bRight  = sal_False;
666cdf0e10cSrcweir 	sal_Bool bTop        = sal_False;
667cdf0e10cSrcweir 	sal_Bool bBottom = sal_False;
668cdf0e10cSrcweir 	sal_Bool bChanged;
669cdf0e10cSrcweir 	sal_Bool bFound;
670cdf0e10cSrcweir 	SCCOL i;
671cdf0e10cSrcweir 	SCROW nTest;
672cdf0e10cSrcweir 
673cdf0e10cSrcweir 	do
674cdf0e10cSrcweir 	{
675cdf0e10cSrcweir 		bChanged = sal_False;
676cdf0e10cSrcweir 
677cdf0e10cSrcweir         if (!bOnlyDown)
678cdf0e10cSrcweir         {
679cdf0e10cSrcweir             SCROW nStart = rStartRow;
680cdf0e10cSrcweir             SCROW nEnd = rEndRow;
681cdf0e10cSrcweir             if (nStart>0) --nStart;
682cdf0e10cSrcweir             if (nEnd<MAXROW) ++nEnd;
683cdf0e10cSrcweir 
684cdf0e10cSrcweir             if (rEndCol < MAXCOL)
685cdf0e10cSrcweir                 if (!aCol[rEndCol+1].IsEmptyBlock(nStart,nEnd))
686cdf0e10cSrcweir                 {
687cdf0e10cSrcweir                     ++rEndCol;
688cdf0e10cSrcweir                     bChanged = sal_True;
689cdf0e10cSrcweir                     bRight = sal_True;
690cdf0e10cSrcweir                 }
691cdf0e10cSrcweir 
692cdf0e10cSrcweir             if (rStartCol > 0)
693cdf0e10cSrcweir                 if (!aCol[rStartCol-1].IsEmptyBlock(nStart,nEnd))
694cdf0e10cSrcweir                 {
695cdf0e10cSrcweir                     --rStartCol;
696cdf0e10cSrcweir                     bChanged = sal_True;
697cdf0e10cSrcweir                     bLeft = sal_True;
698cdf0e10cSrcweir                 }
699cdf0e10cSrcweir 
700cdf0e10cSrcweir             if (rStartRow > 0)
701cdf0e10cSrcweir             {
702cdf0e10cSrcweir                 nTest = rStartRow-1;
703cdf0e10cSrcweir                 bFound = sal_False;
704cdf0e10cSrcweir                 for (i=rStartCol; i<=rEndCol && !bFound; i++)
705cdf0e10cSrcweir                     if (aCol[i].HasDataAt(nTest))
706cdf0e10cSrcweir                         bFound = sal_True;
707cdf0e10cSrcweir                 if (bFound)
708cdf0e10cSrcweir                 {
709cdf0e10cSrcweir                     --rStartRow;
710cdf0e10cSrcweir                     bChanged = sal_True;
711cdf0e10cSrcweir                     bTop = sal_True;
712cdf0e10cSrcweir                 }
713cdf0e10cSrcweir             }
714cdf0e10cSrcweir         }
715cdf0e10cSrcweir 
716cdf0e10cSrcweir 		if (rEndRow < MAXROW)
717cdf0e10cSrcweir 		{
718cdf0e10cSrcweir 			nTest = rEndRow+1;
719cdf0e10cSrcweir 			bFound = sal_False;
720cdf0e10cSrcweir 			for (i=rStartCol; i<=rEndCol && !bFound; i++)
721cdf0e10cSrcweir 				if (aCol[i].HasDataAt(nTest))
722cdf0e10cSrcweir 					bFound = sal_True;
723cdf0e10cSrcweir 			if (bFound)
724cdf0e10cSrcweir 			{
725cdf0e10cSrcweir 				++rEndRow;
726cdf0e10cSrcweir 				bChanged = sal_True;
727cdf0e10cSrcweir 				bBottom = sal_True;
728cdf0e10cSrcweir 			}
729cdf0e10cSrcweir 		}
730cdf0e10cSrcweir 	}
731cdf0e10cSrcweir 	while( bChanged );
732cdf0e10cSrcweir 
733cdf0e10cSrcweir 	if ( !bIncludeOld )
734cdf0e10cSrcweir 	{
735cdf0e10cSrcweir 		if ( !bLeft && rStartCol < MAXCOL && rStartCol < rEndCol )
736cdf0e10cSrcweir 			if ( aCol[rStartCol].IsEmptyBlock(rStartRow,rEndRow) )
737cdf0e10cSrcweir 				++rStartCol;
738cdf0e10cSrcweir 		if ( !bRight && rEndCol > 0 && rStartCol < rEndCol )
739cdf0e10cSrcweir 			if ( aCol[rEndCol].IsEmptyBlock(rStartRow,rEndRow) )
740cdf0e10cSrcweir 				--rEndCol;
741cdf0e10cSrcweir 		if ( !bTop && rStartRow < MAXROW && rStartRow < rEndRow )
742cdf0e10cSrcweir 		{
743cdf0e10cSrcweir 			bFound = sal_False;
744cdf0e10cSrcweir 			for (i=rStartCol; i<=rEndCol && !bFound; i++)
745cdf0e10cSrcweir 				if (aCol[i].HasDataAt(rStartRow))
746cdf0e10cSrcweir 					bFound = sal_True;
747cdf0e10cSrcweir 			if (!bFound)
748cdf0e10cSrcweir 				++rStartRow;
749cdf0e10cSrcweir 		}
750cdf0e10cSrcweir 		if ( !bBottom && rEndRow > 0 && rStartRow < rEndRow )
751cdf0e10cSrcweir 		{
752cdf0e10cSrcweir 			bFound = sal_False;
753cdf0e10cSrcweir 			for (i=rStartCol; i<=rEndCol && !bFound; i++)
754cdf0e10cSrcweir 				if (aCol[i].HasDataAt(rEndRow))
755cdf0e10cSrcweir 					bFound = sal_True;
756cdf0e10cSrcweir 			if (!bFound)
757cdf0e10cSrcweir 				--rEndRow;
758cdf0e10cSrcweir 		}
759cdf0e10cSrcweir 	}
760cdf0e10cSrcweir }
761cdf0e10cSrcweir 
762cdf0e10cSrcweir 
ShrinkToUsedDataArea(bool & o_bShrunk,SCCOL & rStartCol,SCROW & rStartRow,SCCOL & rEndCol,SCROW & rEndRow,bool bColumnsOnly) const763cdf0e10cSrcweir bool ScTable::ShrinkToUsedDataArea( bool& o_bShrunk, SCCOL& rStartCol, SCROW& rStartRow,
764cdf0e10cSrcweir         SCCOL& rEndCol, SCROW& rEndRow, bool bColumnsOnly ) const
765cdf0e10cSrcweir {
766cdf0e10cSrcweir     o_bShrunk = false;
767cdf0e10cSrcweir 
768cdf0e10cSrcweir     PutInOrder( rStartCol, rEndCol);
769cdf0e10cSrcweir     PutInOrder( rStartRow, rEndRow);
770cdf0e10cSrcweir     if (rStartCol < 0)
771cdf0e10cSrcweir         rStartCol = 0, o_bShrunk = true;
772cdf0e10cSrcweir     if (rStartRow < 0)
773cdf0e10cSrcweir         rStartRow = 0, o_bShrunk = true;
774cdf0e10cSrcweir     if (rEndCol > MAXCOL)
775cdf0e10cSrcweir         rEndCol = MAXCOL, o_bShrunk = true;
776cdf0e10cSrcweir     if (rEndRow > MAXROW)
777cdf0e10cSrcweir         rEndRow = MAXROW, o_bShrunk = true;
778cdf0e10cSrcweir 
779cdf0e10cSrcweir     bool bChanged;
780cdf0e10cSrcweir     do
781cdf0e10cSrcweir     {
782cdf0e10cSrcweir         bChanged = false;
783cdf0e10cSrcweir 
784cdf0e10cSrcweir         while (rStartCol < rEndCol)
785cdf0e10cSrcweir         {
786cdf0e10cSrcweir             if (aCol[rEndCol].IsEmptyBlock( rStartRow, rEndRow))
787cdf0e10cSrcweir             {
788cdf0e10cSrcweir                 --rEndCol;
789cdf0e10cSrcweir                 bChanged = true;
790cdf0e10cSrcweir             }
791cdf0e10cSrcweir             else
792cdf0e10cSrcweir                 break;  // while
793cdf0e10cSrcweir         }
794cdf0e10cSrcweir 
795cdf0e10cSrcweir         while (rStartCol < rEndCol)
796cdf0e10cSrcweir         {
797cdf0e10cSrcweir             if (aCol[rStartCol].IsEmptyBlock( rStartRow, rEndRow))
798cdf0e10cSrcweir             {
799cdf0e10cSrcweir                 ++rStartCol;
800cdf0e10cSrcweir                 bChanged = true;
801cdf0e10cSrcweir             }
802cdf0e10cSrcweir             else
803cdf0e10cSrcweir                 break;  // while
804cdf0e10cSrcweir         }
805cdf0e10cSrcweir 
806cdf0e10cSrcweir         if (!bColumnsOnly)
807cdf0e10cSrcweir         {
808cdf0e10cSrcweir             if (rStartRow < rEndRow)
809cdf0e10cSrcweir             {
810cdf0e10cSrcweir                 bool bFound = false;
811cdf0e10cSrcweir                 for (SCCOL i=rStartCol; i<=rEndCol && !bFound; i++)
812cdf0e10cSrcweir                     if (aCol[i].HasDataAt( rStartRow))
813cdf0e10cSrcweir                         bFound = true;
814cdf0e10cSrcweir                 if (!bFound)
815cdf0e10cSrcweir                 {
816cdf0e10cSrcweir                     ++rStartRow;
817cdf0e10cSrcweir                     bChanged = true;
818cdf0e10cSrcweir                 }
819cdf0e10cSrcweir             }
820cdf0e10cSrcweir 
821cdf0e10cSrcweir             if (rStartRow < rEndRow)
822cdf0e10cSrcweir             {
823cdf0e10cSrcweir                 bool bFound = false;
824cdf0e10cSrcweir                 for (SCCOL i=rStartCol; i<=rEndCol && !bFound; i++)
825cdf0e10cSrcweir                     if (aCol[i].HasDataAt( rEndRow))
826cdf0e10cSrcweir                         bFound = true;
827cdf0e10cSrcweir                 if (!bFound)
828cdf0e10cSrcweir                 {
829cdf0e10cSrcweir                     --rEndRow;
830cdf0e10cSrcweir                     bChanged = true;
831cdf0e10cSrcweir                 }
832cdf0e10cSrcweir             }
833cdf0e10cSrcweir         }
834cdf0e10cSrcweir 
835cdf0e10cSrcweir         if (bChanged)
836cdf0e10cSrcweir             o_bShrunk = true;
837cdf0e10cSrcweir     } while( bChanged );
838cdf0e10cSrcweir 
839cdf0e10cSrcweir     return rStartCol != rEndCol || (bColumnsOnly ?
840cdf0e10cSrcweir             !aCol[rStartCol].IsEmptyBlock( rStartRow, rEndRow) :
841cdf0e10cSrcweir             (rStartRow != rEndRow || aCol[rStartCol].HasDataAt( rStartRow)));
842cdf0e10cSrcweir }
843cdf0e10cSrcweir 
844cdf0e10cSrcweir 
GetEmptyLinesInBlock(SCCOL nStartCol,SCROW nStartRow,SCCOL nEndCol,SCROW nEndRow,ScDirection eDir)845cdf0e10cSrcweir SCSIZE ScTable::GetEmptyLinesInBlock( SCCOL nStartCol, SCROW nStartRow,
846cdf0e10cSrcweir 										SCCOL nEndCol, SCROW nEndRow, ScDirection eDir )
847cdf0e10cSrcweir {
848cdf0e10cSrcweir 	SCSIZE nCount = 0;
849cdf0e10cSrcweir 	SCCOL nCol;
850cdf0e10cSrcweir 	if ((eDir == DIR_BOTTOM) || (eDir == DIR_TOP))
851cdf0e10cSrcweir 	{
852cdf0e10cSrcweir 		nCount = static_cast<SCSIZE>(nEndRow - nStartRow);
853cdf0e10cSrcweir 		for (nCol = nStartCol; nCol <= nEndCol; nCol++)
854cdf0e10cSrcweir 			nCount = Min(nCount, aCol[nCol].GetEmptyLinesInBlock(nStartRow, nEndRow, eDir));
855cdf0e10cSrcweir 	}
856cdf0e10cSrcweir 	else if (eDir == DIR_RIGHT)
857cdf0e10cSrcweir 	{
858cdf0e10cSrcweir 		nCol = nEndCol;
859cdf0e10cSrcweir 		while (((SCsCOL)nCol >= (SCsCOL)nStartCol) &&
860cdf0e10cSrcweir 				 aCol[nCol].IsEmptyBlock(nStartRow, nEndRow))
861cdf0e10cSrcweir 		{
862cdf0e10cSrcweir 			nCount++;
863cdf0e10cSrcweir 			nCol--;
864cdf0e10cSrcweir 		}
865cdf0e10cSrcweir 	}
866cdf0e10cSrcweir 	else
867cdf0e10cSrcweir 	{
868cdf0e10cSrcweir 		nCol = nStartCol;
869cdf0e10cSrcweir 		while ((nCol <= nEndCol) && aCol[nCol].IsEmptyBlock(nStartRow, nEndRow))
870cdf0e10cSrcweir 		{
871cdf0e10cSrcweir 			nCount++;
872cdf0e10cSrcweir 			nCol++;
873cdf0e10cSrcweir 		}
874cdf0e10cSrcweir 	}
875cdf0e10cSrcweir 	return nCount;
876cdf0e10cSrcweir }
877cdf0e10cSrcweir 
IsEmptyLine(SCROW nRow,SCCOL nStartCol,SCCOL nEndCol)878cdf0e10cSrcweir sal_Bool ScTable::IsEmptyLine( SCROW nRow, SCCOL nStartCol, SCCOL nEndCol )
879cdf0e10cSrcweir {
880cdf0e10cSrcweir 	sal_Bool bFound = sal_False;
881cdf0e10cSrcweir 	for (SCCOL i=nStartCol; i<=nEndCol && !bFound; i++)
882cdf0e10cSrcweir 		if (aCol[i].HasDataAt(nRow))
883cdf0e10cSrcweir 			bFound = sal_True;
884cdf0e10cSrcweir 	return !bFound;
885cdf0e10cSrcweir }
886cdf0e10cSrcweir 
LimitChartArea(SCCOL & rStartCol,SCROW & rStartRow,SCCOL & rEndCol,SCROW & rEndRow)887cdf0e10cSrcweir void ScTable::LimitChartArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow )
888cdf0e10cSrcweir {
889cdf0e10cSrcweir 	while ( rStartCol<rEndCol && aCol[rStartCol].IsEmptyBlock(rStartRow,rEndRow) )
890cdf0e10cSrcweir 		++rStartCol;
891cdf0e10cSrcweir 
892cdf0e10cSrcweir 	while ( rStartCol<rEndCol && aCol[rEndCol].IsEmptyBlock(rStartRow,rEndRow) )
893cdf0e10cSrcweir 		--rEndCol;
894cdf0e10cSrcweir 
895cdf0e10cSrcweir 	while ( rStartRow<rEndRow && IsEmptyLine(rStartRow, rStartCol, rEndCol) )
896cdf0e10cSrcweir 		++rStartRow;
897cdf0e10cSrcweir 
898cdf0e10cSrcweir 	while ( rStartRow<rEndRow && IsEmptyLine(rEndRow, rStartCol, rEndCol) )
899cdf0e10cSrcweir 		--rEndRow;
900cdf0e10cSrcweir }
901cdf0e10cSrcweir 
FindAreaPos(SCCOL & rCol,SCROW & rRow,SCsCOL nMovX,SCsROW nMovY)902cdf0e10cSrcweir void ScTable::FindAreaPos( SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY )
903cdf0e10cSrcweir {
904cdf0e10cSrcweir 	if (nMovX)
905cdf0e10cSrcweir 	{
906cdf0e10cSrcweir 		SCsCOL nNewCol = (SCsCOL) rCol;
907cdf0e10cSrcweir 		sal_Bool bThere = aCol[nNewCol].HasVisibleDataAt(rRow);
908cdf0e10cSrcweir 		sal_Bool bFnd;
909cdf0e10cSrcweir 		if (bThere)
910cdf0e10cSrcweir 		{
911cdf0e10cSrcweir 			do
912cdf0e10cSrcweir 			{
913cdf0e10cSrcweir                 nNewCol = sal::static_int_cast<SCsCOL>( nNewCol + nMovX );
914cdf0e10cSrcweir 				bFnd = (nNewCol>=0 && nNewCol<=MAXCOL) ? aCol[nNewCol].HasVisibleDataAt(rRow) : sal_False;
915cdf0e10cSrcweir 			}
916cdf0e10cSrcweir 			while (bFnd);
917cdf0e10cSrcweir             nNewCol = sal::static_int_cast<SCsCOL>( nNewCol - nMovX );
918cdf0e10cSrcweir 
919cdf0e10cSrcweir 			if (nNewCol == (SCsCOL)rCol)
920cdf0e10cSrcweir 				bThere = sal_False;
921cdf0e10cSrcweir 		}
922cdf0e10cSrcweir 
923cdf0e10cSrcweir 		if (!bThere)
924cdf0e10cSrcweir 		{
925cdf0e10cSrcweir 			do
926cdf0e10cSrcweir 			{
927cdf0e10cSrcweir                 nNewCol = sal::static_int_cast<SCsCOL>( nNewCol + nMovX );
928cdf0e10cSrcweir 				bFnd = (nNewCol>=0 && nNewCol<=MAXCOL) ? aCol[nNewCol].HasVisibleDataAt(rRow) : sal_True;
929cdf0e10cSrcweir 			}
930cdf0e10cSrcweir 			while (!bFnd);
931cdf0e10cSrcweir 		}
932cdf0e10cSrcweir 
933cdf0e10cSrcweir 		if (nNewCol<0) nNewCol=0;
934cdf0e10cSrcweir 		if (nNewCol>MAXCOL) nNewCol=MAXCOL;
935cdf0e10cSrcweir 		rCol = (SCCOL) nNewCol;
936cdf0e10cSrcweir 	}
937cdf0e10cSrcweir 
938cdf0e10cSrcweir 	if (nMovY)
939cdf0e10cSrcweir 		aCol[rCol].FindDataAreaPos(rRow,nMovY);
940cdf0e10cSrcweir }
941cdf0e10cSrcweir 
ValidNextPos(SCCOL nCol,SCROW nRow,const ScMarkData & rMark,sal_Bool bMarked,sal_Bool bUnprotected)942cdf0e10cSrcweir sal_Bool ScTable::ValidNextPos( SCCOL nCol, SCROW nRow, const ScMarkData& rMark,
943cdf0e10cSrcweir 								sal_Bool bMarked, sal_Bool bUnprotected )
944cdf0e10cSrcweir {
945cdf0e10cSrcweir 	if (!ValidCol(nCol) || !ValidRow(nRow))
946cdf0e10cSrcweir 		return sal_False;
947cdf0e10cSrcweir 
948cdf0e10cSrcweir     if (pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED))
949cdf0e10cSrcweir         // Skip an overlapped cell.
950cdf0e10cSrcweir         return false;
951cdf0e10cSrcweir 
952cdf0e10cSrcweir 	if (bMarked && !rMark.IsCellMarked(nCol,nRow))
953cdf0e10cSrcweir 		return sal_False;
954cdf0e10cSrcweir 
955cdf0e10cSrcweir 	if (bUnprotected && ((const ScProtectionAttr*)
956cdf0e10cSrcweir 						GetAttr(nCol,nRow,ATTR_PROTECTION))->GetProtection())
957cdf0e10cSrcweir 		return sal_False;
958cdf0e10cSrcweir 
959cdf0e10cSrcweir 	if (bMarked || bUnprotected)		//! auch sonst ???
960cdf0e10cSrcweir 	{
961cdf0e10cSrcweir 		//	#53697# ausgeblendete muessen uebersprungen werden, weil der Cursor sonst
962cdf0e10cSrcweir 		//	auf der naechsten Zelle landet, auch wenn die geschuetzt/nicht markiert ist.
963cdf0e10cSrcweir 		//!	per Extra-Parameter steuern, nur fuer Cursor-Bewegung ???
964cdf0e10cSrcweir 
965cdf0e10cSrcweir         if (RowHidden(nRow))
966cdf0e10cSrcweir 			return sal_False;
967cdf0e10cSrcweir 
968cdf0e10cSrcweir         if (ColHidden(nCol))
969cdf0e10cSrcweir 			return sal_False;
970cdf0e10cSrcweir 	}
971cdf0e10cSrcweir 
972cdf0e10cSrcweir 	return sal_True;
973cdf0e10cSrcweir }
974cdf0e10cSrcweir 
GetNextPos(SCCOL & rCol,SCROW & rRow,SCsCOL nMovX,SCsROW nMovY,sal_Bool bMarked,sal_Bool bUnprotected,const ScMarkData & rMark)975cdf0e10cSrcweir void ScTable::GetNextPos( SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY,
976cdf0e10cSrcweir 								sal_Bool bMarked, sal_Bool bUnprotected, const ScMarkData& rMark )
977cdf0e10cSrcweir {
978cdf0e10cSrcweir 	if (bUnprotected && !IsProtected())		// Tabelle ueberhaupt geschuetzt?
979cdf0e10cSrcweir 		bUnprotected = sal_False;
980cdf0e10cSrcweir 
981cdf0e10cSrcweir 	sal_uInt16 nWrap = 0;
982cdf0e10cSrcweir 	SCsCOL nCol = rCol;
983cdf0e10cSrcweir 	SCsROW nRow = rRow;
984cdf0e10cSrcweir 
985cdf0e10cSrcweir     nCol = sal::static_int_cast<SCsCOL>( nCol + nMovX );
986cdf0e10cSrcweir     nRow = sal::static_int_cast<SCsROW>( nRow + nMovY );
987cdf0e10cSrcweir 
988cdf0e10cSrcweir 	DBG_ASSERT( !nMovY || !bUnprotected,
989cdf0e10cSrcweir 				"GetNextPos mit bUnprotected horizontal nicht implementiert" );
990cdf0e10cSrcweir 
991cdf0e10cSrcweir 	if ( nMovY && bMarked )
992cdf0e10cSrcweir 	{
993cdf0e10cSrcweir 		sal_Bool bUp = ( nMovY < 0 );
994cdf0e10cSrcweir 		nRow = rMark.GetNextMarked( nCol, nRow, bUp );
995cdf0e10cSrcweir         while ( VALIDROW(nRow) &&
996cdf0e10cSrcweir                 (RowHidden(nRow) || pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED)) )
997cdf0e10cSrcweir 		{
998cdf0e10cSrcweir 			//	#53697# ausgeblendete ueberspringen (s.o.)
999cdf0e10cSrcweir 			nRow += nMovY;
1000cdf0e10cSrcweir 			nRow = rMark.GetNextMarked( nCol, nRow, bUp );
1001cdf0e10cSrcweir 		}
1002cdf0e10cSrcweir 
1003cdf0e10cSrcweir 		while ( nRow < 0 || nRow > MAXROW )
1004cdf0e10cSrcweir 		{
1005cdf0e10cSrcweir             nCol = sal::static_int_cast<SCsCOL>( nCol + static_cast<SCsCOL>(nMovY) );
1006cdf0e10cSrcweir 			while ( VALIDCOL(nCol) && ColHidden(nCol) )
1007cdf0e10cSrcweir                 nCol = sal::static_int_cast<SCsCOL>( nCol + static_cast<SCsCOL>(nMovY) );   //	#53697# skip hidden rows (see above)
1008cdf0e10cSrcweir 			if (nCol < 0)
1009cdf0e10cSrcweir 			{
1010cdf0e10cSrcweir 				nCol = MAXCOL;
1011cdf0e10cSrcweir 				if (++nWrap >= 2)
1012cdf0e10cSrcweir 					return;
1013cdf0e10cSrcweir 			}
1014cdf0e10cSrcweir 			else if (nCol > MAXCOL)
1015cdf0e10cSrcweir 			{
1016cdf0e10cSrcweir 				nCol = 0;
1017cdf0e10cSrcweir 				if (++nWrap >= 2)
1018cdf0e10cSrcweir 					return;
1019cdf0e10cSrcweir 			}
1020cdf0e10cSrcweir 			if (nRow < 0)
1021cdf0e10cSrcweir 				nRow = MAXROW;
1022cdf0e10cSrcweir 			else if (nRow > MAXROW)
1023cdf0e10cSrcweir 				nRow = 0;
1024cdf0e10cSrcweir 			nRow = rMark.GetNextMarked( nCol, nRow, bUp );
1025cdf0e10cSrcweir             while ( VALIDROW(nRow) &&
1026cdf0e10cSrcweir                     (RowHidden(nRow) || pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED)) )
1027cdf0e10cSrcweir 			{
1028cdf0e10cSrcweir 				//	#53697# ausgeblendete ueberspringen (s.o.)
1029cdf0e10cSrcweir 				nRow += nMovY;
1030cdf0e10cSrcweir 				nRow = rMark.GetNextMarked( nCol, nRow, bUp );
1031cdf0e10cSrcweir 			}
1032cdf0e10cSrcweir 		}
1033cdf0e10cSrcweir 	}
1034cdf0e10cSrcweir 
1035cdf0e10cSrcweir 	if ( nMovX && ( bMarked || bUnprotected ) )
1036cdf0e10cSrcweir 	{
1037cdf0e10cSrcweir 		// initiales Weiterzaehlen wrappen:
1038cdf0e10cSrcweir 		if (nCol<0)
1039cdf0e10cSrcweir 		{
1040cdf0e10cSrcweir 			nCol = MAXCOL;
1041cdf0e10cSrcweir 			--nRow;
1042cdf0e10cSrcweir 			if (nRow<0)
1043cdf0e10cSrcweir 				nRow = MAXROW;
1044cdf0e10cSrcweir 		}
1045cdf0e10cSrcweir 		if (nCol>MAXCOL)
1046cdf0e10cSrcweir 		{
1047cdf0e10cSrcweir 			nCol = 0;
1048cdf0e10cSrcweir 			++nRow;
1049cdf0e10cSrcweir 			if (nRow>MAXROW)
1050cdf0e10cSrcweir 				nRow = 0;
1051cdf0e10cSrcweir 		}
1052cdf0e10cSrcweir 
1053cdf0e10cSrcweir 		if ( !ValidNextPos(nCol, nRow, rMark, bMarked, bUnprotected) )
1054cdf0e10cSrcweir 		{
1055cdf0e10cSrcweir 			SCsROW* pNextRows = new SCsROW[MAXCOL+1];
1056cdf0e10cSrcweir 			SCCOL i;
1057cdf0e10cSrcweir 
1058cdf0e10cSrcweir 			if ( nMovX > 0 )							//	vorwaerts
1059cdf0e10cSrcweir 			{
1060cdf0e10cSrcweir 				for (i=0; i<=MAXCOL; i++)
1061cdf0e10cSrcweir 					pNextRows[i] = (i<nCol) ? (nRow+1) : nRow;
1062cdf0e10cSrcweir 				do
1063cdf0e10cSrcweir 				{
1064cdf0e10cSrcweir 					SCsROW nNextRow = pNextRows[nCol] + 1;
1065cdf0e10cSrcweir 					if ( bMarked )
1066cdf0e10cSrcweir 						nNextRow = rMark.GetNextMarked( nCol, nNextRow, sal_False );
1067cdf0e10cSrcweir 					if ( bUnprotected )
1068cdf0e10cSrcweir 						nNextRow = aCol[nCol].GetNextUnprotected( nNextRow, sal_False );
1069cdf0e10cSrcweir 					pNextRows[nCol] = nNextRow;
1070cdf0e10cSrcweir 
1071cdf0e10cSrcweir 					SCsROW nMinRow = MAXROW+1;
1072cdf0e10cSrcweir 					for (i=0; i<=MAXCOL; i++)
1073cdf0e10cSrcweir 						if (pNextRows[i] < nMinRow)		// bei gleichen den linken
1074cdf0e10cSrcweir 						{
1075cdf0e10cSrcweir 							nMinRow = pNextRows[i];
1076cdf0e10cSrcweir 							nCol = i;
1077cdf0e10cSrcweir 						}
1078cdf0e10cSrcweir 					nRow = nMinRow;
1079cdf0e10cSrcweir 
1080cdf0e10cSrcweir 					if ( nRow > MAXROW )
1081cdf0e10cSrcweir 					{
1082cdf0e10cSrcweir 						if (++nWrap >= 2) break;		// ungueltigen Wert behalten
1083cdf0e10cSrcweir 						nCol = 0;
1084cdf0e10cSrcweir                         nRow = 0;
1085cdf0e10cSrcweir 						for (i=0; i<=MAXCOL; i++)
1086cdf0e10cSrcweir 							pNextRows[i] = 0;			// alles ganz von vorne
1087cdf0e10cSrcweir 					}
1088cdf0e10cSrcweir 				}
1089cdf0e10cSrcweir 				while ( !ValidNextPos(nCol, nRow, rMark, bMarked, bUnprotected) );
1090cdf0e10cSrcweir 			}
1091cdf0e10cSrcweir 			else										//	rueckwaerts
1092cdf0e10cSrcweir 			{
1093cdf0e10cSrcweir 				for (i=0; i<=MAXCOL; i++)
1094cdf0e10cSrcweir 					pNextRows[i] = (i>nCol) ? (nRow-1) : nRow;
1095cdf0e10cSrcweir 				do
1096cdf0e10cSrcweir 				{
1097cdf0e10cSrcweir 					SCsROW nNextRow = pNextRows[nCol] - 1;
1098cdf0e10cSrcweir 					if ( bMarked )
1099cdf0e10cSrcweir 						nNextRow = rMark.GetNextMarked( nCol, nNextRow, sal_True );
1100cdf0e10cSrcweir 					if ( bUnprotected )
1101cdf0e10cSrcweir 						nNextRow = aCol[nCol].GetNextUnprotected( nNextRow, sal_True );
1102cdf0e10cSrcweir 					pNextRows[nCol] = nNextRow;
1103cdf0e10cSrcweir 
1104cdf0e10cSrcweir 					SCsROW nMaxRow = -1;
1105cdf0e10cSrcweir 					for (i=0; i<=MAXCOL; i++)
1106cdf0e10cSrcweir 						if (pNextRows[i] >= nMaxRow)	// bei gleichen den rechten
1107cdf0e10cSrcweir 						{
1108cdf0e10cSrcweir 							nMaxRow = pNextRows[i];
1109cdf0e10cSrcweir 							nCol = i;
1110cdf0e10cSrcweir 						}
1111cdf0e10cSrcweir 					nRow = nMaxRow;
1112cdf0e10cSrcweir 
1113cdf0e10cSrcweir 					if ( nRow < 0 )
1114cdf0e10cSrcweir 					{
1115cdf0e10cSrcweir 						if (++nWrap >= 2) break;		// ungueltigen Wert behalten
1116cdf0e10cSrcweir 						nCol = MAXCOL;
1117cdf0e10cSrcweir 						nRow = MAXROW;
1118cdf0e10cSrcweir 						for (i=0; i<=MAXCOL; i++)
1119cdf0e10cSrcweir 							pNextRows[i] = MAXROW;		// alles ganz von vorne
1120cdf0e10cSrcweir 					}
1121cdf0e10cSrcweir 				}
1122cdf0e10cSrcweir 				while ( !ValidNextPos(nCol, nRow, rMark, bMarked, bUnprotected) );
1123cdf0e10cSrcweir 			}
1124cdf0e10cSrcweir 
1125cdf0e10cSrcweir 			delete[] pNextRows;
1126cdf0e10cSrcweir 		}
1127cdf0e10cSrcweir 	}
1128cdf0e10cSrcweir 
1129cdf0e10cSrcweir 	//	ungueltige Werte kommen z.b. bei Tab heraus,
1130cdf0e10cSrcweir 	//	wenn nicht markiert und nicht geschuetzt ist (linker / rechter Rand),
1131cdf0e10cSrcweir 	//	dann Werte unveraendert lassen
1132cdf0e10cSrcweir 
1133cdf0e10cSrcweir 	if (VALIDCOLROW(nCol,nRow))
1134cdf0e10cSrcweir 	{
1135cdf0e10cSrcweir 		rCol = nCol;
1136cdf0e10cSrcweir 		rRow = nRow;
1137cdf0e10cSrcweir 	}
1138cdf0e10cSrcweir }
1139cdf0e10cSrcweir 
GetNextMarkedCell(SCCOL & rCol,SCROW & rRow,const ScMarkData & rMark)1140cdf0e10cSrcweir sal_Bool ScTable::GetNextMarkedCell( SCCOL& rCol, SCROW& rRow, const ScMarkData& rMark )
1141cdf0e10cSrcweir {
1142cdf0e10cSrcweir 	const ScMarkArray* pMarkArray = rMark.GetArray();
1143cdf0e10cSrcweir 	DBG_ASSERT(pMarkArray,"GetNextMarkedCell ohne MarkArray");
1144cdf0e10cSrcweir 	if ( !pMarkArray )
1145cdf0e10cSrcweir 		return sal_False;
1146cdf0e10cSrcweir 
1147cdf0e10cSrcweir 	++rRow;					// naechste Zelle ist gesucht
1148cdf0e10cSrcweir 
1149cdf0e10cSrcweir 	while ( rCol <= MAXCOL )
1150cdf0e10cSrcweir 	{
1151cdf0e10cSrcweir 		const ScMarkArray& rArray = pMarkArray[rCol];
1152cdf0e10cSrcweir 		while ( rRow <= MAXROW )
1153cdf0e10cSrcweir 		{
1154cdf0e10cSrcweir 			SCROW nStart = (SCROW) rArray.GetNextMarked( (SCsROW) rRow, sal_False );
1155cdf0e10cSrcweir 			if ( nStart <= MAXROW )
1156cdf0e10cSrcweir 			{
1157cdf0e10cSrcweir 				SCROW nEnd = rArray.GetMarkEnd( nStart, sal_False );
1158cdf0e10cSrcweir 				ScColumnIterator aColIter( &aCol[rCol], nStart, nEnd );
1159cdf0e10cSrcweir 				SCROW nCellRow;
1160cdf0e10cSrcweir 				ScBaseCell* pCell = NULL;
1161cdf0e10cSrcweir 				while ( aColIter.Next( nCellRow, pCell ) )
1162cdf0e10cSrcweir 				{
1163cdf0e10cSrcweir 					if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE )
1164cdf0e10cSrcweir 					{
1165cdf0e10cSrcweir 						rRow = nCellRow;
1166cdf0e10cSrcweir 						return sal_True;			// Zelle gefunden
1167cdf0e10cSrcweir 					}
1168cdf0e10cSrcweir 				}
1169cdf0e10cSrcweir 				rRow = nEnd + 1;				// naechsten markierten Bereich suchen
1170cdf0e10cSrcweir 			}
1171cdf0e10cSrcweir 			else
1172cdf0e10cSrcweir 				rRow = MAXROW + 1;				// Ende der Spalte
1173cdf0e10cSrcweir 		}
1174cdf0e10cSrcweir 		rRow = 0;
1175cdf0e10cSrcweir 		++rCol;									// naechste Spalte testen
1176cdf0e10cSrcweir 	}
1177cdf0e10cSrcweir 
1178cdf0e10cSrcweir 	return sal_False;								// alle Spalten durch
1179cdf0e10cSrcweir }
1180cdf0e10cSrcweir 
UpdateDrawRef(UpdateRefMode eUpdateRefMode,SCCOL nCol1,SCROW nRow1,SCTAB nTab1,SCCOL nCol2,SCROW nRow2,SCTAB nTab2,SCsCOL nDx,SCsROW nDy,SCsTAB nDz,bool bUpdateNoteCaptionPos)1181cdf0e10cSrcweir void ScTable::UpdateDrawRef( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
1182cdf0e10cSrcweir 									SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
1183cdf0e10cSrcweir 									SCsCOL nDx, SCsROW nDy, SCsTAB nDz, bool bUpdateNoteCaptionPos )
1184cdf0e10cSrcweir {
1185cdf0e10cSrcweir 	if ( nTab >= nTab1 && nTab <= nTab2 && nDz == 0 )		// only within the table
1186cdf0e10cSrcweir 	{
1187cdf0e10cSrcweir         InitializeNoteCaptions();
1188cdf0e10cSrcweir 		ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
1189cdf0e10cSrcweir 		if ( eUpdateRefMode != URM_COPY && pDrawLayer )
1190cdf0e10cSrcweir 		{
1191cdf0e10cSrcweir 			if ( eUpdateRefMode == URM_MOVE )
1192cdf0e10cSrcweir 			{												// source range
1193cdf0e10cSrcweir                 nCol1 = sal::static_int_cast<SCCOL>( nCol1 - nDx );
1194cdf0e10cSrcweir                 nRow1 = sal::static_int_cast<SCROW>( nRow1 - nDy );
1195cdf0e10cSrcweir                 nCol2 = sal::static_int_cast<SCCOL>( nCol2 - nDx );
1196cdf0e10cSrcweir                 nRow2 = sal::static_int_cast<SCROW>( nRow2 - nDy );
1197cdf0e10cSrcweir 			}
1198cdf0e10cSrcweir 			pDrawLayer->MoveArea( nTab, nCol1,nRow1, nCol2,nRow2, nDx,nDy,
1199cdf0e10cSrcweir 									(eUpdateRefMode == URM_INSDEL), bUpdateNoteCaptionPos );
1200cdf0e10cSrcweir 		}
1201cdf0e10cSrcweir 	}
1202cdf0e10cSrcweir }
1203cdf0e10cSrcweir 
UpdateReference(UpdateRefMode eUpdateRefMode,SCCOL nCol1,SCROW nRow1,SCTAB nTab1,SCCOL nCol2,SCROW nRow2,SCTAB nTab2,SCsCOL nDx,SCsROW nDy,SCsTAB nDz,ScDocument * pUndoDoc,sal_Bool bIncludeDraw,bool bUpdateNoteCaptionPos)1204cdf0e10cSrcweir void ScTable::UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
1205cdf0e10cSrcweir 					 SCCOL nCol2, SCROW nRow2, SCTAB nTab2, SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
1206cdf0e10cSrcweir 					 ScDocument* pUndoDoc, sal_Bool bIncludeDraw, bool bUpdateNoteCaptionPos )
1207cdf0e10cSrcweir {
1208cdf0e10cSrcweir 	SCCOL i;
1209cdf0e10cSrcweir 	SCCOL iMax;
1210cdf0e10cSrcweir 	if ( eUpdateRefMode == URM_COPY )
1211cdf0e10cSrcweir 	{
1212cdf0e10cSrcweir 		i = nCol1;
1213cdf0e10cSrcweir 		iMax = nCol2;
1214cdf0e10cSrcweir 	}
1215cdf0e10cSrcweir 	else
1216cdf0e10cSrcweir 	{
1217cdf0e10cSrcweir 		i = 0;
1218cdf0e10cSrcweir 		iMax = MAXCOL;
1219cdf0e10cSrcweir 	}
1220cdf0e10cSrcweir 	for ( ; i<=iMax; i++)
1221cdf0e10cSrcweir 		aCol[i].UpdateReference( eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2,
1222cdf0e10cSrcweir 									nDx, nDy, nDz, pUndoDoc );
1223cdf0e10cSrcweir 
1224cdf0e10cSrcweir 	if ( bIncludeDraw )
1225cdf0e10cSrcweir 		UpdateDrawRef( eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz, bUpdateNoteCaptionPos );
1226cdf0e10cSrcweir 
1227cdf0e10cSrcweir 	if ( nTab >= nTab1 && nTab <= nTab2 && nDz == 0 )		// print ranges: only within the table
1228cdf0e10cSrcweir 	{
1229cdf0e10cSrcweir         SCTAB nSTab = nTab;
1230cdf0e10cSrcweir         SCTAB nETab = nTab;
1231cdf0e10cSrcweir         SCCOL nSCol = 0;
1232cdf0e10cSrcweir         SCROW nSRow = 0;
1233cdf0e10cSrcweir         SCCOL nECol = 0;
1234cdf0e10cSrcweir         SCROW nERow = 0;
1235cdf0e10cSrcweir 		sal_Bool bRecalcPages = sal_False;
1236cdf0e10cSrcweir 
1237cdf0e10cSrcweir         for ( ScRangeVec::iterator aIt = aPrintRanges.begin(), aEnd = aPrintRanges.end(); aIt != aEnd; ++aIt )
1238cdf0e10cSrcweir         {
1239cdf0e10cSrcweir             nSCol = aIt->aStart.Col();
1240cdf0e10cSrcweir             nSRow = aIt->aStart.Row();
1241cdf0e10cSrcweir             nECol = aIt->aEnd.Col();
1242cdf0e10cSrcweir             nERow = aIt->aEnd.Row();
1243cdf0e10cSrcweir 
1244cdf0e10cSrcweir             // do not try to modify sheet index of print range
1245cdf0e10cSrcweir             if ( ScRefUpdate::Update( pDocument, eUpdateRefMode,
1246cdf0e10cSrcweir                                       nCol1,nRow1,nTab, nCol2,nRow2,nTab,
1247cdf0e10cSrcweir                                       nDx,nDy,0,
1248cdf0e10cSrcweir                                       nSCol,nSRow,nSTab, nECol,nERow,nETab ) )
1249cdf0e10cSrcweir             {
1250cdf0e10cSrcweir                 *aIt = ScRange( nSCol, nSRow, 0, nECol, nERow, 0 );
1251cdf0e10cSrcweir                 bRecalcPages = sal_True;
1252cdf0e10cSrcweir             }
1253cdf0e10cSrcweir         }
1254cdf0e10cSrcweir 
1255cdf0e10cSrcweir 		if ( pRepeatColRange )
1256cdf0e10cSrcweir 		{
1257cdf0e10cSrcweir 			nSCol = pRepeatColRange->aStart.Col();
1258cdf0e10cSrcweir 			nSRow = pRepeatColRange->aStart.Row();
1259cdf0e10cSrcweir 			nECol = pRepeatColRange->aEnd.Col();
1260cdf0e10cSrcweir 			nERow = pRepeatColRange->aEnd.Row();
1261cdf0e10cSrcweir 
1262cdf0e10cSrcweir             // do not try to modify sheet index of repeat range
1263cdf0e10cSrcweir 			if ( ScRefUpdate::Update( pDocument, eUpdateRefMode,
1264cdf0e10cSrcweir                                       nCol1,nRow1,nTab, nCol2,nRow2,nTab,
1265cdf0e10cSrcweir                                       nDx,nDy,0,
1266cdf0e10cSrcweir                                       nSCol,nSRow,nSTab, nECol,nERow,nETab ) )
1267cdf0e10cSrcweir 			{
1268cdf0e10cSrcweir                 *pRepeatColRange = ScRange( nSCol, nSRow, 0, nECol, nERow, 0 );
1269cdf0e10cSrcweir 				bRecalcPages = sal_True;
1270cdf0e10cSrcweir 				nRepeatStartX = nSCol;	// fuer UpdatePageBreaks
1271cdf0e10cSrcweir 				nRepeatEndX = nECol;
1272cdf0e10cSrcweir 			}
1273cdf0e10cSrcweir 		}
1274cdf0e10cSrcweir 
1275cdf0e10cSrcweir 		if ( pRepeatRowRange )
1276cdf0e10cSrcweir 		{
1277cdf0e10cSrcweir 			nSCol = pRepeatRowRange->aStart.Col();
1278cdf0e10cSrcweir 			nSRow = pRepeatRowRange->aStart.Row();
1279cdf0e10cSrcweir 			nECol = pRepeatRowRange->aEnd.Col();
1280cdf0e10cSrcweir 			nERow = pRepeatRowRange->aEnd.Row();
1281cdf0e10cSrcweir 
1282cdf0e10cSrcweir             // do not try to modify sheet index of repeat range
1283cdf0e10cSrcweir 			if ( ScRefUpdate::Update( pDocument, eUpdateRefMode,
1284cdf0e10cSrcweir                                       nCol1,nRow1,nTab, nCol2,nRow2,nTab,
1285cdf0e10cSrcweir                                       nDx,nDy,0,
1286cdf0e10cSrcweir                                       nSCol,nSRow,nSTab, nECol,nERow,nETab ) )
1287cdf0e10cSrcweir 			{
1288cdf0e10cSrcweir                 *pRepeatRowRange = ScRange( nSCol, nSRow, 0, nECol, nERow, 0 );
1289cdf0e10cSrcweir 				bRecalcPages = sal_True;
1290cdf0e10cSrcweir 				nRepeatStartY = nSRow;	// fuer UpdatePageBreaks
1291cdf0e10cSrcweir 				nRepeatEndY = nERow;
1292cdf0e10cSrcweir 			}
1293cdf0e10cSrcweir 		}
1294cdf0e10cSrcweir 
1295cdf0e10cSrcweir 		//	updating print ranges is not necessary with multiple print ranges
1296cdf0e10cSrcweir 		if ( bRecalcPages && GetPrintRangeCount() <= 1 )
1297cdf0e10cSrcweir 		{
1298cdf0e10cSrcweir 			UpdatePageBreaks(NULL);
1299cdf0e10cSrcweir 
1300cdf0e10cSrcweir             pDocument->RepaintRange( ScRange(0,0,nTab,MAXCOL,MAXROW,nTab) );
1301cdf0e10cSrcweir 		}
1302cdf0e10cSrcweir 	}
1303cdf0e10cSrcweir }
1304cdf0e10cSrcweir 
UpdateTranspose(const ScRange & rSource,const ScAddress & rDest,ScDocument * pUndoDoc)1305cdf0e10cSrcweir void ScTable::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
1306cdf0e10cSrcweir 									ScDocument* pUndoDoc )
1307cdf0e10cSrcweir {
1308cdf0e10cSrcweir 	for ( SCCOL i=0; i<=MAXCOL; i++ )
1309cdf0e10cSrcweir 		aCol[i].UpdateTranspose( rSource, rDest, pUndoDoc );
1310cdf0e10cSrcweir }
1311cdf0e10cSrcweir 
UpdateGrow(const ScRange & rArea,SCCOL nGrowX,SCROW nGrowY)1312cdf0e10cSrcweir void ScTable::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
1313cdf0e10cSrcweir {
1314cdf0e10cSrcweir 	for ( SCCOL i=0; i<=MAXCOL; i++ )
1315cdf0e10cSrcweir 		aCol[i].UpdateGrow( rArea, nGrowX, nGrowY );
1316cdf0e10cSrcweir }
1317cdf0e10cSrcweir 
UpdateInsertTab(SCTAB nTable)1318cdf0e10cSrcweir void ScTable::UpdateInsertTab(SCTAB nTable)
1319cdf0e10cSrcweir {
1320cdf0e10cSrcweir 	if (nTab >= nTable) nTab++;
1321cdf0e10cSrcweir 	for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].UpdateInsertTab(nTable);
1322cdf0e10cSrcweir 
1323cdf0e10cSrcweir     if (IsStreamValid())
1324cdf0e10cSrcweir         SetStreamValid(sal_False);
1325cdf0e10cSrcweir }
1326cdf0e10cSrcweir 
1327cdf0e10cSrcweir //UNUSED2008-05  void ScTable::UpdateInsertTabOnlyCells(SCTAB nTable)
1328cdf0e10cSrcweir //UNUSED2008-05  {
1329cdf0e10cSrcweir //UNUSED2008-05      for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].UpdateInsertTabOnlyCells(nTable);
1330cdf0e10cSrcweir //UNUSED2008-05  }
1331cdf0e10cSrcweir 
UpdateDeleteTab(SCTAB nTable,sal_Bool bIsMove,ScTable * pRefUndo)1332cdf0e10cSrcweir void ScTable::UpdateDeleteTab( SCTAB nTable, sal_Bool bIsMove, ScTable* pRefUndo )
1333cdf0e10cSrcweir {
1334cdf0e10cSrcweir 	if (nTab > nTable) nTab--;
1335cdf0e10cSrcweir 
1336cdf0e10cSrcweir 	SCCOL i;
1337cdf0e10cSrcweir 	if (pRefUndo)
1338cdf0e10cSrcweir 		for (i=0; i <= MAXCOL; i++) aCol[i].UpdateDeleteTab(nTable, bIsMove, &pRefUndo->aCol[i]);
1339cdf0e10cSrcweir 	else
1340cdf0e10cSrcweir 		for (i=0; i <= MAXCOL; i++) aCol[i].UpdateDeleteTab(nTable, bIsMove, NULL);
1341cdf0e10cSrcweir 
1342cdf0e10cSrcweir     if (IsStreamValid())
1343cdf0e10cSrcweir         SetStreamValid(sal_False);
1344cdf0e10cSrcweir }
1345cdf0e10cSrcweir 
UpdateMoveTab(SCTAB nOldPos,SCTAB nNewPos,SCTAB nTabNo,ScProgress & rProgress)1346cdf0e10cSrcweir void ScTable::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos, SCTAB nTabNo,
1347cdf0e10cSrcweir 		ScProgress& rProgress )
1348cdf0e10cSrcweir {
1349cdf0e10cSrcweir 	nTab = nTabNo;
1350cdf0e10cSrcweir 	for ( SCCOL i=0; i <= MAXCOL; i++ )
1351cdf0e10cSrcweir 	{
1352cdf0e10cSrcweir 		aCol[i].UpdateMoveTab( nOldPos, nNewPos, nTabNo );
1353cdf0e10cSrcweir 		rProgress.SetState( rProgress.GetState() + aCol[i].GetCodeCount() );
1354cdf0e10cSrcweir 	}
1355cdf0e10cSrcweir 
1356cdf0e10cSrcweir     if (IsStreamValid())
1357cdf0e10cSrcweir         SetStreamValid(sal_False);
1358cdf0e10cSrcweir }
1359cdf0e10cSrcweir 
UpdateCompile(sal_Bool bForceIfNameInUse)1360cdf0e10cSrcweir void ScTable::UpdateCompile( sal_Bool bForceIfNameInUse )
1361cdf0e10cSrcweir {
1362cdf0e10cSrcweir 	for (SCCOL i=0; i <= MAXCOL; i++)
1363cdf0e10cSrcweir 	{
1364cdf0e10cSrcweir 		aCol[i].UpdateCompile( bForceIfNameInUse );
1365cdf0e10cSrcweir 	}
1366cdf0e10cSrcweir }
1367cdf0e10cSrcweir 
SetTabNo(SCTAB nNewTab)1368cdf0e10cSrcweir void ScTable::SetTabNo(SCTAB nNewTab)
1369cdf0e10cSrcweir {
1370cdf0e10cSrcweir 	nTab = nNewTab;
1371cdf0e10cSrcweir 	for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].SetTabNo(nNewTab);
1372cdf0e10cSrcweir }
1373cdf0e10cSrcweir 
IsRangeNameInUse(SCCOL nCol1,SCROW nRow1,SCCOL nCol2,SCROW nRow2,sal_uInt16 nIndex) const1374cdf0e10cSrcweir sal_Bool ScTable::IsRangeNameInUse(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
1375cdf0e10cSrcweir 							   sal_uInt16 nIndex) const
1376cdf0e10cSrcweir {
1377cdf0e10cSrcweir 	sal_Bool bInUse = sal_False;
1378cdf0e10cSrcweir 	for (SCCOL i = nCol1; !bInUse && (i <= nCol2) && (ValidCol(i)); i++)
1379cdf0e10cSrcweir 		bInUse = aCol[i].IsRangeNameInUse(nRow1, nRow2, nIndex);
1380cdf0e10cSrcweir 	return bInUse;
1381cdf0e10cSrcweir }
1382cdf0e10cSrcweir 
FindRangeNamesInUse(SCCOL nCol1,SCROW nRow1,SCCOL nCol2,SCROW nRow2,std::set<sal_uInt16> & rIndexes) const1383cdf0e10cSrcweir void ScTable::FindRangeNamesInUse(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
1384cdf0e10cSrcweir 							   std::set<sal_uInt16>& rIndexes) const
1385cdf0e10cSrcweir {
1386cdf0e10cSrcweir     for (SCCOL i = nCol1; i <= nCol2 && ValidCol(i); i++)
1387cdf0e10cSrcweir         aCol[i].FindRangeNamesInUse(nRow1, nRow2, rIndexes);
1388cdf0e10cSrcweir }
1389cdf0e10cSrcweir 
ReplaceRangeNamesInUse(SCCOL nCol1,SCROW nRow1,SCCOL nCol2,SCROW nRow2,const ScRangeData::IndexMap & rMap)1390cdf0e10cSrcweir void ScTable::ReplaceRangeNamesInUse(SCCOL nCol1, SCROW nRow1,
1391cdf0e10cSrcweir                                     SCCOL nCol2, SCROW nRow2,
1392cdf0e10cSrcweir                                     const ScRangeData::IndexMap& rMap )
1393cdf0e10cSrcweir {
1394cdf0e10cSrcweir     for (SCCOL i = nCol1; i <= nCol2 && (ValidCol(i)); i++)
1395cdf0e10cSrcweir     {
1396cdf0e10cSrcweir         aCol[i].ReplaceRangeNamesInUse( nRow1, nRow2, rMap );
1397cdf0e10cSrcweir     }
1398cdf0e10cSrcweir }
1399cdf0e10cSrcweir 
ExtendPrintArea(OutputDevice * pDev,SCCOL,SCROW nStartRow,SCCOL & rEndCol,SCROW nEndRow)1400cdf0e10cSrcweir void ScTable::ExtendPrintArea( OutputDevice* pDev,
1401cdf0e10cSrcweir                     SCCOL /* nStartCol */, SCROW nStartRow, SCCOL& rEndCol, SCROW nEndRow )
1402cdf0e10cSrcweir {
1403cdf0e10cSrcweir     if ( !pColFlags || !pRowFlags )
1404cdf0e10cSrcweir     {
1405cdf0e10cSrcweir         DBG_ERROR("keine ColInfo oder RowInfo in ExtendPrintArea");
1406cdf0e10cSrcweir         return;
1407cdf0e10cSrcweir     }
1408cdf0e10cSrcweir 
1409cdf0e10cSrcweir     Point aPix1000 = pDev->LogicToPixel( Point(1000,1000), MAP_TWIP );
1410cdf0e10cSrcweir     double nPPTX = aPix1000.X() / 1000.0;
1411cdf0e10cSrcweir     double nPPTY = aPix1000.Y() / 1000.0;
1412cdf0e10cSrcweir 
1413cdf0e10cSrcweir     // First, mark those columns that we need to skip i.e. hidden and empty columns.
1414cdf0e10cSrcweir 
1415cdf0e10cSrcweir     ScFlatBoolColSegments aSkipCols;
1416cdf0e10cSrcweir     aSkipCols.setInsertFromBack(true); // speed optimazation.
1417cdf0e10cSrcweir     aSkipCols.setFalse(0, MAXCOL);
1418cdf0e10cSrcweir     for (SCCOL i = 0; i <= MAXCOL; ++i)
1419cdf0e10cSrcweir     {
1420cdf0e10cSrcweir         SCCOL nLastCol = i;
1421cdf0e10cSrcweir         if (ColHidden(i, NULL, &nLastCol))
1422cdf0e10cSrcweir         {
1423cdf0e10cSrcweir             // Columns are hidden in this range.
1424cdf0e10cSrcweir             aSkipCols.setTrue(i, nLastCol);
1425cdf0e10cSrcweir         }
1426cdf0e10cSrcweir         else
1427cdf0e10cSrcweir         {
1428cdf0e10cSrcweir             // These columns are visible.  Check for empty columns.
1429cdf0e10cSrcweir             for (SCCOL j = i; j <= nLastCol; ++j)
1430cdf0e10cSrcweir             {
1431cdf0e10cSrcweir                 if (aCol[j].GetCellCount() == 0)
1432cdf0e10cSrcweir                     // empty
1433cdf0e10cSrcweir                     aSkipCols.setTrue(j,j);
1434cdf0e10cSrcweir             }
1435cdf0e10cSrcweir         }
1436cdf0e10cSrcweir         i = nLastCol;
1437cdf0e10cSrcweir     }
1438cdf0e10cSrcweir 
1439cdf0e10cSrcweir     ScFlatBoolColSegments::RangeData aColData;
1440cdf0e10cSrcweir     for (SCCOL nCol = rEndCol; nCol >= 0; --nCol)
1441cdf0e10cSrcweir     {
1442cdf0e10cSrcweir         if (!aSkipCols.getRangeData(nCol, aColData))
1443cdf0e10cSrcweir             // Failed to get the data.  This should never happen!
1444cdf0e10cSrcweir             return;
1445cdf0e10cSrcweir 
1446cdf0e10cSrcweir         if (aColData.mbValue)
1447cdf0e10cSrcweir         {
1448cdf0e10cSrcweir             // Skip these columns.
1449cdf0e10cSrcweir             nCol = aColData.mnCol1; // move toward 0.
1450cdf0e10cSrcweir             continue;
1451cdf0e10cSrcweir         }
1452cdf0e10cSrcweir 
1453cdf0e10cSrcweir         // These are visible and non-empty columns.
1454cdf0e10cSrcweir         for (SCCOL nDataCol = nCol; 0 <= nDataCol && nDataCol >= aColData.mnCol1; --nDataCol)
1455cdf0e10cSrcweir         {
1456cdf0e10cSrcweir             SCCOL nPrintCol = nDataCol;
1457cdf0e10cSrcweir             VisibleDataCellIterator aIter(*mpHiddenRows, aCol[nDataCol]);
1458cdf0e10cSrcweir             ScBaseCell* pCell = aIter.reset(nStartRow);
1459cdf0e10cSrcweir             if (!pCell)
1460cdf0e10cSrcweir                 // No visible cells found in this column.  Skip it.
1461cdf0e10cSrcweir                 continue;
1462cdf0e10cSrcweir 
1463cdf0e10cSrcweir             while (pCell)
1464cdf0e10cSrcweir             {
1465cdf0e10cSrcweir                 SCCOL nNewCol = nDataCol;
1466cdf0e10cSrcweir                 SCROW nRow = aIter.getRow();
1467cdf0e10cSrcweir                 if (nRow > nEndRow)
1468cdf0e10cSrcweir                     // Went past the last row position.  Bail out.
1469cdf0e10cSrcweir                     break;
1470cdf0e10cSrcweir 
1471cdf0e10cSrcweir                 MaybeAddExtraColumn(nNewCol, nRow, pDev, nPPTX, nPPTY);
1472cdf0e10cSrcweir                 if (nNewCol > nPrintCol)
1473cdf0e10cSrcweir                     nPrintCol = nNewCol;
1474cdf0e10cSrcweir                 pCell = aIter.next();
1475cdf0e10cSrcweir             }
1476cdf0e10cSrcweir 
1477cdf0e10cSrcweir             if (nPrintCol > rEndCol)
1478cdf0e10cSrcweir                 // Make sure we don't shrink the print area.
1479cdf0e10cSrcweir                 rEndCol = nPrintCol;
1480cdf0e10cSrcweir         }
1481cdf0e10cSrcweir         nCol = aColData.mnCol1; // move toward 0.
1482cdf0e10cSrcweir     }
1483cdf0e10cSrcweir }
1484cdf0e10cSrcweir 
MaybeAddExtraColumn(SCCOL & rCol,SCROW nRow,OutputDevice * pDev,double nPPTX,double nPPTY)1485cdf0e10cSrcweir void ScTable::MaybeAddExtraColumn(SCCOL& rCol, SCROW nRow, OutputDevice* pDev, double nPPTX, double nPPTY)
1486cdf0e10cSrcweir {
1487cdf0e10cSrcweir     ScBaseCell* pCell = aCol[rCol].GetCell(nRow);
1488cdf0e10cSrcweir     if (!pCell || !pCell->HasStringData())
1489cdf0e10cSrcweir         return;
1490cdf0e10cSrcweir 
1491cdf0e10cSrcweir     bool bFormula = false;  //! ueberge
1492cdf0e10cSrcweir     long nPixel = pCell->GetTextWidth();
1493cdf0e10cSrcweir 
1494cdf0e10cSrcweir     // Breite bereits im Idle-Handler berechnet?
1495cdf0e10cSrcweir     if ( TEXTWIDTH_DIRTY == nPixel )
1496cdf0e10cSrcweir     {
1497cdf0e10cSrcweir         ScNeededSizeOptions aOptions;
1498cdf0e10cSrcweir         aOptions.bTotalSize  = sal_True;
1499cdf0e10cSrcweir         aOptions.bFormula    = bFormula;
1500cdf0e10cSrcweir         aOptions.bSkipMerged = sal_False;
1501cdf0e10cSrcweir 
1502cdf0e10cSrcweir         Fraction aZoom(1,1);
1503cdf0e10cSrcweir         nPixel = aCol[rCol].GetNeededSize(
1504cdf0e10cSrcweir             nRow, pDev, nPPTX, nPPTY, aZoom, aZoom, true, aOptions );
1505cdf0e10cSrcweir         pCell->SetTextWidth( (sal_uInt16)nPixel );
1506cdf0e10cSrcweir     }
1507cdf0e10cSrcweir 
1508cdf0e10cSrcweir     long nTwips = (long) (nPixel / nPPTX);
1509cdf0e10cSrcweir     long nDocW = GetColWidth( rCol );
1510cdf0e10cSrcweir 
1511cdf0e10cSrcweir     long nMissing = nTwips - nDocW;
1512cdf0e10cSrcweir     if ( nMissing > 0 )
1513cdf0e10cSrcweir     {
1514cdf0e10cSrcweir         //  look at alignment
1515cdf0e10cSrcweir 
1516cdf0e10cSrcweir         const ScPatternAttr* pPattern = GetPattern( rCol, nRow );
1517cdf0e10cSrcweir         const SfxItemSet* pCondSet = NULL;
1518cdf0e10cSrcweir         if ( ((const SfxUInt32Item&)pPattern->GetItem(ATTR_CONDITIONAL)).GetValue() )
1519cdf0e10cSrcweir             pCondSet = pDocument->GetCondResult( rCol, nRow, nTab );
1520cdf0e10cSrcweir 
1521cdf0e10cSrcweir         SvxCellHorJustify eHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)
1522cdf0e10cSrcweir                         pPattern->GetItem( ATTR_HOR_JUSTIFY, pCondSet )).GetValue();
1523cdf0e10cSrcweir         if ( eHorJust == SVX_HOR_JUSTIFY_CENTER )
1524cdf0e10cSrcweir             nMissing /= 2;                          // distributed into both directions
1525cdf0e10cSrcweir         else
1526cdf0e10cSrcweir         {
1527cdf0e10cSrcweir             // STANDARD is LEFT (only text is handled here)
1528cdf0e10cSrcweir             bool bRight = ( eHorJust == SVX_HOR_JUSTIFY_RIGHT );
1529cdf0e10cSrcweir             if ( IsLayoutRTL() )
1530cdf0e10cSrcweir                 bRight = !bRight;
1531cdf0e10cSrcweir             if ( bRight )
1532cdf0e10cSrcweir                 nMissing = 0;       // extended only to the left (logical)
1533cdf0e10cSrcweir         }
1534cdf0e10cSrcweir     }
1535cdf0e10cSrcweir 
1536cdf0e10cSrcweir     SCCOL nNewCol = rCol;
1537cdf0e10cSrcweir     while (nMissing > 0 && nNewCol < MAXCOL)
1538cdf0e10cSrcweir     {
1539cdf0e10cSrcweir         ScBaseCell* pNextCell = aCol[nNewCol+1].GetCell(nRow);
1540cdf0e10cSrcweir         if (pNextCell && pNextCell->GetCellType() != CELLTYPE_NOTE)
1541cdf0e10cSrcweir             // Cell content in a next column ends display of this string.
1542cdf0e10cSrcweir             nMissing = 0;
1543cdf0e10cSrcweir         else
1544cdf0e10cSrcweir             nMissing -= GetColWidth(++nNewCol);
1545cdf0e10cSrcweir     }
1546cdf0e10cSrcweir     rCol = nNewCol;
1547cdf0e10cSrcweir }
1548cdf0e10cSrcweir 
DoColResize(SCCOL nCol1,SCCOL nCol2,SCSIZE nAdd)1549cdf0e10cSrcweir void ScTable::DoColResize( SCCOL nCol1, SCCOL nCol2, SCSIZE nAdd )
1550cdf0e10cSrcweir {
1551cdf0e10cSrcweir 	for (SCCOL nCol=nCol1; nCol<=nCol2; nCol++)
1552cdf0e10cSrcweir 		aCol[nCol].Resize(aCol[nCol].GetCellCount() + nAdd);
1553cdf0e10cSrcweir }
1554cdf0e10cSrcweir 
1555cdf0e10cSrcweir #define SET_PRINTRANGE( p1, p2 ) \
1556cdf0e10cSrcweir 	if ( (p2) )								\
1557cdf0e10cSrcweir 	{										\
1558cdf0e10cSrcweir 		if ( (p1) )							\
1559cdf0e10cSrcweir 			*(p1) = *(p2);					\
1560cdf0e10cSrcweir 		else								\
1561cdf0e10cSrcweir 			(p1) = new ScRange( *(p2) );	\
1562cdf0e10cSrcweir 	}										\
1563cdf0e10cSrcweir 	else									\
1564cdf0e10cSrcweir 		DELETEZ( (p1) )
1565cdf0e10cSrcweir 
SetRepeatColRange(const ScRange * pNew)1566cdf0e10cSrcweir void ScTable::SetRepeatColRange( const ScRange* pNew )
1567cdf0e10cSrcweir {
1568cdf0e10cSrcweir 	SET_PRINTRANGE( pRepeatColRange, pNew );
1569cdf0e10cSrcweir 
1570cdf0e10cSrcweir     if (IsStreamValid())
1571cdf0e10cSrcweir         SetStreamValid(sal_False);
1572cdf0e10cSrcweir }
1573cdf0e10cSrcweir 
SetRepeatRowRange(const ScRange * pNew)1574cdf0e10cSrcweir void ScTable::SetRepeatRowRange( const ScRange* pNew )
1575cdf0e10cSrcweir {
1576cdf0e10cSrcweir 	SET_PRINTRANGE( pRepeatRowRange, pNew );
1577cdf0e10cSrcweir 
1578cdf0e10cSrcweir     if (IsStreamValid())
1579cdf0e10cSrcweir         SetStreamValid(sal_False);
1580cdf0e10cSrcweir }
1581cdf0e10cSrcweir 
ClearPrintRanges()1582cdf0e10cSrcweir void ScTable::ClearPrintRanges()
1583cdf0e10cSrcweir {
1584cdf0e10cSrcweir     aPrintRanges.clear();
1585cdf0e10cSrcweir     bPrintEntireSheet = sal_False;
1586dcafab4fSMichael Stahl     InvalidatePageBreaks();     // #i117952# forget page breaks for an old print range
1587cdf0e10cSrcweir 
1588cdf0e10cSrcweir     if (IsStreamValid())
1589cdf0e10cSrcweir         SetStreamValid(sal_False);
1590cdf0e10cSrcweir }
1591cdf0e10cSrcweir 
AddPrintRange(const ScRange & rNew)1592cdf0e10cSrcweir void ScTable::AddPrintRange( const ScRange& rNew )
1593cdf0e10cSrcweir {
1594cdf0e10cSrcweir     bPrintEntireSheet = sal_False;
1595cdf0e10cSrcweir     if( aPrintRanges.size() < 0xFFFF )
1596cdf0e10cSrcweir         aPrintRanges.push_back( rNew );
1597cdf0e10cSrcweir 
1598cdf0e10cSrcweir     if (IsStreamValid())
1599cdf0e10cSrcweir         SetStreamValid(sal_False);
1600cdf0e10cSrcweir }
1601cdf0e10cSrcweir 
1602cdf0e10cSrcweir //UNUSED2009-05 void ScTable::SetPrintRange( const ScRange& rNew )
1603cdf0e10cSrcweir //UNUSED2009-05 {
1604cdf0e10cSrcweir //UNUSED2009-05     ClearPrintRanges();
1605cdf0e10cSrcweir //UNUSED2009-05     AddPrintRange( rNew );
1606cdf0e10cSrcweir //UNUSED2009-05 }
1607cdf0e10cSrcweir 
SetPrintEntireSheet()1608cdf0e10cSrcweir void ScTable::SetPrintEntireSheet()
1609cdf0e10cSrcweir {
1610cdf0e10cSrcweir     if( !IsPrintEntireSheet() )
1611cdf0e10cSrcweir     {
1612cdf0e10cSrcweir         ClearPrintRanges();
1613cdf0e10cSrcweir         bPrintEntireSheet = sal_True;
1614cdf0e10cSrcweir     }
1615cdf0e10cSrcweir }
1616cdf0e10cSrcweir 
GetPrintRange(sal_uInt16 nPos) const1617cdf0e10cSrcweir const ScRange* ScTable::GetPrintRange(sal_uInt16 nPos) const
1618cdf0e10cSrcweir {
1619cdf0e10cSrcweir     return (nPos < GetPrintRangeCount()) ? &aPrintRanges[ nPos ] : NULL;
1620cdf0e10cSrcweir }
1621cdf0e10cSrcweir 
FillPrintSaver(ScPrintSaverTab & rSaveTab) const1622cdf0e10cSrcweir void ScTable::FillPrintSaver( ScPrintSaverTab& rSaveTab ) const
1623cdf0e10cSrcweir {
1624cdf0e10cSrcweir     rSaveTab.SetAreas( aPrintRanges, bPrintEntireSheet );
1625cdf0e10cSrcweir 	rSaveTab.SetRepeat( pRepeatColRange, pRepeatRowRange );
1626cdf0e10cSrcweir }
1627cdf0e10cSrcweir 
RestorePrintRanges(const ScPrintSaverTab & rSaveTab)1628cdf0e10cSrcweir void ScTable::RestorePrintRanges( const ScPrintSaverTab& rSaveTab )
1629cdf0e10cSrcweir {
1630cdf0e10cSrcweir     aPrintRanges = rSaveTab.GetPrintRanges();
1631cdf0e10cSrcweir     bPrintEntireSheet = rSaveTab.IsEntireSheet();
1632cdf0e10cSrcweir 	SetRepeatColRange( rSaveTab.GetRepeatCol() );
1633cdf0e10cSrcweir 	SetRepeatRowRange( rSaveTab.GetRepeatRow() );
1634cdf0e10cSrcweir 
1635dcafab4fSMichael Stahl     InvalidatePageBreaks();     // #i117952# forget page breaks for an old print range
1636cdf0e10cSrcweir     UpdatePageBreaks(NULL);
1637cdf0e10cSrcweir }
1638cdf0e10cSrcweir 
1639cdf0e10cSrcweir SCROW ScTable::VisibleDataCellIterator::ROW_NOT_FOUND = -1;
1640cdf0e10cSrcweir 
VisibleDataCellIterator(ScFlatBoolRowSegments & rRowSegs,ScColumn & rColumn)1641cdf0e10cSrcweir ScTable::VisibleDataCellIterator::VisibleDataCellIterator(ScFlatBoolRowSegments& rRowSegs, ScColumn& rColumn) :
1642cdf0e10cSrcweir     mrRowSegs(rRowSegs),
1643cdf0e10cSrcweir     mrColumn(rColumn),
1644cdf0e10cSrcweir     mpCell(NULL),
1645cdf0e10cSrcweir     mnCurRow(ROW_NOT_FOUND),
1646cdf0e10cSrcweir     mnUBound(ROW_NOT_FOUND)
1647cdf0e10cSrcweir {
1648cdf0e10cSrcweir }
1649cdf0e10cSrcweir 
~VisibleDataCellIterator()1650cdf0e10cSrcweir ScTable::VisibleDataCellIterator::~VisibleDataCellIterator()
1651cdf0e10cSrcweir {
1652cdf0e10cSrcweir }
1653cdf0e10cSrcweir 
reset(SCROW nRow)1654cdf0e10cSrcweir ScBaseCell* ScTable::VisibleDataCellIterator::reset(SCROW nRow)
1655cdf0e10cSrcweir {
1656cdf0e10cSrcweir     if (nRow > MAXROW)
1657cdf0e10cSrcweir     {
1658cdf0e10cSrcweir         mnCurRow = ROW_NOT_FOUND;
1659cdf0e10cSrcweir         return NULL;
1660cdf0e10cSrcweir     }
1661cdf0e10cSrcweir 
1662cdf0e10cSrcweir     ScFlatBoolRowSegments::RangeData aData;
1663cdf0e10cSrcweir     if (!mrRowSegs.getRangeData(nRow, aData))
1664cdf0e10cSrcweir     {
1665cdf0e10cSrcweir         mnCurRow = ROW_NOT_FOUND;
1666cdf0e10cSrcweir         return NULL;
1667cdf0e10cSrcweir     }
1668cdf0e10cSrcweir 
1669cdf0e10cSrcweir     if (!aData.mbValue)
1670cdf0e10cSrcweir     {
1671cdf0e10cSrcweir         // specified row is visible.  Take it.
1672cdf0e10cSrcweir         mnCurRow = nRow;
1673cdf0e10cSrcweir         mnUBound = aData.mnRow2;
1674cdf0e10cSrcweir     }
1675cdf0e10cSrcweir     else
1676cdf0e10cSrcweir     {
1677cdf0e10cSrcweir         // specified row is not-visible.  The first visible row is the start of
1678cdf0e10cSrcweir         // the next segment.
1679cdf0e10cSrcweir         mnCurRow = aData.mnRow2 + 1;
1680cdf0e10cSrcweir         mnUBound = mnCurRow; // get range data on the next iteration.
1681cdf0e10cSrcweir         if (mnCurRow > MAXROW)
1682cdf0e10cSrcweir         {
1683cdf0e10cSrcweir             // Make sure the row doesn't exceed our current limit.
1684cdf0e10cSrcweir             mnCurRow = ROW_NOT_FOUND;
1685cdf0e10cSrcweir             return NULL;
1686cdf0e10cSrcweir         }
1687cdf0e10cSrcweir     }
1688cdf0e10cSrcweir 
1689cdf0e10cSrcweir     mpCell = mrColumn.GetCell(mnCurRow);
1690cdf0e10cSrcweir     if (mpCell)
1691cdf0e10cSrcweir         // First visible cell found.
1692cdf0e10cSrcweir         return mpCell;
1693cdf0e10cSrcweir 
1694cdf0e10cSrcweir     // Find a first visible cell below this row (if any).
1695cdf0e10cSrcweir     return next();
1696cdf0e10cSrcweir }
1697cdf0e10cSrcweir 
next()1698cdf0e10cSrcweir ScBaseCell* ScTable::VisibleDataCellIterator::next()
1699cdf0e10cSrcweir {
1700cdf0e10cSrcweir     if (mnCurRow == ROW_NOT_FOUND)
1701cdf0e10cSrcweir         return NULL;
1702cdf0e10cSrcweir 
1703cdf0e10cSrcweir     while (mrColumn.GetNextDataPos(mnCurRow))
1704cdf0e10cSrcweir     {
1705cdf0e10cSrcweir         if (mnCurRow > mnUBound)
1706cdf0e10cSrcweir         {
1707cdf0e10cSrcweir             // We don't know the visibility of this row range.  Query it.
1708cdf0e10cSrcweir             ScFlatBoolRowSegments::RangeData aData;
1709cdf0e10cSrcweir             if (!mrRowSegs.getRangeData(mnCurRow, aData))
1710cdf0e10cSrcweir             {
1711cdf0e10cSrcweir                 mnCurRow = ROW_NOT_FOUND;
1712cdf0e10cSrcweir                 return NULL;
1713cdf0e10cSrcweir             }
1714cdf0e10cSrcweir 
1715cdf0e10cSrcweir             if (aData.mbValue)
1716cdf0e10cSrcweir             {
1717cdf0e10cSrcweir                 // This row is invisible.  Skip to the last invisible row and
1718cdf0e10cSrcweir                 // try again.
1719cdf0e10cSrcweir                 mnCurRow = mnUBound = aData.mnRow2;
1720cdf0e10cSrcweir                 continue;
1721cdf0e10cSrcweir             }
1722cdf0e10cSrcweir 
1723cdf0e10cSrcweir             // This row is visible.
1724cdf0e10cSrcweir             mnUBound = aData.mnRow2;
1725cdf0e10cSrcweir         }
1726cdf0e10cSrcweir 
1727cdf0e10cSrcweir         mpCell = mrColumn.GetCell(mnCurRow);
1728cdf0e10cSrcweir         if (mpCell)
1729cdf0e10cSrcweir             return mpCell;
1730cdf0e10cSrcweir     }
1731cdf0e10cSrcweir     mnCurRow = ROW_NOT_FOUND;
1732cdf0e10cSrcweir     return NULL;
1733cdf0e10cSrcweir }
1734cdf0e10cSrcweir 
getRow() const1735cdf0e10cSrcweir SCROW ScTable::VisibleDataCellIterator::getRow() const
1736cdf0e10cSrcweir {
1737cdf0e10cSrcweir     return mnCurRow;
1738cdf0e10cSrcweir }
1739cdf0e10cSrcweir 
1740