xref: /trunk/main/sw/inc/swtable.hxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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