LCOV - code coverage report
Current view: top level - sw/source/core/doc - htmltbl.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 742 0.0 %
Date: 2012-08-25 Functions: 0 38 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 801 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : #include "hintids.hxx"
      30                 :            : 
      31                 :            : #include <vcl/wrkwin.hxx>
      32                 :            : #include <vcl/svapp.hxx>
      33                 :            : #include <sot/storage.hxx>
      34                 :            : #include <fmtornt.hxx>
      35                 :            : #include <fmtfsize.hxx>
      36                 :            : #include <frmfmt.hxx>
      37                 :            : #include <docary.hxx>
      38                 :            : #include "ndtxt.hxx"
      39                 :            : #include "doc.hxx"
      40                 :            : #include "swtable.hxx"
      41                 :            : #include "rootfrm.hxx"
      42                 :            : #include "docsh.hxx"
      43                 :            : #include "flyfrm.hxx"
      44                 :            : #include "poolfmt.hxx"
      45                 :            : #include "viewsh.hxx"
      46                 :            : #include "tabfrm.hxx"
      47                 :            : #include "viewopt.hxx"
      48                 :            : #include "htmltbl.hxx"
      49                 :            : #include "ndindex.hxx"
      50                 :            : #include "switerator.hxx"
      51                 :            : #include <boost/foreach.hpp>
      52                 :            : 
      53                 :            : using namespace ::com::sun::star;
      54                 :            : 
      55                 :            : 
      56                 :            : #define COLFUZZY 20
      57                 :            : #define MAX_TABWIDTH (USHRT_MAX - 2001)
      58                 :            : 
      59                 :            : 
      60                 :            : class SwHTMLTableLayoutConstraints
      61                 :            : {
      62                 :            :     sal_uInt16 nRow;                    // start row
      63                 :            :     sal_uInt16 nCol;                    // start column
      64                 :            :     sal_uInt16 nColSpan;                // the column's COLSPAN
      65                 :            : 
      66                 :            :     SwHTMLTableLayoutConstraints *pNext;        // the next constraint
      67                 :            : 
      68                 :            :     sal_uLong nMinNoAlign, nMaxNoAlign; // provisional result of AL-Pass 1
      69                 :            : 
      70                 :            : public:
      71                 :            : 
      72                 :            :     SwHTMLTableLayoutConstraints( sal_uLong nMin, sal_uLong nMax, sal_uInt16 nRow,
      73                 :            :                                 sal_uInt16 nCol, sal_uInt16 nColSp );
      74                 :            :     ~SwHTMLTableLayoutConstraints();
      75                 :            : 
      76                 :          0 :     sal_uLong GetMinNoAlign() const { return nMinNoAlign; }
      77                 :          0 :     sal_uLong GetMaxNoAlign() const { return nMaxNoAlign; }
      78                 :            : 
      79                 :            :     SwHTMLTableLayoutConstraints *InsertNext( SwHTMLTableLayoutConstraints *pNxt );
      80                 :          0 :     SwHTMLTableLayoutConstraints* GetNext() const { return pNext; }
      81                 :            : 
      82                 :          0 :     sal_uInt16 GetRow() const { return nRow; }
      83                 :            : 
      84                 :          0 :     sal_uInt16 GetColSpan() const { return nColSpan; }
      85                 :          0 :     sal_uInt16 GetColumn() const { return nCol; }
      86                 :            : };
      87                 :            : 
      88                 :            : 
      89                 :          0 : SwHTMLTableLayoutCnts::SwHTMLTableLayoutCnts( const SwStartNode *pSttNd,
      90                 :            :                                           SwHTMLTableLayout* pTab,
      91                 :            :                                           sal_Bool bNoBrTag,
      92                 :            :                                           SwHTMLTableLayoutCnts* pNxt ) :
      93                 :            :     pNext( pNxt ), pBox( 0 ), pTable( pTab ), pStartNode( pSttNd ),
      94                 :          0 :     nPass1Done( 0 ), nWidthSet( 0 ), bNoBreakTag( bNoBrTag )
      95                 :          0 : {}
      96                 :            : 
      97                 :          0 : SwHTMLTableLayoutCnts::~SwHTMLTableLayoutCnts()
      98                 :            : {
      99         [ #  # ]:          0 :     delete pNext;
     100         [ #  # ]:          0 :     delete pTable;
     101                 :          0 : }
     102                 :            : 
     103                 :          0 : const SwStartNode *SwHTMLTableLayoutCnts::GetStartNode() const
     104                 :            : {
     105         [ #  # ]:          0 :     return pBox ? pBox->GetSttNd() : pStartNode;
     106                 :            : }
     107                 :            : 
     108                 :            : 
     109                 :          0 : SwHTMLTableLayoutCell::SwHTMLTableLayoutCell( SwHTMLTableLayoutCnts *pCnts,
     110                 :            :                                           sal_uInt16 nRSpan, sal_uInt16 nCSpan,
     111                 :            :                                           sal_uInt16 nWidth, sal_Bool bPrcWidth,
     112                 :            :                                           sal_Bool bNWrapOpt ) :
     113                 :            :     pContents( pCnts ),
     114                 :            :     nRowSpan( nRSpan ), nColSpan( nCSpan ),
     115                 :            :     nWidthOption( nWidth ), bPrcWidthOption( bPrcWidth ),
     116                 :          0 :     bNoWrapOption( bNWrapOpt )
     117                 :          0 : {}
     118                 :            : 
     119                 :          0 : SwHTMLTableLayoutCell::~SwHTMLTableLayoutCell()
     120                 :            : {
     121 [ #  # ][ #  # ]:          0 :     if( nRowSpan==1 && nColSpan==1 )
     122                 :            :     {
     123         [ #  # ]:          0 :         delete pContents;
     124                 :            :     }
     125                 :          0 : }
     126                 :            : 
     127                 :            : 
     128                 :          0 : SwHTMLTableLayoutColumn::SwHTMLTableLayoutColumn( sal_uInt16 nWidth,
     129                 :            :                                                   sal_Bool bRelWidth,
     130                 :            :                                                   sal_Bool bLBorder ) :
     131                 :            :     nMinNoAlign(MINLAY), nMaxNoAlign(MINLAY), nAbsMinNoAlign(MINLAY),
     132                 :            :     nMin(0), nMax(0),
     133                 :            :     nAbsColWidth(0), nRelColWidth(0),
     134                 :            :     nWidthOption( nWidth ), bRelWidthOption( bRelWidth ),
     135                 :          0 :     bLeftBorder( bLBorder )
     136                 :          0 : {}
     137                 :            : 
     138                 :            : 
     139                 :          0 : SwHTMLTableLayoutConstraints::SwHTMLTableLayoutConstraints(
     140                 :            :     sal_uLong nMin, sal_uLong nMax, sal_uInt16 nRw, sal_uInt16 nColumn, sal_uInt16 nColSp ):
     141                 :            :     nRow( nRw ), nCol( nColumn ), nColSpan( nColSp ),
     142                 :            :     pNext( 0 ),
     143                 :          0 :     nMinNoAlign( nMin ), nMaxNoAlign( nMax )
     144                 :          0 : {}
     145                 :            : 
     146                 :          0 : SwHTMLTableLayoutConstraints::~SwHTMLTableLayoutConstraints()
     147                 :            : {
     148         [ #  # ]:          0 :     delete pNext;
     149                 :          0 : }
     150                 :            : 
     151                 :          0 : SwHTMLTableLayoutConstraints *SwHTMLTableLayoutConstraints::InsertNext(
     152                 :            :     SwHTMLTableLayoutConstraints *pNxt )
     153                 :            : {
     154                 :          0 :     SwHTMLTableLayoutConstraints *pPrev = 0;
     155                 :          0 :     SwHTMLTableLayoutConstraints *pConstr = this;
     156         [ #  # ]:          0 :     while( pConstr )
     157                 :            :     {
     158   [ #  #  #  # ]:          0 :         if( pConstr->GetRow() > pNxt->GetRow() ||
                 [ #  # ]
     159                 :          0 :             pConstr->GetColumn() > pNxt->GetColumn() )
     160                 :          0 :             break;
     161                 :          0 :         pPrev = pConstr;
     162                 :          0 :         pConstr = pConstr->GetNext();
     163                 :            :     }
     164                 :            : 
     165         [ #  # ]:          0 :     if( pPrev )
     166                 :            :     {
     167                 :          0 :         pNxt->pNext = pPrev->GetNext();
     168                 :          0 :         pPrev->pNext = pNxt;
     169                 :          0 :         pConstr = this;
     170                 :            :     }
     171                 :            :     else
     172                 :            :     {
     173                 :          0 :         pNxt->pNext = this;
     174                 :          0 :         pConstr = pNxt;
     175                 :            :     }
     176                 :            : 
     177                 :          0 :     return pConstr;
     178                 :            : }
     179                 :            : 
     180                 :            : 
     181                 :            : typedef SwHTMLTableLayoutColumn *SwHTMLTableLayoutColumnPtr;
     182                 :            : typedef SwHTMLTableLayoutCell *SwHTMLTableLayoutCellPtr;
     183                 :            : 
     184                 :          0 : SwHTMLTableLayout::SwHTMLTableLayout(
     185                 :            :                         const SwTable * pSwTbl,
     186                 :            :                         sal_uInt16 nRws, sal_uInt16 nCls, sal_Bool bColsOpt, sal_Bool bColTgs,
     187                 :            :                         sal_uInt16 nWdth, sal_Bool bPrcWdth, sal_uInt16 nBorderOpt,
     188                 :            :                         sal_uInt16 nCellPad, sal_uInt16 nCellSp, SvxAdjust eAdjust,
     189                 :            :                         sal_uInt16 nLMargin, sal_uInt16 nRMargin,
     190                 :            :                         sal_uInt16 nBWidth, sal_uInt16 nLeftBWidth,
     191                 :            :                         sal_uInt16 nRightBWidth,
     192                 :            :                         sal_uInt16 nInhLeftBWidth, sal_uInt16 nInhRightBWidth ) :
     193         [ #  # ]:          0 :     aColumns( new SwHTMLTableLayoutColumnPtr[nCls] ),
     194         [ #  # ]:          0 :     aCells( new SwHTMLTableLayoutCellPtr[nRws*nCls] ),
     195                 :            :     pSwTable( pSwTbl ), pLeftFillerBox( 0 ), pRightFillerBox( 0 ),
     196                 :            :     nMin( 0 ), nMax( 0 ),
     197                 :            :     nRows( nRws ), nCols( nCls ),
     198                 :            :     nLeftMargin( nLMargin ), nRightMargin( nRMargin ),
     199                 :            :     nInhAbsLeftSpace( 0 ), nInhAbsRightSpace( 0 ),
     200                 :            :     nRelLeftFill( 0 ), nRelRightFill( 0 ),
     201                 :            :     nRelTabWidth( 0 ), nWidthOption( nWdth ),
     202                 :            :     nCellPadding( nCellPad ), nCellSpacing( nCellSp ), nBorder( nBorderOpt ),
     203                 :            :     nLeftBorderWidth( nLeftBWidth ), nRightBorderWidth( nRightBWidth ),
     204                 :            :     nInhLeftBorderWidth( nInhLeftBWidth ),
     205                 :            :     nInhRightBorderWidth( nInhRightBWidth ),
     206                 :            :     nBorderWidth( nBWidth ),
     207                 :            :     nDelayedResizeAbsAvail( 0 ), nLastResizeAbsAvail( 0 ),
     208                 :            :     nPass1Done( 0 ), nWidthSet( 0 ), eTableAdjust( eAdjust ),
     209                 :            :     bColsOption( bColsOpt ), bColTags( bColTgs ),
     210                 :            :     bPrcWidthOption( bPrcWdth ), bUseRelWidth( sal_False ),
     211                 :            :     bMustResize( sal_True ), bExportable( sal_True ), bBordersChanged( sal_False ),
     212                 :          0 :     bMustNotResize( sal_False ), bMustNotRecalc( sal_False )
     213                 :            : {
     214                 :            :     aResizeTimer.SetTimeoutHdl( STATIC_LINK( this, SwHTMLTableLayout,
     215         [ #  # ]:          0 :                                              DelayedResize_Impl ) );
     216                 :          0 : }
     217                 :            : 
     218                 :          0 : SwHTMLTableLayout::~SwHTMLTableLayout()
     219                 :            : {
     220                 :            :     sal_uInt16 i;
     221                 :            : 
     222         [ #  # ]:          0 :     for( i = 0; i < nCols; i++ )
     223         [ #  # ]:          0 :         delete aColumns[i];
     224         [ #  # ]:          0 :     delete[] aColumns;
     225                 :            : 
     226                 :          0 :     sal_uInt16 nCount = nRows*nCols;
     227         [ #  # ]:          0 :     for( i=0; i<nCount; i++ )
     228 [ #  # ][ #  # ]:          0 :         delete aCells[i];
     229         [ #  # ]:          0 :     delete[] aCells;
     230                 :          0 : }
     231                 :            : 
     232                 :            : // The border width are calculated like in Netscape:
     233                 :            : // Outer border: BORDER + CELLSPACING + CELLPADDING
     234                 :            : // Inner border: CELLSPACING + CELLPADDING
     235                 :            : // However, we respect the border width in SW if bSwBorders is set,
     236                 :            : // so that we don't wrap wrongly.
     237                 :            : // We also need to respect the distance to the content. Even if
     238                 :            : // only the opposite side has a border.
     239                 :          0 : sal_uInt16 SwHTMLTableLayout::GetLeftCellSpace( sal_uInt16 nCol, sal_uInt16 nColSpan,
     240                 :            :                                             sal_Bool bSwBorders ) const
     241                 :            : {
     242                 :          0 :     sal_uInt16 nSpace = nCellSpacing + nCellPadding;
     243                 :            : 
     244         [ #  # ]:          0 :     if( nCol == 0 )
     245                 :            :     {
     246                 :          0 :         nSpace = nSpace + nBorder;
     247                 :            : 
     248 [ #  # ][ #  # ]:          0 :         if( bSwBorders && nSpace < nLeftBorderWidth )
     249                 :          0 :             nSpace = nLeftBorderWidth;
     250                 :            :     }
     251         [ #  # ]:          0 :     else if( bSwBorders )
     252                 :            :     {
     253         [ #  # ]:          0 :         if( GetColumn(nCol)->HasLeftBorder() )
     254                 :            :         {
     255         [ #  # ]:          0 :             if( nSpace < nBorderWidth )
     256                 :          0 :                 nSpace = nBorderWidth;
     257                 :            :         }
     258 [ #  # ][ #  # ]:          0 :         else if( nCol+nColSpan == nCols && nRightBorderWidth &&
                 [ #  # ]
     259                 :            :                  nSpace < MIN_BORDER_DIST )
     260                 :            :         {
     261                 :            :             OSL_ENSURE( !nCellPadding, "GetLeftCellSpace: CELLPADDING!=0" );
     262                 :            :             // If the opposite side has a border we need to respect at
     263                 :            :             // least the minimum distance to the content.
     264                 :            :             // Additionally, we could also use nCellPadding for this.
     265                 :          0 :             nSpace = MIN_BORDER_DIST;
     266                 :            :         }
     267                 :            :     }
     268                 :            : 
     269                 :          0 :     return nSpace;
     270                 :            : }
     271                 :            : 
     272                 :          0 : sal_uInt16 SwHTMLTableLayout::GetRightCellSpace( sal_uInt16 nCol, sal_uInt16 nColSpan,
     273                 :            :                                              sal_Bool bSwBorders ) const
     274                 :            : {
     275                 :          0 :     sal_uInt16 nSpace = nCellPadding;
     276                 :            : 
     277         [ #  # ]:          0 :     if( nCol+nColSpan == nCols )
     278                 :            :     {
     279                 :          0 :         nSpace += nBorder + nCellSpacing;
     280 [ #  # ][ #  # ]:          0 :         if( bSwBorders && nSpace < nRightBorderWidth )
     281                 :          0 :             nSpace = nRightBorderWidth;
     282                 :            :     }
     283 [ #  # ][ #  # ]:          0 :     else if( bSwBorders && GetColumn(nCol)->HasLeftBorder() &&
         [ #  # ][ #  # ]
     284                 :            :              nSpace < MIN_BORDER_DIST )
     285                 :            :     {
     286                 :            :         OSL_ENSURE( !nCellPadding, "GetRightCellSpace: CELLPADDING!=0" );
     287                 :            :         // If the opposite side has a border we need to respect at
     288                 :            :         // least the minimum distance to the content.
     289                 :            :         // Additionally, we could also use nCellPadding for this.
     290                 :          0 :         nSpace = MIN_BORDER_DIST;
     291                 :            :     }
     292                 :            : 
     293                 :          0 :     return nSpace;
     294                 :            : }
     295                 :            : 
     296                 :          0 : void SwHTMLTableLayout::AddBorderWidth( sal_uLong &rMin, sal_uLong &rMax,
     297                 :            :                                         sal_uLong &rAbsMin,
     298                 :            :                                         sal_uInt16 nCol, sal_uInt16 nColSpan,
     299                 :            :                                         sal_Bool bSwBorders ) const
     300                 :            : {
     301                 :          0 :     sal_uLong nAdd = GetLeftCellSpace( nCol, nColSpan, bSwBorders ) +
     302                 :          0 :                  GetRightCellSpace( nCol, nColSpan, bSwBorders );
     303                 :            : 
     304                 :          0 :     rMin += nAdd;
     305                 :          0 :     rMax += nAdd;
     306                 :          0 :     rAbsMin += nAdd;
     307                 :          0 : }
     308                 :            : 
     309                 :          0 : void SwHTMLTableLayout::SetBoxWidth( SwTableBox *pBox, sal_uInt16 nCol,
     310                 :            :                              sal_uInt16 nColSpan ) const
     311                 :            : {
     312                 :          0 :     SwFrmFmt *pFrmFmt = pBox->GetFrmFmt();
     313                 :            : 
     314                 :            :     // calculate the box's width
     315                 :          0 :     SwTwips nFrmWidth = 0;
     316         [ #  # ]:          0 :     while( nColSpan-- )
     317                 :          0 :         nFrmWidth += GetColumn( nCol++ )->GetRelColWidth();
     318                 :            : 
     319                 :            :     // and reset
     320         [ #  # ]:          0 :     pFrmFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, nFrmWidth, 0 ));
     321                 :          0 : }
     322                 :            : 
     323                 :          0 : void SwHTMLTableLayout::GetAvail( sal_uInt16 nCol, sal_uInt16 nColSpan,
     324                 :            :                                   sal_uInt16& rAbsAvail, sal_uInt16& rRelAvail ) const
     325                 :            : {
     326                 :          0 :     rAbsAvail = 0;
     327                 :          0 :     rRelAvail = 0;
     328         [ #  # ]:          0 :     for( sal_uInt16 i=nCol; i<nCol+nColSpan;i++ )
     329                 :            :     {
     330                 :          0 :         const SwHTMLTableLayoutColumn *pColumn = GetColumn(i);
     331                 :          0 :         rAbsAvail = rAbsAvail + pColumn->GetAbsColWidth();
     332                 :          0 :         rRelAvail = rRelAvail + pColumn->GetRelColWidth();
     333                 :            :     }
     334                 :          0 : }
     335                 :            : 
     336                 :          0 : sal_uInt16 SwHTMLTableLayout::GetBrowseWidthByVisArea( const SwDoc& rDoc )
     337                 :            : {
     338                 :          0 :     ViewShell *pVSh = 0;
     339         [ #  # ]:          0 :     rDoc.GetEditShell( &pVSh );
     340         [ #  # ]:          0 :     if( pVSh )
     341                 :            :     {
     342         [ #  # ]:          0 :         return (sal_uInt16)pVSh->GetBrowseWidth();
     343                 :            :     }
     344                 :            : 
     345                 :          0 :     return 0;
     346                 :            : }
     347                 :            : 
     348                 :          0 : sal_uInt16 SwHTMLTableLayout::GetBrowseWidth( const SwDoc& rDoc )
     349                 :            : {
     350                 :            :     // If we have a layout, we can get the width from there.
     351                 :          0 :     const SwRootFrm *pRootFrm = rDoc.GetCurrentLayout();    //swmod 080218
     352         [ #  # ]:          0 :     if( pRootFrm )
     353                 :            :     {
     354                 :          0 :         const SwFrm *pPageFrm = pRootFrm->GetLower();
     355         [ #  # ]:          0 :         if( pPageFrm )
     356                 :          0 :             return (sal_uInt16)pPageFrm->Prt().Width();
     357                 :            :     }
     358                 :            : 
     359                 :            :     // #i91658#
     360                 :            :     // Assertion removed which state that no browse width is available.
     361                 :            :     // Investigation reveals that all calls can handle the case that no browse
     362                 :            :     // width is provided.
     363                 :          0 :     return GetBrowseWidthByVisArea( rDoc );
     364                 :            : }
     365                 :            : 
     366                 :          0 : sal_uInt16 SwHTMLTableLayout::GetBrowseWidthByTabFrm(
     367                 :            :     const SwTabFrm& rTabFrm ) const
     368                 :            : {
     369                 :          0 :     SwTwips nWidth = 0;
     370                 :            : 
     371                 :          0 :     const SwFrm *pUpper = rTabFrm.GetUpper();
     372 [ #  # ][ #  # ]:          0 :     if( MayBeInFlyFrame() && pUpper->IsFlyFrm() &&
         [ #  # ][ #  # ]
     373         [ #  # ]:          0 :         ((const SwFlyFrm *)pUpper)->GetAnchorFrm() )
     374                 :            :     {
     375                 :            :         // If the table is located within a self-created frame, the anchor's
     376                 :            :         // width is relevant not the frame's width.
     377                 :            :         // For paragraph-bound frames we don't respect paragraph indents.
     378         [ #  # ]:          0 :         const SwFrm *pAnchor = ((const SwFlyFrm *)pUpper)->GetAnchorFrm();
     379         [ #  # ]:          0 :         if( pAnchor->IsTxtFrm() )
     380                 :          0 :             nWidth = pAnchor->Frm().Width();
     381                 :            :         else
     382                 :          0 :             nWidth = pAnchor->Prt().Width();
     383                 :            :     }
     384                 :            :     else
     385                 :            :     {
     386                 :          0 :         nWidth = pUpper->Prt().Width();
     387                 :            :     }
     388                 :            : 
     389                 :          0 :     SwTwips nUpperDummy = 0;
     390                 :          0 :     long nRightOffset = 0,
     391                 :          0 :          nLeftOffset  = 0;
     392         [ #  # ]:          0 :     rTabFrm.CalcFlyOffsets( nUpperDummy, nLeftOffset, nRightOffset );
     393                 :          0 :     nWidth -= (nLeftOffset + nRightOffset);
     394                 :            : 
     395         [ #  # ]:          0 :     return nWidth < USHRT_MAX ? static_cast<sal_uInt16>(nWidth) : USHRT_MAX;
     396                 :            : }
     397                 :            : 
     398                 :          0 : sal_uInt16 SwHTMLTableLayout::GetBrowseWidthByTable( const SwDoc& rDoc ) const
     399                 :            : {
     400                 :          0 :     sal_uInt16 nBrowseWidth = 0;
     401                 :          0 :     SwTabFrm* pFrm = SwIterator<SwTabFrm,SwFmt>::FirstElement( *pSwTable->GetFrmFmt() );
     402         [ #  # ]:          0 :     if( pFrm )
     403                 :            :     {
     404                 :          0 :         nBrowseWidth = GetBrowseWidthByTabFrm( *pFrm );
     405                 :            :     }
     406                 :            :     else
     407                 :            :     {
     408                 :          0 :         nBrowseWidth = SwHTMLTableLayout::GetBrowseWidth( rDoc );
     409                 :            :     }
     410                 :            : 
     411                 :          0 :     return nBrowseWidth;
     412                 :            : }
     413                 :            : 
     414                 :          0 : const SwStartNode *SwHTMLTableLayout::GetAnyBoxStartNode() const
     415                 :            : {
     416                 :            :     const SwStartNode *pBoxSttNd;
     417                 :            : 
     418                 :          0 :     const SwTableBox* pBox = pSwTable->GetTabLines()[0]->GetTabBoxes()[0];
     419         [ #  # ]:          0 :     while( 0 == (pBoxSttNd = pBox->GetSttNd()) )
     420                 :            :     {
     421                 :            :         OSL_ENSURE( pBox->GetTabLines().size() > 0,
     422                 :            :                 "Box without start node and lines" );
     423                 :            :         OSL_ENSURE( pBox->GetTabLines().front()->GetTabBoxes().size() > 0,
     424                 :            :                 "Line without boxes" );
     425                 :          0 :         pBox = pBox->GetTabLines().front()->GetTabBoxes().front();
     426                 :            :     }
     427                 :            : 
     428                 :          0 :     return pBoxSttNd;
     429                 :            : }
     430                 :            : 
     431                 :          0 : SwFrmFmt *SwHTMLTableLayout::FindFlyFrmFmt() const
     432                 :            : {
     433                 :          0 :     const SwTableNode *pTblNd = GetAnyBoxStartNode()->FindTableNode();
     434                 :            :     OSL_ENSURE( pTblNd, "Kein Table-Node?" );
     435                 :          0 :     return pTblNd->GetFlyFmt();
     436                 :            : }
     437                 :            : 
     438                 :          0 : static void lcl_GetMinMaxSize( sal_uLong& rMinNoAlignCnts, sal_uLong& rMaxNoAlignCnts,
     439                 :            :                         sal_uLong& rAbsMinNoAlignCnts,
     440                 :            :                         SwTxtNode *pTxtNd, sal_uLong nIdx, sal_Bool bNoBreak )
     441                 :            : {
     442                 :            :     pTxtNd->GetMinMaxSize( nIdx, rMinNoAlignCnts, rMaxNoAlignCnts,
     443                 :          0 :                            rAbsMinNoAlignCnts );
     444                 :            :     OSL_ENSURE( rAbsMinNoAlignCnts <= rMinNoAlignCnts,
     445                 :            :             "GetMinMaxSize: absmin > min" );
     446                 :            :     OSL_ENSURE( rMinNoAlignCnts <= rMaxNoAlignCnts,
     447                 :            :             "GetMinMaxSize: max > min" );
     448                 :            : 
     449                 :            :     // The maximal width for a <PRE> paragraph is the minimal width
     450                 :          0 :     const SwFmtColl *pColl = &pTxtNd->GetAnyFmtColl();
     451         [ #  # ]:          0 :     while( pColl && !pColl->IsDefault() &&
           [ #  #  #  # ]
                 [ #  # ]
     452                 :          0 :             (USER_FMT & pColl->GetPoolFmtId()) )
     453                 :            :     {
     454                 :          0 :         pColl = (const SwFmtColl *)pColl->DerivedFrom();
     455                 :            :     }
     456                 :            : 
     457                 :            :     // <NOBR> in the whole cell apply to text but not to tables.
     458                 :            :     // Netscape only considers this for graphics.
     459 [ #  # ][ #  # ]:          0 :     if( (pColl && RES_POOLCOLL_HTML_PRE==pColl->GetPoolFmtId()) || bNoBreak )
         [ #  # ][ #  # ]
     460                 :            :     {
     461                 :          0 :         rMinNoAlignCnts = rMaxNoAlignCnts;
     462                 :          0 :         rAbsMinNoAlignCnts = rMaxNoAlignCnts;
     463                 :            :     }
     464                 :          0 : }
     465                 :            : 
     466                 :          0 : void SwHTMLTableLayout::AutoLayoutPass1()
     467                 :            : {
     468                 :          0 :     nPass1Done++;
     469                 :            : 
     470                 :          0 :     ClearPass1Info();
     471                 :            : 
     472                 :          0 :     sal_Bool bFixRelWidths = sal_False;
     473                 :            :     sal_uInt16 i;
     474                 :            : 
     475                 :          0 :     SwHTMLTableLayoutConstraints *pConstraints = 0;
     476                 :            : 
     477         [ #  # ]:          0 :     for( i=0; i<nCols; i++ )
     478                 :            :     {
     479                 :          0 :         SwHTMLTableLayoutColumn *pColumn = GetColumn( i );
     480                 :          0 :         pColumn->ClearPass1Info( !HasColTags() );
     481                 :          0 :         sal_uInt16 nMinColSpan = USHRT_MAX; // Column count to which the calculated width refers to
     482                 :          0 :         sal_uInt16 nColSkip = USHRT_MAX;    // How many columns need to be skipped
     483                 :            : 
     484         [ #  # ]:          0 :         for( sal_uInt16 j=0; j<nRows; j++ )
     485                 :            :         {
     486                 :          0 :             SwHTMLTableLayoutCell *pCell = GetCell(j,i);
     487                 :          0 :             SwHTMLTableLayoutCnts *pCnts = pCell->GetContents();
     488                 :            : 
     489                 :            :             // We need to examine all rows in order to
     490                 :            :             // get the column that should be calculated next.
     491                 :          0 :             sal_uInt16 nColSpan = pCell->GetColSpan();
     492         [ #  # ]:          0 :             if( nColSpan < nColSkip )
     493                 :          0 :                 nColSkip = nColSpan;
     494                 :            : 
     495 [ #  # ][ #  # ]:          0 :             if( !pCnts || (pCnts && !pCnts->IsPass1Done(nPass1Done)) )
         [ #  # ][ #  # ]
     496                 :            :             {
     497                 :            :                 // The cell is empty or it's content was not edited
     498         [ #  # ]:          0 :                 if( nColSpan < nMinColSpan )
     499                 :          0 :                     nMinColSpan = nColSpan;
     500                 :            : 
     501                 :          0 :                 sal_uLong nMinNoAlignCell = 0;
     502                 :          0 :                 sal_uLong nMaxNoAlignCell = 0;
     503                 :          0 :                 sal_uLong nAbsMinNoAlignCell = 0;
     504                 :          0 :                 sal_uLong nMaxTableCell = 0;
     505                 :          0 :                 sal_uLong nAbsMinTableCell = 0;
     506                 :            : 
     507         [ #  # ]:          0 :                 while( pCnts )
     508                 :            :                 {
     509                 :          0 :                     const SwStartNode *pSttNd = pCnts->GetStartNode();
     510         [ #  # ]:          0 :                     if( pSttNd )
     511                 :            :                     {
     512                 :          0 :                         const SwDoc *pDoc = pSttNd->GetDoc();
     513                 :          0 :                         sal_uLong nIdx = pSttNd->GetIndex();
     514 [ #  # ][ #  # ]:          0 :                         while( !(pDoc->GetNodes()[nIdx])->IsEndNode() )
                 [ #  # ]
     515                 :            :                         {
     516 [ #  # ][ #  # ]:          0 :                             SwTxtNode *pTxtNd = (pDoc->GetNodes()[nIdx])->GetTxtNode();
     517         [ #  # ]:          0 :                             if( pTxtNd )
     518                 :            :                             {
     519                 :          0 :                                 sal_uLong nMinNoAlignCnts = 0;
     520                 :          0 :                                 sal_uLong nMaxNoAlignCnts = 0;
     521                 :          0 :                                 sal_uLong nAbsMinNoAlignCnts = 0;
     522                 :            : 
     523                 :            :                                 lcl_GetMinMaxSize( nMinNoAlignCnts,
     524                 :            :                                                    nMaxNoAlignCnts,
     525                 :            :                                                    nAbsMinNoAlignCnts,
     526                 :            :                                                    pTxtNd, nIdx,
     527         [ #  # ]:          0 :                                                    pCnts->HasNoBreakTag() );
     528                 :            : 
     529         [ #  # ]:          0 :                                 if( nMinNoAlignCnts > nMinNoAlignCell )
     530                 :          0 :                                     nMinNoAlignCell = nMinNoAlignCnts;
     531         [ #  # ]:          0 :                                 if( nMaxNoAlignCnts > nMaxNoAlignCell )
     532                 :          0 :                                     nMaxNoAlignCell = nMaxNoAlignCnts;
     533         [ #  # ]:          0 :                                 if( nAbsMinNoAlignCnts > nAbsMinNoAlignCell )
     534                 :          0 :                                     nAbsMinNoAlignCell = nAbsMinNoAlignCnts;
     535                 :            :                             }
     536                 :            :                             else
     537                 :            :                             {
     538 [ #  # ][ #  # ]:          0 :                                 SwTableNode *pTabNd = (pDoc->GetNodes()[nIdx])->GetTableNode();
     539         [ #  # ]:          0 :                                 if( pTabNd )
     540                 :            :                                 {
     541                 :          0 :                                     SwHTMLTableLayout *pChild = pTabNd->GetTable().GetHTMLTableLayout();
     542         [ #  # ]:          0 :                                     if( pChild )
     543                 :            :                                     {
     544         [ #  # ]:          0 :                                         pChild->AutoLayoutPass1();
     545                 :          0 :                                         sal_uLong nMaxTableCnts = pChild->nMax;
     546                 :          0 :                                         sal_uLong nAbsMinTableCnts = pChild->nMin;
     547                 :            : 
     548                 :            :                                         // A fixed table width is taken over as minimum and
     549                 :            :                                         // maximum at the same time
     550 [ #  # ][ #  # ]:          0 :                                         if( !pChild->bPrcWidthOption && pChild->nWidthOption )
     551                 :            :                                         {
     552                 :          0 :                                             sal_uLong nTabWidth = pChild->nWidthOption;
     553         [ #  # ]:          0 :                                             if( nTabWidth >= nAbsMinTableCnts  )
     554                 :            :                                             {
     555                 :          0 :                                                 nMaxTableCnts = nTabWidth;
     556                 :          0 :                                                 nAbsMinTableCnts = nTabWidth;
     557                 :            :                                             }
     558                 :            :                                             else
     559                 :            :                                             {
     560                 :          0 :                                                 nMaxTableCnts = nAbsMinTableCnts;
     561                 :            :                                             }
     562                 :            :                                         }
     563                 :            : 
     564         [ #  # ]:          0 :                                         if( nMaxTableCnts > nMaxTableCell )
     565                 :          0 :                                             nMaxTableCell = nMaxTableCnts;
     566         [ #  # ]:          0 :                                         if( nAbsMinTableCnts > nAbsMinTableCell )
     567                 :          0 :                                             nAbsMinTableCell = nAbsMinTableCnts;
     568                 :            :                                     }
     569                 :          0 :                                     nIdx = pTabNd->EndOfSectionNode()->GetIndex();
     570                 :            :                                 }
     571                 :            :                             }
     572                 :          0 :                             nIdx++;
     573                 :            :                         }
     574                 :            :                     }
     575                 :            :                     else
     576                 :            :                     {
     577                 :            :                         OSL_ENSURE( !this, "Sub tables in HTML import?" );
     578                 :          0 :                         SwHTMLTableLayout *pChild = pCnts->GetTable();
     579         [ #  # ]:          0 :                         pChild->AutoLayoutPass1();
     580                 :          0 :                         sal_uLong nMaxTableCnts = pChild->nMax;
     581                 :          0 :                         sal_uLong nAbsMinTableCnts = pChild->nMin;
     582                 :            : 
     583                 :            :                         // A fixed table width is taken over as minimum and
     584                 :            :                         // maximum at the same time
     585 [ #  # ][ #  # ]:          0 :                         if( !pChild->bPrcWidthOption && pChild->nWidthOption )
     586                 :            :                         {
     587                 :          0 :                             sal_uLong nTabWidth = pChild->nWidthOption;
     588         [ #  # ]:          0 :                             if( nTabWidth >= nAbsMinTableCnts  )
     589                 :            :                             {
     590                 :          0 :                                 nMaxTableCnts = nTabWidth;
     591                 :          0 :                                 nAbsMinTableCnts = nTabWidth;
     592                 :            :                             }
     593                 :            :                             else
     594                 :            :                             {
     595                 :          0 :                                 nMaxTableCnts = nAbsMinTableCnts;
     596                 :            :                             }
     597                 :            :                         }
     598                 :            : 
     599         [ #  # ]:          0 :                         if( nMaxTableCnts > nMaxTableCell )
     600                 :          0 :                             nMaxTableCell = nMaxTableCnts;
     601         [ #  # ]:          0 :                         if( nAbsMinTableCnts > nAbsMinTableCell )
     602                 :          0 :                             nAbsMinTableCell = nAbsMinTableCnts;
     603                 :            :                     }
     604                 :          0 :                     pCnts->SetPass1Done( nPass1Done );
     605                 :          0 :                     pCnts = pCnts->GetNext();
     606                 :            :                 }
     607                 :            : 
     608                 :            : // This code previously came after AddBorderWidth
     609                 :            :                 // If a table's width is wider in a cell than what we've calculated
     610                 :            :                 // for the other content we need to use the table's width.
     611         [ #  # ]:          0 :                 if( nMaxTableCell > nMaxNoAlignCell )
     612                 :          0 :                     nMaxNoAlignCell = nMaxTableCell;
     613         [ #  # ]:          0 :                 if( nAbsMinTableCell > nAbsMinNoAlignCell )
     614                 :            :                 {
     615                 :          0 :                     nAbsMinNoAlignCell = nAbsMinTableCell;
     616         [ #  # ]:          0 :                     if( nMinNoAlignCell < nAbsMinNoAlignCell )
     617                 :          0 :                         nMinNoAlignCell = nAbsMinNoAlignCell;
     618         [ #  # ]:          0 :                     if( nMaxNoAlignCell < nMinNoAlignCell )
     619                 :          0 :                         nMaxNoAlignCell = nMinNoAlignCell;
     620                 :            :                 }
     621                 :            : // This code previously came after AddBorderWidth
     622                 :            : 
     623                 :          0 :                 sal_Bool bRelWidth = pCell->IsPrcWidthOption();
     624                 :          0 :                 sal_uInt16 nWidth = pCell->GetWidthOption();
     625                 :            : 
     626                 :            :                 // A NOWRAP option applies to text and tables, but is
     627                 :            :                 // not applied for fixed cell width.
     628                 :            :                 // Instead, the stated cell width behaves like a minimal
     629                 :            :                 // width.
     630         [ #  # ]:          0 :                 if( pCell->HasNoWrapOption() )
     631                 :            :                 {
     632 [ #  # ][ #  # ]:          0 :                     if( nWidth==0 || bRelWidth )
     633                 :            :                     {
     634                 :          0 :                         nMinNoAlignCell = nMaxNoAlignCell;
     635                 :          0 :                         nAbsMinNoAlignCell = nMaxNoAlignCell;
     636                 :            :                     }
     637                 :            :                     else
     638                 :            :                     {
     639         [ #  # ]:          0 :                         if( nWidth>nMinNoAlignCell )
     640                 :          0 :                             nMinNoAlignCell = nWidth;
     641         [ #  # ]:          0 :                         if( nWidth>nAbsMinNoAlignCell )
     642                 :          0 :                             nAbsMinNoAlignCell = nWidth;
     643                 :            :                     }
     644                 :            :                 }
     645                 :            : 
     646                 :            :                 // Respect minimum width for content
     647         [ #  # ]:          0 :                 if( nMinNoAlignCell < MINLAY )
     648                 :          0 :                     nMinNoAlignCell = MINLAY;
     649         [ #  # ]:          0 :                 if( nMaxNoAlignCell < MINLAY )
     650                 :          0 :                     nMaxNoAlignCell = MINLAY;
     651         [ #  # ]:          0 :                 if( nAbsMinNoAlignCell < MINLAY )
     652                 :          0 :                     nAbsMinNoAlignCell = MINLAY;
     653                 :            : 
     654                 :            :                 // Respect the border and distance to the content
     655                 :            :                 AddBorderWidth( nMinNoAlignCell, nMaxNoAlignCell,
     656                 :          0 :                                 nAbsMinNoAlignCell, i, nColSpan );
     657                 :            : 
     658         [ #  # ]:          0 :                 if( 1==nColSpan )
     659                 :            :                 {
     660                 :            :                     // take over the values directly
     661                 :            :                     pColumn->MergeMinMaxNoAlign( nMinNoAlignCell,
     662                 :            :                                                  nMaxNoAlignCell,
     663                 :          0 :                                                  nAbsMinNoAlignCell );
     664                 :            : 
     665                 :            :                     // the widest WIDTH wins
     666         [ #  # ]:          0 :                     if( !HasColTags() )
     667                 :          0 :                         pColumn->MergeCellWidthOption( nWidth, bRelWidth );
     668                 :            :                 }
     669                 :            :                 else
     670                 :            :                 {
     671                 :            :                     // Process the data line by line from left to right at the end
     672                 :            : 
     673                 :            :                     // When which values is taken over will be explained further down.
     674 [ #  # ][ #  # ]:          0 :                     if( !HasColTags() && nWidth && !bRelWidth )
         [ #  # ][ #  # ]
     675                 :            :                     {
     676                 :          0 :                         sal_uLong nAbsWidth = nWidth, nDummy = 0, nDummy2 = 0;
     677                 :            :                         AddBorderWidth( nAbsWidth, nDummy, nDummy2,
     678                 :          0 :                                         i, nColSpan, sal_False );
     679                 :            : 
     680         [ #  # ]:          0 :                         if( nAbsWidth >= nMinNoAlignCell )
     681                 :            :                         {
     682                 :          0 :                             nMaxNoAlignCell = nAbsWidth;
     683         [ #  # ]:          0 :                             if( HasColsOption() )
     684                 :          0 :                                 nMinNoAlignCell = nAbsWidth;
     685                 :            :                         }
     686         [ #  # ]:          0 :                         else if( nAbsWidth >= nAbsMinNoAlignCell )
     687                 :            :                         {
     688                 :          0 :                             nMaxNoAlignCell = nAbsWidth;
     689                 :          0 :                             nMinNoAlignCell = nAbsWidth;
     690                 :            :                         }
     691                 :            :                         else
     692                 :            :                         {
     693                 :          0 :                             nMaxNoAlignCell = nAbsMinNoAlignCell;
     694                 :          0 :                             nMinNoAlignCell = nAbsMinNoAlignCell;
     695                 :            :                         }
     696                 :            :                     }
     697 [ #  # ][ #  # ]:          0 :                     else if( HasColsOption() || HasColTags() )
                 [ #  # ]
     698                 :          0 :                         nMinNoAlignCell = nAbsMinNoAlignCell;
     699                 :            : 
     700                 :            :                     SwHTMLTableLayoutConstraints *pConstr =
     701                 :            :                         new SwHTMLTableLayoutConstraints( nMinNoAlignCell,
     702         [ #  # ]:          0 :                             nMaxNoAlignCell, j, i, nColSpan );
     703         [ #  # ]:          0 :                     if( pConstraints )
     704                 :          0 :                         pConstraints = pConstraints->InsertNext( pConstr );
     705                 :            :                     else
     706                 :          0 :                         pConstraints = pConstr;
     707                 :            :                 }
     708                 :            :             }
     709                 :            :         }
     710                 :            : 
     711                 :            :         OSL_ENSURE( nMinColSpan>0 && nColSkip>0 && nColSkip <= nMinColSpan,
     712                 :            :                 "Layout pass 1: Columns are being forgotten!" );
     713                 :            :         OSL_ENSURE( nMinColSpan!=USHRT_MAX,
     714                 :            :                 "Layout pass 1: unnecessary pass through the loop or a bug" );
     715                 :            : 
     716         [ #  # ]:          0 :         if( 1==nMinColSpan )
     717                 :            :         {
     718                 :            :             // There are cells with COLSPAN 1 and therefore also useful
     719                 :            :             // values in pColumn
     720                 :            : 
     721                 :            :             // Take over values according to the following table (Netscape 4.0 pv 3):
     722                 :            :             //
     723                 :            :             // WIDTH:           no COLS         COLS
     724                 :            :             //
     725                 :            :             // none             min = min       min = absmin
     726                 :            :             //                  max = max       max = max
     727                 :            :             //
     728                 :            :             // >= min           min = min       min = width
     729                 :            :             //                  max = width     max = width
     730                 :            :             //
     731                 :            :             // >= absmin        min = wdith(*)  min = width
     732                 :            :             //                  max = width     max = width
     733                 :            :             //
     734                 :            :             // < absmin         min = absmin    min = absmin
     735                 :            :             //                  max = absmin    max = absmin
     736                 :            :             //
     737                 :            :             // (*) Netscape uses the minimum width without a break before
     738                 :            :             //     the last graphic here. We don't have that (yet?),
     739                 :            :             //     so we leave it set to width.
     740                 :            : 
     741 [ #  # ][ #  # ]:          0 :             if( pColumn->GetWidthOption() && !pColumn->IsRelWidthOption() )
                 [ #  # ]
     742                 :            :             {
     743                 :            :                 // Take over absolute widths as minimal and maximal widths.
     744                 :          0 :                 sal_uLong nAbsWidth = pColumn->GetWidthOption();
     745                 :          0 :                 sal_uLong nDummy = 0, nDummy2 = 0;
     746                 :          0 :                 AddBorderWidth( nAbsWidth, nDummy, nDummy2, i, 1, sal_False );
     747                 :            : 
     748         [ #  # ]:          0 :                 if( nAbsWidth >= pColumn->GetMinNoAlign() )
     749                 :            :                 {
     750                 :          0 :                     pColumn->SetMinMax( HasColsOption() ? nAbsWidth
     751                 :            :                                                    : pColumn->GetMinNoAlign(),
     752         [ #  # ]:          0 :                                         nAbsWidth );
     753                 :            :                 }
     754         [ #  # ]:          0 :                 else if( nAbsWidth >= pColumn->GetAbsMinNoAlign() )
     755                 :            :                 {
     756                 :          0 :                     pColumn->SetMinMax( nAbsWidth, nAbsWidth );
     757                 :            :                 }
     758                 :            :                 else
     759                 :            :                 {
     760                 :            :                     pColumn->SetMinMax( pColumn->GetAbsMinNoAlign(),
     761                 :          0 :                                         pColumn->GetAbsMinNoAlign() );
     762                 :            :                 }
     763                 :            :             }
     764                 :            :             else
     765                 :            :             {
     766                 :          0 :                 pColumn->SetMinMax( HasColsOption() ? pColumn->GetAbsMinNoAlign()
     767                 :            :                                                : pColumn->GetMinNoAlign(),
     768         [ #  # ]:          0 :                                     pColumn->GetMaxNoAlign() );
     769                 :            :             }
     770                 :            :         }
     771         [ #  # ]:          0 :         else if( USHRT_MAX!=nMinColSpan )
     772                 :            :         {
     773                 :            :             // Can be anything != 0, because it is altered by the constraints.
     774                 :          0 :             pColumn->SetMinMax( MINLAY, MINLAY );
     775                 :            : 
     776                 :            :             // the next columns need not to be processed
     777                 :          0 :             i += (nColSkip-1);
     778                 :            :         }
     779                 :            : 
     780                 :          0 :         nMin += pColumn->GetMin();
     781                 :          0 :         nMax += pColumn->GetMax();
     782                 :          0 :         bFixRelWidths |= pColumn->IsRelWidthOption();
     783                 :            :     }
     784                 :            : 
     785                 :            :     // Now process the constraints
     786                 :          0 :     SwHTMLTableLayoutConstraints *pConstr = pConstraints;
     787         [ #  # ]:          0 :     while( pConstr )
     788                 :            :     {
     789                 :            :         // At first we need to process the width in the same way
     790                 :            :         // as the column widths
     791                 :          0 :         sal_uInt16 nCol = pConstr->GetColumn();
     792                 :          0 :         sal_uInt16 nColSpan = pConstr->GetColSpan();
     793                 :          0 :         sal_uLong nConstrMin = pConstr->GetMinNoAlign();
     794                 :          0 :         sal_uLong nConstrMax = pConstr->GetMaxNoAlign();
     795                 :            : 
     796                 :            :         // We get the hitherto width of the spanned columns
     797                 :          0 :         sal_uLong nColsMin = 0;
     798                 :          0 :         sal_uLong nColsMax = 0;
     799         [ #  # ]:          0 :         for( sal_uInt16 j=nCol; j<nCol+nColSpan; j++ )
     800                 :            :         {
     801                 :          0 :             SwHTMLTableLayoutColumn *pColumn = GetColumn( j );
     802                 :          0 :             nColsMin += pColumn->GetMin();
     803                 :          0 :             nColsMax += pColumn->GetMax();
     804                 :            :         }
     805                 :            : 
     806         [ #  # ]:          0 :         if( nColsMin<nConstrMin )
     807                 :            :         {
     808                 :            :             // Proportionately distribute the minimum value to the columns
     809                 :          0 :             sal_uLong nMinD = nConstrMin-nColsMin;
     810                 :            : 
     811         [ #  # ]:          0 :             if( nConstrMin > nColsMax )
     812                 :            :             {
     813                 :            :                 // Proportional according to the minimum widths
     814                 :          0 :                 sal_uInt16 nEndCol = nCol+nColSpan;
     815                 :          0 :                 sal_uLong nDiff = nMinD;
     816         [ #  # ]:          0 :                 for( sal_uInt16 ic=nCol; ic<nEndCol; ic++ )
     817                 :            :                 {
     818                 :          0 :                     SwHTMLTableLayoutColumn *pColumn = GetColumn( ic );
     819                 :            : 
     820                 :          0 :                     sal_uLong nColMin = pColumn->GetMin();
     821                 :          0 :                     sal_uLong nColMax = pColumn->GetMax();
     822                 :            : 
     823                 :          0 :                     nMin -= nColMin;
     824                 :            :                     sal_uLong nAdd = ic<nEndCol-1 ? (nColMin * nMinD) / nColsMin
     825         [ #  # ]:          0 :                                              : nDiff;
     826                 :          0 :                     nColMin += nAdd;
     827                 :          0 :                     nMin += nColMin;
     828                 :            :                     OSL_ENSURE( nDiff >= nAdd, "Ooops: nDiff is not correct anymore" );
     829                 :          0 :                     nDiff -= nAdd;
     830                 :            : 
     831         [ #  # ]:          0 :                     if( nColMax < nColMin )
     832                 :            :                     {
     833                 :          0 :                         nMax -= nColMax;
     834                 :          0 :                         nColsMax -= nColMax;
     835                 :          0 :                         nColMax = nColMin;
     836                 :          0 :                         nMax += nColMax;
     837                 :          0 :                         nColsMax += nColMax;
     838                 :            :                     }
     839                 :            : 
     840                 :          0 :                     pColumn->SetMinMax( nColMin, nColMax );
     841                 :            :                 }
     842                 :            :             }
     843                 :            :             else
     844                 :            :             {
     845                 :            :                 // Proportional according to the difference of max and min
     846         [ #  # ]:          0 :                 for( sal_uInt16 ic=nCol; ic<nCol+nColSpan; ic++ )
     847                 :            :                 {
     848                 :          0 :                     SwHTMLTableLayoutColumn *pColumn = GetColumn( ic );
     849                 :            : 
     850                 :          0 :                     sal_uLong nDiff = pColumn->GetMax()-pColumn->GetMin();
     851         [ #  # ]:          0 :                     if( nMinD < nDiff )
     852                 :          0 :                         nDiff = nMinD;
     853                 :            : 
     854                 :          0 :                     pColumn->AddToMin( nDiff );
     855                 :            : 
     856                 :            :                     OSL_ENSURE( pColumn->GetMax() >= pColumn->GetMin(),
     857                 :            :                             "Why is the Column suddenly too narrow?" );
     858                 :            : 
     859                 :          0 :                     nMin += nDiff;
     860                 :          0 :                     nMinD -= nDiff;
     861                 :            :                 }
     862                 :            :             }
     863                 :            :         }
     864                 :            : 
     865 [ #  # ][ #  # ]:          0 :         if( !HasColTags() && nColsMax<nConstrMax )
                 [ #  # ]
     866                 :            :         {
     867                 :          0 :             sal_uLong nMaxD = nConstrMax-nColsMax;
     868                 :            : 
     869         [ #  # ]:          0 :             for( sal_uInt16 ic=nCol; ic<nCol+nColSpan; ic++ )
     870                 :            :             {
     871                 :          0 :                 SwHTMLTableLayoutColumn *pColumn = GetColumn( ic );
     872                 :            : 
     873                 :          0 :                 nMax -= pColumn->GetMax();
     874                 :            : 
     875                 :          0 :                 pColumn->AddToMax( (pColumn->GetMax() * nMaxD) / nColsMax );
     876                 :            : 
     877                 :          0 :                 nMax += pColumn->GetMax();
     878                 :            :             }
     879                 :            :         }
     880                 :            : 
     881                 :          0 :         pConstr = pConstr->GetNext();
     882                 :            :     }
     883                 :            : 
     884                 :            : 
     885         [ #  # ]:          0 :     if( bFixRelWidths )
     886                 :            :     {
     887         [ #  # ]:          0 :         if( HasColTags() )
     888                 :            :         {
     889                 :            :             // To adapt the relative widths, in a first step we multiply the
     890                 :            :             // minimum width of all affected cells with the relative width
     891                 :            :             // of the column.
     892                 :            :             // Thus, the width ratio among the columns is correct.
     893                 :            :             //
     894                 :            :             // Furthermore, a factor is calculated that says by how much the
     895                 :            :             // cell has gotten wider than the minimum width.
     896                 :            :             //
     897                 :            :             // In the second step the calculated widths are divided by this
     898                 :            :             // factor.  Thereby a cell's width is preserved and serves as a
     899                 :            :             // basis for the other cells.
     900                 :            :             // We only change the maximum widths here!
     901                 :            : 
     902                 :          0 :             sal_uLong nAbsMin = 0;  // absolute minimum width of all widths with relative width
     903                 :          0 :             sal_uLong nRel = 0;     // sum of all relative widths of all columns
     904         [ #  # ]:          0 :             for( i=0; i<nCols; i++ )
     905                 :            :             {
     906                 :          0 :                 SwHTMLTableLayoutColumn *pColumn = GetColumn( i );
     907 [ #  # ][ #  # ]:          0 :                 if( pColumn->IsRelWidthOption() && pColumn->GetWidthOption() )
                 [ #  # ]
     908                 :            :                 {
     909                 :          0 :                     nAbsMin += pColumn->GetMin();
     910                 :          0 :                     nRel += pColumn->GetWidthOption();
     911                 :            :                 }
     912                 :            :             }
     913                 :            : 
     914                 :          0 :             sal_uLong nQuot = ULONG_MAX;
     915         [ #  # ]:          0 :             for( i=0; i<nCols; i++ )
     916                 :            :             {
     917                 :          0 :                 SwHTMLTableLayoutColumn *pColumn = GetColumn( i );
     918         [ #  # ]:          0 :                 if( pColumn->IsRelWidthOption() )
     919                 :            :                 {
     920                 :          0 :                     nMax -= pColumn->GetMax();
     921 [ #  # ][ #  # ]:          0 :                     if( pColumn->GetWidthOption() && pColumn->GetMin() )
                 [ #  # ]
     922                 :            :                     {
     923                 :          0 :                         pColumn->SetMax( nAbsMin * pColumn->GetWidthOption() );
     924                 :          0 :                         sal_uLong nColQuot = pColumn->GetMax() / pColumn->GetMin();
     925         [ #  # ]:          0 :                         if( nColQuot<nQuot )
     926                 :          0 :                             nQuot = nColQuot;
     927                 :            :                     }
     928                 :            :                 }
     929                 :            :             }
     930                 :            :             OSL_ENSURE( 0==nRel || nQuot!=ULONG_MAX,
     931                 :            :                     "Where did the relative columns go?" );
     932         [ #  # ]:          0 :             for( i=0; i<nCols; i++ )
     933                 :            :             {
     934                 :          0 :                 SwHTMLTableLayoutColumn *pColumn = GetColumn( i );
     935         [ #  # ]:          0 :                 if( pColumn->IsRelWidthOption() )
     936                 :            :                 {
     937         [ #  # ]:          0 :                     if( pColumn->GetWidthOption() )
     938                 :          0 :                         pColumn->SetMax( pColumn->GetMax() / nQuot );
     939                 :            :                     else
     940                 :          0 :                         pColumn->SetMax( pColumn->GetMin() );
     941                 :            :                     OSL_ENSURE( pColumn->GetMax() >= pColumn->GetMin(),
     942                 :            :                             "Maximum column width is lower than the minimum column width" );
     943                 :          0 :                     nMax += pColumn->GetMax();
     944                 :            :                 }
     945                 :            :             }
     946                 :            :         }
     947                 :            :         else
     948                 :            :         {
     949                 :          0 :             sal_uInt16 nRel = 0;        // sum of the relative widths of all columns
     950                 :          0 :             sal_uInt16 nRelCols = 0;    // count of the columns with a relative setting
     951                 :          0 :             sal_uLong nRelMax = 0;      // fraction of the maximum of this column
     952         [ #  # ]:          0 :             for( i=0; i<nCols; i++ )
     953                 :            :             {
     954                 :            :                 OSL_ENSURE( nRel<=100, "relative width of all columns > 100%" );
     955                 :          0 :                 SwHTMLTableLayoutColumn *pColumn = GetColumn( i );
     956 [ #  # ][ #  # ]:          0 :                 if( pColumn->IsRelWidthOption() && pColumn->GetWidthOption() )
                 [ #  # ]
     957                 :            :                 {
     958                 :            :                     // Make sure that the relative widths don't go above 100%
     959                 :          0 :                     sal_uInt16 nColWidth = pColumn->GetWidthOption();
     960         [ #  # ]:          0 :                     if( nRel+nColWidth > 100 )
     961                 :            :                     {
     962                 :          0 :                         nColWidth = 100 - nRel;
     963                 :          0 :                         pColumn->SetWidthOption( nColWidth, sal_True, sal_False );
     964                 :            :                     }
     965                 :          0 :                     nRelMax += pColumn->GetMax();
     966                 :          0 :                     nRel = nRel + nColWidth;
     967                 :          0 :                     nRelCols++;
     968                 :            :                 }
     969         [ #  # ]:          0 :                 else if( !pColumn->GetMin() )
     970                 :            :                 {
     971                 :            :                     // The column is empty (so it was solely created by
     972                 :            :                     // COLSPAN) and therefore must not be assigned a % width.
     973                 :          0 :                     nRelCols++;
     974                 :            :                 }
     975                 :            :             }
     976                 :            : 
     977                 :            :             // If there are percentages left we distribute them to the columns
     978                 :            :             // that don't have a width setting. Like in Netscape we distribute
     979                 :            :             // the remaining percentages according to the ratio of the maximum
     980                 :            :             // width of the affected columns.
     981                 :            :             // For the maximum widths we also take the fixed-width columns
     982                 :            :             // into account.  Is that correct?
     983 [ #  # ][ #  # ]:          0 :             if( nRel < 100 && nRelCols < nCols )
     984                 :            :             {
     985                 :          0 :                 sal_uInt16 nRelLeft = 100 - nRel;
     986                 :          0 :                 sal_uLong nFixMax = nMax - nRelMax;
     987         [ #  # ]:          0 :                 for( i=0; i<nCols; i++ )
     988                 :            :                 {
     989                 :          0 :                     SwHTMLTableLayoutColumn *pColumn = GetColumn( i );
     990 [ #  # ][ #  #  :          0 :                     if( !pColumn->IsRelWidthOption() &&
             #  #  #  # ]
     991                 :          0 :                         !pColumn->GetWidthOption() &&
     992                 :          0 :                         pColumn->GetMin() )
     993                 :            :                     {
     994                 :            :                         // the next column gets the rest
     995                 :            :                         sal_uInt16 nColWidth =
     996                 :          0 :                             (sal_uInt16)((pColumn->GetMax() * nRelLeft) / nFixMax);
     997                 :          0 :                         pColumn->SetWidthOption( nColWidth, sal_True, sal_False );
     998                 :            :                     }
     999                 :            :                 }
    1000                 :            :             }
    1001                 :            : 
    1002                 :            :             // adjust the maximum widths now accordingly
    1003                 :          0 :             sal_uLong nQuotMax = ULONG_MAX;
    1004                 :          0 :             sal_uLong nOldMax = nMax;
    1005                 :          0 :             nMax = 0;
    1006         [ #  # ]:          0 :             for( i=0; i<nCols; i++ )
    1007                 :            :             {
    1008                 :            :                 // Columns with a % setting are adapted accordingly.
    1009                 :            :                 // Columns, that
    1010                 :            :                 // - do not have a % setting and are located within a tables
    1011                 :            :                 // with COLS and WIDTH, or
    1012                 :            :                 // - their width is 0%
    1013                 :            :                 // get set to the minimum width.
    1014                 :          0 :                 SwHTMLTableLayoutColumn *pColumn = GetColumn( i );
    1015 [ #  # ][ #  # ]:          0 :                 if( pColumn->IsRelWidthOption() && pColumn->GetWidthOption() )
                 [ #  # ]
    1016                 :            :                 {
    1017                 :            :                     sal_uLong nNewMax;
    1018                 :            :                     sal_uLong nColQuotMax;
    1019         [ #  # ]:          0 :                     if( !nWidthOption )
    1020                 :            :                     {
    1021                 :          0 :                         nNewMax = nOldMax * pColumn->GetWidthOption();
    1022                 :          0 :                         nColQuotMax = nNewMax / pColumn->GetMax();
    1023                 :            :                     }
    1024                 :            :                     else
    1025                 :            :                     {
    1026                 :          0 :                         nNewMax = nMin * pColumn->GetWidthOption();
    1027                 :          0 :                         nColQuotMax = nNewMax / pColumn->GetMin();
    1028                 :            :                     }
    1029                 :          0 :                     pColumn->SetMax( nNewMax );
    1030         [ #  # ]:          0 :                     if( nColQuotMax < nQuotMax )
    1031                 :          0 :                         nQuotMax = nColQuotMax;
    1032                 :            :                 }
    1033 [ #  # ][ #  #  :          0 :                 else if( HasColsOption() || nWidthOption ||
             #  #  #  # ]
                 [ #  # ]
    1034                 :          0 :                          (pColumn->IsRelWidthOption() &&
    1035                 :          0 :                           !pColumn->GetWidthOption()) )
    1036                 :          0 :                     pColumn->SetMax( pColumn->GetMin() );
    1037                 :            :             }
    1038                 :            :             // and divide by the quotient
    1039                 :            :             OSL_ENSURE( nQuotMax!=ULONG_MAX, "Where did the relative columns go?" );
    1040         [ #  # ]:          0 :             for( i=0; i<nCols; i++ )
    1041                 :            :             {
    1042                 :          0 :                 SwHTMLTableLayoutColumn *pColumn = GetColumn( i );
    1043 [ #  # ][ #  # ]:          0 :                 if( pColumn->IsRelWidthOption() && pColumn->GetWidthOption() )
                 [ #  # ]
    1044                 :            :                 {
    1045         [ #  # ]:          0 :                     if( pColumn->GetWidthOption() )
    1046                 :            :                     {
    1047                 :          0 :                         pColumn->SetMax( pColumn->GetMax() / nQuotMax );
    1048                 :            :                         OSL_ENSURE( pColumn->GetMax() >= pColumn->GetMin(),
    1049                 :            :                                 "Minimum width is one column bigger than maximum" );
    1050         [ #  # ]:          0 :                         if( pColumn->GetMax() < pColumn->GetMin() )
    1051                 :          0 :                             pColumn->SetMax( pColumn->GetMin() );
    1052                 :            :                     }
    1053                 :            :                 }
    1054                 :          0 :                 nMax += pColumn->GetMax();
    1055                 :            :             }
    1056                 :            :         }
    1057                 :            :     }
    1058                 :            : 
    1059         [ #  # ]:          0 :     delete pConstraints;
    1060                 :          0 : }
    1061                 :            : 
    1062                 :            : // nAbsAvail is the available space in TWIPS.
    1063                 :            : // nRelAvail is the available space related to USHRT_MAX or 0
    1064                 :            : // nAbsSpace is the fraction of nAbsAvail, which is reserved by the surrounding
    1065                 :            : //           cell for the border and the distance to the paragraph.
    1066                 :          0 : void SwHTMLTableLayout::AutoLayoutPass2( sal_uInt16 nAbsAvail, sal_uInt16 nRelAvail,
    1067                 :            :                                          sal_uInt16 nAbsLeftSpace,
    1068                 :            :                                          sal_uInt16 nAbsRightSpace,
    1069                 :            :                                          sal_uInt16 nParentInhAbsSpace )
    1070                 :            : {
    1071                 :            :     // For a start we do a lot of plausability tests
    1072                 :            : 
    1073                 :            :     // An absolute width always has to be passed
    1074                 :            :     OSL_ENSURE( nAbsAvail, "AutoLayout pass 2: No absolute width given" );
    1075                 :            : 
    1076                 :            :     // A relative width must only be passed for tables within tables (?)
    1077                 :            :     OSL_ENSURE( IsTopTable() == (nRelAvail==0),
    1078                 :            :             "AutoLayout pass 2: Relative width at table in table or the other way around" );
    1079                 :            : 
    1080                 :            :     // The table's minimum width must not be bigger than it's maximum width
    1081                 :            :     OSL_ENSURE( nMin<=nMax, "AutoLayout pass 2: nMin > nMax" );
    1082                 :            : 
    1083                 :            :     // Remember the available width for which the table was calculated.
    1084                 :            :     // This is a good place as we pass by here for the initial calculation
    1085                 :            :     // of the table in the parser and for each _Resize call.
    1086                 :          0 :     nLastResizeAbsAvail = nAbsAvail;
    1087                 :            : 
    1088                 :            :     // Step 1: The available space is readjusted for the left/right border,
    1089                 :            :     // possibly existing filler cells and distances.
    1090                 :            : 
    1091                 :            :     // Distance to the content and border
    1092                 :          0 :     sal_uInt16 nAbsLeftFill = 0, nAbsRightFill = 0;
    1093   [ #  #  #  # ]:          0 :     if( !IsTopTable() &&
                 [ #  # ]
    1094                 :          0 :         GetMin() + nAbsLeftSpace + nAbsRightSpace <= nAbsAvail )
    1095                 :            :     {
    1096                 :          0 :         nAbsLeftFill = nAbsLeftSpace;
    1097                 :          0 :         nAbsRightFill = nAbsRightSpace;
    1098                 :            :     }
    1099                 :            : 
    1100                 :            :     // Left and right distance
    1101 [ #  # ][ #  # ]:          0 :     if( nLeftMargin || nRightMargin )
    1102                 :            :     {
    1103         [ #  # ]:          0 :         if( IsTopTable() )
    1104                 :            :         {
    1105                 :            :             // For the top table we always respect the borders, because we
    1106                 :            :             // never go below the table's minimum width.
    1107                 :          0 :             nAbsAvail -= (nLeftMargin + nRightMargin);
    1108                 :            :         }
    1109         [ #  # ]:          0 :         else if( GetMin() + nLeftMargin + nRightMargin <= nAbsAvail )
    1110                 :            :         {
    1111                 :            :             // Else, we only respect the borders if there's space available
    1112                 :            :             // for them (nMin has already been calculated!)
    1113                 :          0 :             nAbsLeftFill = nAbsLeftFill + nLeftMargin;
    1114                 :          0 :             nAbsRightFill = nAbsRightFill + nRightMargin;
    1115                 :            :         }
    1116                 :            :     }
    1117                 :            : 
    1118                 :            :     // Filler cells
    1119         [ #  # ]:          0 :     if( !IsTopTable() )
    1120                 :            :     {
    1121 [ #  # ][ #  # ]:          0 :         if( pLeftFillerBox && nAbsLeftFill<MINLAY+nInhLeftBorderWidth )
    1122                 :          0 :             nAbsLeftFill = MINLAY+nInhLeftBorderWidth;
    1123 [ #  # ][ #  # ]:          0 :         if( pRightFillerBox && nAbsRightFill<MINLAY+nInhRightBorderWidth )
    1124                 :          0 :             nAbsRightFill = MINLAY+nInhRightBorderWidth;
    1125                 :            :     }
    1126                 :            : 
    1127                 :            :     // Read just the available space
    1128                 :          0 :     nRelLeftFill = 0;
    1129                 :          0 :     nRelRightFill = 0;
    1130 [ #  # ][ #  # ]:          0 :     if( !IsTopTable() && (nAbsLeftFill>0 || nAbsRightFill) )
         [ #  # ][ #  # ]
    1131                 :            :     {
    1132                 :          0 :         sal_uLong nAbsLeftFillL = nAbsLeftFill, nAbsRightFillL = nAbsRightFill;
    1133                 :            : 
    1134                 :          0 :         nRelLeftFill = (sal_uInt16)((nAbsLeftFillL * nRelAvail) / nAbsAvail);
    1135                 :          0 :         nRelRightFill = (sal_uInt16)((nAbsRightFillL * nRelAvail) / nAbsAvail);
    1136                 :            : 
    1137                 :          0 :         nAbsAvail -= (nAbsLeftFill + nAbsRightFill);
    1138         [ #  # ]:          0 :         if( nRelAvail )
    1139                 :          0 :             nRelAvail -= (nRelLeftFill + nRelRightFill);
    1140                 :            :     }
    1141                 :            : 
    1142                 :            : 
    1143                 :            :     // Step 2: Calculate the absolute table width.
    1144                 :          0 :     sal_uInt16 nAbsTabWidth = 0;
    1145                 :          0 :     bUseRelWidth = sal_False;
    1146         [ #  # ]:          0 :     if( nWidthOption )
    1147                 :            :     {
    1148         [ #  # ]:          0 :         if( bPrcWidthOption )
    1149                 :            :         {
    1150                 :            :             OSL_ENSURE( nWidthOption<=100, "Percentage value too high" );
    1151         [ #  # ]:          0 :             if( nWidthOption > 100 )
    1152                 :          0 :                 nWidthOption = 100;
    1153                 :            : 
    1154                 :            :             // The absolute width is equal to the given percentage of
    1155                 :            :             // the available width.
    1156                 :            :             // Top tables only get a relative width if the available space
    1157                 :            :             // is *strictly larger* than the minimum width.
    1158                 :            :             //
    1159                 :            :             // CAUTION: We need the "strictly larger" because changing from a
    1160                 :            :             // relative width to an absolute width by resizing would lead
    1161                 :            :             // to an infinite loop.
    1162                 :            :             //
    1163                 :            :             // Because we do not call resize for tables in frames if the
    1164                 :            :             // frame has a non-relative width, we cannot play such games.
    1165                 :            :             //
    1166                 :            :             // Let's play such games now anyway. We had a graphic in a 1% wide
    1167                 :            :             // table and it didn't fit in of course.
    1168                 :          0 :             nAbsTabWidth = (sal_uInt16)( ((sal_uLong)nAbsAvail * nWidthOption) / 100 );
    1169 [ #  # ][ #  # ]:          0 :             if( IsTopTable() &&
                 [ #  # ]
    1170                 :            :                 ( /*MayBeInFlyFrame() ||*/ (sal_uLong)nAbsTabWidth > nMin ) )
    1171                 :            :             {
    1172                 :          0 :                 nRelAvail = USHRT_MAX;
    1173                 :          0 :                 bUseRelWidth = sal_True;
    1174                 :            :             }
    1175                 :            :         }
    1176                 :            :         else
    1177                 :            :         {
    1178                 :          0 :             nAbsTabWidth = nWidthOption;
    1179         [ #  # ]:          0 :             if( nAbsTabWidth > MAX_TABWIDTH )
    1180                 :          0 :                 nAbsTabWidth = MAX_TABWIDTH;
    1181                 :            : 
    1182                 :            :             // Tables within tables must never get wider than the available
    1183                 :            :             // space.
    1184 [ #  # ][ #  # ]:          0 :             if( !IsTopTable() && nAbsTabWidth > nAbsAvail )
                 [ #  # ]
    1185                 :          0 :                 nAbsTabWidth = nAbsAvail;
    1186                 :            :         }
    1187                 :            :     }
    1188                 :            : 
    1189                 :            :     OSL_ENSURE( IsTopTable() || nAbsTabWidth<=nAbsAvail,
    1190                 :            :             "AutoLayout pass 2: nAbsTabWidth > nAbsAvail for table in table" );
    1191                 :            :     OSL_ENSURE( !nRelAvail || nAbsTabWidth<=nAbsAvail,
    1192                 :            :             "AutoLayout pass 2: nAbsTabWidth > nAbsAvail for relative width" );
    1193                 :            : 
    1194                 :            :     // Catch for the two asserts above (we never know!)
    1195 [ #  # ][ #  # ]:          0 :     if( (!IsTopTable() || nRelAvail>0) && nAbsTabWidth>nAbsAvail )
         [ #  # ][ #  # ]
    1196                 :          0 :         nAbsTabWidth = nAbsAvail;
    1197                 :            : 
    1198                 :            : 
    1199                 :            :     // Step 3: Identify the column width and, if applicable, the absolute
    1200                 :            :     // and relative table widths.
    1201 [ #  # ][ #  # ]:          0 :     if( (!IsTopTable() && nMin > (sal_uLong)nAbsAvail) ||
         [ #  # ][ #  # ]
    1202                 :            :         nMin > MAX_TABWIDTH )
    1203                 :            :     {
    1204                 :            :         // If
    1205                 :            :         // - a inner table's minimum is larger than the available space, or
    1206                 :            :         // - a top table's minimum is larger than USHORT_MAX the table
    1207                 :            :         // has to be adapted to the available space or USHORT_MAX.
    1208                 :            :         // We preserve the widths' ratio amongst themselves, however.
    1209                 :            : 
    1210         [ #  # ]:          0 :         nAbsTabWidth = IsTopTable() ? MAX_TABWIDTH : nAbsAvail;
    1211         [ #  # ]:          0 :         nRelTabWidth = (nRelAvail ? nRelAvail : nAbsTabWidth );
    1212                 :            : 
    1213                 :            :         // First of all, we check whether we can fit the layout constrains,
    1214                 :            :         // which are: Every cell's width excluding the borders must be at least
    1215                 :            :         // MINLAY:
    1216                 :            : 
    1217                 :          0 :         sal_uLong nRealMin = 0;
    1218         [ #  # ]:          0 :         for( sal_uInt16 i=0; i<nCols; i++ )
    1219                 :            :         {
    1220                 :          0 :             sal_uLong nRealColMin = MINLAY, nDummy1, nDummy2;
    1221                 :          0 :             AddBorderWidth( nRealColMin, nDummy1, nDummy2, i, 1 );
    1222                 :          0 :             nRealMin += nRealColMin;
    1223                 :            :         }
    1224 [ #  # ][ #  # ]:          0 :         if( (nRealMin >= nAbsTabWidth) || (nRealMin >= nMin) )
    1225                 :            :         {
    1226                 :            :             // "Rien ne va plus": we cannot get the minimum column widths
    1227                 :            :             // the layout wants to have.
    1228                 :            : 
    1229                 :          0 :             sal_uInt16 nAbs = 0, nRel = 0;
    1230                 :            :             SwHTMLTableLayoutColumn *pColumn;
    1231         [ #  # ]:          0 :             for( sal_uInt16 i=0; i<nCols-1; i++ )
    1232                 :            :             {
    1233                 :          0 :                 pColumn = GetColumn( i );
    1234                 :          0 :                 sal_uLong nColMin = pColumn->GetMin();
    1235         [ #  # ]:          0 :                 if( nColMin <= USHRT_MAX )
    1236                 :            :                 {
    1237                 :            :                     pColumn->SetAbsColWidth(
    1238                 :          0 :                         (sal_uInt16)((nColMin * nAbsTabWidth) / nMin) );
    1239                 :            :                     pColumn->SetRelColWidth(
    1240                 :          0 :                         (sal_uInt16)((nColMin * nRelTabWidth) / nMin) );
    1241                 :            :                 }
    1242                 :            :                 else
    1243                 :            :                 {
    1244                 :          0 :                     double nColMinD = nColMin;
    1245                 :            :                     pColumn->SetAbsColWidth(
    1246                 :          0 :                         (sal_uInt16)((nColMinD * nAbsTabWidth) / nMin) );
    1247                 :            :                     pColumn->SetRelColWidth(
    1248                 :          0 :                         (sal_uInt16)((nColMinD * nRelTabWidth) / nMin) );
    1249                 :            :                 }
    1250                 :            : 
    1251                 :          0 :                 nAbs = nAbs + (sal_uInt16)pColumn->GetAbsColWidth();
    1252                 :          0 :                 nRel = nRel + (sal_uInt16)pColumn->GetRelColWidth();
    1253                 :            :             }
    1254                 :          0 :             pColumn = GetColumn( nCols-1 );
    1255                 :          0 :             pColumn->SetAbsColWidth( nAbsTabWidth - nAbs );
    1256                 :          0 :             pColumn->SetRelColWidth( nRelTabWidth - nRel );
    1257                 :            :         }
    1258                 :            :         else
    1259                 :            :         {
    1260                 :          0 :             sal_uLong nDistAbs = nAbsTabWidth - nRealMin;
    1261                 :          0 :             sal_uLong nDistRel = nRelTabWidth - nRealMin;
    1262                 :          0 :             sal_uLong nDistMin = nMin - nRealMin;
    1263                 :          0 :             sal_uInt16 nAbs = 0, nRel = 0;
    1264                 :            :             SwHTMLTableLayoutColumn *pColumn;
    1265         [ #  # ]:          0 :             for( sal_uInt16 i=0; i<nCols-1; i++ )
    1266                 :            :             {
    1267                 :          0 :                 pColumn = GetColumn( i );
    1268                 :          0 :                 sal_uLong nColMin = pColumn->GetMin();
    1269                 :          0 :                 sal_uLong nRealColMin = MINLAY, nDummy1, nDummy2;
    1270                 :          0 :                 AddBorderWidth( nRealColMin, nDummy1, nDummy2, i, 1 );
    1271                 :            : 
    1272         [ #  # ]:          0 :                 if( nColMin <= USHRT_MAX )
    1273                 :            :                 {
    1274                 :            :                     pColumn->SetAbsColWidth(
    1275                 :          0 :                         (sal_uInt16)((((nColMin-nRealColMin) * nDistAbs) / nDistMin) + nRealColMin) );
    1276                 :            :                     pColumn->SetRelColWidth(
    1277                 :          0 :                         (sal_uInt16)((((nColMin-nRealColMin) * nDistRel) / nDistMin) + nRealColMin) );
    1278                 :            :                 }
    1279                 :            :                 else
    1280                 :            :                 {
    1281                 :          0 :                     double nColMinD = nColMin;
    1282                 :            :                     pColumn->SetAbsColWidth(
    1283                 :          0 :                         (sal_uInt16)((((nColMinD-nRealColMin) * nDistAbs) / nDistMin) + nRealColMin) );
    1284                 :            :                     pColumn->SetRelColWidth(
    1285                 :          0 :                         (sal_uInt16)((((nColMinD-nRealColMin) * nDistRel) / nDistMin) + nRealColMin) );
    1286                 :            :                 }
    1287                 :            : 
    1288                 :          0 :                 nAbs = nAbs + (sal_uInt16)pColumn->GetAbsColWidth();
    1289                 :          0 :                 nRel = nRel + (sal_uInt16)pColumn->GetRelColWidth();
    1290                 :            :             }
    1291                 :          0 :             pColumn = GetColumn( nCols-1 );
    1292                 :          0 :             pColumn->SetAbsColWidth( nAbsTabWidth - nAbs );
    1293                 :          0 :             pColumn->SetRelColWidth( nRelTabWidth - nRel );
    1294                 :            :         }
    1295                 :            :     }
    1296 [ #  # ][ #  # ]:          0 :     else if( nMax <= (sal_uLong)(nAbsTabWidth ? nAbsTabWidth : nAbsAvail) )
    1297                 :            :     {
    1298                 :            :         // If
    1299                 :            :         // - the table has a fixed width and the table's maximum is
    1300                 :            :         //   smaller, or
    1301                 :            :         //- the maximum is smaller than the available space,
    1302                 :            :         // we can take over the maximum as it is. Respectively
    1303                 :            :         // the table can only be adapted to the fixed width by
    1304                 :            :         // respecting the maximum.
    1305                 :            : 
    1306                 :            :         // No fixed width, use the maximum.
    1307         [ #  # ]:          0 :         if( !nAbsTabWidth )
    1308                 :          0 :             nAbsTabWidth = (sal_uInt16)nMax;
    1309                 :            : 
    1310                 :            :         // A top table may also get wider then the available space.
    1311         [ #  # ]:          0 :         if( nAbsTabWidth > nAbsAvail )
    1312                 :            :         {
    1313                 :            :             OSL_ENSURE( IsTopTable(),
    1314                 :            :                     "Table in table should get wider than the surrounding cell." );
    1315                 :          0 :             nAbsAvail = nAbsTabWidth;
    1316                 :            :         }
    1317                 :            : 
    1318                 :            :         // Only use the relative widths' fraction, that is used for the
    1319                 :            :         // absolute width.
    1320                 :          0 :         sal_uLong nAbsTabWidthL = nAbsTabWidth;
    1321                 :            :         nRelTabWidth =
    1322                 :            :             ( nRelAvail ? (sal_uInt16)((nAbsTabWidthL * nRelAvail) / nAbsAvail)
    1323         [ #  # ]:          0 :                         : nAbsTabWidth );
    1324                 :            : 
    1325                 :            :         // Are there columns width a percentage setting and some without one?
    1326                 :          0 :         sal_uLong nFixMax = nMax;
    1327         [ #  # ]:          0 :         for( sal_uInt16 i=0; i<nCols; i++ )
    1328                 :            :         {
    1329                 :          0 :             const SwHTMLTableLayoutColumn *pColumn = GetColumn( i );
    1330 [ #  # ][ #  # ]:          0 :             if( pColumn->IsRelWidthOption() && pColumn->GetWidthOption()>0 )
                 [ #  # ]
    1331                 :          0 :                 nFixMax -= pColumn->GetMax();
    1332                 :            :         }
    1333                 :            : 
    1334 [ #  # ][ #  # ]:          0 :         if( nFixMax > 0 && nFixMax < nMax )
    1335                 :            :         {
    1336                 :            :             // Yes, distribute the to-be-distributed space only to the
    1337                 :            :             // columns with a percentage setting.
    1338                 :            : 
    1339                 :            :             // In this case (and in this case only) there are columns
    1340                 :            :             // that exactly keep their maximum width, that is they neither
    1341                 :            :             // get smaller nor wider. When calculating the absolute width
    1342                 :            :             // from the relative width we can get rounding errors.
    1343                 :            :             // To correct this, we first make the fixed widths compensate for
    1344                 :            :             // this error. We then fix the relative widths the same way.
    1345                 :            : 
    1346                 :          0 :             sal_uInt16 nAbs = 0, nRel = 0;
    1347                 :          0 :             sal_uInt16 nFixedCols = 0;
    1348                 :            :             sal_uInt16 i;
    1349                 :            : 
    1350         [ #  # ]:          0 :             for( i = 0; i < nCols; i++ )
    1351                 :            :             {
    1352                 :          0 :                 SwHTMLTableLayoutColumn *pColumn = GetColumn( i );
    1353 [ #  # ][ #  # ]:          0 :                 if( !pColumn->IsRelWidthOption() || !pColumn->GetWidthOption() )
                 [ #  # ]
    1354                 :            :                 {
    1355                 :            :                     // The column keeps it's width.
    1356                 :          0 :                     nFixedCols++;
    1357                 :          0 :                     sal_uLong nColMax = pColumn->GetMax();
    1358                 :          0 :                     pColumn->SetAbsColWidth( (sal_uInt16)nColMax );
    1359                 :            : 
    1360                 :            :                     sal_uLong nRelColWidth =
    1361                 :          0 :                         (nColMax * nRelTabWidth) / nAbsTabWidth;
    1362                 :            :                     sal_uLong nChkWidth =
    1363                 :          0 :                         (nRelColWidth * nAbsTabWidth) / nRelTabWidth;
    1364         [ #  # ]:          0 :                     if( nChkWidth < nColMax )
    1365                 :          0 :                         nRelColWidth++;
    1366         [ #  # ]:          0 :                     else if( nChkWidth > nColMax )
    1367                 :          0 :                         nRelColWidth--;
    1368                 :          0 :                     pColumn->SetRelColWidth( (sal_uInt16)nRelColWidth );
    1369                 :            : 
    1370                 :          0 :                     nAbs = nAbs + (sal_uInt16)nColMax;
    1371                 :          0 :                     nRel = nRel + (sal_uInt16)nRelColWidth;
    1372                 :            :                 }
    1373                 :            :             }
    1374                 :            : 
    1375                 :            :             // The to-be-distributed percentage of the maximum, the
    1376                 :            :             // relative and absolute widths. Here, nFixMax corresponds
    1377                 :            :             // to nAbs, so that we could've called it nAbs.
    1378                 :            :             // The code is, however, more readable like that.
    1379                 :            :             OSL_ENSURE( nFixMax == nAbs, "Two loops, two sums?" );
    1380                 :          0 :             sal_uLong nDistMax = nMax - nFixMax;
    1381                 :          0 :             sal_uInt16 nDistAbsTabWidth = nAbsTabWidth - nAbs;
    1382                 :          0 :             sal_uInt16 nDistRelTabWidth = nRelTabWidth - nRel;
    1383                 :            : 
    1384         [ #  # ]:          0 :             for( i=0; i<nCols; i++ )
    1385                 :            :             {
    1386                 :          0 :                 SwHTMLTableLayoutColumn *pColumn = GetColumn( i );
    1387 [ #  # ][ #  # ]:          0 :                 if( pColumn->IsRelWidthOption() && pColumn->GetWidthOption() > 0 )
                 [ #  # ]
    1388                 :            :                 {
    1389                 :            :                     // The column gets proportionately wider.
    1390                 :          0 :                     nFixedCols++;
    1391         [ #  # ]:          0 :                     if( nFixedCols == nCols )
    1392                 :            :                     {
    1393                 :          0 :                         pColumn->SetAbsColWidth( nAbsTabWidth-nAbs );
    1394                 :          0 :                         pColumn->SetRelColWidth( nRelTabWidth-nRel );
    1395                 :            :                     }
    1396                 :            :                     else
    1397                 :            :                     {
    1398                 :          0 :                         sal_uLong nColMax = pColumn->GetMax();
    1399                 :            :                         pColumn->SetAbsColWidth(
    1400                 :          0 :                             (sal_uInt16)((nColMax * nDistAbsTabWidth) / nDistMax) );
    1401                 :            :                         pColumn->SetRelColWidth(
    1402                 :          0 :                             (sal_uInt16)((nColMax * nDistRelTabWidth) / nDistMax) );
    1403                 :            :                     }
    1404                 :          0 :                     nAbs = nAbs + pColumn->GetAbsColWidth();
    1405                 :          0 :                     nRel = nRel + pColumn->GetRelColWidth();
    1406                 :            :                 }
    1407                 :            :             }
    1408                 :          0 :             OSL_ENSURE( nCols==nFixedCols, "Missed a column!" );
    1409                 :            :         }
    1410                 :            :         else
    1411                 :            :         {
    1412                 :            :             // No. So distribute the space regularily among all columns.
    1413         [ #  # ]:          0 :             for( sal_uInt16 i=0; i<nCols; i++ )
    1414                 :            :             {
    1415                 :          0 :                 sal_uLong nColMax = GetColumn( i )->GetMax();
    1416                 :            :                 GetColumn( i )->SetAbsColWidth(
    1417                 :          0 :                     (sal_uInt16)((nColMax * nAbsTabWidth) / nMax) );
    1418                 :            :                 GetColumn( i )->SetRelColWidth(
    1419                 :          0 :                     (sal_uInt16)((nColMax * nRelTabWidth) / nMax) );
    1420                 :            :             }
    1421                 :            :         }
    1422                 :            :     }
    1423                 :            :     else
    1424                 :            :     {
    1425                 :            :         // Proportionately distribute the space that extends over the minimum
    1426                 :            :         // width among the columns.
    1427         [ #  # ]:          0 :         if( !nAbsTabWidth )
    1428                 :          0 :             nAbsTabWidth = nAbsAvail;
    1429         [ #  # ]:          0 :         if( nAbsTabWidth < nMin )
    1430                 :          0 :             nAbsTabWidth = (sal_uInt16)nMin;
    1431                 :            : 
    1432         [ #  # ]:          0 :         if( nAbsTabWidth > nAbsAvail )
    1433                 :            :         {
    1434                 :            :             OSL_ENSURE( IsTopTable(),
    1435                 :            :                     "A nested table should become wider than the available space." );
    1436                 :          0 :             nAbsAvail = nAbsTabWidth;
    1437                 :            :         }
    1438                 :            : 
    1439                 :          0 :         sal_uLong nAbsTabWidthL = nAbsTabWidth;
    1440                 :            :         nRelTabWidth =
    1441                 :            :             ( nRelAvail ? (sal_uInt16)((nAbsTabWidthL * nRelAvail) / nAbsAvail)
    1442         [ #  # ]:          0 :                         : nAbsTabWidth );
    1443                 :          0 :         double nW = nAbsTabWidth - nMin;
    1444         [ #  # ]:          0 :         double nD = (nMax==nMin ? 1 : nMax-nMin);
    1445                 :          0 :         sal_uInt16 nAbs = 0, nRel = 0;
    1446         [ #  # ]:          0 :         for( sal_uInt16 i=0; i<nCols-1; i++ )
    1447                 :            :         {
    1448                 :          0 :             double nd = GetColumn( i )->GetMax() - GetColumn( i )->GetMin();
    1449                 :          0 :             sal_uLong nAbsColWidth = GetColumn( i )->GetMin() + (sal_uLong)((nd*nW)/nD);
    1450                 :            :             sal_uLong nRelColWidth = nRelAvail
    1451                 :            :                                     ? (nAbsColWidth * nRelTabWidth) / nAbsTabWidth
    1452         [ #  # ]:          0 :                                     : nAbsColWidth;
    1453                 :            : 
    1454                 :          0 :             GetColumn( i )->SetAbsColWidth( (sal_uInt16)nAbsColWidth );
    1455                 :          0 :             GetColumn( i )->SetRelColWidth( (sal_uInt16)nRelColWidth );
    1456                 :          0 :             nAbs = nAbs + (sal_uInt16)nAbsColWidth;
    1457                 :          0 :             nRel = nRel + (sal_uInt16)nRelColWidth;
    1458                 :            :         }
    1459                 :          0 :         GetColumn( nCols-1 )->SetAbsColWidth( nAbsTabWidth - nAbs );
    1460                 :          0 :         GetColumn( nCols-1 )->SetRelColWidth( nRelTabWidth - nRel );
    1461                 :            : 
    1462                 :            :     }
    1463                 :            : 
    1464                 :            :     // Step 4: For nested tables we can have balancing cells on the
    1465                 :            :     // left or right. Here we calculate their width.
    1466                 :          0 :     nInhAbsLeftSpace = 0;
    1467                 :          0 :     nInhAbsRightSpace = 0;
    1468 [ #  # ][ #  # ]:          0 :     if( !IsTopTable() && (nRelLeftFill>0 || nRelRightFill>0 ||
         [ #  # ][ #  # ]
                 [ #  # ]
    1469                 :            :                           nAbsTabWidth<nAbsAvail) )
    1470                 :            :     {
    1471                 :            :         // Calculate the width of additional cells we use for
    1472                 :            :         // aligning inner tables.
    1473                 :          0 :         sal_uInt16 nAbsDist = (sal_uInt16)(nAbsAvail-nAbsTabWidth);
    1474                 :          0 :         sal_uInt16 nRelDist = (sal_uInt16)(nRelAvail-nRelTabWidth);
    1475                 :          0 :         sal_uInt16 nParentInhAbsLeftSpace = 0, nParentInhAbsRightSpace = 0;
    1476                 :            : 
    1477                 :            :         // Calculate the size and position of the additional cells.
    1478      [ #  #  # ]:          0 :         switch( eTableAdjust )
    1479                 :            :         {
    1480                 :            :         case SVX_ADJUST_RIGHT:
    1481                 :          0 :             nAbsLeftFill = nAbsLeftFill + nAbsDist;
    1482                 :          0 :             nRelLeftFill = nRelLeftFill + nRelDist;
    1483                 :          0 :             nParentInhAbsLeftSpace = nParentInhAbsSpace;
    1484                 :          0 :             break;
    1485                 :            :         case SVX_ADJUST_CENTER:
    1486                 :            :             {
    1487                 :          0 :                 sal_uInt16 nAbsLeftDist = nAbsDist / 2;
    1488                 :          0 :                 nAbsLeftFill = nAbsLeftFill + nAbsLeftDist;
    1489                 :          0 :                 nAbsRightFill += nAbsDist - nAbsLeftDist;
    1490                 :          0 :                 sal_uInt16 nRelLeftDist = nRelDist / 2;
    1491                 :          0 :                 nRelLeftFill = nRelLeftFill + nRelLeftDist;
    1492                 :          0 :                 nRelRightFill += nRelDist - nRelLeftDist;
    1493                 :          0 :                 nParentInhAbsLeftSpace = nParentInhAbsSpace / 2;
    1494                 :            :                 nParentInhAbsRightSpace = nParentInhAbsSpace -
    1495                 :          0 :                                           nParentInhAbsLeftSpace;
    1496                 :            :             }
    1497                 :          0 :             break;
    1498                 :            :         case SVX_ADJUST_LEFT:
    1499                 :            :         default:
    1500                 :          0 :             nAbsRightFill = nAbsRightFill + nAbsDist;
    1501                 :          0 :             nRelRightFill = nRelRightFill + nRelDist;
    1502                 :          0 :             nParentInhAbsRightSpace = nParentInhAbsSpace;
    1503                 :          0 :             break;
    1504                 :            :         }
    1505                 :            : 
    1506                 :            :         OSL_ENSURE( !pLeftFillerBox || nRelLeftFill>0,
    1507                 :            :                 "We don't have a width for the left filler box!" );
    1508                 :            :         OSL_ENSURE( !pRightFillerBox || nRelRightFill>0,
    1509                 :            :                 "We don't have a width for the right filler box!" );
    1510                 :            : 
    1511                 :            :         // Filler widths are added to the outer columns, if there are no boxes
    1512                 :            :         // for them after the first pass (nWidth>0) or their width would become
    1513                 :            :         // too small or if there are COL tags and the filler width corresponds
    1514                 :            :         // to the border width.
    1515                 :            :         // In the last case we probably exported the table ourselves.
    1516 [ #  # ][ #  # ]:          0 :         if( nRelLeftFill && !pLeftFillerBox &&
                 [ #  # ]
           [ #  #  #  # ]
         [ #  # ][ #  # ]
    1517                 :            :             ( nWidthSet>0 || nAbsLeftFill<MINLAY+nInhLeftBorderWidth ||
    1518                 :          0 :               (HasColTags() && nAbsLeftFill < nAbsLeftSpace+nParentInhAbsLeftSpace+20) ) )
    1519                 :            :         {
    1520                 :          0 :             SwHTMLTableLayoutColumn *pColumn = GetColumn( 0 );
    1521                 :          0 :             pColumn->SetAbsColWidth( pColumn->GetAbsColWidth()+nAbsLeftFill );
    1522                 :          0 :             pColumn->SetRelColWidth( pColumn->GetRelColWidth()+nRelLeftFill );
    1523                 :          0 :             nRelLeftFill = 0;
    1524                 :          0 :             nInhAbsLeftSpace = nAbsLeftSpace + nParentInhAbsLeftSpace;
    1525                 :            :         }
    1526 [ #  # ][ #  # ]:          0 :         if( nRelRightFill && !pRightFillerBox &&
                 [ #  # ]
           [ #  #  #  # ]
         [ #  # ][ #  # ]
    1527                 :            :             ( nWidthSet>0 || nAbsRightFill<MINLAY+nInhRightBorderWidth ||
    1528                 :          0 :               (HasColTags() && nAbsRightFill < nAbsRightSpace+nParentInhAbsRightSpace+20) ) )
    1529                 :            :         {
    1530                 :          0 :             SwHTMLTableLayoutColumn *pColumn = GetColumn( nCols-1 );
    1531                 :          0 :             pColumn->SetAbsColWidth( pColumn->GetAbsColWidth()+nAbsRightFill );
    1532                 :          0 :             pColumn->SetRelColWidth( pColumn->GetRelColWidth()+nRelRightFill );
    1533                 :          0 :             nRelRightFill = 0;
    1534                 :          0 :             nInhAbsRightSpace = nAbsRightSpace + nParentInhAbsRightSpace;
    1535                 :            :         }
    1536                 :            :     }
    1537                 :          0 : }
    1538                 :            : 
    1539                 :            : static void lcl_ResizeLine( const SwTableLine* pLine, sal_uInt16 *pWidth );
    1540                 :            : 
    1541                 :          0 : static void lcl_ResizeBox( const SwTableBox* pBox, sal_uInt16* pWidth )
    1542                 :            : {
    1543         [ #  # ]:          0 :     if( !pBox->GetSttNd() )
    1544                 :            :     {
    1545                 :          0 :         sal_uInt16 nWidth = 0;
    1546 [ #  # ][ #  # ]:          0 :         BOOST_FOREACH( const SwTableLine *pLine, pBox->GetTabLines() )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1547         [ #  # ]:          0 :             lcl_ResizeLine( pLine, &nWidth );
    1548 [ #  # ][ #  # ]:          0 :         pBox->GetFrmFmt()->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, nWidth, 0 ));
                 [ #  # ]
    1549                 :          0 :         *pWidth = *pWidth + nWidth;
    1550                 :            :     }
    1551                 :            :     else
    1552                 :            :     {
    1553                 :          0 :         *pWidth = *pWidth + (sal_uInt16)pBox->GetFrmFmt()->GetFrmSize().GetSize().Width();
    1554                 :            :     }
    1555                 :          0 : }
    1556                 :            : 
    1557                 :          0 : static void lcl_ResizeLine( const SwTableLine* pLine, sal_uInt16 *pWidth )
    1558                 :            : {
    1559                 :            : #if OSL_DEBUG_LEVEL > 0
    1560                 :            :     sal_uInt16 nOldWidth = *pWidth;
    1561                 :            : #endif
    1562                 :          0 :     *pWidth = 0;
    1563 [ #  # ][ #  # ]:          0 :     BOOST_FOREACH( const SwTableBox* pBox, pLine->GetTabBoxes() )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1564         [ #  # ]:          0 :         lcl_ResizeBox(pBox, pWidth );
    1565                 :            : 
    1566                 :            : #if OSL_DEBUG_LEVEL > 0
    1567                 :            :     OSL_ENSURE( !nOldWidth || Abs(*pWidth-nOldWidth) < COLFUZZY,
    1568                 :            :             "A box's rows have all a different length." );
    1569                 :            : #endif
    1570                 :          0 : }
    1571                 :            : 
    1572                 :          0 : void SwHTMLTableLayout::SetWidths( sal_Bool bCallPass2, sal_uInt16 nAbsAvail,
    1573                 :            :                                    sal_uInt16 nRelAvail, sal_uInt16 nAbsLeftSpace,
    1574                 :            :                                    sal_uInt16 nAbsRightSpace,
    1575                 :            :                                    sal_uInt16 nParentInhAbsSpace )
    1576                 :            : {
    1577                 :            :     // SetWidth must have been passed through once more for every cell in the
    1578                 :            :     // end.
    1579                 :          0 :     nWidthSet++;
    1580                 :            : 
    1581                 :            :     // Step 0: If necessary, we call the layout algorithm of Pass2.
    1582         [ #  # ]:          0 :     if( bCallPass2 )
    1583                 :            :         AutoLayoutPass2( nAbsAvail, nRelAvail, nAbsLeftSpace, nAbsRightSpace,
    1584                 :          0 :                          nParentInhAbsSpace );
    1585                 :            : 
    1586                 :            :     // Step 1: Set the new width in all content boxes.
    1587                 :            :     // Because the boxes don't know anything about the HTML table structure,
    1588                 :            :     // we iterate over the HTML table structure.
    1589                 :            :     // For tables in tables in tables we call SetWidth recursively.
    1590         [ #  # ]:          0 :     for( sal_uInt16 i=0; i<nRows; i++ )
    1591                 :            :     {
    1592         [ #  # ]:          0 :         for( sal_uInt16 j=0; j<nCols; j++ )
    1593                 :            :         {
    1594                 :          0 :             SwHTMLTableLayoutCell *pCell = GetCell( i, j );
    1595                 :            : 
    1596                 :          0 :             SwHTMLTableLayoutCnts* pCntnts = pCell->GetContents();
    1597 [ #  # ][ #  # ]:          0 :             while( pCntnts && !pCntnts->IsWidthSet(nWidthSet) )
                 [ #  # ]
    1598                 :            :             {
    1599                 :          0 :                 SwTableBox *pBox = pCntnts->GetTableBox();
    1600         [ #  # ]:          0 :                 if( pBox )
    1601                 :            :                 {
    1602                 :          0 :                     SetBoxWidth( pBox, j, pCell->GetColSpan() );
    1603                 :            :                 }
    1604                 :            :                 else
    1605                 :            :                 {
    1606                 :          0 :                     sal_uInt16 nAbs = 0, nRel = 0, nLSpace = 0, nRSpace = 0,
    1607                 :          0 :                            nInhSpace = 0;
    1608         [ #  # ]:          0 :                     if( bCallPass2 )
    1609                 :            :                     {
    1610                 :          0 :                         sal_uInt16 nColSpan = pCell->GetColSpan();
    1611                 :          0 :                         GetAvail( j, nColSpan, nAbs, nRel );
    1612                 :          0 :                         nLSpace = GetLeftCellSpace( j, nColSpan );
    1613                 :          0 :                         nRSpace = GetRightCellSpace( j, nColSpan );
    1614         [ #  # ]:          0 :                         nInhSpace = GetInhCellSpace( j, nColSpan );
    1615                 :            :                     }
    1616                 :            :                     pCntnts->GetTable()->SetWidths( bCallPass2, nAbs, nRel,
    1617                 :            :                                                     nLSpace, nRSpace,
    1618         [ #  # ]:          0 :                                                     nInhSpace );
    1619                 :            :                 }
    1620                 :            : 
    1621                 :          0 :                 pCntnts->SetWidthSet( nWidthSet );
    1622                 :          0 :                 pCntnts = pCntnts->GetNext();
    1623                 :            :             }
    1624                 :            :         }
    1625                 :            :     }
    1626                 :            : 
    1627                 :            :     // Step 2: If we have a top table, we adapt the formats of the
    1628                 :            :     // non-content-boxes. Because they are not known in the HTML table
    1629                 :            :     // due to garbage collection there, we need the iterate over the
    1630                 :            :     // whole table.
    1631                 :            :     // We also adapt the table frame format. For nested tables we set the
    1632                 :            :     // filler cell's width instead.
    1633         [ #  # ]:          0 :     if( IsTopTable() )
    1634                 :            :     {
    1635                 :          0 :         sal_uInt16 nCalcTabWidth = 0;
    1636 [ #  # ][ #  # ]:          0 :         BOOST_FOREACH( const SwTableLine *pLine, pSwTable->GetTabLines() )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1637         [ #  # ]:          0 :             lcl_ResizeLine( pLine, &nCalcTabWidth );
    1638                 :            :         OSL_ENSURE( Abs( nRelTabWidth-nCalcTabWidth ) < COLFUZZY,
    1639                 :            :                 "Table width is not equal to the row width." );
    1640                 :            : 
    1641                 :            :         // Lock the table format when altering it, or else the box formats
    1642                 :            :         // are altered again.
    1643                 :            :         // Also, we need to preserve a percent setting if it exists.
    1644                 :          0 :         SwFrmFmt *pFrmFmt = pSwTable->GetFrmFmt();
    1645                 :          0 :         ((SwTable *)pSwTable)->LockModify();
    1646 [ #  # ][ #  # ]:          0 :         SwFmtFrmSize aFrmSize( pFrmFmt->GetFrmSize() );
    1647                 :          0 :         aFrmSize.SetWidth( nRelTabWidth );
    1648                 :            :         sal_Bool bRel = bUseRelWidth &&
    1649 [ #  # ][ #  # ]:          0 :                     text::HoriOrientation::FULL!=pFrmFmt->GetHoriOrient().GetHoriOrient();
                 [ #  # ]
    1650         [ #  # ]:          0 :         aFrmSize.SetWidthPercent( (sal_uInt8)(bRel ? nWidthOption : 0) );
    1651         [ #  # ]:          0 :         pFrmFmt->SetFmtAttr( aFrmSize );
    1652                 :          0 :         ((SwTable *)pSwTable)->UnlockModify();
    1653                 :            : 
    1654                 :            :         // If the table is located in a frame, we also need to adapt the
    1655                 :            :         // frame's width.
    1656         [ #  # ]:          0 :         if( MayBeInFlyFrame() )
    1657                 :            :         {
    1658         [ #  # ]:          0 :             SwFrmFmt *pFlyFrmFmt = FindFlyFrmFmt();
    1659         [ #  # ]:          0 :             if( pFlyFrmFmt )
    1660                 :            :             {
    1661         [ #  # ]:          0 :                 SwFmtFrmSize aFlyFrmSize( ATT_VAR_SIZE, nRelTabWidth, MINLAY );
    1662                 :            : 
    1663         [ #  # ]:          0 :                 if( bUseRelWidth )
    1664                 :            :                 {
    1665                 :            :                     // For percentage settings we set the width to the minimum.
    1666                 :            :                     aFlyFrmSize.SetWidth(  nMin > USHRT_MAX ? USHRT_MAX
    1667                 :          0 :                                                             : nMin );
    1668                 :          0 :                     aFlyFrmSize.SetWidthPercent( (sal_uInt8)nWidthOption );
    1669                 :            :                 }
    1670 [ #  # ][ #  # ]:          0 :                 pFlyFrmFmt->SetFmtAttr( aFlyFrmSize );
    1671                 :            :             }
    1672         [ #  # ]:          0 :         }
    1673                 :            : 
    1674                 :            : #ifdef DBG_UTIL
    1675                 :            :         {
    1676                 :            :             // is located in tblrwcl.cxx
    1677                 :            :             extern void _CheckBoxWidth( const SwTableLine&, SwTwips );
    1678                 :            : 
    1679                 :            :             // check if the tables have correct widths
    1680                 :            :             SwTwips nSize = pSwTable->GetFrmFmt()->GetFrmSize().GetWidth();
    1681                 :            :             const SwTableLines& rLines = pSwTable->GetTabLines();
    1682                 :            :             for (size_t n = 0; n < rLines.size(); ++n)
    1683                 :            :             {
    1684                 :            :                 _CheckBoxWidth( *rLines[ n ], nSize );
    1685                 :            :             }
    1686                 :            :         }
    1687                 :            : #endif
    1688                 :            : 
    1689                 :            :     }
    1690                 :            :     else
    1691                 :            :     {
    1692         [ #  # ]:          0 :         if( pLeftFillerBox )
    1693                 :            :         {
    1694                 :          0 :             pLeftFillerBox->GetFrmFmt()->SetFmtAttr(
    1695         [ #  # ]:          0 :                 SwFmtFrmSize( ATT_VAR_SIZE, nRelLeftFill, 0 ));
    1696                 :            :         }
    1697         [ #  # ]:          0 :         if( pRightFillerBox )
    1698                 :            :         {
    1699                 :          0 :             pRightFillerBox->GetFrmFmt()->SetFmtAttr(
    1700         [ #  # ]:          0 :                 SwFmtFrmSize( ATT_VAR_SIZE, nRelRightFill, 0 ));
    1701                 :            :         }
    1702                 :            :     }
    1703                 :          0 : }
    1704                 :            : 
    1705                 :          0 : void SwHTMLTableLayout::_Resize( sal_uInt16 nAbsAvail, sal_Bool bRecalc )
    1706                 :            : {
    1707                 :            :     // If bRecalc is set, the table's content changed.
    1708                 :            :     // We need to execute pass 1 again.
    1709         [ #  # ]:          0 :     if( bRecalc )
    1710                 :          0 :         AutoLayoutPass1();
    1711                 :            : 
    1712                 :          0 :     SwRootFrm *pRoot = (SwRootFrm*)GetDoc()->GetCurrentViewShell()->GetLayout();
    1713 [ #  # ][ #  # ]:          0 :     if ( pRoot && pRoot->IsCallbackActionEnabled() )
                 [ #  # ]
    1714                 :          0 :         pRoot->StartAllAction();    //swmod 071108//swmod 071225
    1715                 :            : 
    1716                 :            :     // Else we can set the widths, in which we have to run Pass 2 in each case.
    1717                 :          0 :     SetWidths( sal_True, nAbsAvail );
    1718                 :            : 
    1719 [ #  # ][ #  # ]:          0 :     if ( pRoot && pRoot->IsCallbackActionEnabled() )
                 [ #  # ]
    1720                 :          0 :         pRoot->EndAllAction( sal_True );    //True per VirDev (browsing is calmer) //swmod 071108//swmod 071225
    1721                 :          0 : }
    1722                 :            : 
    1723                 :          0 : IMPL_STATIC_LINK( SwHTMLTableLayout, DelayedResize_Impl, void*, EMPTYARG )
    1724                 :            : {
    1725                 :          0 :     pThis->aResizeTimer.Stop();
    1726                 :            :     pThis->_Resize( pThis->nDelayedResizeAbsAvail,
    1727                 :          0 :                     pThis->bDelayedResizeRecalc );
    1728                 :            : 
    1729                 :          0 :     return 0;
    1730                 :            : }
    1731                 :            : 
    1732                 :            : 
    1733                 :          0 : sal_Bool SwHTMLTableLayout::Resize( sal_uInt16 nAbsAvail, sal_Bool bRecalc,
    1734                 :            :                                 sal_Bool bForce, sal_uLong nDelay )
    1735                 :            : {
    1736         [ #  # ]:          0 :     if( 0 == nAbsAvail )
    1737                 :          0 :         return sal_False;
    1738                 :            :     OSL_ENSURE( IsTopTable(), "Resize must only be called for top tables!" );
    1739                 :            : 
    1740                 :            :     // May the table be resized at all? Or is it forced?
    1741 [ #  # ][ #  # ]:          0 :     if( bMustNotResize && !bForce )
    1742                 :          0 :         return sal_False;
    1743                 :            : 
    1744                 :            :     // May the table be recalculated? Or is it forced?
    1745 [ #  # ][ #  # ]:          0 :     if( bMustNotRecalc && !bForce )
    1746                 :          0 :         bRecalc = sal_False;
    1747                 :            : 
    1748                 :          0 :     const SwDoc *pDoc = GetDoc();
    1749                 :            : 
    1750                 :            :     // If there is a layout, the root frame's size instead of the
    1751                 :            :     // VisArea's size was potentially passed.
    1752                 :            :     // If we're not in a frame we need to calculate the table for the VisArea,
    1753                 :            :     // because switching from relative to absolute wouldn't work.
    1754 [ #  # ][ #  # ]:          0 :     if( pDoc->GetCurrentViewShell() && pDoc->GetCurrentViewShell()->GetViewOptions()->getBrowseMode() )
                 [ #  # ]
    1755                 :            :     {
    1756                 :          0 :         const sal_uInt16 nVisAreaWidth = GetBrowseWidthByVisArea( *pDoc );
    1757 [ #  # ][ #  # ]:          0 :         if( nVisAreaWidth < nAbsAvail && !FindFlyFrmFmt() )
                 [ #  # ]
    1758                 :          0 :             nAbsAvail = nVisAreaWidth;
    1759                 :            :     }
    1760                 :            : 
    1761 [ #  # ][ #  # ]:          0 :     if( nDelay==0 && aResizeTimer.IsActive() )
                 [ #  # ]
    1762                 :            :     {
    1763                 :            :         // If there is an asynchronous resize left to process when we call
    1764                 :            :         // a synchronous resize, we only take over the new values.
    1765                 :          0 :         bRecalc |= bDelayedResizeRecalc;
    1766                 :          0 :         nDelayedResizeAbsAvail = nAbsAvail;
    1767                 :          0 :         return sal_False;
    1768                 :            :     }
    1769                 :            : 
    1770                 :            :     // Optimisation:
    1771                 :            :     // If the minimums or maximums should not be recalculated and
    1772                 :            :     // - the table's width never needs to be recalculated, or
    1773                 :            :     // - the table was already calculated for the passed width, or
    1774                 :            :     // - the available space is less or equal to the minimum width
    1775                 :            :     //   and the table already has the minimum width, or
    1776                 :            :     // - the available space is larger than the maximum width and
    1777                 :            :     //   the table already has the maximum width
    1778                 :            :     // nothing will happen to the table.
    1779 [ #  # ][ #  # ]:          0 :     if( !bRecalc && ( !bMustResize ||
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1780                 :            :                       (nLastResizeAbsAvail==nAbsAvail) ||
    1781                 :            :                       (nAbsAvail<=nMin && nRelTabWidth==nMin) ||
    1782                 :          0 :                       (!bPrcWidthOption && nAbsAvail>=nMax && nRelTabWidth==nMax) ) )
    1783                 :          0 :         return sal_False;
    1784                 :            : 
    1785         [ #  # ]:          0 :     if( nDelay==HTMLTABLE_RESIZE_NOW )
    1786                 :            :     {
    1787         [ #  # ]:          0 :         if( aResizeTimer.IsActive() )
    1788                 :          0 :             aResizeTimer.Stop();
    1789                 :          0 :         _Resize( nAbsAvail, bRecalc );
    1790                 :            :     }
    1791         [ #  # ]:          0 :     else if( nDelay > 0 )
    1792                 :            :     {
    1793                 :          0 :         nDelayedResizeAbsAvail = nAbsAvail;
    1794                 :          0 :         bDelayedResizeRecalc = bRecalc;
    1795                 :          0 :         aResizeTimer.SetTimeout( nDelay );
    1796                 :          0 :         aResizeTimer.Start();
    1797                 :            :     }
    1798                 :            :     else
    1799                 :            :     {
    1800                 :          0 :         _Resize( nAbsAvail, bRecalc );
    1801                 :            :     }
    1802                 :            : 
    1803                 :          0 :     return sal_True;
    1804                 :            : }
    1805                 :            : 
    1806                 :          0 : void SwHTMLTableLayout::BordersChanged( sal_uInt16 nAbsAvail, sal_Bool bRecalc )
    1807                 :            : {
    1808                 :          0 :     bBordersChanged = sal_True;
    1809                 :            : 
    1810                 :          0 :     Resize( nAbsAvail, bRecalc );
    1811                 :          0 : }
    1812                 :            : 
    1813                 :            : 
    1814                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10