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