1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
29 #include <tools/mempool.hxx>
30 #ifndef _TOOLS_REF_HXX
31 #include <tools/ref.hxx>
33 #include <svl/svarray.hxx>
34 #include <tblenum.hxx>
35 #include <swtypes.hxx>
39 #include <node.hxx> // fuer StartNode->GetMyIndex
43 #include <boost/noncopyable.hpp>
51 class SwHTMLTableLayout
;
67 class SwTableBox_Impl
;
68 class SwUndoTblCpyTbl
;
73 #ifndef SW_DECL_SWSERVEROBJECT_DEFINED
74 #define SW_DECL_SWSERVEROBJECT_DEFINED
75 SV_DECL_REF( SwServerObject
)
78 SV_DECL_PTRARR_DEL(SwTableLines
, SwTableLine
*, 10, 20)
79 SV_DECL_PTRARR_DEL(SwTableBoxes
, SwTableBox
*, 25, 50)
81 // speicher die Inhaltstragenden Box-Pointer zusaetzlich in einem
82 // sortierten Array (fuers rechnen in der Tabelle)
83 typedef SwTableBox
* SwTableBoxPtr
;
84 SV_DECL_PTRARR_SORT( SwTableSortBoxes
, SwTableBoxPtr
, 25, 50 )
85 typedef SwTableLine
* SwTableLinePtr
;
87 class SW_DLLPUBLIC SwTable
: public SwClient
//Client vom FrmFmt
89 using SwClient::IsModifyLocked
;
93 SwTableSortBoxes aSortCntBoxes
;
94 SwServerObjectRef refObj
; // falls DataServer -> Pointer gesetzt
96 SwHTMLTableLayout
*pHTMLLayout
;
98 // Usually, the table node of a SwTable can be accessed by getting a box
99 // out of aSortCntBoxes, which know their SwStartNode. But in some rare
100 // cases, we need to know the table node of a SwTable, before the table
101 // boxes have been build (SwTableNode::MakeCopy with tables in tables).
102 SwTableNode
* pTableNode
;
104 //SOLL das fuer jede Tabelle einstellbar sein?
105 TblChgMode eTblChgMode
;
107 USHORT nGrfsThatResize
; // Anzahl der Grfs, die beim HTML-Import
108 // noch ein Resize der Tbl. anstossen
109 USHORT nRowsToRepeat
; // number of rows to repeat on every page
111 BOOL bModifyLocked
:1;
112 BOOL bNewModel
:1; // FALSE: old SubTableModel; TRUE: new RowSpanModel
114 bool bDontChangeModel
; // This is set by functions (like Merge()) to forbid a laet model change
117 BOOL
IsModifyLocked(){ return bModifyLocked
;}
122 SEARCH_NONE
, // Default: expand to rectangle
123 SEARCH_ROW
, // row selection
124 SEARCH_COL
// column selection
129 // single argument ctors shall be explicit.
130 explicit SwTable( SwTableFmt
* );
133 // @@@ public copy ctor, but no copy assignment?
134 SwTable( const SwTable
& rTable
); // kein Copy der Lines !!
136 // @@@ public copy ctor, but no copy assignment?
137 SwTable
& operator= (const SwTable
&);
140 BOOL
OldMerge( SwDoc
*, const SwSelBoxes
&, SwTableBox
*, SwUndoTblMerge
* );
141 BOOL
OldSplitRow( SwDoc
*, const SwSelBoxes
&, USHORT
, BOOL
);
142 BOOL
NewMerge( SwDoc
*, const SwSelBoxes
&, const SwSelBoxes
& rMerged
,
143 SwTableBox
*, SwUndoTblMerge
* );
144 BOOL
NewSplitRow( SwDoc
*, const SwSelBoxes
&, USHORT
, BOOL
);
145 SwBoxSelection
* CollectBoxSelection( const SwPaM
& rPam
) const;
146 void InsertSpannedRow( SwDoc
* pDoc
, USHORT nIdx
, USHORT nCnt
);
147 BOOL
_InsertRow( SwDoc
*, const SwSelBoxes
&, USHORT nCnt
, BOOL bBehind
);
148 BOOL
NewInsertCol( SwDoc
*, const SwSelBoxes
& rBoxes
, USHORT nCnt
, BOOL
);
149 void _FindSuperfluousRows( SwSelBoxes
& rBoxes
, SwTableLine
*, SwTableLine
* );
150 void AdjustWidths( const long nOld
, const long nNew
);
151 void NewSetTabCols( Parm
&rP
, const SwTabCols
&rNew
, const SwTabCols
&rOld
,
152 const SwTableBox
*pStart
, BOOL bCurRowOnly
);
156 SwHTMLTableLayout
*GetHTMLTableLayout() { return pHTMLLayout
; }
157 const SwHTMLTableLayout
*GetHTMLTableLayout() const { return pHTMLLayout
; }
158 void SetHTMLTableLayout( SwHTMLTableLayout
*p
); //Eigentumsuebergang!
160 USHORT
IncGrfsThatResize() { return ++nGrfsThatResize
; }
161 USHORT
DecGrfsThatResize() { return nGrfsThatResize
? --nGrfsThatResize
: 0; }
163 void LockModify() { bModifyLocked
= TRUE
; } //Muessen _immer_ paarig
164 void UnlockModify() { bModifyLocked
= FALSE
;} //benutzt werden!
166 void SetTableModel( BOOL bNew
){ bNewModel
= bNew
; }
167 BOOL
IsNewModel() const { return bNewModel
; }
169 USHORT
GetRowsToRepeat() const { return Min( GetTabLines().Count(), nRowsToRepeat
); }
170 USHORT
_GetRowsToRepeat() const { return nRowsToRepeat
; }
171 void SetRowsToRepeat( USHORT nNumOfRows
) { nRowsToRepeat
= nNumOfRows
; }
173 bool IsHeadline( const SwTableLine
& rLine
) const;
175 SwTableLines
&GetTabLines() { return aLines
; }
176 const SwTableLines
&GetTabLines() const { return aLines
; }
178 SwFrmFmt
* GetFrmFmt() { return (SwFrmFmt
*)pRegisteredIn
; }
179 SwFrmFmt
* GetFrmFmt() const { return (SwFrmFmt
*)pRegisteredIn
; }
181 virtual void Modify( SfxPoolItem
* pOld
, SfxPoolItem
* pNew
);
183 void GetTabCols( SwTabCols
&rToFill
, const SwTableBox
*pStart
,
184 BOOL bHidden
= FALSE
, BOOL bCurRowOnly
= FALSE
) const;
185 void SetTabCols( const SwTabCols
&rNew
, const SwTabCols
&rOld
,
186 const SwTableBox
*pStart
, BOOL bCurRowOnly
);
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
199 SwSaveRowSpan
* CleanUpTopRowSpan( USHORT 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( USHORT nDelLines
);
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.
209 BOOL
Merge( SwDoc
* pDoc
, const SwSelBoxes
& rBoxes
, const SwSelBoxes
& rMerged
,
210 SwTableBox
* pMergeBox
, SwUndoTblMerge
* pUndo
= 0 )
213 bDontChangeModel
= true;
215 return bNewModel
? NewMerge( pDoc
, rBoxes
, rMerged
, pMergeBox
, pUndo
) :
216 OldMerge( pDoc
, rBoxes
, pMergeBox
, pUndo
);
218 BOOL
SplitRow( SwDoc
* pDoc
, const SwSelBoxes
& rBoxes
, USHORT nCnt
=1,
219 BOOL bSameHeight
= FALSE
)
222 bDontChangeModel
= true;
224 return bNewModel
? NewSplitRow( pDoc
, rBoxes
, nCnt
, bSameHeight
) :
225 OldSplitRow( pDoc
, rBoxes
, nCnt
, bSameHeight
);
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
);
232 BOOL
InsertCol( SwDoc
*, const SwSelBoxes
& rBoxes
,
233 USHORT nCnt
= 1, BOOL bBehind
= TRUE
);
234 BOOL
InsertRow( SwDoc
*, const SwSelBoxes
& rBoxes
,
235 USHORT nCnt
= 1, BOOL bBehind
= TRUE
);
236 BOOL
AppendRow( SwDoc
* pDoc
, USHORT nCnt
= 1 );
237 void PrepareDelBoxes( const SwSelBoxes
& rBoxes
);
238 BOOL
DeleteSel( SwDoc
*, const SwSelBoxes
& rBoxes
, const SwSelBoxes
* pMerged
,
239 SwUndo
* pUndo
, const BOOL bDelMakeFrms
, const BOOL bCorrBorder
);
240 BOOL
SplitCol( SwDoc
* pDoc
, const SwSelBoxes
& rBoxes
, USHORT nCnt
=1 );
241 BOOL
Merge( const SwSelBoxes
& rBoxes
,
242 SwTableBox
* pMergeBox
, SwUndoTblMerge
* = 0 );
244 void FindSuperfluousRows( SwSelBoxes
& rBoxes
)
245 { _FindSuperfluousRows( rBoxes
, 0, 0 ); }
246 void CheckRowSpan( SwTableLinePtr
&rpLine
, bool bUp
) const;
248 SwTableSortBoxes
& GetTabSortBoxes() { return aSortCntBoxes
; }
249 const SwTableSortBoxes
& GetTabSortBoxes() const { return aSortCntBoxes
; }
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 USHORT
_GetBoxNum( String
& rStr
,
257 const bool bPerformValidCheck
= false );
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
263 const SwTableBox
* GetTblBox( const String
& rName
,
264 const bool bPerformValidCheck
= false ) const;
266 // kopiere die selektierten Boxen in ein anderes Dokument.
267 BOOL
MakeCopy( SwDoc
*, const SwPosition
&, const SwSelBoxes
&,
268 BOOL bCpyNds
= TRUE
, BOOL bCpyName
= FALSE
) const;
269 // kopiere die Tabelle in diese. (die Logik steht im TBLRWCL.CXX)
270 BOOL
InsTable( const SwTable
& rCpyTbl
, const SwNodeIndex
&,
271 SwUndoTblCpyTbl
* pUndo
= 0 );
272 BOOL
InsTable( const SwTable
& rCpyTbl
, const SwSelBoxes
&,
273 SwUndoTblCpyTbl
* pUndo
= 0 );
274 BOOL
InsNewTable( const SwTable
& rCpyTbl
, const SwSelBoxes
&,
275 SwUndoTblCpyTbl
* pUndo
);
276 // kopiere die Headline (mit Inhalt!) der Tabelle in eine andere
277 BOOL
CopyHeadlineIntoTable( SwTableNode
& rTblNd
);
279 // erfrage die Box, dessen Start-Index auf nBoxStt steht
280 SwTableBox
* GetTblBox( ULONG nSttIdx
);
281 const SwTableBox
* GetTblBox( ULONG nSttIdx
) const
282 { return ((SwTable
*)this)->GetTblBox( nSttIdx
); }
284 // returnt TRUE wenn sich in der Tabelle Verschachtelungen befinden
285 BOOL
IsTblComplex() const;
287 //returnt TRUE wenn die Tabelle oder Selektion ausgeglichen ist
288 BOOL
IsTblComplexForChart( const String
& rSel
,
289 SwChartLines
* pGetCLines
= 0 ) const;
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 = TRUE -> hoch bis zur Grundline,
294 // FALSE-> sonst nur die Line der Box
295 SwSelBoxes
& SelLineFromBox( const SwTableBox
* pBox
,
296 SwSelBoxes
& rBoxes
, BOOL bToTop
= TRUE
) const;
297 // erfrage vom Client Informationen
298 virtual BOOL
GetInfo( SfxPoolItem
& ) const;
300 // suche im Format nach der angemeldeten Tabelle
301 static SwTable
* FindTable( SwFrmFmt
const*const pFmt
);
303 // Struktur ein wenig aufraeumen
306 // returns the table node via aSortCntBoxes or pTableNode
307 SwTableNode
* GetTableNode() const;
308 void SetTableNode( SwTableNode
* pNode
) { pTableNode
= pNode
; }
310 // Daten Server-Methoden
311 void SetRefObject( SwServerObject
* );
312 const SwServerObject
* GetObject() const { return &refObj
; }
313 SwServerObject
* GetObject() { return &refObj
; }
315 //Daten fuer das Chart fuellen.
316 void UpdateCharts() const;
318 TblChgMode
GetTblChgMode() const { return eTblChgMode
; }
319 void SetTblChgMode( TblChgMode eMode
) { eTblChgMode
= eMode
; }
321 BOOL
SetColWidth( SwTableBox
& rAktBox
, USHORT eType
,
322 SwTwips nAbsDiff
, SwTwips nRelDiff
, SwUndo
** ppUndo
);
323 BOOL
SetRowHeight( SwTableBox
& rAktBox
, USHORT eType
,
324 SwTwips nAbsDiff
, SwTwips nRelDiff
, SwUndo
** ppUndo
);
326 void CheckConsistency() const;
330 class SW_DLLPUBLIC SwTableLine
: public SwClient
// Client vom FrmFmt
338 SwTableLine() : pUpper(0) {}
340 SwTableLine( SwTableLineFmt
*, USHORT nBoxes
, SwTableBox
*pUp
);
341 virtual ~SwTableLine();
343 SwTableBoxes
&GetTabBoxes() { return aBoxes
; }
344 const SwTableBoxes
&GetTabBoxes() const { return aBoxes
; }
346 SwTableBox
*GetUpper() { return pUpper
; }
347 const SwTableBox
*GetUpper() const { return pUpper
; }
348 void SetUpper( SwTableBox
*pNew
) { pUpper
= pNew
; }
351 SwFrmFmt
* GetFrmFmt() { return (SwFrmFmt
*)pRegisteredIn
; }
352 SwFrmFmt
* GetFrmFmt() const { return (SwFrmFmt
*)pRegisteredIn
; }
354 //Macht ein eingenes FrmFmt wenn noch mehr Lines von ihm abhaengen.
355 SwFrmFmt
* ClaimFrmFmt();
356 void ChgFrmFmt( SwTableLineFmt
* pNewFmt
);
358 // suche nach der naechsten/vorherigen Box mit Inhalt
359 SwTableBox
* FindNextBox( const SwTable
&, const SwTableBox
* =0,
360 BOOL bOvrTblLns
=TRUE
) const;
361 SwTableBox
* FindPreviousBox( const SwTable
&, const SwTableBox
* =0,
362 BOOL bOvrTblLns
=TRUE
) const;
364 SwTwips
GetTableLineHeight( bool& bLayoutAvailable
) const;
366 bool hasSoftPageBreak() const;
369 class SW_DLLPUBLIC SwTableBox
: public SwClient
//Client vom FrmFmt
371 friend class SwNodes
; // um den Index umzusetzen !
372 friend void DelBoxNode(SwTableSortBoxes
&); // um den StartNode* zu loeschen !
373 friend class SwXMLTableContext
;
375 //nicht (mehr) implementiert.
376 SwTableBox( const SwTableBox
& );
377 SwTableBox
&operator=( const SwTableBox
&); //gibts nicht.
380 const SwStartNode
* pSttNd
;
382 SwTableBox_Impl
* pImpl
;
384 // falls das Format schon Formeln/Values enthaelt, muss ein neues
385 // fuer die neue Box erzeugt werden.
386 SwTableBoxFmt
* CheckBoxFmt( SwTableBoxFmt
* );
391 SwTableBox() : pSttNd(0), pUpper(0), pImpl(0) {}
393 SwTableBox( SwTableBoxFmt
*, USHORT nLines
, SwTableLine
*pUp
= 0 );
394 SwTableBox( SwTableBoxFmt
*, const SwStartNode
&, SwTableLine
*pUp
= 0 );
395 SwTableBox( SwTableBoxFmt
*, const SwNodeIndex
&, SwTableLine
*pUp
= 0 );
396 virtual ~SwTableBox();
398 SwTableLines
&GetTabLines() { return aLines
; }
399 const SwTableLines
&GetTabLines() const { return aLines
; }
401 SwTableLine
*GetUpper() { return pUpper
; }
402 const SwTableLine
*GetUpper() const { return pUpper
; }
403 void SetUpper( SwTableLine
*pNew
) { pUpper
= pNew
; }
405 SwFrmFmt
* GetFrmFmt() { return (SwFrmFmt
*)pRegisteredIn
; }
406 SwFrmFmt
* GetFrmFmt() const { return (SwFrmFmt
*)pRegisteredIn
; }
408 //Macht ein eingenes FrmFmt wenn noch mehr Boxen von ihm abhaengen.
409 SwFrmFmt
* ClaimFrmFmt();
410 void ChgFrmFmt( SwTableBoxFmt
*pNewFmt
);
412 const SwStartNode
*GetSttNd() const { return pSttNd
; }
413 ULONG
GetSttIdx() const
415 { return pSttNd
? pSttNd
->GetIndex() : 0; }
420 // suche nach der naechsten/vorherigen Box mit Inhalt
421 SwTableBox
* FindNextBox( const SwTable
&, const SwTableBox
* =0,
422 BOOL bOvrTblLns
=TRUE
) const;
423 SwTableBox
* FindPreviousBox( const SwTable
&, const SwTableBox
* =0,
424 BOOL bOvrTblLns
=TRUE
) const;
425 // gebe den Namen dieser Box zurueck. Dieser wird dynamisch bestimmt
426 // und ergibt sich aus der Position in den Lines/Boxen/Tabelle
427 String
GetName() const;
428 // gebe den "Wert" der Box zurueck (fuers rechnen in der Tabelle)
429 double GetValue( SwTblCalcPara
& rPara
) const;
431 BOOL
IsInHeadline( const SwTable
* pTbl
= 0 ) const;
433 // enthaelt die Box Inhalt, der als Nummer formatiert werden kann?
434 BOOL
HasNumCntnt( double& rNum
, sal_uInt32
& rFmtIndex
,
435 BOOL
& rIsEmptyTxtNd
) const;
436 ULONG
IsValidNumTxtNd( BOOL bCheckAttr
= TRUE
) const;
437 // teste ob der BoxInhalt mit der Nummer uebereinstimmt, wenn eine
438 // Tabellenformel gesetzt ist. (fuers Redo des Change vom NumFormat!)
439 BOOL
IsNumberChanged() const;
441 // ist das eine FormelBox oder eine Box mit numerischen Inhalt (AutoSum)
442 // Was es ist, besagt der ReturnWert - die WhichId des Attributes
443 // Leere Boxen haben den ReturnWert USHRT_MAX !!
444 USHORT
IsFormulaOrValueBox() const;
446 // Loading of a document requires an actualisation of cells with values
447 void ActualiseValueBox();
449 DECL_FIXEDMEMPOOL_NEWDEL(SwTableBox
)
451 // zugriff auf interne Daten - z.Z. benutzt fuer den NumFormatter
452 inline const Color
* GetSaveUserColor() const;
453 inline const Color
* GetSaveNumFmtColor() const;
454 inline void SetSaveUserColor(const Color
* p
);
455 inline void SetSaveNumFmtColor( const Color
* p
);
457 long getRowSpan() const;
458 void setRowSpan( long nNewRowSpan
);
459 bool getDummyFlag() const;
460 void setDummyFlag( bool bDummy
);
462 SwTableBox
& FindStartOfRowSpan( const SwTable
&, USHORT nMaxStep
= USHRT_MAX
);
463 const SwTableBox
& FindStartOfRowSpan( const SwTable
& rTable
,
464 USHORT nMaxStep
= USHRT_MAX
) const
465 { return const_cast<SwTableBox
*>(this)->FindStartOfRowSpan( rTable
, nMaxStep
); }
467 SwTableBox
& FindEndOfRowSpan( const SwTable
&, USHORT nMaxStep
= USHRT_MAX
);
468 const SwTableBox
& FindEndOfRowSpan( const SwTable
& rTable
,
469 USHORT nMaxStep
= USHRT_MAX
) const
470 { return const_cast<SwTableBox
*>(this)->FindEndOfRowSpan( rTable
, nMaxStep
); }
474 class SW_DLLPUBLIC SwTableCellInfo
: public ::boost::noncopyable
477 ::std::auto_ptr
<Impl
> m_pImpl
;
479 const SwCellFrm
* getCellFrm() const ;
482 SwTableCellInfo(const SwTable
* pTable
);
486 SwRect
getRect() const;
487 const SwTableBox
* getTableBox() const;
490 #endif //_SWTABLE_HXX