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: swtable.hxx,v $
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 ************************************************************************/
32 #include <tools/mempool.hxx>
33 #ifndef _TOOLS_REF_HXX
34 #include <tools/ref.hxx>
36 #include <svtools/svarray.hxx>
37 #include <tblenum.hxx>
38 #include <swtypes.hxx>
42 #include <node.hxx> // fuer StartNode->GetMyIndex
52 class SwHTMLTableLayout
;
68 class SwTableBox_Impl
;
69 class SwUndoTblCpyTbl
;
74 #ifndef SW_DECL_SWSERVEROBJECT_DEFINED
75 #define SW_DECL_SWSERVEROBJECT_DEFINED
76 SV_DECL_REF( SwServerObject
)
79 SV_DECL_PTRARR_DEL(SwTableLines
, SwTableLine
*, 10, 20)
80 SV_DECL_PTRARR_DEL(SwTableBoxes
, SwTableBox
*, 25, 50)
82 // speicher die Inhaltstragenden Box-Pointer zusaetzlich in einem
83 // sortierten Array (fuers rechnen in der Tabelle)
84 typedef SwTableBox
* SwTableBoxPtr
;
85 SV_DECL_PTRARR_SORT( SwTableSortBoxes
, SwTableBoxPtr
, 25, 50 )
86 typedef SwTableLine
* SwTableLinePtr
;
88 class SW_DLLPUBLIC SwTable
: public SwClient
//Client vom FrmFmt
90 using SwClient::IsModifyLocked
;
94 SwTableSortBoxes aSortCntBoxes
;
95 SwServerObjectRef refObj
; // falls DataServer -> Pointer gesetzt
97 SwHTMLTableLayout
*pHTMLLayout
;
99 // Usually, the table node of a SwTable can be accessed by getting a box
100 // out of aSortCntBoxes, which know their SwStartNode. But in some rare
101 // cases, we need to know the table node of a SwTable, before the table
102 // boxes have been build (SwTableNode::MakeCopy with tables in tables).
103 SwTableNode
* pTableNode
;
105 //SOLL das fuer jede Tabelle einstellbar sein?
106 TblChgMode eTblChgMode
;
108 USHORT nGrfsThatResize
; // Anzahl der Grfs, die beim HTML-Import
109 // noch ein Resize der Tbl. anstossen
110 USHORT nRowsToRepeat
; // number of rows to repeat on every page
112 BOOL bModifyLocked
:1;
113 BOOL bNewModel
:1; // FALSE: old SubTableModel; TRUE: new RowSpanModel
115 bool bDontChangeModel
; // This is set by functions (like Merge()) to forbid a laet model change
118 BOOL
IsModifyLocked(){ return bModifyLocked
;}
123 SEARCH_NONE
, // Default: expand to rectangle
124 SEARCH_ROW
, // row selection
125 SEARCH_COL
// column selection
130 // single argument ctors shall be explicit.
131 explicit SwTable( SwTableFmt
* );
134 // @@@ public copy ctor, but no copy assignment?
135 SwTable( const SwTable
& rTable
); // kein Copy der Lines !!
137 // @@@ public copy ctor, but no copy assignment?
138 SwTable
& operator= (const SwTable
&);
141 BOOL
OldMerge( SwDoc
*, const SwSelBoxes
&, SwTableBox
*, SwUndoTblMerge
* );
142 BOOL
OldSplitRow( SwDoc
*, const SwSelBoxes
&, USHORT
, BOOL
);
143 BOOL
NewMerge( SwDoc
*, const SwSelBoxes
&, const SwSelBoxes
& rMerged
,
144 SwTableBox
*, SwUndoTblMerge
* );
145 BOOL
NewSplitRow( SwDoc
*, const SwSelBoxes
&, USHORT
, BOOL
);
146 SwBoxSelection
* CollectBoxSelection( const SwPaM
& rPam
) const;
147 void InsertSpannedRow( SwDoc
* pDoc
, USHORT nIdx
, USHORT nCnt
);
148 BOOL
_InsertRow( SwDoc
*, const SwSelBoxes
&, USHORT nCnt
, BOOL bBehind
);
149 BOOL
NewInsertCol( SwDoc
*, const SwSelBoxes
& rBoxes
, USHORT nCnt
, 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
, BOOL bCurRowOnly
);
157 SwHTMLTableLayout
*GetHTMLTableLayout() { return pHTMLLayout
; }
158 const SwHTMLTableLayout
*GetHTMLTableLayout() const { return pHTMLLayout
; }
159 void SetHTMLTableLayout( SwHTMLTableLayout
*p
); //Eigentumsuebergang!
161 USHORT
IncGrfsThatResize() { return ++nGrfsThatResize
; }
162 USHORT
DecGrfsThatResize() { return nGrfsThatResize
? --nGrfsThatResize
: 0; }
164 void LockModify() { bModifyLocked
= TRUE
; } //Muessen _immer_ paarig
165 void UnlockModify() { bModifyLocked
= FALSE
;} //benutzt werden!
167 void SetTableModel( BOOL bNew
){ bNewModel
= bNew
; }
168 BOOL
IsNewModel() const { return bNewModel
; }
170 USHORT
GetRowsToRepeat() const { return Min( GetTabLines().Count(), nRowsToRepeat
); }
171 USHORT
_GetRowsToRepeat() const { return nRowsToRepeat
; }
172 void SetRowsToRepeat( USHORT nNumOfRows
) { nRowsToRepeat
= nNumOfRows
; }
174 bool IsHeadline( const SwTableLine
& rLine
) const;
176 SwTableLines
&GetTabLines() { return aLines
; }
177 const SwTableLines
&GetTabLines() const { return aLines
; }
179 SwFrmFmt
* GetFrmFmt() { return (SwFrmFmt
*)pRegisteredIn
; }
180 SwFrmFmt
* GetFrmFmt() const { return (SwFrmFmt
*)pRegisteredIn
; }
182 virtual void Modify( SfxPoolItem
* pOld
, SfxPoolItem
* pNew
);
184 void GetTabCols( SwTabCols
&rToFill
, const SwTableBox
*pStart
,
185 BOOL bHidden
= FALSE
, BOOL bCurRowOnly
= FALSE
) const;
186 void SetTabCols( const SwTabCols
&rNew
, const SwTabCols
&rOld
,
187 const SwTableBox
*pStart
, BOOL bCurRowOnly
);
189 // The following functions are for new table model only...
190 void CreateSelection( const SwPaM
& rPam
, SwSelBoxes
& rBoxes
,
191 const SearchType eSearchType
, bool bProtect
) const;
192 void CreateSelection( const SwNode
* pStart
, const SwNode
* pEnd
,
193 SwSelBoxes
& rBoxes
, const SearchType eSearchType
, bool bProtect
) const;
194 void ExpandSelection( SwSelBoxes
& rBoxes
) const;
195 // When a table is splitted into two tables, the row spans which overlaps
196 // the split have to be corrected and stored for undo
197 // SwSavRowSpan is the structure needed by Undo to undo the split operation
198 // CleanUpRowSpan corrects the (top of the) second table and delviers the structure
200 SwSaveRowSpan
* CleanUpTopRowSpan( USHORT nSplitLine
);
201 // RestoreRowSpan is called by Undo to restore the old row span values
202 void RestoreRowSpan( const SwSaveRowSpan
& );
203 // CleanUpBottomRowSpan corrects the overhanging row spans at the end of the first table
204 void CleanUpBottomRowSpan( USHORT nDelLines
);
207 // The following functions are "pseudo-virtual", i.e. they are different for old and new table model
208 // It's not allowed to change the table model after the first call of one of these functions.
210 BOOL
Merge( SwDoc
* pDoc
, const SwSelBoxes
& rBoxes
, const SwSelBoxes
& rMerged
,
211 SwTableBox
* pMergeBox
, SwUndoTblMerge
* pUndo
= 0 )
214 bDontChangeModel
= true;
216 return bNewModel
? NewMerge( pDoc
, rBoxes
, rMerged
, pMergeBox
, pUndo
) :
217 OldMerge( pDoc
, rBoxes
, pMergeBox
, pUndo
);
219 BOOL
SplitRow( SwDoc
* pDoc
, const SwSelBoxes
& rBoxes
, USHORT nCnt
=1,
220 BOOL bSameHeight
= FALSE
)
223 bDontChangeModel
= true;
225 return bNewModel
? NewSplitRow( pDoc
, rBoxes
, nCnt
, bSameHeight
) :
226 OldSplitRow( pDoc
, rBoxes
, nCnt
, bSameHeight
);
228 bool PrepareMerge( const SwPaM
& rPam
, SwSelBoxes
& rBoxes
,
229 SwSelBoxes
& rMerged
, SwTableBox
** ppMergeBox
, SwUndoTblMerge
* pUndo
);
230 void ExpandColumnSelection( SwSelBoxes
& rBoxes
, long &rMin
, long &rMax
) const;
231 void PrepareDeleteCol( long nMin
, long nMax
);
233 BOOL
InsertCol( SwDoc
*, const SwSelBoxes
& rBoxes
,
234 USHORT nCnt
= 1, BOOL bBehind
= TRUE
);
235 BOOL
InsertRow( SwDoc
*, const SwSelBoxes
& rBoxes
,
236 USHORT nCnt
= 1, BOOL bBehind
= TRUE
);
237 BOOL
AppendRow( SwDoc
* pDoc
, USHORT nCnt
= 1 );
238 void PrepareDelBoxes( const SwSelBoxes
& rBoxes
);
239 BOOL
DeleteSel( SwDoc
*, const SwSelBoxes
& rBoxes
, const SwSelBoxes
* pMerged
,
240 SwUndo
* pUndo
, const BOOL bDelMakeFrms
, const BOOL bCorrBorder
);
241 BOOL
SplitCol( SwDoc
* pDoc
, const SwSelBoxes
& rBoxes
, USHORT nCnt
=1 );
242 BOOL
Merge( const SwSelBoxes
& rBoxes
,
243 SwTableBox
* pMergeBox
, SwUndoTblMerge
* = 0 );
245 void FindSuperfluousRows( SwSelBoxes
& rBoxes
)
246 { _FindSuperfluousRows( rBoxes
, 0, 0 ); }
247 void CheckRowSpan( SwTableLinePtr
&rpLine
, bool bUp
) const;
249 SwTableSortBoxes
& GetTabSortBoxes() { return aSortCntBoxes
; }
250 const SwTableSortBoxes
& GetTabSortBoxes() const { return aSortCntBoxes
; }
252 // lese die 1. Nummer und loesche sie aus dem String
253 // (wird von GetTblBox und SwTblFld benutzt)
254 // --> OD 2007-08-03 #i80314#
255 // add 3rd parameter in order to control validation check on <rStr>
256 static USHORT
_GetBoxNum( String
& rStr
,
258 const bool bPerformValidCheck
= false );
260 // suche die Inhaltstragende Box mit dem Namen
261 // --> OD 2007-08-03 #i80314#
262 // add 2nd parameter in order to control validation check in called method
264 const SwTableBox
* GetTblBox( const String
& rName
,
265 const bool bPerformValidCheck
= false ) const;
267 // kopiere die selektierten Boxen in ein anderes Dokument.
268 BOOL
MakeCopy( SwDoc
*, const SwPosition
&, const SwSelBoxes
&,
269 BOOL bCpyNds
= TRUE
, BOOL bCpyName
= FALSE
) const;
270 // kopiere die Tabelle in diese. (die Logik steht im TBLRWCL.CXX)
271 BOOL
InsTable( const SwTable
& rCpyTbl
, const SwNodeIndex
&,
272 SwUndoTblCpyTbl
* pUndo
= 0 );
273 BOOL
InsTable( const SwTable
& rCpyTbl
, const SwSelBoxes
&,
274 SwUndoTblCpyTbl
* pUndo
= 0 );
275 BOOL
InsNewTable( const SwTable
& rCpyTbl
, const SwSelBoxes
&,
276 SwUndoTblCpyTbl
* pUndo
);
277 // kopiere die Headline (mit Inhalt!) der Tabelle in eine andere
278 BOOL
CopyHeadlineIntoTable( SwTableNode
& rTblNd
);
280 // erfrage die Box, dessen Start-Index auf nBoxStt steht
281 SwTableBox
* GetTblBox( ULONG nSttIdx
);
282 const SwTableBox
* GetTblBox( ULONG nSttIdx
) const
283 { return ((SwTable
*)this)->GetTblBox( nSttIdx
); }
285 // returnt TRUE wenn sich in der Tabelle Verschachtelungen befinden
286 BOOL
IsTblComplex() const;
288 //returnt TRUE wenn die Tabelle oder Selektion ausgeglichen ist
289 BOOL
IsTblComplexForChart( const String
& rSel
,
290 SwChartLines
* pGetCLines
= 0 ) const;
292 // suche alle Inhaltstragenden-Boxen der Grundline in der diese Box
293 // steht. rBoxes auch als Return-Wert, um es gleich weiter zu benutzen
294 //JP 31.01.97: bToTop = TRUE -> hoch bis zur Grundline,
295 // FALSE-> sonst nur die Line der Box
296 SwSelBoxes
& SelLineFromBox( const SwTableBox
* pBox
,
297 SwSelBoxes
& rBoxes
, BOOL bToTop
= TRUE
) const;
298 // erfrage vom Client Informationen
299 virtual BOOL
GetInfo( SfxPoolItem
& ) const;
301 // suche im Format nach der angemeldeten Tabelle
302 static SwTable
* FindTable( SwFrmFmt
* pFmt
);
304 // Struktur ein wenig aufraeumen
307 // returns the table node via aSortCntBoxes or pTableNode
308 SwTableNode
* GetTableNode() const;
309 void SetTableNode( SwTableNode
* pNode
) { pTableNode
= pNode
; }
311 // Daten Server-Methoden
312 void SetRefObject( SwServerObject
* );
313 const SwServerObject
* GetObject() const { return &refObj
; }
314 SwServerObject
* GetObject() { return &refObj
; }
316 //Daten fuer das Chart fuellen.
317 void UpdateCharts() const;
319 TblChgMode
GetTblChgMode() const { return eTblChgMode
; }
320 void SetTblChgMode( TblChgMode eMode
) { eTblChgMode
= eMode
; }
322 BOOL
SetColWidth( SwTableBox
& rAktBox
, USHORT eType
,
323 SwTwips nAbsDiff
, SwTwips nRelDiff
, SwUndo
** ppUndo
);
324 BOOL
SetRowHeight( SwTableBox
& rAktBox
, USHORT eType
,
325 SwTwips nAbsDiff
, SwTwips nRelDiff
, SwUndo
** ppUndo
);
327 void CheckConsistency() const;
331 class SW_DLLPUBLIC SwTableLine
: public SwClient
// Client vom FrmFmt
339 SwTableLine() : pUpper(0) {}
341 SwTableLine( SwTableLineFmt
*, USHORT nBoxes
, SwTableBox
*pUp
);
342 virtual ~SwTableLine();
344 SwTableBoxes
&GetTabBoxes() { return aBoxes
; }
345 const SwTableBoxes
&GetTabBoxes() const { return aBoxes
; }
347 SwTableBox
*GetUpper() { return pUpper
; }
348 const SwTableBox
*GetUpper() const { return pUpper
; }
349 void SetUpper( SwTableBox
*pNew
) { pUpper
= pNew
; }
352 SwFrmFmt
* GetFrmFmt() { return (SwFrmFmt
*)pRegisteredIn
; }
353 SwFrmFmt
* GetFrmFmt() const { return (SwFrmFmt
*)pRegisteredIn
; }
355 //Macht ein eingenes FrmFmt wenn noch mehr Lines von ihm abhaengen.
356 SwFrmFmt
* ClaimFrmFmt();
357 void ChgFrmFmt( SwTableLineFmt
* pNewFmt
);
359 // suche nach der naechsten/vorherigen Box mit Inhalt
360 SwTableBox
* FindNextBox( const SwTable
&, const SwTableBox
* =0,
361 BOOL bOvrTblLns
=TRUE
) const;
362 SwTableBox
* FindPreviousBox( const SwTable
&, const SwTableBox
* =0,
363 BOOL bOvrTblLns
=TRUE
) const;
365 SwTwips
GetTableLineHeight( bool& bLayoutAvailable
) const;
367 bool hasSoftPageBreak() const;
370 class SW_DLLPUBLIC SwTableBox
: public SwClient
//Client vom FrmFmt
372 friend class SwNodes
; // um den Index umzusetzen !
373 friend void DelBoxNode(SwTableSortBoxes
&); // um den StartNode* zu loeschen !
374 friend class SwXMLTableContext
;
376 //nicht (mehr) implementiert.
377 SwTableBox( const SwTableBox
& );
378 SwTableBox
&operator=( const SwTableBox
&); //gibts nicht.
381 const SwStartNode
* pSttNd
;
383 SwTableBox_Impl
* pImpl
;
385 // falls das Format schon Formeln/Values enthaelt, muss ein neues
386 // fuer die neue Box erzeugt werden.
387 SwTableBoxFmt
* CheckBoxFmt( SwTableBoxFmt
* );
392 SwTableBox() : pSttNd(0), pUpper(0), pImpl(0) {}
394 SwTableBox( SwTableBoxFmt
*, USHORT nLines
, SwTableLine
*pUp
= 0 );
395 SwTableBox( SwTableBoxFmt
*, const SwStartNode
&, SwTableLine
*pUp
= 0 );
396 SwTableBox( SwTableBoxFmt
*, const SwNodeIndex
&, SwTableLine
*pUp
= 0 );
397 virtual ~SwTableBox();
399 SwTableLines
&GetTabLines() { return aLines
; }
400 const SwTableLines
&GetTabLines() const { return aLines
; }
402 SwTableLine
*GetUpper() { return pUpper
; }
403 const SwTableLine
*GetUpper() const { return pUpper
; }
404 void SetUpper( SwTableLine
*pNew
) { pUpper
= pNew
; }
406 SwFrmFmt
* GetFrmFmt() { return (SwFrmFmt
*)pRegisteredIn
; }
407 SwFrmFmt
* GetFrmFmt() const { return (SwFrmFmt
*)pRegisteredIn
; }
409 //Macht ein eingenes FrmFmt wenn noch mehr Boxen von ihm abhaengen.
410 SwFrmFmt
* ClaimFrmFmt();
411 void ChgFrmFmt( SwTableBoxFmt
*pNewFmt
);
413 const SwStartNode
*GetSttNd() const { return pSttNd
; }
414 ULONG
GetSttIdx() const
416 { return pSttNd
? pSttNd
->GetIndex() : 0; }
421 // suche nach der naechsten/vorherigen Box mit Inhalt
422 SwTableBox
* FindNextBox( const SwTable
&, const SwTableBox
* =0,
423 BOOL bOvrTblLns
=TRUE
) const;
424 SwTableBox
* FindPreviousBox( const SwTable
&, const SwTableBox
* =0,
425 BOOL bOvrTblLns
=TRUE
) const;
426 // gebe den Namen dieser Box zurueck. Dieser wird dynamisch bestimmt
427 // und ergibt sich aus der Position in den Lines/Boxen/Tabelle
428 String
GetName() const;
429 // gebe den "Wert" der Box zurueck (fuers rechnen in der Tabelle)
430 double GetValue( SwTblCalcPara
& rPara
) const;
432 BOOL
IsInHeadline( const SwTable
* pTbl
= 0 ) const;
434 // enthaelt die Box Inhalt, der als Nummer formatiert werden kann?
435 BOOL
HasNumCntnt( double& rNum
, sal_uInt32
& rFmtIndex
,
436 BOOL
& rIsEmptyTxtNd
) const;
437 ULONG
IsValidNumTxtNd( BOOL bCheckAttr
= TRUE
) const;
438 // teste ob der BoxInhalt mit der Nummer uebereinstimmt, wenn eine
439 // Tabellenformel gesetzt ist. (fuers Redo des Change vom NumFormat!)
440 BOOL
IsNumberChanged() const;
442 // ist das eine FormelBox oder eine Box mit numerischen Inhalt (AutoSum)
443 // Was es ist, besagt der ReturnWert - die WhichId des Attributes
444 // Leere Boxen haben den ReturnWert USHRT_MAX !!
445 USHORT
IsFormulaOrValueBox() const;
447 // Loading of a document requires an actualisation of cells with values
448 void ActualiseValueBox();
450 DECL_FIXEDMEMPOOL_NEWDEL(SwTableBox
)
452 // zugriff auf interne Daten - z.Z. benutzt fuer den NumFormatter
453 inline const Color
* GetSaveUserColor() const;
454 inline const Color
* GetSaveNumFmtColor() const;
455 inline void SetSaveUserColor(const Color
* p
);
456 inline void SetSaveNumFmtColor( const Color
* p
);
458 long getRowSpan() const;
459 void setRowSpan( long nNewRowSpan
);
460 bool getDummyFlag() const;
461 void setDummyFlag( bool bDummy
);
463 SwTableBox
& FindStartOfRowSpan( const SwTable
&, USHORT nMaxStep
= USHRT_MAX
);
464 const SwTableBox
& FindStartOfRowSpan( const SwTable
& rTable
,
465 USHORT nMaxStep
= USHRT_MAX
) const
466 { return const_cast<SwTableBox
*>(this)->FindStartOfRowSpan( rTable
, nMaxStep
); }
468 SwTableBox
& FindEndOfRowSpan( const SwTable
&, USHORT nMaxStep
= USHRT_MAX
);
469 const SwTableBox
& FindEndOfRowSpan( const SwTable
& rTable
,
470 USHORT nMaxStep
= USHRT_MAX
) const
471 { return const_cast<SwTableBox
*>(this)->FindEndOfRowSpan( rTable
, nMaxStep
); }
474 #endif //_SWTABLE_HXX