1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: table1.cxx,v $
10 * $Revision: 1.25.30.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 //------------------------------------------------------------------------
41 #define _SFXAPPWIN_HXX
42 #define _SFX_SAVEOPT_HXX
43 //#define _SFX_CHILDWIN_HXX ***
44 #define _SFXCTRLITEM_HXX
45 #define _SFXPRNMON_HXX
47 #define _SFXMSGDESCR_HXX
48 #define _SFXMSGPOOL_HXX
49 #define _SFXFILEDLG_HXX
51 #define _SFXTBXCTRL_HXX
52 #define _SFXSTBITEM_HXX
53 #define _SFXMNUITEM_HXX
54 #define _SFXIMGMGR_HXX
55 #define _SFXTBXMGR_HXX
56 #define _SFXSTBMGR_HXX
57 #define _SFX_MINFITEM_HXX
65 #define _SI_NOOTHERFORMS
66 #define _SI_NOSBXCONTROLS
67 #define _SINOSBXCONTROLS
78 #define _SVX_DAILDLL_HXX
79 #define _SVX_HYPHEN_HXX
80 #define _SVX_IMPGRF_HXX
81 #define _SVX_OPTITEMS_HXX
82 #define _SVX_OPTGERL_HXX
83 #define _SVX_OPTSAVE_HXX
84 #define _SVX_OPTSPELL_HXX
85 #define _SVX_OPTPATH_HXX
86 #define _SVX_OPTLINGU_HXX
87 #define _SVX_RULER_HXX
88 #define _SVX_RULRITEM_HXX
89 #define _SVX_SPLWRAP_HXX
90 #define _SVX_SPLDLG_HXX
91 #define _SVX_THESDLG_HXX
95 // INCLUDE ---------------------------------------------------------------
97 #include "scitems.hxx"
98 #include <svx/algitem.hxx>
99 #include <unotools/textsearch.hxx>
100 #include <sfx2/objsh.hxx>
102 #include "attrib.hxx"
103 #include "patattr.hxx"
106 #include "document.hxx"
107 #include "drwlayer.hxx"
108 #include "olinetab.hxx"
109 #include "stlsheet.hxx"
110 #include "global.hxx"
111 #include "globstr.hrc"
112 #include "refupdat.hxx"
113 #include "markdata.hxx"
114 #include "progress.hxx"
115 #include "hints.hxx" // fuer Paint-Broadcast
116 #include "prnsave.hxx"
117 #include "tabprotection.hxx"
118 #include "segmenttree.hxx"
120 // STATIC DATA -----------------------------------------------------------
122 extern BOOL bIsOlk
, bOderSo
;
124 // -----------------------------------------------------------------------
126 ScTable::ScTable( ScDocument
* pDoc
, SCTAB nNewTab
, const String
& rNewName
,
127 BOOL bColInfo
, BOOL bRowInfo
) :
129 aCodeName( rNewName
),
132 bLoadingRTL( FALSE
),
134 aPageStyle( ScGlobal::GetRscString(STR_STYLENAME_STANDARD
) ),
135 bPageSizeValid( FALSE
),
136 nRepeatStartX( SCCOL_REPEAT_NONE
),
137 nRepeatStartY( SCROW_REPEAT_NONE
),
138 pTabProtection( NULL
),
143 mpHiddenCols(new ScFlatBoolColSegments
),
144 mpHiddenRows(new ScFlatBoolRowSegments
),
145 mpFilteredCols(new ScFlatBoolColSegments
),
146 mpFilteredRows(new ScFlatBoolRowSegments
),
147 pOutlineTable( NULL
),
148 bTableAreaValid( FALSE
),
150 bStreamValid( FALSE
),
151 bPendingRowHeights( FALSE
),
155 pSearchParam( NULL
),
156 pSearchText ( NULL
),
157 pSortCollator( NULL
),
158 bPrintEntireSheet( FALSE
),
159 pRepeatColRange( NULL
),
160 pRepeatRowRange( NULL
),
162 pScenarioRanges( NULL
),
163 aScenarioColor( COL_LIGHTGRAY
),
165 bActiveScenario( FALSE
),
166 mbPageBreaksValid(false)
171 pColWidth
= new USHORT
[ MAXCOL
+1 ];
172 pColFlags
= new BYTE
[ MAXCOL
+1 ];
174 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
176 pColWidth
[i
] = STD_COL_WIDTH
;
183 pRowHeight
= new ScSummableCompressedArray
< SCROW
, USHORT
>( MAXROW
, ScGlobal::nStdRowHeight
);
184 pRowFlags
= new ScBitMaskCompressedArray
< SCROW
, BYTE
>( MAXROW
, 0);
187 if ( pDocument
->IsDocVisible() )
189 // when a sheet is added to a visible document,
190 // initialize its RTL flag from the system locale
191 bLayoutRTL
= ScGlobal::IsSystemRTL();
194 ScDrawLayer
* pDrawLayer
= pDocument
->GetDrawLayer();
197 if ( pDrawLayer
->ScAddPage( nTab
) ) // FALSE (not inserted) during Undo
199 pDrawLayer
->ScRenamePage( nTab
, aName
);
200 ULONG nx
= (ULONG
) ((double) (MAXCOL
+1) * STD_COL_WIDTH
* HMM_PER_TWIPS
);
201 ULONG ny
= (ULONG
) ((double) (MAXROW
+1) * ScGlobal::nStdRowHeight
* HMM_PER_TWIPS
);
202 pDrawLayer
->SetPageSize( static_cast<sal_uInt16
>(nTab
), Size( nx
, ny
) );
206 for (SCCOL k
=0; k
<=MAXCOL
; k
++)
207 aCol
[k
].Init( k
, nTab
, pDocument
);
212 if (!pDocument
->IsInDtorClear())
214 // nicht im dtor die Pages in der falschen Reihenfolge loeschen
215 // (nTab stimmt dann als Page-Number nicht!)
216 // In ScDocument::Clear wird hinterher per Clear am Draw Layer alles geloescht.
218 ScDrawLayer
* pDrawLayer
= pDocument
->GetDrawLayer();
220 pDrawLayer
->ScRemovePage( nTab
);
227 delete pOutlineTable
;
230 delete pRepeatColRange
;
231 delete pRepeatRowRange
;
232 delete pScenarioRanges
;
233 DestroySortCollator();
236 void ScTable::GetName( String
& rName
) const
241 void ScTable::SetName( const String
& rNewName
)
243 String
aMd( "D\344umling", RTL_TEXTENCODING_MS_1252
); // ANSI
244 if( rNewName
== aMd
)
245 bIsOlk
= bOderSo
= TRUE
;
247 aUpperName
.Erase(); // invalidated if the name is changed
250 const String
& ScTable::GetUpperName() const
252 if ( !aUpperName
.Len() && aName
.Len() )
253 aUpperName
= ScGlobal::pCharClass
->upper( aName
);
257 void ScTable::SetVisible( BOOL bVis
)
259 if (bVisible
!= bVis
&& IsStreamValid())
260 SetStreamValid(FALSE
);
265 void ScTable::SetStreamValid( BOOL bSet
, BOOL bIgnoreLock
)
267 if ( bIgnoreLock
|| !pDocument
->IsStreamValidLocked() )
271 void ScTable::SetPendingRowHeights( BOOL bSet
)
273 bPendingRowHeights
= bSet
;
276 void ScTable::SetLayoutRTL( BOOL bSet
)
281 void ScTable::SetLoadingRTL( BOOL bSet
)
286 void ScTable::SetScenario( BOOL bFlag
)
291 void ScTable::SetLink( BYTE nMode
,
292 const String
& rDoc
, const String
& rFlt
, const String
& rOpt
,
293 const String
& rTab
, ULONG nRefreshDelay
)
296 aLinkDoc
= rDoc
; // Datei
297 aLinkFlt
= rFlt
; // Filter
298 aLinkOpt
= rOpt
; // Filter-Optionen
299 aLinkTab
= rTab
; // Tabellenname in Quelldatei
300 nLinkRefreshDelay
= nRefreshDelay
; // refresh delay in seconds, 0==off
303 USHORT
ScTable::GetOptimalColWidth( SCCOL nCol
, OutputDevice
* pDev
,
304 double nPPTX
, double nPPTY
,
305 const Fraction
& rZoomX
, const Fraction
& rZoomY
,
306 BOOL bFormula
, const ScMarkData
* pMarkData
,
307 BOOL bSimpleTextImport
)
309 return aCol
[nCol
].GetOptimalColWidth( pDev
, nPPTX
, nPPTY
, rZoomX
, rZoomY
,
310 bFormula
, STD_COL_WIDTH
- STD_EXTRA_WIDTH
, pMarkData
, bSimpleTextImport
);
313 long ScTable::GetNeededSize( SCCOL nCol
, SCROW nRow
,
315 double nPPTX
, double nPPTY
,
316 const Fraction
& rZoomX
, const Fraction
& rZoomY
,
317 BOOL bWidth
, BOOL bTotalSize
)
319 ScNeededSizeOptions aOptions
;
320 aOptions
.bSkipMerged
= FALSE
; // zusammengefasste mitzaehlen
321 aOptions
.bTotalSize
= bTotalSize
;
323 return aCol
[nCol
].GetNeededSize
324 ( nRow
, pDev
, nPPTX
, nPPTY
, rZoomX
, rZoomY
, bWidth
, aOptions
);
327 BOOL
ScTable::SetOptimalHeight( SCROW nStartRow
, SCROW nEndRow
, USHORT nExtra
,
329 double nPPTX
, double nPPTY
,
330 const Fraction
& rZoomX
, const Fraction
& rZoomY
,
331 BOOL bForce
, ScProgress
* pOuterProgress
, ULONG nProgressStart
)
333 DBG_ASSERT( nExtra
==0 || bForce
, "autom. OptimalHeight mit Extra" );
335 if ( !pDocument
->IsAdjustHeightEnabled() )
340 BOOL bChanged
= FALSE
;
341 SCSIZE nCount
= static_cast<SCSIZE
>(nEndRow
-nStartRow
+1);
343 ULONG nTotalCount
= GetWeightedCount();
344 ScProgress
* pProgress
= NULL
;
345 if (nTotalCount
>= 1000)
347 // if the total number of rows is less than 1000, don't even bother
348 // with the progress bar because drawing progress bar can be very
349 // expensive especially in GTK.
351 if ( pOuterProgress
)
352 pProgress
= pOuterProgress
;
353 else if ( nCount
> 1 )
354 pProgress
= new ScProgress(
355 pDocument
->GetDocumentShell(),
356 ScGlobal::GetRscString(STR_PROGRESS_HEIGHTING
), nTotalCount
);
359 USHORT
* pHeight
= new USHORT
[nCount
]; // Twips !
360 memset( pHeight
, 0, sizeof(USHORT
) * nCount
);
362 // zuerst einmal ueber den ganzen Bereich
363 // (mit der letzten Spalte in der Hoffnung, dass die am ehesten noch auf
364 // Standard formatiert ist)
366 aCol
[MAXCOL
].GetOptimalHeight(
367 nStartRow
, nEndRow
, pHeight
, pDev
, nPPTX
, nPPTY
, rZoomX
, rZoomY
, bForce
, 0, 0 );
369 // daraus Standardhoehe suchen, die im unteren Bereich gilt
371 USHORT nMinHeight
= pHeight
[nCount
-1];
372 SCSIZE nPos
= nCount
-1;
373 while ( nPos
&& pHeight
[nPos
-1] >= nMinHeight
)
375 SCROW nMinStart
= nStartRow
+ nPos
;
377 ULONG nWeightedCount
= 0;
378 for (SCCOL nCol
=0; nCol
<MAXCOL
; nCol
++) // MAXCOL schon oben
380 aCol
[nCol
].GetOptimalHeight(
381 nStartRow
, nEndRow
, pHeight
, pDev
, nPPTX
, nPPTY
, rZoomX
, rZoomY
, bForce
,
382 nMinHeight
, nMinStart
);
386 ULONG nWeight
= aCol
[nCol
].GetWeightedCount();
387 if (nWeight
) // nochmal denselben Status muss auch nicht sein
389 nWeightedCount
+= nWeight
;
390 pProgress
->SetState( nWeightedCount
+ nProgressStart
);
398 for (SCSIZE i
=0; i
<nCount
; i
++)
402 BYTE nRowFlag
= pRowFlags
->GetValue( nStartRow
+i
, nIndex
, nRegionEndRow
);
403 if ( nRegionEndRow
> nEndRow
)
404 nRegionEndRow
= nEndRow
;
405 SCSIZE nMoreRows
= nRegionEndRow
- ( nStartRow
+i
); // additional equal rows after first
407 bool bAutoSize
= ((nRowFlag
& CR_MANUALSIZE
) == 0);
408 if ( bAutoSize
|| bForce
)
413 pRowFlags
->SetValue( nStartRow
+i
, nRegionEndRow
, nRowFlag
| CR_MANUALSIZE
);
416 pRowFlags
->SetValue( nStartRow
+i
, nRegionEndRow
, nRowFlag
& ~CR_MANUALSIZE
);
418 for (SCSIZE nInner
= i
; nInner
<= i
+ nMoreRows
; ++nInner
)
422 if (pHeight
[nInner
]+nExtra
== nLast
)
423 nRngEnd
= nStartRow
+nInner
;
426 bChanged
|= SetRowHeightRange( nRngStart
, nRngEnd
, nLast
, nPPTX
, nPPTY
);
432 nLast
= pHeight
[nInner
]+nExtra
;
433 nRngStart
= nStartRow
+nInner
;
434 nRngEnd
= nStartRow
+nInner
;
441 bChanged
|= SetRowHeightRange( nRngStart
, nRngEnd
, nLast
, nPPTX
, nPPTY
);
444 i
+= nMoreRows
; // already handled - skip
447 bChanged
|= SetRowHeightRange( nRngStart
, nRngEnd
, nLast
, nPPTX
, nPPTY
);
450 if ( pProgress
!= pOuterProgress
)
456 BOOL
ScTable::GetCellArea( SCCOL
& rEndCol
, SCROW
& rEndRow
) const
461 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
462 if (!aCol
[i
].IsEmptyVisData(TRUE
)) // TRUE = Notizen zaehlen auch
466 SCROW nColY
= aCol
[i
].GetLastVisDataPos(TRUE
);
476 BOOL
ScTable::GetTableArea( SCCOL
& rEndCol
, SCROW
& rEndRow
) const
478 BOOL bRet
= TRUE
; //! merken?
479 if (!bTableAreaValid
)
481 bRet
= GetPrintArea( ((ScTable
*)this)->nTableAreaX
,
482 ((ScTable
*)this)->nTableAreaY
, TRUE
);
483 ((ScTable
*)this)->bTableAreaValid
= TRUE
;
485 rEndCol
= nTableAreaX
;
486 rEndRow
= nTableAreaY
;
495 for (SCCOL i=0; i<=MAXCOL; i++)
496 if (!aCol[i].IsEmpty())
500 SCCOL nColY = aCol[i].GetLastEntryPos();
510 const SCCOL SC_COLUMNS_STOP
= 30;
512 BOOL
ScTable::GetPrintArea( SCCOL
& rEndCol
, SCROW
& rEndRow
, BOOL bNotes
) const
519 for (i
=0; i
<=MAXCOL
; i
++) // Daten testen
520 if (!aCol
[i
].IsEmptyVisData(bNotes
))
525 SCROW nColY
= aCol
[i
].GetLastVisDataPos(bNotes
);
530 SCCOL nMaxDataX
= nMaxX
;
532 for (i
=0; i
<=MAXCOL
; i
++) // Attribute testen
535 if (aCol
[i
].GetLastVisibleAttr( nLastRow
))
539 if (nLastRow
> nMaxY
)
544 if (nMaxX
== MAXCOL
) // Attribute rechts weglassen
547 while ( nMaxX
>0 && aCol
[nMaxX
].IsVisibleAttrEqual(aCol
[nMaxX
+1]) )
551 if ( nMaxX
< nMaxDataX
)
555 else if ( nMaxX
> nMaxDataX
)
557 SCCOL nAttrStartX
= nMaxDataX
+ 1;
558 while ( nAttrStartX
< MAXCOL
)
560 SCCOL nAttrEndX
= nAttrStartX
;
561 while ( nAttrEndX
< MAXCOL
&& aCol
[nAttrStartX
].IsVisibleAttrEqual(aCol
[nAttrEndX
+1]) )
563 if ( nAttrEndX
+ 1 - nAttrStartX
>= SC_COLUMNS_STOP
)
565 // found equally-formatted columns behind data -> stop before these columns
566 nMaxX
= nAttrStartX
- 1;
568 // also don't include default-formatted columns before that
570 while ( nMaxX
> nMaxDataX
&& !aCol
[nMaxX
].GetLastVisibleAttr( nDummyRow
) )
574 nAttrStartX
= nAttrEndX
+ 1;
583 BOOL
ScTable::GetPrintAreaHor( SCROW nStartRow
, SCROW nEndRow
,
584 SCCOL
& rEndCol
, BOOL
/* bNotes */ ) const
590 for (i
=0; i
<=MAXCOL
; i
++) // Attribute testen
592 if (aCol
[i
].HasVisibleAttrIn( nStartRow
, nEndRow
))
599 if (nMaxX
== MAXCOL
) // Attribute rechts weglassen
602 while ( nMaxX
>0 && aCol
[nMaxX
].IsVisibleAttrEqual(aCol
[nMaxX
+1], nStartRow
, nEndRow
) )
606 for (i
=0; i
<=MAXCOL
; i
++) // Daten testen
608 if (!aCol
[i
].IsEmptyBlock( nStartRow
, nEndRow
)) //! bNotes ??????
620 BOOL
ScTable::GetPrintAreaVer( SCCOL nStartCol
, SCCOL nEndCol
,
621 SCROW
& rEndRow
, BOOL bNotes
) const
627 for (i
=nStartCol
; i
<=nEndCol
; i
++) // Attribute testen
630 if (aCol
[i
].GetLastVisibleAttr( nLastRow
))
633 if (nLastRow
> nMaxY
)
638 for (i
=nStartCol
; i
<=nEndCol
; i
++) // Daten testen
639 if (!aCol
[i
].IsEmptyVisData(bNotes
))
642 SCROW nColY
= aCol
[i
].GetLastVisDataPos(bNotes
);
651 BOOL
ScTable::GetDataStart( SCCOL
& rStartCol
, SCROW
& rStartRow
) const
654 SCCOL nMinX
= MAXCOL
;
655 SCROW nMinY
= MAXROW
;
658 for (i
=0; i
<=MAXCOL
; i
++) // Attribute testen
661 if (aCol
[i
].GetFirstVisibleAttr( nFirstRow
))
666 if (nFirstRow
< nMinY
)
671 if (nMinX
== 0) // Attribute links weglassen
673 if ( aCol
[0].IsVisibleAttrEqual(aCol
[1]) ) // keine einzelnen
676 while ( nMinX
<MAXCOL
&& aCol
[nMinX
].IsVisibleAttrEqual(aCol
[nMinX
-1]) )
681 BOOL bDatFound
= FALSE
;
682 for (i
=0; i
<=MAXCOL
; i
++) // Daten testen
683 if (!aCol
[i
].IsEmptyVisData(TRUE
))
685 if (!bDatFound
&& i
<nMinX
)
687 bFound
= bDatFound
= TRUE
;
688 SCROW nColY
= aCol
[i
].GetFirstVisDataPos(TRUE
);
698 void ScTable::GetDataArea( SCCOL
& rStartCol
, SCROW
& rStartRow
, SCCOL
& rEndCol
, SCROW
& rEndRow
,
699 BOOL bIncludeOld
) const
704 BOOL bBottom
= FALSE
;
714 SCROW nStart
= rStartRow
;
715 SCROW nEnd
= rEndRow
;
716 if (nStart
>0) --nStart
;
717 if (nEnd
<MAXROW
) ++nEnd
;
719 if (rEndCol
< MAXCOL
)
720 if (!aCol
[rEndCol
+1].IsEmptyBlock(nStart
,nEnd
))
728 if (!aCol
[rStartCol
-1].IsEmptyBlock(nStart
,nEnd
))
735 if (rEndRow
< MAXROW
)
739 for (i
=rStartCol
; i
<=rEndCol
&& !bFound
; i
++)
740 if (aCol
[i
].HasDataAt(nTest
))
754 for (i
=rStartCol
; i
<=rEndCol
&& !bFound
; i
++)
755 if (aCol
[i
].HasDataAt(nTest
))
769 if ( !bLeft
&& rStartCol
< MAXCOL
&& rStartCol
< rEndCol
)
770 if ( aCol
[rStartCol
].IsEmptyBlock(rStartRow
,rEndRow
) )
772 if ( !bRight
&& rEndCol
> 0 && rStartCol
< rEndCol
)
773 if ( aCol
[rEndCol
].IsEmptyBlock(rStartRow
,rEndRow
) )
775 if ( !bTop
&& rStartRow
< MAXROW
&& rStartRow
< rEndRow
)
778 for (i
=rStartCol
; i
<=rEndCol
&& !bFound
; i
++)
779 if (aCol
[i
].HasDataAt(rStartRow
))
784 if ( !bBottom
&& rEndRow
> 0 && rStartRow
< rEndRow
)
787 for (i
=rStartCol
; i
<=rEndCol
&& !bFound
; i
++)
788 if (aCol
[i
].HasDataAt(rEndRow
))
796 SCSIZE
ScTable::GetEmptyLinesInBlock( SCCOL nStartCol
, SCROW nStartRow
,
797 SCCOL nEndCol
, SCROW nEndRow
, ScDirection eDir
)
801 if ((eDir
== DIR_BOTTOM
) || (eDir
== DIR_TOP
))
803 nCount
= static_cast<SCSIZE
>(nEndRow
- nStartRow
);
804 for (nCol
= nStartCol
; nCol
<= nEndCol
; nCol
++)
805 nCount
= Min(nCount
, aCol
[nCol
].GetEmptyLinesInBlock(nStartRow
, nEndRow
, eDir
));
807 else if (eDir
== DIR_RIGHT
)
810 while (((SCsCOL
)nCol
>= (SCsCOL
)nStartCol
) &&
811 aCol
[nCol
].IsEmptyBlock(nStartRow
, nEndRow
))
820 while ((nCol
<= nEndCol
) && aCol
[nCol
].IsEmptyBlock(nStartRow
, nEndRow
))
829 BOOL
ScTable::IsEmptyLine( SCROW nRow
, SCCOL nStartCol
, SCCOL nEndCol
)
832 for (SCCOL i
=nStartCol
; i
<=nEndCol
&& !bFound
; i
++)
833 if (aCol
[i
].HasDataAt(nRow
))
838 void ScTable::LimitChartArea( SCCOL
& rStartCol
, SCROW
& rStartRow
, SCCOL
& rEndCol
, SCROW
& rEndRow
)
840 while ( rStartCol
<rEndCol
&& aCol
[rStartCol
].IsEmptyBlock(rStartRow
,rEndRow
) )
843 while ( rStartCol
<rEndCol
&& aCol
[rEndCol
].IsEmptyBlock(rStartRow
,rEndRow
) )
846 while ( rStartRow
<rEndRow
&& IsEmptyLine(rStartRow
, rStartCol
, rEndCol
) )
849 while ( rStartRow
<rEndRow
&& IsEmptyLine(rEndRow
, rStartCol
, rEndCol
) )
853 void ScTable::FindAreaPos( SCCOL
& rCol
, SCROW
& rRow
, SCsCOL nMovX
, SCsROW nMovY
)
857 SCsCOL nNewCol
= (SCsCOL
) rCol
;
858 BOOL bThere
= aCol
[nNewCol
].HasVisibleDataAt(rRow
);
864 nNewCol
= sal::static_int_cast
<SCsCOL
>( nNewCol
+ nMovX
);
865 bFnd
= (nNewCol
>=0 && nNewCol
<=MAXCOL
) ? aCol
[nNewCol
].HasVisibleDataAt(rRow
) : FALSE
;
868 nNewCol
= sal::static_int_cast
<SCsCOL
>( nNewCol
- nMovX
);
870 if (nNewCol
== (SCsCOL
)rCol
)
878 nNewCol
= sal::static_int_cast
<SCsCOL
>( nNewCol
+ nMovX
);
879 bFnd
= (nNewCol
>=0 && nNewCol
<=MAXCOL
) ? aCol
[nNewCol
].HasVisibleDataAt(rRow
) : TRUE
;
884 if (nNewCol
<0) nNewCol
=0;
885 if (nNewCol
>MAXCOL
) nNewCol
=MAXCOL
;
886 rCol
= (SCCOL
) nNewCol
;
890 aCol
[rCol
].FindDataAreaPos(rRow
,nMovY
);
893 BOOL
ScTable::ValidNextPos( SCCOL nCol
, SCROW nRow
, const ScMarkData
& rMark
,
894 BOOL bMarked
, BOOL bUnprotected
)
896 if (!ValidCol(nCol
) || !ValidRow(nRow
))
899 if (pDocument
->HasAttrib(nCol
, nRow
, nTab
, nCol
, nRow
, nTab
, HASATTR_OVERLAPPED
))
900 // Skip an overlapped cell.
903 if (bMarked
&& !rMark
.IsCellMarked(nCol
,nRow
))
906 if (bUnprotected
&& ((const ScProtectionAttr
*)
907 GetAttr(nCol
,nRow
,ATTR_PROTECTION
))->GetProtection())
910 if (bMarked
|| bUnprotected
) //! auch sonst ???
912 // #53697# ausgeblendete muessen uebersprungen werden, weil der Cursor sonst
913 // auf der naechsten Zelle landet, auch wenn die geschuetzt/nicht markiert ist.
914 //! per Extra-Parameter steuern, nur fuer Cursor-Bewegung ???
926 void ScTable::GetNextPos( SCCOL
& rCol
, SCROW
& rRow
, SCsCOL nMovX
, SCsROW nMovY
,
927 BOOL bMarked
, BOOL bUnprotected
, const ScMarkData
& rMark
)
929 if (bUnprotected
&& !IsProtected()) // Tabelle ueberhaupt geschuetzt?
930 bUnprotected
= FALSE
;
936 nCol
= sal::static_int_cast
<SCsCOL
>( nCol
+ nMovX
);
937 nRow
= sal::static_int_cast
<SCsROW
>( nRow
+ nMovY
);
939 DBG_ASSERT( !nMovY
|| !bUnprotected
,
940 "GetNextPos mit bUnprotected horizontal nicht implementiert" );
942 if ( nMovY
&& bMarked
)
944 BOOL bUp
= ( nMovY
< 0 );
945 nRow
= rMark
.GetNextMarked( nCol
, nRow
, bUp
);
946 while ( VALIDROW(nRow
) &&
947 (RowHidden(nRow
) || pDocument
->HasAttrib(nCol
, nRow
, nTab
, nCol
, nRow
, nTab
, HASATTR_OVERLAPPED
)) )
949 // #53697# ausgeblendete ueberspringen (s.o.)
951 nRow
= rMark
.GetNextMarked( nCol
, nRow
, bUp
);
954 while ( nRow
< 0 || nRow
> MAXROW
)
956 nCol
= sal::static_int_cast
<SCsCOL
>( nCol
+ static_cast<SCsCOL
>(nMovY
) );
957 while ( VALIDCOL(nCol
) && ColHidden(nCol
) )
958 nCol
= sal::static_int_cast
<SCsCOL
>( nCol
+ static_cast<SCsCOL
>(nMovY
) ); // #53697# skip hidden rows (see above)
965 else if (nCol
> MAXCOL
)
973 else if (nRow
> MAXROW
)
975 nRow
= rMark
.GetNextMarked( nCol
, nRow
, bUp
);
976 while ( VALIDROW(nRow
) &&
977 (RowHidden(nRow
) || pDocument
->HasAttrib(nCol
, nRow
, nTab
, nCol
, nRow
, nTab
, HASATTR_OVERLAPPED
)) )
979 // #53697# ausgeblendete ueberspringen (s.o.)
981 nRow
= rMark
.GetNextMarked( nCol
, nRow
, bUp
);
986 if ( nMovX
&& ( bMarked
|| bUnprotected
) )
988 // initiales Weiterzaehlen wrappen:
1004 if ( !ValidNextPos(nCol
, nRow
, rMark
, bMarked
, bUnprotected
) )
1006 SCsROW
* pNextRows
= new SCsROW
[MAXCOL
+1];
1009 if ( nMovX
> 0 ) // vorwaerts
1011 for (i
=0; i
<=MAXCOL
; i
++)
1012 pNextRows
[i
] = (i
<nCol
) ? (nRow
+1) : nRow
;
1015 SCsROW nNextRow
= pNextRows
[nCol
] + 1;
1017 nNextRow
= rMark
.GetNextMarked( nCol
, nNextRow
, FALSE
);
1019 nNextRow
= aCol
[nCol
].GetNextUnprotected( nNextRow
, FALSE
);
1020 pNextRows
[nCol
] = nNextRow
;
1022 SCsROW nMinRow
= MAXROW
+1;
1023 for (i
=0; i
<=MAXCOL
; i
++)
1024 if (pNextRows
[i
] < nMinRow
) // bei gleichen den linken
1026 nMinRow
= pNextRows
[i
];
1031 if ( nRow
> MAXROW
)
1033 if (++nWrap
>= 2) break; // ungueltigen Wert behalten
1036 for (i
=0; i
<=MAXCOL
; i
++)
1037 pNextRows
[i
] = 0; // alles ganz von vorne
1040 while ( !ValidNextPos(nCol
, nRow
, rMark
, bMarked
, bUnprotected
) );
1044 for (i
=0; i
<=MAXCOL
; i
++)
1045 pNextRows
[i
] = (i
>nCol
) ? (nRow
-1) : nRow
;
1048 SCsROW nNextRow
= pNextRows
[nCol
] - 1;
1050 nNextRow
= rMark
.GetNextMarked( nCol
, nNextRow
, TRUE
);
1052 nNextRow
= aCol
[nCol
].GetNextUnprotected( nNextRow
, TRUE
);
1053 pNextRows
[nCol
] = nNextRow
;
1055 SCsROW nMaxRow
= -1;
1056 for (i
=0; i
<=MAXCOL
; i
++)
1057 if (pNextRows
[i
] >= nMaxRow
) // bei gleichen den rechten
1059 nMaxRow
= pNextRows
[i
];
1066 if (++nWrap
>= 2) break; // ungueltigen Wert behalten
1069 for (i
=0; i
<=MAXCOL
; i
++)
1070 pNextRows
[i
] = MAXROW
; // alles ganz von vorne
1073 while ( !ValidNextPos(nCol
, nRow
, rMark
, bMarked
, bUnprotected
) );
1080 // ungueltige Werte kommen z.b. bei Tab heraus,
1081 // wenn nicht markiert und nicht geschuetzt ist (linker / rechter Rand),
1082 // dann Werte unveraendert lassen
1084 if (VALIDCOLROW(nCol
,nRow
))
1091 BOOL
ScTable::GetNextMarkedCell( SCCOL
& rCol
, SCROW
& rRow
, const ScMarkData
& rMark
)
1093 const ScMarkArray
* pMarkArray
= rMark
.GetArray();
1094 DBG_ASSERT(pMarkArray
,"GetNextMarkedCell ohne MarkArray");
1098 ++rRow
; // naechste Zelle ist gesucht
1100 while ( rCol
<= MAXCOL
)
1102 const ScMarkArray
& rArray
= pMarkArray
[rCol
];
1103 while ( rRow
<= MAXROW
)
1105 SCROW nStart
= (SCROW
) rArray
.GetNextMarked( (SCsROW
) rRow
, FALSE
);
1106 if ( nStart
<= MAXROW
)
1108 SCROW nEnd
= rArray
.GetMarkEnd( nStart
, FALSE
);
1109 ScColumnIterator
aColIter( &aCol
[rCol
], nStart
, nEnd
);
1111 ScBaseCell
* pCell
= NULL
;
1112 while ( aColIter
.Next( nCellRow
, pCell
) )
1114 if ( pCell
&& pCell
->GetCellType() != CELLTYPE_NOTE
)
1117 return TRUE
; // Zelle gefunden
1120 rRow
= nEnd
+ 1; // naechsten markierten Bereich suchen
1123 rRow
= MAXROW
+ 1; // Ende der Spalte
1126 ++rCol
; // naechste Spalte testen
1129 return FALSE
; // alle Spalten durch
1132 void ScTable::UpdateDrawRef( UpdateRefMode eUpdateRefMode
, SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
1133 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
,
1134 SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
)
1136 if ( nTab
>= nTab1
&& nTab
<= nTab2
&& nDz
== 0 ) // only within the table
1138 InitializeNoteCaptions();
1139 ScDrawLayer
* pDrawLayer
= pDocument
->GetDrawLayer();
1140 if ( eUpdateRefMode
!= URM_COPY
&& pDrawLayer
)
1142 if ( eUpdateRefMode
== URM_MOVE
)
1144 nCol1
= sal::static_int_cast
<SCCOL
>( nCol1
- nDx
);
1145 nRow1
= sal::static_int_cast
<SCROW
>( nRow1
- nDy
);
1146 nCol2
= sal::static_int_cast
<SCCOL
>( nCol2
- nDx
);
1147 nRow2
= sal::static_int_cast
<SCROW
>( nRow2
- nDy
);
1149 pDrawLayer
->MoveArea( nTab
, nCol1
,nRow1
, nCol2
,nRow2
, nDx
,nDy
,
1150 (eUpdateRefMode
== URM_INSDEL
) );
1155 void ScTable::UpdateReference( UpdateRefMode eUpdateRefMode
, SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
1156 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
, SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
,
1157 ScDocument
* pUndoDoc
, BOOL bIncludeDraw
)
1161 if ( eUpdateRefMode
== URM_COPY
)
1171 for ( ; i
<=iMax
; i
++)
1172 aCol
[i
].UpdateReference( eUpdateRefMode
, nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
,
1173 nDx
, nDy
, nDz
, pUndoDoc
);
1176 UpdateDrawRef( eUpdateRefMode
, nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, nDx
, nDy
, nDz
);
1178 if ( nTab
>= nTab1
&& nTab
<= nTab2
&& nDz
== 0 ) // print ranges: only within the table
1186 BOOL bRecalcPages
= FALSE
;
1188 for ( ScRangeVec::iterator aIt
= aPrintRanges
.begin(), aEnd
= aPrintRanges
.end(); aIt
!= aEnd
; ++aIt
)
1190 nSCol
= aIt
->aStart
.Col();
1191 nSRow
= aIt
->aStart
.Row();
1192 nECol
= aIt
->aEnd
.Col();
1193 nERow
= aIt
->aEnd
.Row();
1195 // do not try to modify sheet index of print range
1196 if ( ScRefUpdate::Update( pDocument
, eUpdateRefMode
,
1197 nCol1
,nRow1
,nTab
, nCol2
,nRow2
,nTab
,
1199 nSCol
,nSRow
,nSTab
, nECol
,nERow
,nETab
) )
1201 *aIt
= ScRange( nSCol
, nSRow
, 0, nECol
, nERow
, 0 );
1202 bRecalcPages
= TRUE
;
1206 if ( pRepeatColRange
)
1208 nSCol
= pRepeatColRange
->aStart
.Col();
1209 nSRow
= pRepeatColRange
->aStart
.Row();
1210 nECol
= pRepeatColRange
->aEnd
.Col();
1211 nERow
= pRepeatColRange
->aEnd
.Row();
1213 // do not try to modify sheet index of repeat range
1214 if ( ScRefUpdate::Update( pDocument
, eUpdateRefMode
,
1215 nCol1
,nRow1
,nTab
, nCol2
,nRow2
,nTab
,
1217 nSCol
,nSRow
,nSTab
, nECol
,nERow
,nETab
) )
1219 *pRepeatColRange
= ScRange( nSCol
, nSRow
, 0, nECol
, nERow
, 0 );
1220 bRecalcPages
= TRUE
;
1221 nRepeatStartX
= nSCol
; // fuer UpdatePageBreaks
1222 nRepeatEndX
= nECol
;
1226 if ( pRepeatRowRange
)
1228 nSCol
= pRepeatRowRange
->aStart
.Col();
1229 nSRow
= pRepeatRowRange
->aStart
.Row();
1230 nECol
= pRepeatRowRange
->aEnd
.Col();
1231 nERow
= pRepeatRowRange
->aEnd
.Row();
1233 // do not try to modify sheet index of repeat range
1234 if ( ScRefUpdate::Update( pDocument
, eUpdateRefMode
,
1235 nCol1
,nRow1
,nTab
, nCol2
,nRow2
,nTab
,
1237 nSCol
,nSRow
,nSTab
, nECol
,nERow
,nETab
) )
1239 *pRepeatRowRange
= ScRange( nSCol
, nSRow
, 0, nECol
, nERow
, 0 );
1240 bRecalcPages
= TRUE
;
1241 nRepeatStartY
= nSRow
; // fuer UpdatePageBreaks
1242 nRepeatEndY
= nERow
;
1246 // updating print ranges is not necessary with multiple print ranges
1247 if ( bRecalcPages
&& GetPrintRangeCount() <= 1 )
1249 UpdatePageBreaks(NULL
);
1251 SfxObjectShell
* pDocSh
= pDocument
->GetDocumentShell();
1253 pDocSh
->Broadcast( ScPaintHint(
1254 ScRange(0,0,nTab
,MAXCOL
,MAXROW
,nTab
),
1260 void ScTable::UpdateTranspose( const ScRange
& rSource
, const ScAddress
& rDest
,
1261 ScDocument
* pUndoDoc
)
1263 for ( SCCOL i
=0; i
<=MAXCOL
; i
++ )
1264 aCol
[i
].UpdateTranspose( rSource
, rDest
, pUndoDoc
);
1267 void ScTable::UpdateGrow( const ScRange
& rArea
, SCCOL nGrowX
, SCROW nGrowY
)
1269 for ( SCCOL i
=0; i
<=MAXCOL
; i
++ )
1270 aCol
[i
].UpdateGrow( rArea
, nGrowX
, nGrowY
);
1273 void ScTable::UpdateInsertTab(SCTAB nTable
)
1275 if (nTab
>= nTable
) nTab
++;
1276 for (SCCOL i
=0; i
<= MAXCOL
; i
++) aCol
[i
].UpdateInsertTab(nTable
);
1278 if (IsStreamValid())
1279 SetStreamValid(FALSE
);
1282 //UNUSED2008-05 void ScTable::UpdateInsertTabOnlyCells(SCTAB nTable)
1284 //UNUSED2008-05 for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].UpdateInsertTabOnlyCells(nTable);
1287 void ScTable::UpdateDeleteTab( SCTAB nTable
, BOOL bIsMove
, ScTable
* pRefUndo
)
1289 if (nTab
> nTable
) nTab
--;
1293 for (i
=0; i
<= MAXCOL
; i
++) aCol
[i
].UpdateDeleteTab(nTable
, bIsMove
, &pRefUndo
->aCol
[i
]);
1295 for (i
=0; i
<= MAXCOL
; i
++) aCol
[i
].UpdateDeleteTab(nTable
, bIsMove
, NULL
);
1297 if (IsStreamValid())
1298 SetStreamValid(FALSE
);
1301 void ScTable::UpdateMoveTab( SCTAB nOldPos
, SCTAB nNewPos
, SCTAB nTabNo
,
1302 ScProgress
& rProgress
)
1305 for ( SCCOL i
=0; i
<= MAXCOL
; i
++ )
1307 aCol
[i
].UpdateMoveTab( nOldPos
, nNewPos
, nTabNo
);
1308 rProgress
.SetState( rProgress
.GetState() + aCol
[i
].GetCodeCount() );
1311 if (IsStreamValid())
1312 SetStreamValid(FALSE
);
1315 void ScTable::UpdateCompile( BOOL bForceIfNameInUse
)
1317 for (SCCOL i
=0; i
<= MAXCOL
; i
++)
1319 aCol
[i
].UpdateCompile( bForceIfNameInUse
);
1323 void ScTable::SetTabNo(SCTAB nNewTab
)
1326 for (SCCOL i
=0; i
<= MAXCOL
; i
++) aCol
[i
].SetTabNo(nNewTab
);
1329 BOOL
ScTable::IsRangeNameInUse(SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
1330 USHORT nIndex
) const
1332 BOOL bInUse
= FALSE
;
1333 for (SCCOL i
= nCol1
; !bInUse
&& (i
<= nCol2
) && (ValidCol(i
)); i
++)
1334 bInUse
= aCol
[i
].IsRangeNameInUse(nRow1
, nRow2
, nIndex
);
1338 void ScTable::FindRangeNamesInUse(SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
1339 std::set
<USHORT
>& rIndexes
) const
1341 for (SCCOL i
= nCol1
; i
<= nCol2
&& ValidCol(i
); i
++)
1342 aCol
[i
].FindRangeNamesInUse(nRow1
, nRow2
, rIndexes
);
1345 void ScTable::ReplaceRangeNamesInUse(SCCOL nCol1
, SCROW nRow1
,
1346 SCCOL nCol2
, SCROW nRow2
,
1347 const ScRangeData::IndexMap
& rMap
)
1349 for (SCCOL i
= nCol1
; i
<= nCol2
&& (ValidCol(i
)); i
++)
1351 aCol
[i
].ReplaceRangeNamesInUse( nRow1
, nRow2
, rMap
);
1355 void ScTable::ExtendPrintArea( OutputDevice
* pDev
,
1356 SCCOL
/* nStartCol */, SCROW nStartRow
, SCCOL
& rEndCol
, SCROW nEndRow
)
1358 if ( !pColFlags
|| !pRowFlags
)
1360 DBG_ERROR("keine ColInfo oder RowInfo in ExtendPrintArea");
1364 Point aPix1000
= pDev
->LogicToPixel( Point(1000,1000), MAP_TWIP
);
1365 double nPPTX
= aPix1000
.X() / 1000.0;
1366 double nPPTY
= aPix1000
.Y() / 1000.0;
1368 BOOL bEmpty
[MAXCOLCOUNT
];
1369 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1370 bEmpty
[i
] = ( aCol
[i
].GetCellCount() == 0 );
1373 SCCOL nPrintCol
= rEndCol
;
1374 for (SCROW nRow
= nStartRow
; nRow
<=nEndRow
; nRow
++)
1376 if (!RowHidden(nRow
))
1378 SCCOL nDataCol
= rEndCol
;
1379 while (nDataCol
> 0 && ( bEmpty
[nDataCol
] || !aCol
[nDataCol
].Search(nRow
,nIndex
) ) )
1381 if (!ColHidden(nDataCol
))
1383 ScBaseCell
* pCell
= aCol
[nDataCol
].GetCell(nRow
);
1386 CellType eType
= pCell
->GetCellType();
1387 if (eType
== CELLTYPE_STRING
|| eType
== CELLTYPE_EDIT
1388 || (eType
== CELLTYPE_FORMULA
&& !((ScFormulaCell
*)pCell
)->IsValue()) )
1390 BOOL bFormula
= FALSE
; //! uebergeben
1391 long nPixel
= pCell
->GetTextWidth();
1393 // Breite bereits im Idle-Handler berechnet?
1394 if ( TEXTWIDTH_DIRTY
== nPixel
)
1396 ScNeededSizeOptions aOptions
;
1397 aOptions
.bTotalSize
= TRUE
;
1398 aOptions
.bFormula
= bFormula
;
1399 aOptions
.bSkipMerged
= FALSE
;
1401 Fraction
aZoom(1,1);
1402 nPixel
= aCol
[nDataCol
].GetNeededSize( nRow
,
1403 pDev
,nPPTX
,nPPTY
,aZoom
,aZoom
,
1405 pCell
->SetTextWidth( (USHORT
)nPixel
);
1408 long nTwips
= (long) (nPixel
/ nPPTX
);
1409 long nDocW
= GetColWidth( nDataCol
);
1411 long nMissing
= nTwips
- nDocW
;
1414 // look at alignment
1416 const ScPatternAttr
* pPattern
= GetPattern( nDataCol
, nRow
);
1417 const SfxItemSet
* pCondSet
= NULL
;
1418 if ( ((const SfxUInt32Item
&)pPattern
->GetItem(ATTR_CONDITIONAL
)).GetValue() )
1419 pCondSet
= pDocument
->GetCondResult( nDataCol
, nRow
, nTab
);
1421 SvxCellHorJustify eHorJust
= (SvxCellHorJustify
)((const SvxHorJustifyItem
&)
1422 pPattern
->GetItem( ATTR_HOR_JUSTIFY
, pCondSet
)).GetValue();
1423 if ( eHorJust
== SVX_HOR_JUSTIFY_CENTER
)
1424 nMissing
/= 2; // distributed into both directions
1427 // STANDARD is LEFT (only text is handled here)
1428 BOOL bRight
= ( eHorJust
== SVX_HOR_JUSTIFY_RIGHT
);
1429 if ( IsLayoutRTL() )
1432 nMissing
= 0; // extended only to the left (logical)
1436 SCCOL nCol
= nDataCol
;
1437 while (nMissing
> 0 && nCol
< MAXCOL
)
1440 nMissing
-= GetColWidth( nCol
);
1449 rEndCol
= nPrintCol
;
1452 void ScTable::DoColResize( SCCOL nCol1
, SCCOL nCol2
, SCSIZE nAdd
)
1454 for (SCCOL nCol
=nCol1
; nCol
<=nCol2
; nCol
++)
1455 aCol
[nCol
].Resize(aCol
[nCol
].GetCellCount() + nAdd
);
1458 #define SET_PRINTRANGE( p1, p2 ) \
1464 (p1) = new ScRange( *(p2) ); \
1469 void ScTable::SetRepeatColRange( const ScRange
* pNew
)
1471 SET_PRINTRANGE( pRepeatColRange
, pNew
);
1474 void ScTable::SetRepeatRowRange( const ScRange
* pNew
)
1476 SET_PRINTRANGE( pRepeatRowRange
, pNew
);
1479 void ScTable::ClearPrintRanges()
1481 aPrintRanges
.clear();
1482 bPrintEntireSheet
= FALSE
;
1485 void ScTable::AddPrintRange( const ScRange
& rNew
)
1487 bPrintEntireSheet
= FALSE
;
1488 if( aPrintRanges
.size() < 0xFFFF )
1489 aPrintRanges
.push_back( rNew
);
1492 //UNUSED2009-05 void ScTable::SetPrintRange( const ScRange& rNew )
1494 //UNUSED2009-05 ClearPrintRanges();
1495 //UNUSED2009-05 AddPrintRange( rNew );
1498 void ScTable::SetPrintEntireSheet()
1500 if( !IsPrintEntireSheet() )
1503 bPrintEntireSheet
= TRUE
;
1507 const ScRange
* ScTable::GetPrintRange(USHORT nPos
) const
1509 return (nPos
< GetPrintRangeCount()) ? &aPrintRanges
[ nPos
] : NULL
;
1512 void ScTable::FillPrintSaver( ScPrintSaverTab
& rSaveTab
) const
1514 rSaveTab
.SetAreas( aPrintRanges
, bPrintEntireSheet
);
1515 rSaveTab
.SetRepeat( pRepeatColRange
, pRepeatRowRange
);
1518 void ScTable::RestorePrintRanges( const ScPrintSaverTab
& rSaveTab
)
1520 aPrintRanges
= rSaveTab
.GetPrintRanges();
1521 bPrintEntireSheet
= rSaveTab
.IsEntireSheet();
1522 SetRepeatColRange( rSaveTab
.GetRepeatCol() );
1523 SetRepeatRowRange( rSaveTab
.GetRepeatRow() );
1525 UpdatePageBreaks(NULL
);