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: htmltbl.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 ************************************************************************/
35 #include <vcl/timer.hxx>
36 #include <svx/svxenum.hxx>
38 #include "swtypes.hxx"
39 #include "node.hxx" // Fuer SwStartNode
44 class SwHTMLTableLayout
;
48 #define HTMLTABLE_RESIZE_NOW (ULONG_MAX)
50 class SwHTMLTableLayoutCnts
52 SwHTMLTableLayoutCnts
*pNext
; // der naechste Inhalt
54 // von den beiden naechsten Pointern darf nur einer gesetzt sein!
55 SwTableBox
*pBox
; // ein Box
56 SwHTMLTableLayout
*pTable
; // eine "Tabelle in der Tabelle"
58 // Beim ersten Durchlauf gibt es noch keine Boxen. Es wird dann
59 // pStartNode anstelle von pBox verwendet.
60 const SwStartNode
*pStartNode
;
62 // Die folgenden Zahler geben an, wie oft ein Pass bereits fuer diesen
63 // Inhalt durchgefuehrt wurde. Dazu werden sie mit einer Soll-Vorgabe
64 // verglichen. Wird 255 erreicht laufen sie bei 0 weiter. So wird
65 // eine Reinitialisierung bei jedem Resize vermieden.
66 BYTE nPass1Done
; // Wieoft wurde Pass 1 aufgerufen?
67 BYTE nWidthSet
; // Wieoft wurde die Breite gesetzt?
69 BOOL bNoBreakTag
; // <NOBR>-Tag ueber gesamten Inhalt
73 SwHTMLTableLayoutCnts( const SwStartNode
* pSttNd
, SwHTMLTableLayout
* pTab
,
74 BOOL bNoBreakTag
, SwHTMLTableLayoutCnts
* pNxt
);
76 ~SwHTMLTableLayoutCnts();
78 void SetTableBox( SwTableBox
*pBx
) { pBox
= pBx
; }
79 SwTableBox
*GetTableBox() const { return pBox
; }
81 SwHTMLTableLayout
*GetTable() const { return pTable
; }
83 const SwStartNode
*GetStartNode() const;
85 // Ermitteln des naechsten Knotens
86 SwHTMLTableLayoutCnts
*GetNext() const { return pNext
; }
88 void SetWidthSet( BYTE nRef
) { nWidthSet
= nRef
; }
89 BOOL
IsWidthSet( BYTE nRef
) const { return nRef
==nWidthSet
; }
91 void SetPass1Done( BYTE nRef
) { nPass1Done
= nRef
; }
92 BOOL
IsPass1Done( BYTE nRef
) const { return nRef
==nPass1Done
; }
94 BOOL
HasNoBreakTag() const { return bNoBreakTag
; }
99 class SwHTMLTableLayoutCell
101 SwHTMLTableLayoutCnts
*pContents
; // der Inhalt der Zelle
103 USHORT nRowSpan
; // ROWSPAN der Zelle
104 USHORT nColSpan
; // COLSPAN der Zelle
105 USHORT nWidthOption
;// angegebene Breite der Zelle in Twip oder %
107 BOOL bPrcWidthOption
: 1;// nWidth ist %-Angabe
108 BOOL bNoWrapOption
: 1; // NOWRAP-Option
112 SwHTMLTableLayoutCell( SwHTMLTableLayoutCnts
*pCnts
,
113 USHORT nRSpan
, USHORT nCSpan
,
114 USHORT nWidthOpt
, BOOL bPrcWdthOpt
,
117 ~SwHTMLTableLayoutCell();
119 // Setzen/Ermitteln des Inhalts einer Zelle
120 void SetContents( SwHTMLTableLayoutCnts
*pCnts
) { pContents
= pCnts
; }
121 SwHTMLTableLayoutCnts
*GetContents() const { return pContents
; }
123 inline void SetProtected();
125 // ROWSPAN/COLSPAN der Zelle Setzen/Ermitteln
126 void SetRowSpan( USHORT nRSpan
) { nRowSpan
= nRSpan
; }
127 USHORT
GetRowSpan() const { return nRowSpan
; }
128 USHORT
GetColSpan() const { return nColSpan
; }
130 USHORT
GetWidthOption() const { return nWidthOption
; }
131 BOOL
IsPrcWidthOption() const { return bPrcWidthOption
; }
133 BOOL
HasNoWrapOption() const { return bNoWrapOption
; }
138 class SwHTMLTableLayoutColumn
140 // Zwischenwerte von AutoLayoutPass1
141 ULONG nMinNoAlign
, nMaxNoAlign
, nAbsMinNoAlign
;
143 // Ergebnisse von AutoLayoutPass1
146 // Ergibnisse von Pass 2
147 USHORT nAbsColWidth
; // in Twips
148 USHORT nRelColWidth
; // in Twips bzw. relativ zu USHRT_MAX
150 USHORT nWidthOption
; // Optionen von <COL> oder <TD>/<TH>
152 BOOL bRelWidthOption
: 1;
153 BOOL bLeftBorder
: 1;
157 SwHTMLTableLayoutColumn( USHORT nColWidthOpt
, BOOL bRelColWidthOpt
,
160 ~SwHTMLTableLayoutColumn() {}
162 inline void MergeCellWidthOption( USHORT nWidth
, BOOL bPrc
);
163 inline void SetWidthOption( USHORT nWidth
, BOOL bRelWidth
, BOOL bTest
);
165 USHORT
GetWidthOption() const { return nWidthOption
; }
166 BOOL
IsRelWidthOption() const { return bRelWidthOption
; }
168 inline void MergeMinMaxNoAlign( ULONG nMin
, ULONG nMax
, ULONG nAbsMin
);
169 ULONG
GetMinNoAlign() const { return nMinNoAlign
; }
170 ULONG
GetMaxNoAlign() const { return nMaxNoAlign
; }
171 ULONG
GetAbsMinNoAlign() const { return nAbsMinNoAlign
; }
172 inline void ClearPass1Info( BOOL bWidthOpt
);
174 inline void SetMinMax( ULONG nMin
, ULONG nMax
);
175 void SetMax( ULONG nVal
) { nMax
= nVal
; }
176 void AddToMin( ULONG nVal
) { nMin
+= nVal
; }
177 void AddToMax( ULONG nVal
) { nMax
+= nVal
; }
178 ULONG
GetMin() const { return nMin
; }
179 ULONG
GetMax() const { return nMax
; }
181 void SetAbsColWidth( USHORT nWidth
) { nAbsColWidth
= nWidth
; }
182 USHORT
GetAbsColWidth() const { return nAbsColWidth
; }
184 void SetRelColWidth( USHORT nWidth
) { nRelColWidth
= nWidth
; }
185 USHORT
GetRelColWidth() const { return nRelColWidth
; }
187 BOOL
HasLeftBorder() const { return bLeftBorder
; }
192 class SwHTMLTableLayout
194 Timer aResizeTimer
; // Timer fuer DelayedResize
196 SwHTMLTableLayoutColumn
**aColumns
;
197 SwHTMLTableLayoutCell
**aCells
;
199 const SwTable
*pSwTable
; // die SwTable (nur Top-Table)
200 SwTableBox
*pLeftFillerBox
; // linke Filler-Zelle (nur Tab in Tab)
201 SwTableBox
*pRightFillerBox
; // rechte Filler-Zelle (nur Tab-in Tab)
203 ULONG nMin
; // minimale Breite der Tabelle (Twips)
204 ULONG nMax
; // maximale Breite der Tabelle (Twips)
206 USHORT nRows
; // Anzahl Zeilen
207 USHORT nCols
; // Anzahl Spalten
209 USHORT nLeftMargin
; // Abstand zum linken Rand (aus Absatz)
210 USHORT nRightMargin
; // Abstand zum rechten Rand (aus Absatz)
212 USHORT nInhAbsLeftSpace
; // von umgebender Zelle geerbter Abstand,
213 USHORT nInhAbsRightSpace
; // der Zellen zugeschlagen wurde
215 USHORT nRelLeftFill
; // relative Breiten der Zellen zur
216 USHORT nRelRightFill
; // Ausrichtung von Tabellen in Tabellen
218 USHORT nRelTabWidth
; // Die relative Breite der Tabelle
220 USHORT nWidthOption
; // die Breite der Tabelle (in Twip oder %)
221 USHORT nCellPadding
; // Abstand zum Inhalt (in Twip)
222 USHORT nCellSpacing
; // Absatnd zwischen Zellen (in Twip)
223 USHORT nBorder
; // Dicke der ausseren Umrandung bzw.
224 // Platz, den Netscape hierfuer einrechnet.
226 USHORT nLeftBorderWidth
;
227 USHORT nRightBorderWidth
;
228 USHORT nInhLeftBorderWidth
;
229 USHORT nInhRightBorderWidth
;
232 USHORT nDelayedResizeAbsAvail
; // Param fuer's verzoegerte Resize
233 USHORT nLastResizeAbsAvail
;
235 BYTE nPass1Done
; // Vorgabe-Werte fuer die einzelen
236 BYTE nWidthSet
; // Schleifen-Durchlauefe
238 SvxAdjust eTableAdjust
; // Die Ausrichtung der Tabelle
240 BOOL bColsOption
: 1; // Tabelle besitzt eine COLS-Option
241 BOOL bColTags
: 1; // Tabelle besitzt COL/COLGRP-Tags
242 BOOL bPrcWidthOption
: 1; // Breite ist eine %-Angabe
243 BOOL bUseRelWidth
: 1; // SwTable bekommt relative Breite
245 BOOL bMustResize
: 1; // Tabelle muss in der Breite ang. werden
246 BOOL bExportable
: 1; // Layout kann zum Export genutzt werden
247 BOOL bBordersChanged
: 1; // Umrandung wurde geaendert
248 BOOL bMayBeInFlyFrame
: 1; // Die Tabelle koennte im Rahmen sein
250 BOOL bDelayedResizeRecalc
: 1; // Param fuer's verzoegerte Resize
251 BOOL bMustNotResize
: 1; // Die Tabelle darf nicht reseized werden
252 BOOL bMustNotRecalc
: 1; // Tabelle darf nicht an Inhalt angepasst
255 // USHORT GetLeftBorderWidth( USHORT nCol ) const;
256 // USHORT GetRightBorderWidth( USHORT nCol, USHORT nColSpan ) const;
258 void AddBorderWidth( ULONG
&rMin
, ULONG
&rMax
, ULONG
& rAbsMin
,
259 USHORT nCol
, USHORT nColSpan
,
260 BOOL bSwBorders
=TRUE
) const;
261 void SetBoxWidth( SwTableBox
*pBox
, USHORT nCol
, USHORT nColSpan
) const;
263 const SwStartNode
*GetAnyBoxStartNode() const;
264 SwFrmFmt
*FindFlyFrmFmt() const;
265 const SwDoc
*GetDoc() const { return GetAnyBoxStartNode()->GetDoc(); }
267 void ClearPass1Info() { nMin
= nMax
= 0; }
269 void _Resize( USHORT nAbsAvail
, BOOL bRecalc
=FALSE
);
271 DECL_STATIC_LINK( SwHTMLTableLayout
, DelayedResize_Impl
, void* );
275 SwHTMLTableLayout( const SwTable
*pSwTbl
,
276 USHORT nRows
, USHORT nCols
, BOOL bColsOpt
, BOOL ColTgs
,
277 USHORT nWidth
, BOOL bPrcWidth
, USHORT nBorderOpt
,
278 USHORT nCellPad
, USHORT nCellSp
, SvxAdjust eAdjust
,
279 USHORT nLMargin
, USHORT nRMargin
, USHORT nBWidth
,
280 USHORT nLeftBWidth
, USHORT nRightBWidth
,
281 USHORT nInhLeftBWidth
, USHORT nInhRightBWidth
);
283 ~SwHTMLTableLayout();
285 USHORT
GetLeftCellSpace( USHORT nCol
, USHORT nColSpan
,
286 BOOL bSwBorders
=TRUE
) const;
287 USHORT
GetRightCellSpace( USHORT nCol
, USHORT nColSpan
,
288 BOOL bSwBorders
=TRUE
) const;
289 inline USHORT
GetInhCellSpace( USHORT nCol
, USHORT nColSpan
) const;
291 inline void SetInhBorderWidths( USHORT nLeft
, USHORT nRight
);
294 void GetAvail( USHORT nCol
, USHORT nColSpan
, USHORT
& rAbsAvail
,
295 USHORT
& rRelAvail
) const;
297 void AutoLayoutPass1();
298 void AutoLayoutPass2( USHORT nAbsAvail
, USHORT nRelAvail
,
299 USHORT nAbsLeftSpace
, USHORT nAbsRightSpace
,
300 USHORT nParentInhSpace
);
301 void SetWidths( BOOL bCallPass2
=FALSE
, USHORT nAbsAvail
=0,
302 USHORT nRelAvail
=0, USHORT nAbsLeftSpace
=0,
303 USHORT nAbsRightSpace
=0,
304 USHORT nParentInhSpace
=0 );
306 inline SwHTMLTableLayoutColumn
*GetColumn( USHORT nCol
) const;
307 inline void SetColumn( SwHTMLTableLayoutColumn
*pCol
, USHORT nCol
);
309 inline SwHTMLTableLayoutCell
*GetCell( USHORT nRow
, USHORT nCol
) const;
310 inline void SetCell( SwHTMLTableLayoutCell
*pCell
, USHORT nRow
, USHORT nCol
);
312 void SetLeftFillerBox( SwTableBox
*pBox
) { pLeftFillerBox
= pBox
; }
313 void SetRightFillerBox( SwTableBox
*pBox
) { pRightFillerBox
= pBox
; }
315 ULONG
GetMin() const { return nMin
; }
316 ULONG
GetMax() const { return nMax
; }
317 USHORT
GetRelLeftFill() const { return nRelLeftFill
; }
318 USHORT
GetRelRightFill() const { return nRelRightFill
; }
320 inline long GetBrowseWidthMin() const;
322 BOOL
HasColsOption() const { return bColsOption
; }
323 BOOL
HasColTags() const { return bColTags
; }
325 BOOL
IsTopTable() const { return pSwTable
!= 0; }
327 void SetMustResize( BOOL bSet
) { bMustResize
= bSet
; }
328 void SetMustNotResize( BOOL bSet
) { bMustNotResize
= bSet
; }
329 void SetMustNotRecalc( BOOL bSet
) { bMustNotRecalc
= bSet
; }
331 // Neueberechnung der Tabellenbreiten fuer die uebergebene verfuegbare
333 // - Wenn bRecalc gesetzt ist, werden auch der Inhalt der Boxen
334 // zur Berechnung herangezogen.
336 // - Wenn bForce gesetzt ist, wird die Tabelle auch neu berechnet, wenn
337 // dies mit SetMustNotResize unterdrueckt werden soll.
338 // - Wenn nDelay>0 wird die Berechnung entsprechend verzoegert.
339 // Innerhalb der Verzeoegerung auftretende Resize-Aufrufe werden
340 // ignoriert, die Verzeogerung wird aber ggf. uebernommen.
341 // - Wenn nDelay==HTMLTABLE_RESIZE_NOW ist, wird sofort Resized und
342 // eventuell noch asstehende Resize-Aufrufe werden nicht mehr
344 // - Der Rueckgabewert gibt an, ob sich die Tabelle geaendert hat.
345 BOOL
Resize( USHORT nAbsAvail
, BOOL bRecalc
=FALSE
, BOOL bForce
=FALSE
,
348 void BordersChanged( USHORT nAbsAvail
, BOOL bRecalc
=FALSE
);
350 // Ermitteln der verfuegbaren Breite. Das geht nur, wenn ein Layout
351 // oder eine ViewShell vorhanden ist. Sonst wird 0 zurueckgegeben.
352 // (Wird vom HTML-Filter benoetigt, da der nicht an das Layout kommt.)
353 static USHORT
GetBrowseWidth( const SwDoc
& rDoc
);
354 static USHORT
GetBrowseWidthByVisArea( const SwDoc
& rDoc
);
356 // Ermitteln der verfuegbaren Breite uber den Tabellen-Frame
357 USHORT
GetBrowseWidthByTabFrm( const SwTabFrm
& rTabFrm
) const;
359 // Ermitteln der verfuegbaren Breite uber den Tabellen-Frame oder
360 // das statische GetBrowseWidth, wenn kein Layout existiert.
361 USHORT
GetBrowseWidthByTable( const SwDoc
& rDoc
) const;
364 USHORT
GetWidthOption() const { return nWidthOption
; }
365 BOOL
HasPrcWidthOption() const { return bPrcWidthOption
; }
367 USHORT
GetCellPadding() const { return nCellPadding
; }
368 USHORT
GetCellSpacing() const { return nCellSpacing
; }
369 USHORT
GetBorder() const { return nBorder
; }
371 USHORT
GetRowCount() const { return nRows
; }
372 USHORT
GetColCount() const { return nCols
; }
374 void SetExportable( BOOL bSet
) { bExportable
= bSet
; }
375 BOOL
IsExportable() const { return bExportable
; }
377 BOOL
HaveBordersChanged() const { return bBordersChanged
; }
379 void SetMayBeInFlyFrame( BOOL bSet
) { bMayBeInFlyFrame
= bSet
; }
380 BOOL
MayBeInFlyFrame() const { return bMayBeInFlyFrame
; }
385 inline void SwHTMLTableLayoutCell::SetProtected()
395 inline void SwHTMLTableLayoutColumn::MergeMinMaxNoAlign( ULONG nCMin
,
396 ULONG nCMax
, ULONG nAbsMin
)
398 if( nCMin
> nMinNoAlign
)
400 if( nCMax
> nMaxNoAlign
)
402 if( nAbsMin
> nAbsMinNoAlign
)
403 nAbsMinNoAlign
= nAbsMin
;
406 inline void SwHTMLTableLayoutColumn::ClearPass1Info( BOOL bWidthOpt
)
408 nMinNoAlign
= nMaxNoAlign
= nAbsMinNoAlign
= MINLAY
;
413 bRelWidthOption
= FALSE
;
417 inline void SwHTMLTableLayoutColumn::MergeCellWidthOption(
418 USHORT nWidth
, BOOL bRel
)
421 (bRel
==bRelWidthOption
&& nWidthOption
< nWidth
) )
423 nWidthOption
= nWidth
;
424 bRelWidthOption
= bRel
;
428 inline void SwHTMLTableLayoutColumn::SetMinMax( ULONG nMn
, ULONG nMx
)
436 inline USHORT
SwHTMLTableLayout::GetInhCellSpace( USHORT nCol
,
437 USHORT nColSpan
) const
441 nSpace
= nSpace
+ sal::static_int_cast
< USHORT
>(nInhAbsLeftSpace
);
442 if( nCol
+nColSpan
==nCols
)
443 nSpace
= nSpace
+ sal::static_int_cast
< USHORT
>(nInhAbsRightSpace
);
448 inline SwHTMLTableLayoutColumn
*SwHTMLTableLayout::GetColumn( USHORT nCol
) const
450 return aColumns
[nCol
];
453 inline void SwHTMLTableLayoutColumn::SetWidthOption(
454 USHORT nWidth
, BOOL bRelWidth
, BOOL bTest
)
456 if( bTest
&& bRelWidthOption
==bRelWidth
)
458 if( nWidth
> nWidthOption
)
459 nWidthOption
= nWidth
;
462 nWidthOption
= nWidth
;
463 bRelWidthOption
= bRelWidth
;
466 inline void SwHTMLTableLayout::SetColumn( SwHTMLTableLayoutColumn
*pCol
, USHORT nCol
)
468 aColumns
[nCol
] = pCol
;
471 inline SwHTMLTableLayoutCell
*SwHTMLTableLayout::GetCell( USHORT nRow
, USHORT nCol
) const
473 return aCells
[nRow
*nCols
+nCol
];
476 inline void SwHTMLTableLayout::SetCell( SwHTMLTableLayoutCell
*pCell
,
477 USHORT nRow
, USHORT nCol
)
479 aCells
[nRow
*nCols
+nCol
] = pCell
;
482 inline long SwHTMLTableLayout::GetBrowseWidthMin() const
484 return (long)( (!nWidthOption
|| bPrcWidthOption
) ? nMin
: nRelTabWidth
);
487 void SwHTMLTableLayout::SetInhBorderWidths( USHORT nLeft
, USHORT nRight
)
489 nInhLeftBorderWidth
= nLeft
;
490 nInhRightBorderWidth
= nRight
;