xref: /trunk/main/sw/inc/swtable.hxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 #ifndef _SWTABLE_HXX
28 #define _SWTABLE_HXX
29 #include <tools/mempool.hxx>
30 #include <tools/ref.hxx>
31 #include <svl/svarray.hxx>
32 #include <tblenum.hxx>
33 #include <swtypes.hxx>
34 #include <calbck.hxx>
35 #include <swrect.hxx>
36 #ifndef DBG_UTIL
37 #include <node.hxx>			// fuer StartNode->GetMyIndex
38 #else
39 class SwStartNode;
40 #include <memory>
41 #include <boost/noncopyable.hpp>
42 #endif
43 
44 class SwFmt;
45 class Color;
46 class SwFrmFmt;
47 class SwTableFmt;
48 class SwTableLineFmt;
49 class SwTableBoxFmt;
50 class SwHTMLTableLayout;
51 class SwTableLine;
52 class SwTableBox;
53 class SwTableNode;
54 class SwTabCols;
55 class SwDoc;
56 class SwSelBoxes;
57 class SwTblCalcPara;
58 class SwChartLines;
59 struct SwPosition;
60 class SwNodeIndex;
61 class SwNode;
62 class SfxPoolItem;
63 class SwUndoTblMerge;
64 class SwUndo;
65 class SwPaM;
66 class SwTableBox_Impl;
67 class SwUndoTblCpyTbl;
68 class SwBoxSelection;
69 struct SwSaveRowSpan;
70 struct Parm;
71 
72 #ifndef SW_DECL_SWSERVEROBJECT_DEFINED
73 #define SW_DECL_SWSERVEROBJECT_DEFINED
74 SV_DECL_REF( SwServerObject )
75 #endif
76 
77 SV_DECL_PTRARR_DEL(SwTableLines, SwTableLine*, 10, 20)
78 SV_DECL_PTRARR_DEL(SwTableBoxes, SwTableBox*, 25, 50)
79 
80 // speicher die Inhaltstragenden Box-Pointer zusaetzlich in einem
81 // sortierten Array (fuers rechnen in der Tabelle)
82 typedef SwTableBox* SwTableBoxPtr;
83 SV_DECL_PTRARR_SORT( SwTableSortBoxes, SwTableBoxPtr, 25, 50 )
84 typedef SwTableLine* SwTableLinePtr;
85 
86 class SW_DLLPUBLIC SwTable: public SwClient			 //Client vom FrmFmt
87 {
88 
89 
90 protected:
91 	SwTableLines aLines;
92 	SwTableSortBoxes aSortCntBoxes;
93 	SwServerObjectRef refObj;	// falls DataServer -> Pointer gesetzt
94 
95 	SwHTMLTableLayout *pHTMLLayout;
96 
97     // Usually, the table node of a SwTable can be accessed by getting a box
98     // out of aSortCntBoxes, which know their SwStartNode. But in some rare
99     // cases, we need to know the table node of a SwTable, before the table
100     // boxes have been build (SwTableNode::MakeCopy with tables in tables).
101     SwTableNode* pTableNode;
102 
103 //SOLL das fuer jede Tabelle einstellbar sein?
104 	TblChgMode	eTblChgMode;
105 
106 	sal_uInt16		nGrfsThatResize;	// Anzahl der Grfs, die beim HTML-Import
107 									// noch ein Resize der Tbl. anstossen
108     sal_uInt16      nRowsToRepeat;      // number of rows to repeat on every page
109 
110 	sal_Bool		bModifyLocked	:1;
111     sal_Bool        bNewModel       :1; // sal_False: old SubTableModel; sal_True: new RowSpanModel
112 #ifdef DBG_UTIL
113     bool bDontChangeModel;  // This is set by functions (like Merge()) to forbid a laet model change
114 #endif
115 
116 	sal_Bool IsModifyLocked(){ return bModifyLocked;}
117 
118    virtual void Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew );
119 
120 public:
121     enum SearchType
122     {
123         SEARCH_NONE, // Default: expand to rectangle
124         SEARCH_ROW,	// row selection
125         SEARCH_COL  // column selection
126     };
127 
128 	TYPEINFO();
129 
130 	// single argument ctors shall be explicit.
131 	explicit SwTable( SwTableFmt* );
132 	virtual ~SwTable();
133 
134 	// @@@ public copy ctor, but no copy assignment?
135 	SwTable( const SwTable& rTable );		// kein Copy der Lines !!
136 private:
137 	// @@@ public copy ctor, but no copy assignment?
138 	SwTable & operator= (const SwTable &);
139 	// no default ctor.
140 	SwTable();
141 	sal_Bool OldMerge( SwDoc*, const SwSelBoxes&, SwTableBox*, SwUndoTblMerge* );
142     sal_Bool OldSplitRow( SwDoc*, const SwSelBoxes&, sal_uInt16, sal_Bool );
143 	sal_Bool NewMerge( SwDoc*, const SwSelBoxes&, const SwSelBoxes& rMerged,
144                    SwTableBox*, SwUndoTblMerge* );
145     sal_Bool NewSplitRow( SwDoc*, const SwSelBoxes&, sal_uInt16, sal_Bool );
146     SwBoxSelection* CollectBoxSelection( const SwPaM& rPam ) const;
147     void InsertSpannedRow( SwDoc* pDoc, sal_uInt16 nIdx, sal_uInt16 nCnt );
148 	sal_Bool _InsertRow( SwDoc*, const SwSelBoxes&,	sal_uInt16 nCnt, sal_Bool bBehind );
149     sal_Bool NewInsertCol( SwDoc*, const SwSelBoxes& rBoxes, sal_uInt16 nCnt, sal_Bool );
150     void _FindSuperfluousRows( SwSelBoxes& rBoxes, SwTableLine*, SwTableLine* );
151     void AdjustWidths( const long nOld, const long nNew );
152     void NewSetTabCols( Parm &rP, const SwTabCols &rNew, const SwTabCols &rOld,
153 					    const SwTableBox *pStart, sal_Bool bCurRowOnly );
154 
155 public:
156 
157 	SwHTMLTableLayout *GetHTMLTableLayout() { return pHTMLLayout; }
158 	const SwHTMLTableLayout *GetHTMLTableLayout() const { return pHTMLLayout; }
159 	void SetHTMLTableLayout( SwHTMLTableLayout *p );	//Eigentumsuebergang!
160 
161 	sal_uInt16 IncGrfsThatResize() { return ++nGrfsThatResize; }
162 	sal_uInt16 DecGrfsThatResize() { return nGrfsThatResize ? --nGrfsThatResize : 0; }
163 
164 	void LockModify()	{ bModifyLocked = sal_True; }	//Muessen _immer_ paarig
165 	void UnlockModify()	{ bModifyLocked = sal_False;}	//benutzt werden!
166 
167 	void SetTableModel( sal_Bool bNew ){ bNewModel = bNew; }
168 	sal_Bool IsNewModel() const { return bNewModel; }
169 
170     sal_uInt16 GetRowsToRepeat() const { return Min( GetTabLines().Count(), nRowsToRepeat ); }
171     sal_uInt16 _GetRowsToRepeat() const { return nRowsToRepeat; }
172     void SetRowsToRepeat( sal_uInt16 nNumOfRows ) { nRowsToRepeat = nNumOfRows; }
173 
174     bool IsHeadline( const SwTableLine& rLine ) const;
175 
176 		  SwTableLines &GetTabLines() { return aLines; }
177 	const SwTableLines &GetTabLines() const { return aLines; }
178 
179 	SwFrmFmt* GetFrmFmt() 		{ return (SwFrmFmt*)GetRegisteredIn(); }
180 	SwFrmFmt* GetFrmFmt() const	{ return (SwFrmFmt*)GetRegisteredIn(); }
181 	SwTableFmt* GetTableFmt() const	{ return (SwTableFmt*)GetRegisteredIn(); }
182 
183 	void GetTabCols( SwTabCols &rToFill, const SwTableBox *pStart,
184 					 sal_Bool bHidden = sal_False, sal_Bool bCurRowOnly = sal_False ) const;
185     void SetTabCols( const SwTabCols &rNew, const SwTabCols &rOld,
186 					 const SwTableBox *pStart, sal_Bool bCurRowOnly );
187 
188 // The following functions are for new table model only...
189     void CreateSelection(  const SwPaM& rPam, SwSelBoxes& rBoxes,
190         const SearchType eSearchType, bool bProtect ) const;
191     void CreateSelection( const SwNode* pStart, const SwNode* pEnd,
192         SwSelBoxes& rBoxes, const SearchType eSearchType, bool bProtect ) const;
193     void ExpandSelection( SwSelBoxes& rBoxes ) const;
194     // When a table is splitted into two tables, the row spans which overlaps
195     // the split have to be corrected and stored for undo
196     // SwSavRowSpan is the structure needed by Undo to undo the split operation
197     // CleanUpRowSpan corrects the (top of the) second table and delviers the structure
198     // for Undo
199     SwSaveRowSpan* CleanUpTopRowSpan( sal_uInt16 nSplitLine );
200     // RestoreRowSpan is called by Undo to restore the old row span values
201     void RestoreRowSpan( const SwSaveRowSpan& );
202     // CleanUpBottomRowSpan corrects the overhanging row spans at the end of the first table
203     void CleanUpBottomRowSpan( sal_uInt16 nDelLines );
204 
205 
206 // The following functions are "pseudo-virtual", i.e. they are different for old and new table model
207 // It's not allowed to change the table model after the first call of one of these functions.
208 
209 	sal_Bool Merge( SwDoc* pDoc, const SwSelBoxes& rBoxes, const SwSelBoxes& rMerged,
210 				SwTableBox* pMergeBox, SwUndoTblMerge* pUndo = 0 )
211     {
212 #ifdef DBG_UTIL
213         bDontChangeModel = true;
214 #endif
215         return bNewModel ? NewMerge( pDoc, rBoxes, rMerged, pMergeBox, pUndo ) :
216                            OldMerge( pDoc, rBoxes, pMergeBox, pUndo );
217     }
218     sal_Bool SplitRow( SwDoc* pDoc, const SwSelBoxes& rBoxes, sal_uInt16 nCnt=1,
219                    sal_Bool bSameHeight = sal_False )
220     {
221 #ifdef DBG_UTIL
222         bDontChangeModel = true;
223 #endif
224         return bNewModel ? NewSplitRow( pDoc, rBoxes, nCnt, bSameHeight ) :
225                            OldSplitRow( pDoc, rBoxes, nCnt, bSameHeight );
226     }
227     bool PrepareMerge( const SwPaM& rPam, SwSelBoxes& rBoxes,
228         SwSelBoxes& rMerged, SwTableBox** ppMergeBox, SwUndoTblMerge* pUndo );
229     void ExpandColumnSelection( SwSelBoxes& rBoxes, long &rMin, long &rMax ) const;
230     void PrepareDeleteCol( long nMin, long nMax );
231 
232     sal_Bool InsertCol( SwDoc*, const SwSelBoxes& rBoxes,
233 					sal_uInt16 nCnt = 1, sal_Bool bBehind = sal_True );
234 	sal_Bool InsertRow( SwDoc*, const SwSelBoxes& rBoxes,
235 					sal_uInt16 nCnt = 1, sal_Bool bBehind = sal_True );
236 	sal_Bool AppendRow( SwDoc* pDoc, sal_uInt16 nCnt = 1 );
237     void PrepareDelBoxes( const SwSelBoxes& rBoxes );
238 	sal_Bool DeleteSel( SwDoc*, const SwSelBoxes& rBoxes, const SwSelBoxes* pMerged,
239         SwUndo* pUndo, const sal_Bool bDelMakeFrms, const sal_Bool bCorrBorder );
240 	sal_Bool SplitCol( SwDoc* pDoc, const SwSelBoxes& rBoxes, sal_uInt16 nCnt=1 );
241     sal_Bool Merge( const SwSelBoxes& rBoxes,
242 				SwTableBox* pMergeBox, SwUndoTblMerge* = 0 );
243 
244     void FindSuperfluousRows( SwSelBoxes& rBoxes )
245         { _FindSuperfluousRows( rBoxes, 0, 0 ); }
246     void CheckRowSpan( SwTableLinePtr &rpLine, bool bUp ) const;
247 
248 		  SwTableSortBoxes& GetTabSortBoxes() 		{ return aSortCntBoxes; }
249 	const SwTableSortBoxes& GetTabSortBoxes() const { return aSortCntBoxes; }
250 
251 		// lese die 1. Nummer und loesche sie aus dem String
252 		// (wird von GetTblBox und SwTblFld benutzt)
253     // --> OD 2007-08-03 #i80314#
254     // add 3rd parameter in order to control validation check on <rStr>
255     static sal_uInt16 _GetBoxNum( String& rStr,
256                               sal_Bool bFirst = sal_False,
257                               const bool bPerformValidCheck = false );
258     // <--
259 		// suche die Inhaltstragende Box mit dem Namen
260     // --> OD 2007-08-03 #i80314#
261     // add 2nd parameter in order to control validation check in called method
262     // <_GetBoxNum(..)>
263     const SwTableBox* GetTblBox( const String& rName,
264                                  const bool bPerformValidCheck = false ) const;
265     // <--
266 		// kopiere die selektierten Boxen in ein anderes Dokument.
267 	sal_Bool MakeCopy( SwDoc*, const SwPosition&, const SwSelBoxes&,
268 					sal_Bool bCpyNds = sal_True, sal_Bool bCpyName = sal_False ) const;
269 		// kopiere die Tabelle in diese. (die Logik steht im TBLRWCL.CXX)
270 	sal_Bool InsTable( const SwTable& rCpyTbl, const SwNodeIndex&,
271 					SwUndoTblCpyTbl* pUndo = 0 );
272 	sal_Bool InsTable( const SwTable& rCpyTbl, const SwSelBoxes&,
273 					SwUndoTblCpyTbl* pUndo = 0 );
274 	sal_Bool InsNewTable( const SwTable& rCpyTbl, const SwSelBoxes&,
275 					  SwUndoTblCpyTbl* pUndo );
276 		// kopiere die Headline (mit Inhalt!) der Tabelle in eine andere
277 	sal_Bool CopyHeadlineIntoTable( SwTableNode& rTblNd );
278 
279 		// erfrage die Box, dessen Start-Index auf nBoxStt steht
280 		  SwTableBox* GetTblBox( sal_uLong nSttIdx );
281 	const SwTableBox* GetTblBox( sal_uLong nSttIdx ) const
282 						{	return ((SwTable*)this)->GetTblBox( nSttIdx );	}
283 
284 	// returnt sal_True wenn sich in der Tabelle Verschachtelungen befinden
285 	sal_Bool IsTblComplex() const;
286 
287 	//returnt sal_True wenn die Tabelle oder Selektion ausgeglichen ist
288 	sal_Bool IsTblComplexForChart( const String& rSel,
289 								SwChartLines* pGetCLines = 0  ) const;
290 
291 	// suche alle Inhaltstragenden-Boxen der Grundline in der diese Box
292 	// steht. rBoxes auch als Return-Wert, um es gleich weiter zu benutzen
293 	//JP 31.01.97: bToTop = sal_True -> hoch bis zur Grundline,
294 	//						sal_False-> sonst nur die Line der Box
295 	SwSelBoxes& SelLineFromBox( const SwTableBox* pBox,
296 							SwSelBoxes& rBoxes, sal_Bool bToTop = sal_True ) const;
297 		// erfrage vom Client Informationen
298 	virtual sal_Bool GetInfo( SfxPoolItem& ) const;
299 
300 		// suche im Format nach der angemeldeten Tabelle
301     static SwTable * FindTable( SwFrmFmt const*const pFmt );
302 
303 		// Struktur ein wenig aufraeumen
304 	void GCLines();
305 
306     // returns the table node via aSortCntBoxes or pTableNode
307 	SwTableNode* GetTableNode() const;
308     void SetTableNode( SwTableNode* pNode ) { pTableNode = pNode; }
309 
310 		// Daten Server-Methoden
311 	void SetRefObject( SwServerObject* );
312     const SwServerObject* GetObject() const     {  return &refObj; }
313           SwServerObject* GetObject()           {  return &refObj; }
314 
315 	//Daten fuer das Chart fuellen.
316     void UpdateCharts() const;
317 
318 	TblChgMode GetTblChgMode() const 		{ return eTblChgMode; }
319 	void SetTblChgMode( TblChgMode eMode )	{ eTblChgMode = eMode; }
320 
321 	sal_Bool SetColWidth( SwTableBox& rAktBox, sal_uInt16 eType,
322 						SwTwips nAbsDiff, SwTwips nRelDiff, SwUndo** ppUndo );
323 	sal_Bool SetRowHeight( SwTableBox& rAktBox, sal_uInt16 eType,
324 						SwTwips nAbsDiff, SwTwips nRelDiff, SwUndo** ppUndo );
325     void RegisterToFormat( SwFmt& rFmt );
326 #ifdef DBG_UTIL
327     void CheckConsistency() const;
328 #endif
329 };
330 
331 class SW_DLLPUBLIC SwTableLine: public SwClient		// Client vom FrmFmt
332 {
333 	SwTableBoxes aBoxes;
334 	SwTableBox *pUpper;
335 
336 public:
337 	TYPEINFO();
338 
339 	SwTableLine() : pUpper(0) {}
340 
341 	SwTableLine( SwTableLineFmt*, sal_uInt16 nBoxes, SwTableBox *pUp );
342 	virtual ~SwTableLine();
343 
344 		  SwTableBoxes &GetTabBoxes() { return aBoxes; }
345 	const SwTableBoxes &GetTabBoxes() const { return aBoxes; }
346 
347 		  SwTableBox *GetUpper() { return pUpper; }
348 	const SwTableBox *GetUpper() const { return pUpper; }
349 	void SetUpper( SwTableBox *pNew ) { pUpper = pNew; }
350 
351 
352 	SwFrmFmt* GetFrmFmt()		{ return (SwFrmFmt*)GetRegisteredIn(); }
353 	SwFrmFmt* GetFrmFmt() const	{ return (SwFrmFmt*)GetRegisteredIn(); }
354 
355 	//Macht ein eingenes FrmFmt wenn noch mehr Lines von ihm abhaengen.
356 	SwFrmFmt* ClaimFrmFmt();
357 	void ChgFrmFmt( SwTableLineFmt* pNewFmt );
358 
359 	// suche nach der naechsten/vorherigen Box mit Inhalt
360 	SwTableBox* FindNextBox( const SwTable&, const SwTableBox* =0,
361 							sal_Bool bOvrTblLns=sal_True ) const;
362 	SwTableBox* FindPreviousBox( const SwTable&, const SwTableBox* =0,
363 							sal_Bool bOvrTblLns=sal_True ) const;
364 
365     SwTwips GetTableLineHeight( bool& bLayoutAvailable ) const;
366 
367     bool hasSoftPageBreak() const;
368     void RegisterToFormat( SwFmt& rFmt );
369 };
370 
371 class SW_DLLPUBLIC SwTableBox: public SwClient		//Client vom FrmFmt
372 {
373 	friend class SwNodes;			// um den Index umzusetzen !
374 	friend void DelBoxNode(SwTableSortBoxes&);  // um den StartNode* zu loeschen !
375 	friend class SwXMLTableContext;
376 
377 	//nicht (mehr) implementiert.
378 	SwTableBox( const SwTableBox & );
379 	SwTableBox &operator=( const SwTableBox &);	//gibts nicht.
380 
381 	SwTableLines aLines;
382 	const SwStartNode * pSttNd;
383 	SwTableLine *pUpper;
384 	SwTableBox_Impl* pImpl;
385 
386 	// falls das Format schon Formeln/Values enthaelt, muss ein neues
387 	// fuer die neue Box erzeugt werden.
388 	SwTableBoxFmt* CheckBoxFmt( SwTableBoxFmt* );
389 
390 public:
391 	TYPEINFO();
392 
393 	SwTableBox() : pSttNd(0), pUpper(0), pImpl(0) {}
394 
395 	SwTableBox( SwTableBoxFmt*, sal_uInt16 nLines, SwTableLine *pUp = 0 );
396 	SwTableBox( SwTableBoxFmt*, const SwStartNode&, SwTableLine *pUp = 0 );
397 	SwTableBox( SwTableBoxFmt*, const SwNodeIndex&, SwTableLine *pUp = 0 );
398 	virtual ~SwTableBox();
399 
400 		  SwTableLines &GetTabLines() { return aLines; }
401 	const SwTableLines &GetTabLines() const { return aLines; }
402 
403 		  SwTableLine *GetUpper() { return pUpper; }
404 	const SwTableLine *GetUpper() const { return pUpper; }
405 	void SetUpper( SwTableLine *pNew ) { pUpper = pNew; }
406 
407 	SwFrmFmt* GetFrmFmt()		{ return (SwFrmFmt*)GetRegisteredIn(); }
408 	SwFrmFmt* GetFrmFmt() const	{ return (SwFrmFmt*)GetRegisteredIn(); }
409 
410 	//Macht ein eingenes FrmFmt wenn noch mehr Boxen von ihm abhaengen.
411 	SwFrmFmt* ClaimFrmFmt();
412 	void ChgFrmFmt( SwTableBoxFmt *pNewFmt );
413 
414 	const SwStartNode *GetSttNd() const { return pSttNd; }
415 	sal_uLong GetSttIdx() const
416 #ifndef DBG_UTIL
417 		{ return pSttNd ? pSttNd->GetIndex() : 0; }
418 #else
419 		;
420 #endif
421 
422 	// suche nach der naechsten/vorherigen Box mit Inhalt
423 	SwTableBox* FindNextBox( const SwTable&, const SwTableBox* =0,
424 							sal_Bool bOvrTblLns=sal_True ) const;
425 	SwTableBox* FindPreviousBox( const SwTable&, const SwTableBox* =0,
426 							sal_Bool bOvrTblLns=sal_True ) const;
427 	// gebe den Namen dieser Box zurueck. Dieser wird dynamisch bestimmt
428 	// und ergibt sich aus der Position in den Lines/Boxen/Tabelle
429 	String GetName() const;
430 	// gebe den "Wert" der Box zurueck (fuers rechnen in der Tabelle)
431 	double GetValue( SwTblCalcPara& rPara ) const;
432 
433 	sal_Bool IsInHeadline( const SwTable* pTbl = 0 ) const;
434 
435 	// enthaelt die Box Inhalt, der als Nummer formatiert werden kann?
436 	sal_Bool HasNumCntnt( double& rNum, sal_uInt32& rFmtIndex,
437 					sal_Bool& rIsEmptyTxtNd ) const;
438 	sal_uLong IsValidNumTxtNd( sal_Bool bCheckAttr = sal_True ) const;
439 	// teste ob der BoxInhalt mit der Nummer uebereinstimmt, wenn eine
440 	// Tabellenformel gesetzt ist. (fuers Redo des Change vom NumFormat!)
441 	sal_Bool IsNumberChanged() const;
442 
443 	// ist das eine FormelBox oder eine Box mit numerischen Inhalt (AutoSum)
444 	// Was es ist, besagt der ReturnWert - die WhichId des Attributes
445 	// Leere Boxen haben den ReturnWert USHRT_MAX !!
446 	sal_uInt16 IsFormulaOrValueBox() const;
447 
448 	// Loading of a document requires an actualisation of cells with values
449 	void ActualiseValueBox();
450 
451 	DECL_FIXEDMEMPOOL_NEWDEL(SwTableBox)
452 
453 	// zugriff auf interne Daten - z.Z. benutzt fuer den NumFormatter
454 	inline const Color* GetSaveUserColor()	const;
455 	inline const Color* GetSaveNumFmtColor() const;
456 	inline void SetSaveUserColor(const Color* p );
457 	inline void SetSaveNumFmtColor( const Color* p );
458 
459     long getRowSpan() const;
460     void setRowSpan( long nNewRowSpan );
461     bool getDummyFlag() const;
462     void setDummyFlag( bool bDummy );
463 
464     SwTableBox& FindStartOfRowSpan( const SwTable&, sal_uInt16 nMaxStep = USHRT_MAX );
465     const SwTableBox& FindStartOfRowSpan( const SwTable& rTable,
466         sal_uInt16 nMaxStep = USHRT_MAX ) const
467         { return const_cast<SwTableBox*>(this)->FindStartOfRowSpan( rTable, nMaxStep ); }
468 
469     SwTableBox& FindEndOfRowSpan( const SwTable&, sal_uInt16 nMaxStep = USHRT_MAX );
470     const SwTableBox& FindEndOfRowSpan( const SwTable& rTable,
471         sal_uInt16 nMaxStep = USHRT_MAX ) const
472         { return const_cast<SwTableBox*>(this)->FindEndOfRowSpan( rTable, nMaxStep ); }
473     void RegisterToFormat( SwFmt& rFmt ) ;
474     void ForgetFrmFmt();
475 };
476 
477 class SwCellFrm;
478 class SW_DLLPUBLIC SwTableCellInfo : public ::boost::noncopyable
479 {
480     struct Impl;
481     ::std::auto_ptr<Impl> m_pImpl;
482 
483     const SwCellFrm * getCellFrm() const ;
484 
485 public:
486     SwTableCellInfo(const SwTable * pTable);
487     ~SwTableCellInfo();
488 
489     bool getNext();
490     SwRect getRect() const;
491     const SwTableBox * getTableBox() const;
492 };
493 
494 #endif	//_SWTABLE_HXX
495