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 28 #ifndef _HTMLTBL_HXX 29 #define _HTMLTBL_HXX 30 31 32 #include <vcl/timer.hxx> 33 #include <editeng/svxenum.hxx> 34 35 #include "swtypes.hxx" 36 #include "node.hxx" // Fuer SwStartNode 37 38 39 class SwTableBox; 40 class SwTable; 41 class SwHTMLTableLayout; 42 class SwDoc; 43 class SwFrmFmt; 44 45 #define HTMLTABLE_RESIZE_NOW (ULONG_MAX) 46 47 class SwHTMLTableLayoutCnts 48 { 49 SwHTMLTableLayoutCnts *pNext; // der naechste Inhalt 50 51 // von den beiden naechsten Pointern darf nur einer gesetzt sein! 52 SwTableBox *pBox; // ein Box 53 SwHTMLTableLayout *pTable; // eine "Tabelle in der Tabelle" 54 55 // Beim ersten Durchlauf gibt es noch keine Boxen. Es wird dann 56 // pStartNode anstelle von pBox verwendet. 57 const SwStartNode *pStartNode; 58 59 // Die folgenden Zahler geben an, wie oft ein Pass bereits fuer diesen 60 // Inhalt durchgefuehrt wurde. Dazu werden sie mit einer Soll-Vorgabe 61 // verglichen. Wird 255 erreicht laufen sie bei 0 weiter. So wird 62 // eine Reinitialisierung bei jedem Resize vermieden. 63 sal_uInt8 nPass1Done; // Wieoft wurde Pass 1 aufgerufen? 64 sal_uInt8 nWidthSet; // Wieoft wurde die Breite gesetzt? 65 66 sal_Bool bNoBreakTag; // <NOBR>-Tag ueber gesamten Inhalt 67 68 public: 69 70 SwHTMLTableLayoutCnts( const SwStartNode* pSttNd, SwHTMLTableLayout* pTab, 71 sal_Bool bNoBreakTag, SwHTMLTableLayoutCnts* pNxt ); 72 73 ~SwHTMLTableLayoutCnts(); 74 75 void SetTableBox( SwTableBox *pBx ) { pBox = pBx; } 76 SwTableBox *GetTableBox() const { return pBox; } 77 78 SwHTMLTableLayout *GetTable() const { return pTable; } 79 80 const SwStartNode *GetStartNode() const; 81 82 // Ermitteln des naechsten Knotens 83 SwHTMLTableLayoutCnts *GetNext() const { return pNext; } 84 85 void SetWidthSet( sal_uInt8 nRef ) { nWidthSet = nRef; } 86 sal_Bool IsWidthSet( sal_uInt8 nRef ) const { return nRef==nWidthSet; } 87 88 void SetPass1Done( sal_uInt8 nRef ) { nPass1Done = nRef; } 89 sal_Bool IsPass1Done( sal_uInt8 nRef ) const { return nRef==nPass1Done; } 90 91 sal_Bool HasNoBreakTag() const { return bNoBreakTag; } 92 }; 93 94 /* */ 95 96 class SwHTMLTableLayoutCell 97 { 98 SwHTMLTableLayoutCnts *pContents; // der Inhalt der Zelle 99 100 sal_uInt16 nRowSpan; // ROWSPAN der Zelle 101 sal_uInt16 nColSpan; // COLSPAN der Zelle 102 sal_uInt16 nWidthOption;// angegebene Breite der Zelle in Twip oder % 103 104 sal_Bool bPrcWidthOption : 1;// nWidth ist %-Angabe 105 sal_Bool bNoWrapOption : 1; // NOWRAP-Option 106 107 public: 108 109 SwHTMLTableLayoutCell( SwHTMLTableLayoutCnts *pCnts, 110 sal_uInt16 nRSpan, sal_uInt16 nCSpan, 111 sal_uInt16 nWidthOpt, sal_Bool bPrcWdthOpt, 112 sal_Bool nNWrapOpt ); 113 114 ~SwHTMLTableLayoutCell(); 115 116 // Setzen/Ermitteln des Inhalts einer Zelle 117 void SetContents( SwHTMLTableLayoutCnts *pCnts ) { pContents = pCnts; } 118 SwHTMLTableLayoutCnts *GetContents() const { return pContents; } 119 120 inline void SetProtected(); 121 122 // ROWSPAN/COLSPAN der Zelle Setzen/Ermitteln 123 void SetRowSpan( sal_uInt16 nRSpan ) { nRowSpan = nRSpan; } 124 sal_uInt16 GetRowSpan() const { return nRowSpan; } 125 sal_uInt16 GetColSpan() const { return nColSpan; } 126 127 sal_uInt16 GetWidthOption() const { return nWidthOption; } 128 sal_Bool IsPrcWidthOption() const { return bPrcWidthOption; } 129 130 sal_Bool HasNoWrapOption() const { return bNoWrapOption; } 131 }; 132 133 /* */ 134 135 class SwHTMLTableLayoutColumn 136 { 137 // Zwischenwerte von AutoLayoutPass1 138 sal_uLong nMinNoAlign, nMaxNoAlign, nAbsMinNoAlign; 139 140 // Ergebnisse von AutoLayoutPass1 141 sal_uLong nMin, nMax; 142 143 // Ergibnisse von Pass 2 144 sal_uInt16 nAbsColWidth; // in Twips 145 sal_uInt16 nRelColWidth; // in Twips bzw. relativ zu USHRT_MAX 146 147 sal_uInt16 nWidthOption; // Optionen von <COL> oder <TD>/<TH> 148 149 sal_Bool bRelWidthOption : 1; 150 sal_Bool bLeftBorder : 1; 151 152 public: 153 154 SwHTMLTableLayoutColumn( sal_uInt16 nColWidthOpt, sal_Bool bRelColWidthOpt, 155 sal_Bool bLBorder ); 156 157 ~SwHTMLTableLayoutColumn() {} 158 159 inline void MergeCellWidthOption( sal_uInt16 nWidth, sal_Bool bPrc ); 160 inline void SetWidthOption( sal_uInt16 nWidth, sal_Bool bRelWidth, sal_Bool bTest ); 161 162 sal_uInt16 GetWidthOption() const { return nWidthOption; } 163 sal_Bool IsRelWidthOption() const { return bRelWidthOption; } 164 165 inline void MergeMinMaxNoAlign( sal_uLong nMin, sal_uLong nMax, sal_uLong nAbsMin ); 166 sal_uLong GetMinNoAlign() const { return nMinNoAlign; } 167 sal_uLong GetMaxNoAlign() const { return nMaxNoAlign; } 168 sal_uLong GetAbsMinNoAlign() const { return nAbsMinNoAlign; } 169 inline void ClearPass1Info( sal_Bool bWidthOpt ); 170 171 inline void SetMinMax( sal_uLong nMin, sal_uLong nMax ); 172 void SetMax( sal_uLong nVal ) { nMax = nVal; } 173 void AddToMin( sal_uLong nVal ) { nMin += nVal; } 174 void AddToMax( sal_uLong nVal ) { nMax += nVal; } 175 sal_uLong GetMin() const { return nMin; } 176 sal_uLong GetMax() const { return nMax; } 177 178 void SetAbsColWidth( sal_uInt16 nWidth ) { nAbsColWidth = nWidth; } 179 sal_uInt16 GetAbsColWidth() const { return nAbsColWidth; } 180 181 void SetRelColWidth( sal_uInt16 nWidth ) { nRelColWidth = nWidth; } 182 sal_uInt16 GetRelColWidth() const { return nRelColWidth; } 183 184 sal_Bool HasLeftBorder() const { return bLeftBorder; } 185 }; 186 187 /* */ 188 189 class SwHTMLTableLayout 190 { 191 Timer aResizeTimer; // Timer fuer DelayedResize 192 193 SwHTMLTableLayoutColumn **aColumns; 194 SwHTMLTableLayoutCell **aCells; 195 196 const SwTable *pSwTable; // die SwTable (nur Top-Table) 197 SwTableBox *pLeftFillerBox; // linke Filler-Zelle (nur Tab in Tab) 198 SwTableBox *pRightFillerBox; // rechte Filler-Zelle (nur Tab-in Tab) 199 200 sal_uLong nMin; // minimale Breite der Tabelle (Twips) 201 sal_uLong nMax; // maximale Breite der Tabelle (Twips) 202 203 sal_uInt16 nRows; // Anzahl Zeilen 204 sal_uInt16 nCols; // Anzahl Spalten 205 206 sal_uInt16 nLeftMargin; // Abstand zum linken Rand (aus Absatz) 207 sal_uInt16 nRightMargin; // Abstand zum rechten Rand (aus Absatz) 208 209 sal_uInt16 nInhAbsLeftSpace; // von umgebender Zelle geerbter Abstand, 210 sal_uInt16 nInhAbsRightSpace; // der Zellen zugeschlagen wurde 211 212 sal_uInt16 nRelLeftFill; // relative Breiten der Zellen zur 213 sal_uInt16 nRelRightFill; // Ausrichtung von Tabellen in Tabellen 214 215 sal_uInt16 nRelTabWidth; // Die relative Breite der Tabelle 216 217 sal_uInt16 nWidthOption; // die Breite der Tabelle (in Twip oder %) 218 sal_uInt16 nCellPadding; // Abstand zum Inhalt (in Twip) 219 sal_uInt16 nCellSpacing; // Absatnd zwischen Zellen (in Twip) 220 sal_uInt16 nBorder; // Dicke der ausseren Umrandung bzw. 221 // Platz, den Netscape hierfuer einrechnet. 222 223 sal_uInt16 nLeftBorderWidth; 224 sal_uInt16 nRightBorderWidth; 225 sal_uInt16 nInhLeftBorderWidth; 226 sal_uInt16 nInhRightBorderWidth; 227 sal_uInt16 nBorderWidth; 228 229 sal_uInt16 nDelayedResizeAbsAvail; // Param fuer's verzoegerte Resize 230 sal_uInt16 nLastResizeAbsAvail; 231 232 sal_uInt8 nPass1Done; // Vorgabe-Werte fuer die einzelen 233 sal_uInt8 nWidthSet; // Schleifen-Durchlauefe 234 235 SvxAdjust eTableAdjust; // Die Ausrichtung der Tabelle 236 237 sal_Bool bColsOption : 1; // Tabelle besitzt eine COLS-Option 238 sal_Bool bColTags : 1; // Tabelle besitzt COL/COLGRP-Tags 239 sal_Bool bPrcWidthOption : 1; // Breite ist eine %-Angabe 240 sal_Bool bUseRelWidth : 1; // SwTable bekommt relative Breite 241 242 sal_Bool bMustResize : 1; // Tabelle muss in der Breite ang. werden 243 sal_Bool bExportable : 1; // Layout kann zum Export genutzt werden 244 sal_Bool bBordersChanged : 1; // Umrandung wurde geaendert 245 sal_Bool bMayBeInFlyFrame : 1; // Die Tabelle koennte im Rahmen sein 246 247 sal_Bool bDelayedResizeRecalc : 1; // Param fuer's verzoegerte Resize 248 sal_Bool bMustNotResize : 1; // Die Tabelle darf nicht reseized werden 249 sal_Bool bMustNotRecalc : 1; // Tabelle darf nicht an Inhalt angepasst 250 // werden 251 252 // sal_uInt16 GetLeftBorderWidth( sal_uInt16 nCol ) const; 253 // sal_uInt16 GetRightBorderWidth( sal_uInt16 nCol, sal_uInt16 nColSpan ) const; 254 255 void AddBorderWidth( sal_uLong &rMin, sal_uLong &rMax, sal_uLong& rAbsMin, 256 sal_uInt16 nCol, sal_uInt16 nColSpan, 257 sal_Bool bSwBorders=sal_True ) const; 258 void SetBoxWidth( SwTableBox *pBox, sal_uInt16 nCol, sal_uInt16 nColSpan ) const; 259 260 const SwStartNode *GetAnyBoxStartNode() const; 261 SwFrmFmt *FindFlyFrmFmt() const; 262 const SwDoc *GetDoc() const { return GetAnyBoxStartNode()->GetDoc(); } 263 264 void ClearPass1Info() { nMin = nMax = 0; } 265 266 void _Resize( sal_uInt16 nAbsAvail, sal_Bool bRecalc=sal_False ); 267 268 DECL_STATIC_LINK( SwHTMLTableLayout, DelayedResize_Impl, void* ); 269 270 static sal_uInt16 GetBrowseWidthByVisArea( const SwDoc& rDoc ); 271 public: 272 273 SwHTMLTableLayout( const SwTable *pSwTbl, 274 sal_uInt16 nRows, sal_uInt16 nCols, sal_Bool bColsOpt, sal_Bool ColTgs, 275 sal_uInt16 nWidth, sal_Bool bPrcWidth, sal_uInt16 nBorderOpt, 276 sal_uInt16 nCellPad, sal_uInt16 nCellSp, SvxAdjust eAdjust, 277 sal_uInt16 nLMargin, sal_uInt16 nRMargin, sal_uInt16 nBWidth, 278 sal_uInt16 nLeftBWidth, sal_uInt16 nRightBWidth, 279 sal_uInt16 nInhLeftBWidth, sal_uInt16 nInhRightBWidth ); 280 281 ~SwHTMLTableLayout(); 282 283 sal_uInt16 GetLeftCellSpace( sal_uInt16 nCol, sal_uInt16 nColSpan, 284 sal_Bool bSwBorders=sal_True ) const; 285 sal_uInt16 GetRightCellSpace( sal_uInt16 nCol, sal_uInt16 nColSpan, 286 sal_Bool bSwBorders=sal_True ) const; 287 inline sal_uInt16 GetInhCellSpace( sal_uInt16 nCol, sal_uInt16 nColSpan ) const; 288 289 inline void SetInhBorderWidths( sal_uInt16 nLeft, sal_uInt16 nRight ); 290 291 292 void GetAvail( sal_uInt16 nCol, sal_uInt16 nColSpan, sal_uInt16& rAbsAvail, 293 sal_uInt16& rRelAvail ) const; 294 295 void AutoLayoutPass1(); 296 void AutoLayoutPass2( sal_uInt16 nAbsAvail, sal_uInt16 nRelAvail, 297 sal_uInt16 nAbsLeftSpace, sal_uInt16 nAbsRightSpace, 298 sal_uInt16 nParentInhSpace ); 299 void SetWidths( sal_Bool bCallPass2=sal_False, sal_uInt16 nAbsAvail=0, 300 sal_uInt16 nRelAvail=0, sal_uInt16 nAbsLeftSpace=0, 301 sal_uInt16 nAbsRightSpace=0, 302 sal_uInt16 nParentInhSpace=0 ); 303 304 inline SwHTMLTableLayoutColumn *GetColumn( sal_uInt16 nCol ) const; 305 inline void SetColumn( SwHTMLTableLayoutColumn *pCol, sal_uInt16 nCol ); 306 307 inline SwHTMLTableLayoutCell *GetCell( sal_uInt16 nRow, sal_uInt16 nCol ) const; 308 inline void SetCell( SwHTMLTableLayoutCell *pCell, sal_uInt16 nRow, sal_uInt16 nCol ); 309 310 void SetLeftFillerBox( SwTableBox *pBox ) { pLeftFillerBox = pBox; } 311 void SetRightFillerBox( SwTableBox *pBox ) { pRightFillerBox = pBox; } 312 313 sal_uLong GetMin() const { return nMin; } 314 sal_uLong GetMax() const { return nMax; } 315 sal_uInt16 GetRelLeftFill() const { return nRelLeftFill; } 316 sal_uInt16 GetRelRightFill() const { return nRelRightFill; } 317 318 inline long GetBrowseWidthMin() const; 319 320 sal_Bool HasColsOption() const { return bColsOption; } 321 sal_Bool HasColTags() const { return bColTags; } 322 323 sal_Bool IsTopTable() const { return pSwTable != 0; } 324 325 void SetMustResize( sal_Bool bSet ) { bMustResize = bSet; } 326 void SetMustNotResize( sal_Bool bSet ) { bMustNotResize = bSet; } 327 void SetMustNotRecalc( sal_Bool bSet ) { bMustNotRecalc = bSet; } 328 329 // Neueberechnung der Tabellenbreiten fuer die uebergebene verfuegbare 330 // Breite. 331 // - Wenn bRecalc gesetzt ist, werden auch der Inhalt der Boxen 332 // zur Berechnung herangezogen. 333 // neu berechnet. 334 // - Wenn bForce gesetzt ist, wird die Tabelle auch neu berechnet, wenn 335 // dies mit SetMustNotResize unterdrueckt werden soll. 336 // - Wenn nDelay>0 wird die Berechnung entsprechend verzoegert. 337 // Innerhalb der Verzeoegerung auftretende Resize-Aufrufe werden 338 // ignoriert, die Verzeogerung wird aber ggf. uebernommen. 339 // - Wenn nDelay==HTMLTABLE_RESIZE_NOW ist, wird sofort Resized und 340 // eventuell noch asstehende Resize-Aufrufe werden nicht mehr 341 // ausgefuehrt. 342 // - Der Rueckgabewert gibt an, ob sich die Tabelle geaendert hat. 343 sal_Bool Resize( sal_uInt16 nAbsAvail, sal_Bool bRecalc=sal_False, sal_Bool bForce=sal_False, 344 sal_uLong nDelay=0 ); 345 346 void BordersChanged( sal_uInt16 nAbsAvail, sal_Bool bRecalc=sal_False ); 347 348 // Ermitteln der verfuegbaren Breite. Das geht nur, wenn ein Layout 349 // oder eine ViewShell vorhanden ist. Sonst wird 0 zurueckgegeben. 350 // (Wird vom HTML-Filter benoetigt, da der nicht an das Layout kommt.) 351 static sal_uInt16 GetBrowseWidth( const SwDoc& rDoc ); 352 353 // Ermitteln der verfuegbaren Breite uber den Tabellen-Frame 354 sal_uInt16 GetBrowseWidthByTabFrm( const SwTabFrm& rTabFrm ) const; 355 356 // Ermitteln der verfuegbaren Breite uber den Tabellen-Frame oder 357 // das statische GetBrowseWidth, wenn kein Layout existiert. 358 sal_uInt16 GetBrowseWidthByTable( const SwDoc& rDoc ) const; 359 360 // Fuer Export 361 sal_uInt16 GetWidthOption() const { return nWidthOption; } 362 sal_Bool HasPrcWidthOption() const { return bPrcWidthOption; } 363 364 sal_uInt16 GetCellPadding() const { return nCellPadding; } 365 sal_uInt16 GetCellSpacing() const { return nCellSpacing; } 366 sal_uInt16 GetBorder() const { return nBorder; } 367 368 sal_uInt16 GetRowCount() const { return nRows; } 369 sal_uInt16 GetColCount() const { return nCols; } 370 371 void SetExportable( sal_Bool bSet ) { bExportable = bSet; } 372 sal_Bool IsExportable() const { return bExportable; } 373 374 sal_Bool HaveBordersChanged() const { return bBordersChanged; } 375 376 void SetMayBeInFlyFrame( sal_Bool bSet ) { bMayBeInFlyFrame = bSet; } 377 sal_Bool MayBeInFlyFrame() const { return bMayBeInFlyFrame; } 378 }; 379 380 /* */ 381 382 inline void SwHTMLTableLayoutCell::SetProtected() 383 { 384 nRowSpan = 1; 385 nColSpan = 1; 386 387 pContents = 0; 388 } 389 390 /* */ 391 392 inline void SwHTMLTableLayoutColumn::MergeMinMaxNoAlign( sal_uLong nCMin, 393 sal_uLong nCMax, sal_uLong nAbsMin ) 394 { 395 if( nCMin > nMinNoAlign ) 396 nMinNoAlign = nCMin; 397 if( nCMax > nMaxNoAlign ) 398 nMaxNoAlign = nCMax; 399 if( nAbsMin > nAbsMinNoAlign ) 400 nAbsMinNoAlign = nAbsMin; 401 } 402 403 inline void SwHTMLTableLayoutColumn::ClearPass1Info( sal_Bool bWidthOpt ) 404 { 405 nMinNoAlign = nMaxNoAlign = nAbsMinNoAlign = MINLAY; 406 nMin = nMax = 0; 407 if( bWidthOpt ) 408 { 409 nWidthOption = 0; 410 bRelWidthOption = sal_False; 411 } 412 } 413 414 inline void SwHTMLTableLayoutColumn::MergeCellWidthOption( 415 sal_uInt16 nWidth, sal_Bool bRel ) 416 { 417 if( !nWidthOption || 418 (bRel==bRelWidthOption && nWidthOption < nWidth) ) 419 { 420 nWidthOption = nWidth; 421 bRelWidthOption = bRel; 422 } 423 } 424 425 inline void SwHTMLTableLayoutColumn::SetMinMax( sal_uLong nMn, sal_uLong nMx ) 426 { 427 nMin = nMn; 428 nMax = nMx; 429 } 430 431 /* */ 432 433 inline sal_uInt16 SwHTMLTableLayout::GetInhCellSpace( sal_uInt16 nCol, 434 sal_uInt16 nColSpan ) const 435 { 436 sal_uInt16 nSpace = 0; 437 if( nCol==0 ) 438 nSpace = nSpace + sal::static_int_cast< sal_uInt16 >(nInhAbsLeftSpace); 439 if( nCol+nColSpan==nCols ) 440 nSpace = nSpace + sal::static_int_cast< sal_uInt16 >(nInhAbsRightSpace); 441 442 return nSpace; 443 } 444 445 inline SwHTMLTableLayoutColumn *SwHTMLTableLayout::GetColumn( sal_uInt16 nCol ) const 446 { 447 return aColumns[nCol]; 448 } 449 450 inline void SwHTMLTableLayoutColumn::SetWidthOption( 451 sal_uInt16 nWidth, sal_Bool bRelWidth, sal_Bool bTest ) 452 { 453 if( bTest && bRelWidthOption==bRelWidth ) 454 { 455 if( nWidth > nWidthOption ) 456 nWidthOption = nWidth; 457 } 458 else 459 nWidthOption = nWidth; 460 bRelWidthOption = bRelWidth; 461 } 462 463 inline void SwHTMLTableLayout::SetColumn( SwHTMLTableLayoutColumn *pCol, sal_uInt16 nCol ) 464 { 465 aColumns[nCol] = pCol; 466 } 467 468 inline SwHTMLTableLayoutCell *SwHTMLTableLayout::GetCell( sal_uInt16 nRow, sal_uInt16 nCol ) const 469 { 470 return aCells[nRow*nCols+nCol]; 471 } 472 473 inline void SwHTMLTableLayout::SetCell( SwHTMLTableLayoutCell *pCell, 474 sal_uInt16 nRow, sal_uInt16 nCol ) 475 { 476 aCells[nRow*nCols+nCol] = pCell; 477 } 478 479 inline long SwHTMLTableLayout::GetBrowseWidthMin() const 480 { 481 return (long)( (!nWidthOption || bPrcWidthOption) ? nMin : nRelTabWidth ); 482 } 483 484 void SwHTMLTableLayout::SetInhBorderWidths( sal_uInt16 nLeft, sal_uInt16 nRight ) 485 { 486 nInhLeftBorderWidth = nLeft; 487 nInhRightBorderWidth = nRight; 488 } 489 490 491 #endif 492