2010-10-14 08:30:41 +02:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
2011-03-31 10:05:04 +02:00
|
|
|
/*
|
|
|
|
* This file is part of the LibreOffice project.
|
|
|
|
*
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
*
|
|
|
|
* This file incorporates work covered by the following license notice:
|
|
|
|
*
|
|
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
|
|
* with this work for additional information regarding copyright
|
|
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy of
|
|
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
|
|
*/
|
2006-09-16 19:56:50 +00:00
|
|
|
|
2000-09-18 23:08:29 +00:00
|
|
|
#include "hintids.hxx"
|
|
|
|
|
|
|
|
#include <vcl/wrkwin.hxx>
|
|
|
|
#include <vcl/svapp.hxx>
|
|
|
|
#include <sot/storage.hxx>
|
|
|
|
#include <fmtornt.hxx>
|
|
|
|
#include <fmtfsize.hxx>
|
|
|
|
#include <frmfmt.hxx>
|
|
|
|
#include <docary.hxx>
|
|
|
|
#include "ndtxt.hxx"
|
|
|
|
#include "doc.hxx"
|
|
|
|
#include "swtable.hxx"
|
|
|
|
#include "rootfrm.hxx"
|
|
|
|
#include "docsh.hxx"
|
|
|
|
#include "flyfrm.hxx"
|
|
|
|
#include "poolfmt.hxx"
|
|
|
|
#include "viewsh.hxx"
|
|
|
|
#include "tabfrm.hxx"
|
2010-06-13 15:22:56 +02:00
|
|
|
#include "viewopt.hxx"
|
2000-09-18 23:08:29 +00:00
|
|
|
#include "htmltbl.hxx"
|
|
|
|
#include "ndindex.hxx"
|
2010-12-17 09:02:23 +01:00
|
|
|
#include "switerator.hxx"
|
2012-06-18 18:04:44 +02:00
|
|
|
#include <boost/foreach.hpp>
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2007-09-27 07:38:17 +00:00
|
|
|
using namespace ::com::sun::star;
|
|
|
|
|
|
|
|
|
2000-09-18 23:08:29 +00:00
|
|
|
#define COLFUZZY 20
|
|
|
|
#define MAX_TABWIDTH (USHRT_MAX - 2001)
|
|
|
|
|
|
|
|
|
|
|
|
class SwHTMLTableLayoutConstraints
|
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
sal_uInt16 nRow; // start row
|
|
|
|
sal_uInt16 nCol; // start column
|
|
|
|
sal_uInt16 nColSpan; // the column's COLSPAN
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
SwHTMLTableLayoutConstraints *pNext; // the next constraint
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
sal_uLong nMinNoAlign, nMaxNoAlign; // provisional result of AL-Pass 1
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
SwHTMLTableLayoutConstraints( sal_uLong nMin, sal_uLong nMax, sal_uInt16 nRow,
|
|
|
|
sal_uInt16 nCol, sal_uInt16 nColSp );
|
2000-09-18 23:08:29 +00:00
|
|
|
~SwHTMLTableLayoutConstraints();
|
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong GetMinNoAlign() const { return nMinNoAlign; }
|
|
|
|
sal_uLong GetMaxNoAlign() const { return nMaxNoAlign; }
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
SwHTMLTableLayoutConstraints *InsertNext( SwHTMLTableLayoutConstraints *pNxt );
|
|
|
|
SwHTMLTableLayoutConstraints* GetNext() const { return pNext; }
|
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 GetRow() const { return nRow; }
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 GetColSpan() const { return nColSpan; }
|
|
|
|
sal_uInt16 GetColumn() const { return nCol; }
|
2000-09-18 23:08:29 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
SwHTMLTableLayoutCnts::SwHTMLTableLayoutCnts( const SwStartNode *pSttNd,
|
|
|
|
SwHTMLTableLayout* pTab,
|
2012-11-08 12:16:44 +09:00
|
|
|
bool bNoBrTag,
|
2000-09-18 23:08:29 +00:00
|
|
|
SwHTMLTableLayoutCnts* pNxt ) :
|
|
|
|
pNext( pNxt ), pBox( 0 ), pTable( pTab ), pStartNode( pSttNd ),
|
2007-09-27 07:38:17 +00:00
|
|
|
nPass1Done( 0 ), nWidthSet( 0 ), bNoBreakTag( bNoBrTag )
|
2000-09-18 23:08:29 +00:00
|
|
|
{}
|
|
|
|
|
|
|
|
SwHTMLTableLayoutCnts::~SwHTMLTableLayoutCnts()
|
|
|
|
{
|
|
|
|
delete pNext;
|
|
|
|
delete pTable;
|
|
|
|
}
|
|
|
|
|
|
|
|
const SwStartNode *SwHTMLTableLayoutCnts::GetStartNode() const
|
|
|
|
{
|
|
|
|
return pBox ? pBox->GetSttNd() : pStartNode;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SwHTMLTableLayoutCell::SwHTMLTableLayoutCell( SwHTMLTableLayoutCnts *pCnts,
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 nRSpan, sal_uInt16 nCSpan,
|
2012-11-13 06:13:47 +09:00
|
|
|
sal_uInt16 nWidth, bool bPrcWidth,
|
|
|
|
bool bNWrapOpt ) :
|
2000-09-18 23:08:29 +00:00
|
|
|
pContents( pCnts ),
|
|
|
|
nRowSpan( nRSpan ), nColSpan( nCSpan ),
|
|
|
|
nWidthOption( nWidth ), bPrcWidthOption( bPrcWidth ),
|
|
|
|
bNoWrapOption( bNWrapOpt )
|
|
|
|
{}
|
|
|
|
|
|
|
|
SwHTMLTableLayoutCell::~SwHTMLTableLayoutCell()
|
|
|
|
{
|
|
|
|
if( nRowSpan==1 && nColSpan==1 )
|
|
|
|
{
|
|
|
|
delete pContents;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
SwHTMLTableLayoutColumn::SwHTMLTableLayoutColumn( sal_uInt16 nWidth,
|
2012-11-13 06:13:47 +09:00
|
|
|
bool bRelWidth,
|
|
|
|
bool bLBorder ) :
|
2000-09-18 23:08:29 +00:00
|
|
|
nMinNoAlign(MINLAY), nMaxNoAlign(MINLAY), nAbsMinNoAlign(MINLAY),
|
|
|
|
nMin(0), nMax(0),
|
|
|
|
nAbsColWidth(0), nRelColWidth(0),
|
|
|
|
nWidthOption( nWidth ), bRelWidthOption( bRelWidth ),
|
|
|
|
bLeftBorder( bLBorder )
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
|
|
SwHTMLTableLayoutConstraints::SwHTMLTableLayoutConstraints(
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nMin, sal_uLong nMax, sal_uInt16 nRw, sal_uInt16 nColumn, sal_uInt16 nColSp ):
|
2000-09-18 23:08:29 +00:00
|
|
|
nRow( nRw ), nCol( nColumn ), nColSpan( nColSp ),
|
2007-09-27 07:38:17 +00:00
|
|
|
pNext( 0 ),
|
|
|
|
nMinNoAlign( nMin ), nMaxNoAlign( nMax )
|
2000-09-18 23:08:29 +00:00
|
|
|
{}
|
|
|
|
|
|
|
|
SwHTMLTableLayoutConstraints::~SwHTMLTableLayoutConstraints()
|
|
|
|
{
|
|
|
|
delete pNext;
|
|
|
|
}
|
|
|
|
|
|
|
|
SwHTMLTableLayoutConstraints *SwHTMLTableLayoutConstraints::InsertNext(
|
|
|
|
SwHTMLTableLayoutConstraints *pNxt )
|
|
|
|
{
|
|
|
|
SwHTMLTableLayoutConstraints *pPrev = 0;
|
|
|
|
SwHTMLTableLayoutConstraints *pConstr = this;
|
|
|
|
while( pConstr )
|
|
|
|
{
|
|
|
|
if( pConstr->GetRow() > pNxt->GetRow() ||
|
|
|
|
pConstr->GetColumn() > pNxt->GetColumn() )
|
|
|
|
break;
|
|
|
|
pPrev = pConstr;
|
|
|
|
pConstr = pConstr->GetNext();
|
|
|
|
}
|
|
|
|
|
|
|
|
if( pPrev )
|
|
|
|
{
|
|
|
|
pNxt->pNext = pPrev->GetNext();
|
|
|
|
pPrev->pNext = pNxt;
|
|
|
|
pConstr = this;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pNxt->pNext = this;
|
|
|
|
pConstr = pNxt;
|
|
|
|
}
|
|
|
|
|
|
|
|
return pConstr;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
typedef SwHTMLTableLayoutColumn *SwHTMLTableLayoutColumnPtr;
|
|
|
|
typedef SwHTMLTableLayoutCell *SwHTMLTableLayoutCellPtr;
|
|
|
|
|
|
|
|
SwHTMLTableLayout::SwHTMLTableLayout(
|
|
|
|
const SwTable * pSwTbl,
|
2012-11-13 06:13:47 +09:00
|
|
|
sal_uInt16 nRws, sal_uInt16 nCls, bool bColsOpt, bool bColTgs,
|
|
|
|
sal_uInt16 nWdth, bool bPrcWdth, sal_uInt16 nBorderOpt,
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 nCellPad, sal_uInt16 nCellSp, SvxAdjust eAdjust,
|
|
|
|
sal_uInt16 nLMargin, sal_uInt16 nRMargin,
|
|
|
|
sal_uInt16 nBWidth, sal_uInt16 nLeftBWidth,
|
|
|
|
sal_uInt16 nRightBWidth,
|
|
|
|
sal_uInt16 nInhLeftBWidth, sal_uInt16 nInhRightBWidth ) :
|
2000-09-18 23:08:29 +00:00
|
|
|
aColumns( new SwHTMLTableLayoutColumnPtr[nCls] ),
|
|
|
|
aCells( new SwHTMLTableLayoutCellPtr[nRws*nCls] ),
|
|
|
|
pSwTable( pSwTbl ), pLeftFillerBox( 0 ), pRightFillerBox( 0 ),
|
|
|
|
nMin( 0 ), nMax( 0 ),
|
|
|
|
nRows( nRws ), nCols( nCls ),
|
|
|
|
nLeftMargin( nLMargin ), nRightMargin( nRMargin ),
|
2007-09-27 07:38:17 +00:00
|
|
|
nInhAbsLeftSpace( 0 ), nInhAbsRightSpace( 0 ),
|
|
|
|
nRelLeftFill( 0 ), nRelRightFill( 0 ),
|
|
|
|
nRelTabWidth( 0 ), nWidthOption( nWdth ),
|
2000-09-18 23:08:29 +00:00
|
|
|
nCellPadding( nCellPad ), nCellSpacing( nCellSp ), nBorder( nBorderOpt ),
|
|
|
|
nLeftBorderWidth( nLeftBWidth ), nRightBorderWidth( nRightBWidth ),
|
|
|
|
nInhLeftBorderWidth( nInhLeftBWidth ),
|
|
|
|
nInhRightBorderWidth( nInhRightBWidth ),
|
2007-09-27 07:38:17 +00:00
|
|
|
nBorderWidth( nBWidth ),
|
2000-09-18 23:08:29 +00:00
|
|
|
nDelayedResizeAbsAvail( 0 ), nLastResizeAbsAvail( 0 ),
|
|
|
|
nPass1Done( 0 ), nWidthSet( 0 ), eTableAdjust( eAdjust ),
|
|
|
|
bColsOption( bColsOpt ), bColTags( bColTgs ),
|
2012-11-13 06:13:47 +09:00
|
|
|
bPrcWidthOption( bPrcWdth ), bUseRelWidth( false ),
|
2011-01-17 15:06:54 +01:00
|
|
|
bMustResize( sal_True ), bExportable( sal_True ), bBordersChanged( sal_False ),
|
|
|
|
bMustNotResize( sal_False ), bMustNotRecalc( sal_False )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
aResizeTimer.SetTimeoutHdl( STATIC_LINK( this, SwHTMLTableLayout,
|
|
|
|
DelayedResize_Impl ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
SwHTMLTableLayout::~SwHTMLTableLayout()
|
|
|
|
{
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 i;
|
2003-12-01 15:36:04 +00:00
|
|
|
|
|
|
|
for( i = 0; i < nCols; i++ )
|
2000-09-18 23:08:29 +00:00
|
|
|
delete aColumns[i];
|
|
|
|
delete[] aColumns;
|
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 nCount = nRows*nCols;
|
2000-09-18 23:08:29 +00:00
|
|
|
for( i=0; i<nCount; i++ )
|
|
|
|
delete aCells[i];
|
|
|
|
delete[] aCells;
|
|
|
|
}
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// The border width are calculated like in Netscape:
|
|
|
|
// Outer border: BORDER + CELLSPACING + CELLPADDING
|
|
|
|
// Inner border: CELLSPACING + CELLPADDING
|
2012-01-04 13:50:06 +01:00
|
|
|
// However, we respect the border width in SW if bSwBorders is set,
|
|
|
|
// so that we don't wrap wrongly.
|
2012-01-03 13:56:50 +01:00
|
|
|
// We also need to respect the distance to the content. Even if
|
|
|
|
// only the opposite side has a border.
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 SwHTMLTableLayout::GetLeftCellSpace( sal_uInt16 nCol, sal_uInt16 nColSpan,
|
|
|
|
sal_Bool bSwBorders ) const
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 nSpace = nCellSpacing + nCellPadding;
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
if( nCol == 0 )
|
|
|
|
{
|
2007-09-27 07:38:17 +00:00
|
|
|
nSpace = nSpace + nBorder;
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
if( bSwBorders && nSpace < nLeftBorderWidth )
|
|
|
|
nSpace = nLeftBorderWidth;
|
|
|
|
}
|
|
|
|
else if( bSwBorders )
|
|
|
|
{
|
|
|
|
if( GetColumn(nCol)->HasLeftBorder() )
|
|
|
|
{
|
|
|
|
if( nSpace < nBorderWidth )
|
|
|
|
nSpace = nBorderWidth;
|
|
|
|
}
|
|
|
|
else if( nCol+nColSpan == nCols && nRightBorderWidth &&
|
|
|
|
nSpace < MIN_BORDER_DIST )
|
|
|
|
{
|
2010-11-25 17:08:45 +01:00
|
|
|
OSL_ENSURE( !nCellPadding, "GetLeftCellSpace: CELLPADDING!=0" );
|
2012-01-03 13:56:50 +01:00
|
|
|
// If the opposite side has a border we need to respect at
|
|
|
|
// least the minimum distance to the content.
|
|
|
|
// Additionally, we could also use nCellPadding for this.
|
2000-09-18 23:08:29 +00:00
|
|
|
nSpace = MIN_BORDER_DIST;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nSpace;
|
|
|
|
}
|
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 SwHTMLTableLayout::GetRightCellSpace( sal_uInt16 nCol, sal_uInt16 nColSpan,
|
|
|
|
sal_Bool bSwBorders ) const
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 nSpace = nCellPadding;
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
if( nCol+nColSpan == nCols )
|
|
|
|
{
|
|
|
|
nSpace += nBorder + nCellSpacing;
|
|
|
|
if( bSwBorders && nSpace < nRightBorderWidth )
|
|
|
|
nSpace = nRightBorderWidth;
|
|
|
|
}
|
|
|
|
else if( bSwBorders && GetColumn(nCol)->HasLeftBorder() &&
|
|
|
|
nSpace < MIN_BORDER_DIST )
|
|
|
|
{
|
2010-11-25 17:08:45 +01:00
|
|
|
OSL_ENSURE( !nCellPadding, "GetRightCellSpace: CELLPADDING!=0" );
|
2012-01-03 13:56:50 +01:00
|
|
|
// If the opposite side has a border we need to respect at
|
|
|
|
// least the minimum distance to the content.
|
|
|
|
// Additionally, we could also use nCellPadding for this.
|
2000-09-18 23:08:29 +00:00
|
|
|
nSpace = MIN_BORDER_DIST;
|
|
|
|
}
|
|
|
|
|
|
|
|
return nSpace;
|
|
|
|
}
|
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
void SwHTMLTableLayout::AddBorderWidth( sal_uLong &rMin, sal_uLong &rMax,
|
|
|
|
sal_uLong &rAbsMin,
|
|
|
|
sal_uInt16 nCol, sal_uInt16 nColSpan,
|
|
|
|
sal_Bool bSwBorders ) const
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nAdd = GetLeftCellSpace( nCol, nColSpan, bSwBorders ) +
|
2000-09-18 23:08:29 +00:00
|
|
|
GetRightCellSpace( nCol, nColSpan, bSwBorders );
|
|
|
|
|
|
|
|
rMin += nAdd;
|
|
|
|
rMax += nAdd;
|
|
|
|
rAbsMin += nAdd;
|
|
|
|
}
|
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
void SwHTMLTableLayout::SetBoxWidth( SwTableBox *pBox, sal_uInt16 nCol,
|
|
|
|
sal_uInt16 nColSpan ) const
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
SwFrmFmt *pFrmFmt = pBox->GetFrmFmt();
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// calculate the box's width
|
2000-09-18 23:08:29 +00:00
|
|
|
SwTwips nFrmWidth = 0;
|
|
|
|
while( nColSpan-- )
|
|
|
|
nFrmWidth += GetColumn( nCol++ )->GetRelColWidth();
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// and reset
|
2008-06-13 08:37:06 +00:00
|
|
|
pFrmFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, nFrmWidth, 0 ));
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
void SwHTMLTableLayout::GetAvail( sal_uInt16 nCol, sal_uInt16 nColSpan,
|
|
|
|
sal_uInt16& rAbsAvail, sal_uInt16& rRelAvail ) const
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
rAbsAvail = 0;
|
|
|
|
rRelAvail = 0;
|
2011-01-17 15:06:54 +01:00
|
|
|
for( sal_uInt16 i=nCol; i<nCol+nColSpan;i++ )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
const SwHTMLTableLayoutColumn *pColumn = GetColumn(i);
|
2007-09-27 07:38:17 +00:00
|
|
|
rAbsAvail = rAbsAvail + pColumn->GetAbsColWidth();
|
|
|
|
rRelAvail = rRelAvail + pColumn->GetRelColWidth();
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 SwHTMLTableLayout::GetBrowseWidthByVisArea( const SwDoc& rDoc )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
ViewShell *pVSh = 0;
|
|
|
|
rDoc.GetEditShell( &pVSh );
|
|
|
|
if( pVSh )
|
|
|
|
{
|
2011-01-17 15:06:54 +01:00
|
|
|
return (sal_uInt16)pVSh->GetBrowseWidth();
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 SwHTMLTableLayout::GetBrowseWidth( const SwDoc& rDoc )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// If we have a layout, we can get the width from there.
|
2010-06-13 15:22:56 +02:00
|
|
|
const SwRootFrm *pRootFrm = rDoc.GetCurrentLayout(); //swmod 080218
|
2000-09-18 23:08:29 +00:00
|
|
|
if( pRootFrm )
|
|
|
|
{
|
|
|
|
const SwFrm *pPageFrm = pRootFrm->GetLower();
|
|
|
|
if( pPageFrm )
|
2011-01-17 15:06:54 +01:00
|
|
|
return (sal_uInt16)pPageFrm->Prt().Width();
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
2011-02-02 20:41:40 +09:00
|
|
|
// #i91658#
|
2010-05-12 16:03:59 +02:00
|
|
|
// Assertion removed which state that no browse width is available.
|
|
|
|
// Investigation reveals that all calls can handle the case that no browse
|
|
|
|
// width is provided.
|
|
|
|
return GetBrowseWidthByVisArea( rDoc );
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 SwHTMLTableLayout::GetBrowseWidthByTabFrm(
|
2000-09-18 23:08:29 +00:00
|
|
|
const SwTabFrm& rTabFrm ) const
|
|
|
|
{
|
|
|
|
SwTwips nWidth = 0;
|
|
|
|
|
|
|
|
const SwFrm *pUpper = rTabFrm.GetUpper();
|
|
|
|
if( MayBeInFlyFrame() && pUpper->IsFlyFrm() &&
|
2004-06-28 12:32:43 +00:00
|
|
|
((const SwFlyFrm *)pUpper)->GetAnchorFrm() )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// If the table is located within a self-created frame, the anchor's
|
|
|
|
// width is relevant not the frame's width.
|
2012-01-04 13:50:06 +01:00
|
|
|
// For paragraph-bound frames we don't respect paragraph indents.
|
2004-06-28 12:32:43 +00:00
|
|
|
const SwFrm *pAnchor = ((const SwFlyFrm *)pUpper)->GetAnchorFrm();
|
2000-09-18 23:08:29 +00:00
|
|
|
if( pAnchor->IsTxtFrm() )
|
|
|
|
nWidth = pAnchor->Frm().Width();
|
|
|
|
else
|
|
|
|
nWidth = pAnchor->Prt().Width();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nWidth = pUpper->Prt().Width();
|
|
|
|
}
|
|
|
|
|
|
|
|
SwTwips nUpperDummy = 0;
|
|
|
|
long nRightOffset = 0,
|
|
|
|
nLeftOffset = 0;
|
|
|
|
rTabFrm.CalcFlyOffsets( nUpperDummy, nLeftOffset, nRightOffset );
|
|
|
|
nWidth -= (nLeftOffset + nRightOffset);
|
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
return nWidth < USHRT_MAX ? static_cast<sal_uInt16>(nWidth) : USHRT_MAX;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 SwHTMLTableLayout::GetBrowseWidthByTable( const SwDoc& rDoc ) const
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 nBrowseWidth = 0;
|
2010-12-17 09:02:23 +01:00
|
|
|
SwTabFrm* pFrm = SwIterator<SwTabFrm,SwFmt>::FirstElement( *pSwTable->GetFrmFmt() );
|
|
|
|
if( pFrm )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2010-12-17 09:02:23 +01:00
|
|
|
nBrowseWidth = GetBrowseWidthByTabFrm( *pFrm );
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nBrowseWidth = SwHTMLTableLayout::GetBrowseWidth( rDoc );
|
|
|
|
}
|
|
|
|
|
|
|
|
return nBrowseWidth;
|
|
|
|
}
|
|
|
|
|
|
|
|
const SwStartNode *SwHTMLTableLayout::GetAnyBoxStartNode() const
|
|
|
|
{
|
|
|
|
const SwStartNode *pBoxSttNd;
|
|
|
|
|
|
|
|
const SwTableBox* pBox = pSwTable->GetTabLines()[0]->GetTabBoxes()[0];
|
|
|
|
while( 0 == (pBoxSttNd = pBox->GetSttNd()) )
|
|
|
|
{
|
2012-06-18 18:04:44 +02:00
|
|
|
OSL_ENSURE( pBox->GetTabLines().size() > 0,
|
2012-01-03 13:56:50 +01:00
|
|
|
"Box without start node and lines" );
|
2012-06-18 18:04:44 +02:00
|
|
|
OSL_ENSURE( pBox->GetTabLines().front()->GetTabBoxes().size() > 0,
|
2012-01-03 13:56:50 +01:00
|
|
|
"Line without boxes" );
|
2012-06-18 18:04:44 +02:00
|
|
|
pBox = pBox->GetTabLines().front()->GetTabBoxes().front();
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return pBoxSttNd;
|
|
|
|
}
|
|
|
|
|
|
|
|
SwFrmFmt *SwHTMLTableLayout::FindFlyFrmFmt() const
|
|
|
|
{
|
|
|
|
const SwTableNode *pTblNd = GetAnyBoxStartNode()->FindTableNode();
|
2010-11-25 17:08:45 +01:00
|
|
|
OSL_ENSURE( pTblNd, "Kein Table-Node?" );
|
2000-09-18 23:08:29 +00:00
|
|
|
return pTblNd->GetFlyFmt();
|
|
|
|
}
|
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
static void lcl_GetMinMaxSize( sal_uLong& rMinNoAlignCnts, sal_uLong& rMaxNoAlignCnts,
|
|
|
|
sal_uLong& rAbsMinNoAlignCnts,
|
2012-11-08 12:16:44 +09:00
|
|
|
SwTxtNode *pTxtNd, sal_uLong nIdx, bool bNoBreak )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
pTxtNd->GetMinMaxSize( nIdx, rMinNoAlignCnts, rMaxNoAlignCnts,
|
|
|
|
rAbsMinNoAlignCnts );
|
2010-11-25 17:08:45 +01:00
|
|
|
OSL_ENSURE( rAbsMinNoAlignCnts <= rMinNoAlignCnts,
|
2000-09-18 23:08:29 +00:00
|
|
|
"GetMinMaxSize: absmin > min" );
|
2010-11-25 17:08:45 +01:00
|
|
|
OSL_ENSURE( rMinNoAlignCnts <= rMaxNoAlignCnts,
|
2000-09-18 23:08:29 +00:00
|
|
|
"GetMinMaxSize: max > min" );
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// The maximal width for a <PRE> paragraph is the minimal width
|
2000-09-18 23:08:29 +00:00
|
|
|
const SwFmtColl *pColl = &pTxtNd->GetAnyFmtColl();
|
|
|
|
while( pColl && !pColl->IsDefault() &&
|
|
|
|
(USER_FMT & pColl->GetPoolFmtId()) )
|
|
|
|
{
|
|
|
|
pColl = (const SwFmtColl *)pColl->DerivedFrom();
|
|
|
|
}
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// <NOBR> in the whole cell apply to text but not to tables.
|
|
|
|
// Netscape only considers this for graphics.
|
2000-09-18 23:08:29 +00:00
|
|
|
if( (pColl && RES_POOLCOLL_HTML_PRE==pColl->GetPoolFmtId()) || bNoBreak )
|
|
|
|
{
|
|
|
|
rMinNoAlignCnts = rMaxNoAlignCnts;
|
|
|
|
rAbsMinNoAlignCnts = rMaxNoAlignCnts;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SwHTMLTableLayout::AutoLayoutPass1()
|
|
|
|
{
|
|
|
|
nPass1Done++;
|
|
|
|
|
|
|
|
ClearPass1Info();
|
|
|
|
|
2012-11-13 06:13:47 +09:00
|
|
|
bool bFixRelWidths = false;
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 i;
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
SwHTMLTableLayoutConstraints *pConstraints = 0;
|
|
|
|
|
|
|
|
for( i=0; i<nCols; i++ )
|
|
|
|
{
|
|
|
|
SwHTMLTableLayoutColumn *pColumn = GetColumn( i );
|
|
|
|
pColumn->ClearPass1Info( !HasColTags() );
|
2012-01-03 13:56:50 +01:00
|
|
|
sal_uInt16 nMinColSpan = USHRT_MAX; // Column count to which the calculated width refers to
|
|
|
|
sal_uInt16 nColSkip = USHRT_MAX; // How many columns need to be skipped
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
for( sal_uInt16 j=0; j<nRows; j++ )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
SwHTMLTableLayoutCell *pCell = GetCell(j,i);
|
|
|
|
SwHTMLTableLayoutCnts *pCnts = pCell->GetContents();
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// We need to examine all rows in order to
|
|
|
|
// get the column that should be calculated next.
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 nColSpan = pCell->GetColSpan();
|
2000-09-18 23:08:29 +00:00
|
|
|
if( nColSpan < nColSkip )
|
|
|
|
nColSkip = nColSpan;
|
|
|
|
|
|
|
|
if( !pCnts || (pCnts && !pCnts->IsPass1Done(nPass1Done)) )
|
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// The cell is empty or it's content was not edited
|
2000-09-18 23:08:29 +00:00
|
|
|
if( nColSpan < nMinColSpan )
|
|
|
|
nMinColSpan = nColSpan;
|
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nMinNoAlignCell = 0;
|
|
|
|
sal_uLong nMaxNoAlignCell = 0;
|
|
|
|
sal_uLong nAbsMinNoAlignCell = 0;
|
|
|
|
sal_uLong nMaxTableCell = 0;
|
|
|
|
sal_uLong nAbsMinTableCell = 0;
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
while( pCnts )
|
|
|
|
{
|
|
|
|
const SwStartNode *pSttNd = pCnts->GetStartNode();
|
|
|
|
if( pSttNd )
|
|
|
|
{
|
|
|
|
const SwDoc *pDoc = pSttNd->GetDoc();
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nIdx = pSttNd->GetIndex();
|
2000-09-18 23:08:29 +00:00
|
|
|
while( !(pDoc->GetNodes()[nIdx])->IsEndNode() )
|
|
|
|
{
|
|
|
|
SwTxtNode *pTxtNd = (pDoc->GetNodes()[nIdx])->GetTxtNode();
|
|
|
|
if( pTxtNd )
|
|
|
|
{
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nMinNoAlignCnts = 0;
|
|
|
|
sal_uLong nMaxNoAlignCnts = 0;
|
|
|
|
sal_uLong nAbsMinNoAlignCnts = 0;
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
lcl_GetMinMaxSize( nMinNoAlignCnts,
|
|
|
|
nMaxNoAlignCnts,
|
|
|
|
nAbsMinNoAlignCnts,
|
|
|
|
pTxtNd, nIdx,
|
|
|
|
pCnts->HasNoBreakTag() );
|
|
|
|
|
|
|
|
if( nMinNoAlignCnts > nMinNoAlignCell )
|
|
|
|
nMinNoAlignCell = nMinNoAlignCnts;
|
|
|
|
if( nMaxNoAlignCnts > nMaxNoAlignCell )
|
|
|
|
nMaxNoAlignCell = nMaxNoAlignCnts;
|
|
|
|
if( nAbsMinNoAlignCnts > nAbsMinNoAlignCell )
|
|
|
|
nAbsMinNoAlignCell = nAbsMinNoAlignCnts;
|
|
|
|
}
|
2007-07-31 16:40:36 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
SwTableNode *pTabNd = (pDoc->GetNodes()[nIdx])->GetTableNode();
|
|
|
|
if( pTabNd )
|
|
|
|
{
|
|
|
|
SwHTMLTableLayout *pChild = pTabNd->GetTable().GetHTMLTableLayout();
|
|
|
|
if( pChild )
|
|
|
|
{
|
|
|
|
pChild->AutoLayoutPass1();
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nMaxTableCnts = pChild->nMax;
|
|
|
|
sal_uLong nAbsMinTableCnts = pChild->nMin;
|
2007-07-31 16:40:36 +00:00
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// A fixed table width is taken over as minimum and
|
|
|
|
// maximum at the same time
|
2007-07-31 16:40:36 +00:00
|
|
|
if( !pChild->bPrcWidthOption && pChild->nWidthOption )
|
|
|
|
{
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nTabWidth = pChild->nWidthOption;
|
2007-07-31 16:40:36 +00:00
|
|
|
if( nTabWidth >= nAbsMinTableCnts )
|
|
|
|
{
|
|
|
|
nMaxTableCnts = nTabWidth;
|
|
|
|
nAbsMinTableCnts = nTabWidth;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nMaxTableCnts = nAbsMinTableCnts;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( nMaxTableCnts > nMaxTableCell )
|
|
|
|
nMaxTableCell = nMaxTableCnts;
|
|
|
|
if( nAbsMinTableCnts > nAbsMinTableCell )
|
|
|
|
nAbsMinTableCell = nAbsMinTableCnts;
|
|
|
|
}
|
|
|
|
nIdx = pTabNd->EndOfSectionNode()->GetIndex();
|
|
|
|
}
|
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
nIdx++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-11-25 17:08:45 +01:00
|
|
|
OSL_ENSURE( !this, "Sub tables in HTML import?" );
|
2000-09-18 23:08:29 +00:00
|
|
|
SwHTMLTableLayout *pChild = pCnts->GetTable();
|
|
|
|
pChild->AutoLayoutPass1();
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nMaxTableCnts = pChild->nMax;
|
|
|
|
sal_uLong nAbsMinTableCnts = pChild->nMin;
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// A fixed table width is taken over as minimum and
|
|
|
|
// maximum at the same time
|
2000-09-18 23:08:29 +00:00
|
|
|
if( !pChild->bPrcWidthOption && pChild->nWidthOption )
|
|
|
|
{
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nTabWidth = pChild->nWidthOption;
|
2000-09-18 23:08:29 +00:00
|
|
|
if( nTabWidth >= nAbsMinTableCnts )
|
|
|
|
{
|
|
|
|
nMaxTableCnts = nTabWidth;
|
|
|
|
nAbsMinTableCnts = nTabWidth;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nMaxTableCnts = nAbsMinTableCnts;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( nMaxTableCnts > nMaxTableCell )
|
|
|
|
nMaxTableCell = nMaxTableCnts;
|
|
|
|
if( nAbsMinTableCnts > nAbsMinTableCell )
|
|
|
|
nAbsMinTableCell = nAbsMinTableCnts;
|
|
|
|
}
|
|
|
|
pCnts->SetPass1Done( nPass1Done );
|
|
|
|
pCnts = pCnts->GetNext();
|
|
|
|
}
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// This code previously came after AddBorderWidth
|
|
|
|
// If a table's width is wider in a cell than what we've calculated
|
|
|
|
// for the other content we need to use the table's width.
|
2000-09-18 23:08:29 +00:00
|
|
|
if( nMaxTableCell > nMaxNoAlignCell )
|
|
|
|
nMaxNoAlignCell = nMaxTableCell;
|
|
|
|
if( nAbsMinTableCell > nAbsMinNoAlignCell )
|
|
|
|
{
|
|
|
|
nAbsMinNoAlignCell = nAbsMinTableCell;
|
|
|
|
if( nMinNoAlignCell < nAbsMinNoAlignCell )
|
|
|
|
nMinNoAlignCell = nAbsMinNoAlignCell;
|
|
|
|
if( nMaxNoAlignCell < nMinNoAlignCell )
|
|
|
|
nMaxNoAlignCell = nMinNoAlignCell;
|
|
|
|
}
|
2012-01-03 13:56:50 +01:00
|
|
|
// This code previously came after AddBorderWidth
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_Bool bRelWidth = pCell->IsPrcWidthOption();
|
|
|
|
sal_uInt16 nWidth = pCell->GetWidthOption();
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2012-01-04 13:50:06 +01:00
|
|
|
// A NOWRAP option applies to text and tables, but is
|
|
|
|
// not applied for fixed cell width.
|
2012-01-03 13:56:50 +01:00
|
|
|
// Instead, the stated cell width behaves like a minimal
|
|
|
|
// width.
|
2000-09-18 23:08:29 +00:00
|
|
|
if( pCell->HasNoWrapOption() )
|
|
|
|
{
|
|
|
|
if( nWidth==0 || bRelWidth )
|
|
|
|
{
|
|
|
|
nMinNoAlignCell = nMaxNoAlignCell;
|
|
|
|
nAbsMinNoAlignCell = nMaxNoAlignCell;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if( nWidth>nMinNoAlignCell )
|
|
|
|
nMinNoAlignCell = nWidth;
|
|
|
|
if( nWidth>nAbsMinNoAlignCell )
|
|
|
|
nAbsMinNoAlignCell = nWidth;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// Respect minimum width for content
|
2000-09-18 23:08:29 +00:00
|
|
|
if( nMinNoAlignCell < MINLAY )
|
|
|
|
nMinNoAlignCell = MINLAY;
|
|
|
|
if( nMaxNoAlignCell < MINLAY )
|
|
|
|
nMaxNoAlignCell = MINLAY;
|
|
|
|
if( nAbsMinNoAlignCell < MINLAY )
|
|
|
|
nAbsMinNoAlignCell = MINLAY;
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// Respect the border and distance to the content
|
2000-09-18 23:08:29 +00:00
|
|
|
AddBorderWidth( nMinNoAlignCell, nMaxNoAlignCell,
|
|
|
|
nAbsMinNoAlignCell, i, nColSpan );
|
|
|
|
|
|
|
|
if( 1==nColSpan )
|
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// take over the values directly
|
2000-09-18 23:08:29 +00:00
|
|
|
pColumn->MergeMinMaxNoAlign( nMinNoAlignCell,
|
|
|
|
nMaxNoAlignCell,
|
|
|
|
nAbsMinNoAlignCell );
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// the widest WIDTH wins
|
2000-09-18 23:08:29 +00:00
|
|
|
if( !HasColTags() )
|
|
|
|
pColumn->MergeCellWidthOption( nWidth, bRelWidth );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// Process the data line by line from left to right at the end
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// When which values is taken over will be explained further down.
|
2000-09-18 23:08:29 +00:00
|
|
|
if( !HasColTags() && nWidth && !bRelWidth )
|
|
|
|
{
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nAbsWidth = nWidth, nDummy = 0, nDummy2 = 0;
|
2000-09-18 23:08:29 +00:00
|
|
|
AddBorderWidth( nAbsWidth, nDummy, nDummy2,
|
2011-01-17 15:06:54 +01:00
|
|
|
i, nColSpan, sal_False );
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
if( nAbsWidth >= nMinNoAlignCell )
|
|
|
|
{
|
|
|
|
nMaxNoAlignCell = nAbsWidth;
|
|
|
|
if( HasColsOption() )
|
|
|
|
nMinNoAlignCell = nAbsWidth;
|
|
|
|
}
|
|
|
|
else if( nAbsWidth >= nAbsMinNoAlignCell )
|
|
|
|
{
|
|
|
|
nMaxNoAlignCell = nAbsWidth;
|
|
|
|
nMinNoAlignCell = nAbsWidth;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nMaxNoAlignCell = nAbsMinNoAlignCell;
|
|
|
|
nMinNoAlignCell = nAbsMinNoAlignCell;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if( HasColsOption() || HasColTags() )
|
|
|
|
nMinNoAlignCell = nAbsMinNoAlignCell;
|
|
|
|
|
|
|
|
SwHTMLTableLayoutConstraints *pConstr =
|
|
|
|
new SwHTMLTableLayoutConstraints( nMinNoAlignCell,
|
|
|
|
nMaxNoAlignCell, j, i, nColSpan );
|
|
|
|
if( pConstraints )
|
|
|
|
pConstraints = pConstraints->InsertNext( pConstr );
|
|
|
|
else
|
|
|
|
pConstraints = pConstr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-25 17:08:45 +01:00
|
|
|
OSL_ENSURE( nMinColSpan>0 && nColSkip>0 && nColSkip <= nMinColSpan,
|
2012-01-03 13:56:50 +01:00
|
|
|
"Layout pass 1: Columns are being forgotten!" );
|
2010-11-25 17:08:45 +01:00
|
|
|
OSL_ENSURE( nMinColSpan!=USHRT_MAX,
|
2012-01-03 13:56:50 +01:00
|
|
|
"Layout pass 1: unnecessary pass through the loop or a bug" );
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
if( 1==nMinColSpan )
|
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// There are cells with COLSPAN 1 and therefore also useful
|
|
|
|
// values in pColumn
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// Take over values according to the following table (Netscape 4.0 pv 3):
|
2000-09-18 23:08:29 +00:00
|
|
|
//
|
2012-01-03 13:56:50 +01:00
|
|
|
// WIDTH: no COLS COLS
|
2000-09-18 23:08:29 +00:00
|
|
|
//
|
2012-01-03 13:56:50 +01:00
|
|
|
// none min = min min = absmin
|
2000-09-18 23:08:29 +00:00
|
|
|
// max = max max = max
|
|
|
|
//
|
|
|
|
// >= min min = min min = width
|
|
|
|
// max = width max = width
|
|
|
|
//
|
|
|
|
// >= absmin min = wdith(*) min = width
|
|
|
|
// max = width max = width
|
|
|
|
//
|
|
|
|
// < absmin min = absmin min = absmin
|
|
|
|
// max = absmin max = absmin
|
|
|
|
//
|
2012-01-03 13:56:50 +01:00
|
|
|
// (*) Netscape uses the minimum width without a break before
|
2012-01-04 13:50:06 +01:00
|
|
|
// the last graphic here. We don't have that (yet?),
|
|
|
|
// so we leave it set to width.
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
if( pColumn->GetWidthOption() && !pColumn->IsRelWidthOption() )
|
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// Take over absolute widths as minimal and maximal widths.
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nAbsWidth = pColumn->GetWidthOption();
|
|
|
|
sal_uLong nDummy = 0, nDummy2 = 0;
|
|
|
|
AddBorderWidth( nAbsWidth, nDummy, nDummy2, i, 1, sal_False );
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
if( nAbsWidth >= pColumn->GetMinNoAlign() )
|
|
|
|
{
|
|
|
|
pColumn->SetMinMax( HasColsOption() ? nAbsWidth
|
|
|
|
: pColumn->GetMinNoAlign(),
|
|
|
|
nAbsWidth );
|
|
|
|
}
|
|
|
|
else if( nAbsWidth >= pColumn->GetAbsMinNoAlign() )
|
|
|
|
{
|
|
|
|
pColumn->SetMinMax( nAbsWidth, nAbsWidth );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pColumn->SetMinMax( pColumn->GetAbsMinNoAlign(),
|
|
|
|
pColumn->GetAbsMinNoAlign() );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pColumn->SetMinMax( HasColsOption() ? pColumn->GetAbsMinNoAlign()
|
|
|
|
: pColumn->GetMinNoAlign(),
|
|
|
|
pColumn->GetMaxNoAlign() );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if( USHRT_MAX!=nMinColSpan )
|
|
|
|
{
|
2012-01-04 13:50:06 +01:00
|
|
|
// Can be anything != 0, because it is altered by the constraints.
|
2000-09-18 23:08:29 +00:00
|
|
|
pColumn->SetMinMax( MINLAY, MINLAY );
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// the next columns need not to be processed
|
2000-09-18 23:08:29 +00:00
|
|
|
i += (nColSkip-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
nMin += pColumn->GetMin();
|
|
|
|
nMax += pColumn->GetMax();
|
2012-11-13 06:13:47 +09:00
|
|
|
if (pColumn->IsRelWidthOption()) bFixRelWidths = true;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// Now process the constraints
|
2000-09-18 23:08:29 +00:00
|
|
|
SwHTMLTableLayoutConstraints *pConstr = pConstraints;
|
|
|
|
while( pConstr )
|
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// At first we need to process the width in the same way
|
|
|
|
// as the column widths
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 nCol = pConstr->GetColumn();
|
|
|
|
sal_uInt16 nColSpan = pConstr->GetColSpan();
|
|
|
|
sal_uLong nConstrMin = pConstr->GetMinNoAlign();
|
|
|
|
sal_uLong nConstrMax = pConstr->GetMaxNoAlign();
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// We get the hitherto width of the spanned columns
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nColsMin = 0;
|
|
|
|
sal_uLong nColsMax = 0;
|
|
|
|
for( sal_uInt16 j=nCol; j<nCol+nColSpan; j++ )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2007-09-27 07:38:17 +00:00
|
|
|
SwHTMLTableLayoutColumn *pColumn = GetColumn( j );
|
2000-09-18 23:08:29 +00:00
|
|
|
nColsMin += pColumn->GetMin();
|
|
|
|
nColsMax += pColumn->GetMax();
|
|
|
|
}
|
|
|
|
|
|
|
|
if( nColsMin<nConstrMin )
|
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// Proportionately distribute the minimum value to the columns
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nMinD = nConstrMin-nColsMin;
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
if( nConstrMin > nColsMax )
|
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// Proportional according to the minimum widths
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 nEndCol = nCol+nColSpan;
|
|
|
|
sal_uLong nDiff = nMinD;
|
|
|
|
for( sal_uInt16 ic=nCol; ic<nEndCol; ic++ )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2007-09-27 07:38:17 +00:00
|
|
|
SwHTMLTableLayoutColumn *pColumn = GetColumn( ic );
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nColMin = pColumn->GetMin();
|
|
|
|
sal_uLong nColMax = pColumn->GetMax();
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
nMin -= nColMin;
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nAdd = ic<nEndCol-1 ? (nColMin * nMinD) / nColsMin
|
2000-09-18 23:08:29 +00:00
|
|
|
: nDiff;
|
|
|
|
nColMin += nAdd;
|
|
|
|
nMin += nColMin;
|
2012-01-03 13:56:50 +01:00
|
|
|
OSL_ENSURE( nDiff >= nAdd, "Ooops: nDiff is not correct anymore" );
|
2000-09-18 23:08:29 +00:00
|
|
|
nDiff -= nAdd;
|
|
|
|
|
|
|
|
if( nColMax < nColMin )
|
|
|
|
{
|
|
|
|
nMax -= nColMax;
|
|
|
|
nColsMax -= nColMax;
|
|
|
|
nColMax = nColMin;
|
|
|
|
nMax += nColMax;
|
|
|
|
nColsMax += nColMax;
|
|
|
|
}
|
|
|
|
|
|
|
|
pColumn->SetMinMax( nColMin, nColMax );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// Proportional according to the difference of max and min
|
2011-01-17 15:06:54 +01:00
|
|
|
for( sal_uInt16 ic=nCol; ic<nCol+nColSpan; ic++ )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2007-09-27 07:38:17 +00:00
|
|
|
SwHTMLTableLayoutColumn *pColumn = GetColumn( ic );
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nDiff = pColumn->GetMax()-pColumn->GetMin();
|
2000-09-18 23:08:29 +00:00
|
|
|
if( nMinD < nDiff )
|
|
|
|
nDiff = nMinD;
|
|
|
|
|
|
|
|
pColumn->AddToMin( nDiff );
|
|
|
|
|
2010-11-25 17:08:45 +01:00
|
|
|
OSL_ENSURE( pColumn->GetMax() >= pColumn->GetMin(),
|
2012-01-04 13:50:06 +01:00
|
|
|
"Why is the Column suddenly too narrow?" );
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
nMin += nDiff;
|
|
|
|
nMinD -= nDiff;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !HasColTags() && nColsMax<nConstrMax )
|
|
|
|
{
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nMaxD = nConstrMax-nColsMax;
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
for( sal_uInt16 ic=nCol; ic<nCol+nColSpan; ic++ )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2007-09-27 07:38:17 +00:00
|
|
|
SwHTMLTableLayoutColumn *pColumn = GetColumn( ic );
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
nMax -= pColumn->GetMax();
|
|
|
|
|
|
|
|
pColumn->AddToMax( (pColumn->GetMax() * nMaxD) / nColsMax );
|
|
|
|
|
|
|
|
nMax += pColumn->GetMax();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pConstr = pConstr->GetNext();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if( bFixRelWidths )
|
|
|
|
{
|
|
|
|
if( HasColTags() )
|
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// To adapt the relative widths, in a first step we multiply the
|
|
|
|
// minimum width of all affected cells with the relative width
|
|
|
|
// of the column.
|
|
|
|
// Thus, the width ratio among the columns is correct.
|
|
|
|
//
|
2012-01-04 13:50:06 +01:00
|
|
|
// Furthermore, a factor is calculated that says by how much the
|
|
|
|
// cell has gotten wider than the minimum width.
|
2012-01-03 13:56:50 +01:00
|
|
|
//
|
2012-01-04 13:50:06 +01:00
|
|
|
// In the second step the calculated widths are divided by this
|
|
|
|
// factor. Thereby a cell's width is preserved and serves as a
|
|
|
|
// basis for the other cells.
|
2012-01-03 13:56:50 +01:00
|
|
|
// We only change the maximum widths here!
|
|
|
|
|
|
|
|
sal_uLong nAbsMin = 0; // absolute minimum width of all widths with relative width
|
|
|
|
sal_uLong nRel = 0; // sum of all relative widths of all columns
|
2000-09-18 23:08:29 +00:00
|
|
|
for( i=0; i<nCols; i++ )
|
|
|
|
{
|
|
|
|
SwHTMLTableLayoutColumn *pColumn = GetColumn( i );
|
|
|
|
if( pColumn->IsRelWidthOption() && pColumn->GetWidthOption() )
|
|
|
|
{
|
|
|
|
nAbsMin += pColumn->GetMin();
|
|
|
|
nRel += pColumn->GetWidthOption();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nQuot = ULONG_MAX;
|
2000-09-18 23:08:29 +00:00
|
|
|
for( i=0; i<nCols; i++ )
|
|
|
|
{
|
|
|
|
SwHTMLTableLayoutColumn *pColumn = GetColumn( i );
|
|
|
|
if( pColumn->IsRelWidthOption() )
|
|
|
|
{
|
|
|
|
nMax -= pColumn->GetMax();
|
|
|
|
if( pColumn->GetWidthOption() && pColumn->GetMin() )
|
|
|
|
{
|
|
|
|
pColumn->SetMax( nAbsMin * pColumn->GetWidthOption() );
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nColQuot = pColumn->GetMax() / pColumn->GetMin();
|
2000-09-18 23:08:29 +00:00
|
|
|
if( nColQuot<nQuot )
|
|
|
|
nQuot = nColQuot;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-11-25 17:08:45 +01:00
|
|
|
OSL_ENSURE( 0==nRel || nQuot!=ULONG_MAX,
|
2012-01-03 13:56:50 +01:00
|
|
|
"Where did the relative columns go?" );
|
2000-09-18 23:08:29 +00:00
|
|
|
for( i=0; i<nCols; i++ )
|
|
|
|
{
|
|
|
|
SwHTMLTableLayoutColumn *pColumn = GetColumn( i );
|
|
|
|
if( pColumn->IsRelWidthOption() )
|
|
|
|
{
|
|
|
|
if( pColumn->GetWidthOption() )
|
|
|
|
pColumn->SetMax( pColumn->GetMax() / nQuot );
|
|
|
|
else
|
|
|
|
pColumn->SetMax( pColumn->GetMin() );
|
2010-11-25 17:08:45 +01:00
|
|
|
OSL_ENSURE( pColumn->GetMax() >= pColumn->GetMin(),
|
2012-01-03 13:56:50 +01:00
|
|
|
"Maximum column width is lower than the minimum column width" );
|
2000-09-18 23:08:29 +00:00
|
|
|
nMax += pColumn->GetMax();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
sal_uInt16 nRel = 0; // sum of the relative widths of all columns
|
|
|
|
sal_uInt16 nRelCols = 0; // count of the columns with a relative setting
|
|
|
|
sal_uLong nRelMax = 0; // fraction of the maximum of this column
|
2000-09-18 23:08:29 +00:00
|
|
|
for( i=0; i<nCols; i++ )
|
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
OSL_ENSURE( nRel<=100, "relative width of all columns > 100%" );
|
2000-09-18 23:08:29 +00:00
|
|
|
SwHTMLTableLayoutColumn *pColumn = GetColumn( i );
|
|
|
|
if( pColumn->IsRelWidthOption() && pColumn->GetWidthOption() )
|
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// Make sure that the relative widths don't go above 100%
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 nColWidth = pColumn->GetWidthOption();
|
2000-09-18 23:08:29 +00:00
|
|
|
if( nRel+nColWidth > 100 )
|
|
|
|
{
|
|
|
|
nColWidth = 100 - nRel;
|
2012-11-13 06:13:47 +09:00
|
|
|
pColumn->SetWidthOption( nColWidth, true, false );
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
nRelMax += pColumn->GetMax();
|
2007-09-27 07:38:17 +00:00
|
|
|
nRel = nRel + nColWidth;
|
2000-09-18 23:08:29 +00:00
|
|
|
nRelCols++;
|
|
|
|
}
|
|
|
|
else if( !pColumn->GetMin() )
|
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// The column is empty (so it was solely created by
|
|
|
|
// COLSPAN) and therefore must not be assigned a % width.
|
2000-09-18 23:08:29 +00:00
|
|
|
nRelCols++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// If there are percentages left we distribute them to the columns
|
|
|
|
// that don't have a width setting. Like in Netscape we distribute
|
2012-01-04 13:50:06 +01:00
|
|
|
// the remaining percentages according to the ratio of the maximum
|
|
|
|
// width of the affected columns.
|
|
|
|
// For the maximum widths we also take the fixed-width columns
|
|
|
|
// into account. Is that correct?
|
2000-09-18 23:08:29 +00:00
|
|
|
if( nRel < 100 && nRelCols < nCols )
|
|
|
|
{
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 nRelLeft = 100 - nRel;
|
|
|
|
sal_uLong nFixMax = nMax - nRelMax;
|
2000-09-18 23:08:29 +00:00
|
|
|
for( i=0; i<nCols; i++ )
|
|
|
|
{
|
|
|
|
SwHTMLTableLayoutColumn *pColumn = GetColumn( i );
|
|
|
|
if( !pColumn->IsRelWidthOption() &&
|
|
|
|
!pColumn->GetWidthOption() &&
|
|
|
|
pColumn->GetMin() )
|
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// the next column gets the rest
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 nColWidth =
|
|
|
|
(sal_uInt16)((pColumn->GetMax() * nRelLeft) / nFixMax);
|
2012-11-13 06:13:47 +09:00
|
|
|
pColumn->SetWidthOption( nColWidth, true, false );
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// adjust the maximum widths now accordingly
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nQuotMax = ULONG_MAX;
|
|
|
|
sal_uLong nOldMax = nMax;
|
2000-09-18 23:08:29 +00:00
|
|
|
nMax = 0;
|
|
|
|
for( i=0; i<nCols; i++ )
|
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// Columns with a % setting are adapted accordingly.
|
|
|
|
// Columns, that
|
|
|
|
// - do not have a % setting and are located within a tables
|
|
|
|
// with COLS and WIDTH, or
|
|
|
|
// - their width is 0%
|
|
|
|
// get set to the minimum width.
|
2000-09-18 23:08:29 +00:00
|
|
|
SwHTMLTableLayoutColumn *pColumn = GetColumn( i );
|
|
|
|
if( pColumn->IsRelWidthOption() && pColumn->GetWidthOption() )
|
|
|
|
{
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nNewMax;
|
|
|
|
sal_uLong nColQuotMax;
|
2000-09-18 23:08:29 +00:00
|
|
|
if( !nWidthOption )
|
|
|
|
{
|
|
|
|
nNewMax = nOldMax * pColumn->GetWidthOption();
|
|
|
|
nColQuotMax = nNewMax / pColumn->GetMax();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nNewMax = nMin * pColumn->GetWidthOption();
|
|
|
|
nColQuotMax = nNewMax / pColumn->GetMin();
|
|
|
|
}
|
|
|
|
pColumn->SetMax( nNewMax );
|
|
|
|
if( nColQuotMax < nQuotMax )
|
|
|
|
nQuotMax = nColQuotMax;
|
|
|
|
}
|
|
|
|
else if( HasColsOption() || nWidthOption ||
|
|
|
|
(pColumn->IsRelWidthOption() &&
|
|
|
|
!pColumn->GetWidthOption()) )
|
|
|
|
pColumn->SetMax( pColumn->GetMin() );
|
|
|
|
}
|
2012-01-03 13:56:50 +01:00
|
|
|
// and divide by the quotient
|
|
|
|
OSL_ENSURE( nQuotMax!=ULONG_MAX, "Where did the relative columns go?" );
|
2000-09-18 23:08:29 +00:00
|
|
|
for( i=0; i<nCols; i++ )
|
|
|
|
{
|
|
|
|
SwHTMLTableLayoutColumn *pColumn = GetColumn( i );
|
|
|
|
if( pColumn->IsRelWidthOption() && pColumn->GetWidthOption() )
|
|
|
|
{
|
|
|
|
if( pColumn->GetWidthOption() )
|
|
|
|
{
|
|
|
|
pColumn->SetMax( pColumn->GetMax() / nQuotMax );
|
2010-11-25 17:08:45 +01:00
|
|
|
OSL_ENSURE( pColumn->GetMax() >= pColumn->GetMin(),
|
2012-01-03 13:56:50 +01:00
|
|
|
"Minimum width is one column bigger than maximum" );
|
2000-09-18 23:08:29 +00:00
|
|
|
if( pColumn->GetMax() < pColumn->GetMin() )
|
|
|
|
pColumn->SetMax( pColumn->GetMin() );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
nMax += pColumn->GetMax();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
delete pConstraints;
|
|
|
|
}
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// nAbsAvail is the available space in TWIPS.
|
|
|
|
// nRelAvail is the available space related to USHRT_MAX or 0
|
|
|
|
// nAbsSpace is the fraction of nAbsAvail, which is reserved by the surrounding
|
|
|
|
// cell for the border and the distance to the paragraph.
|
2011-01-17 15:06:54 +01:00
|
|
|
void SwHTMLTableLayout::AutoLayoutPass2( sal_uInt16 nAbsAvail, sal_uInt16 nRelAvail,
|
|
|
|
sal_uInt16 nAbsLeftSpace,
|
|
|
|
sal_uInt16 nAbsRightSpace,
|
|
|
|
sal_uInt16 nParentInhAbsSpace )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// For a start we do a lot of plausability tests
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// An absolute width always has to be passed
|
|
|
|
OSL_ENSURE( nAbsAvail, "AutoLayout pass 2: No absolute width given" );
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// A relative width must only be passed for tables within tables (?)
|
2010-11-25 17:08:45 +01:00
|
|
|
OSL_ENSURE( IsTopTable() == (nRelAvail==0),
|
2012-01-03 13:56:50 +01:00
|
|
|
"AutoLayout pass 2: Relative width at table in table or the other way around" );
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// The table's minimum width must not be bigger than it's maximum width
|
|
|
|
OSL_ENSURE( nMin<=nMax, "AutoLayout pass 2: nMin > nMax" );
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// Remember the available width for which the table was calculated.
|
|
|
|
// This is a good place as we pass by here for the initial calculation
|
|
|
|
// of the table in the parser and for each _Resize call.
|
2000-09-18 23:08:29 +00:00
|
|
|
nLastResizeAbsAvail = nAbsAvail;
|
|
|
|
|
2012-01-04 13:50:06 +01:00
|
|
|
// Step 1: The available space is readjusted for the left/right border,
|
|
|
|
// possibly existing filler cells and distances.
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// Distance to the content and border
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 nAbsLeftFill = 0, nAbsRightFill = 0;
|
2000-09-18 23:08:29 +00:00
|
|
|
if( !IsTopTable() &&
|
|
|
|
GetMin() + nAbsLeftSpace + nAbsRightSpace <= nAbsAvail )
|
|
|
|
{
|
|
|
|
nAbsLeftFill = nAbsLeftSpace;
|
|
|
|
nAbsRightFill = nAbsRightSpace;
|
|
|
|
}
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// Left and right distance
|
2000-09-18 23:08:29 +00:00
|
|
|
if( nLeftMargin || nRightMargin )
|
|
|
|
{
|
|
|
|
if( IsTopTable() )
|
|
|
|
{
|
2012-01-04 13:50:06 +01:00
|
|
|
// For the top table we always respect the borders, because we
|
|
|
|
// never go below the table's minimum width.
|
2000-09-18 23:08:29 +00:00
|
|
|
nAbsAvail -= (nLeftMargin + nRightMargin);
|
|
|
|
}
|
|
|
|
else if( GetMin() + nLeftMargin + nRightMargin <= nAbsAvail )
|
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// Else, we only respect the borders if there's space available
|
|
|
|
// for them (nMin has already been calculated!)
|
2007-09-27 07:38:17 +00:00
|
|
|
nAbsLeftFill = nAbsLeftFill + nLeftMargin;
|
|
|
|
nAbsRightFill = nAbsRightFill + nRightMargin;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// Filler cells
|
2000-09-18 23:08:29 +00:00
|
|
|
if( !IsTopTable() )
|
|
|
|
{
|
|
|
|
if( pLeftFillerBox && nAbsLeftFill<MINLAY+nInhLeftBorderWidth )
|
|
|
|
nAbsLeftFill = MINLAY+nInhLeftBorderWidth;
|
|
|
|
if( pRightFillerBox && nAbsRightFill<MINLAY+nInhRightBorderWidth )
|
|
|
|
nAbsRightFill = MINLAY+nInhRightBorderWidth;
|
|
|
|
}
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// Read just the available space
|
2000-09-18 23:08:29 +00:00
|
|
|
nRelLeftFill = 0;
|
|
|
|
nRelRightFill = 0;
|
|
|
|
if( !IsTopTable() && (nAbsLeftFill>0 || nAbsRightFill) )
|
|
|
|
{
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nAbsLeftFillL = nAbsLeftFill, nAbsRightFillL = nAbsRightFill;
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
nRelLeftFill = (sal_uInt16)((nAbsLeftFillL * nRelAvail) / nAbsAvail);
|
|
|
|
nRelRightFill = (sal_uInt16)((nAbsRightFillL * nRelAvail) / nAbsAvail);
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
nAbsAvail -= (nAbsLeftFill + nAbsRightFill);
|
|
|
|
if( nRelAvail )
|
|
|
|
nRelAvail -= (nRelLeftFill + nRelRightFill);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// Step 2: Calculate the absolute table width.
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 nAbsTabWidth = 0;
|
2012-11-13 06:13:47 +09:00
|
|
|
bUseRelWidth = false;
|
2000-09-18 23:08:29 +00:00
|
|
|
if( nWidthOption )
|
|
|
|
{
|
|
|
|
if( bPrcWidthOption )
|
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
OSL_ENSURE( nWidthOption<=100, "Percentage value too high" );
|
2000-09-18 23:08:29 +00:00
|
|
|
if( nWidthOption > 100 )
|
|
|
|
nWidthOption = 100;
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// The absolute width is equal to the given percentage of
|
|
|
|
// the available width.
|
|
|
|
// Top tables only get a relative width if the available space
|
2012-01-04 13:50:06 +01:00
|
|
|
// is *strictly larger* than the minimum width.
|
2012-01-03 13:56:50 +01:00
|
|
|
//
|
2012-01-04 13:50:06 +01:00
|
|
|
// CAUTION: We need the "strictly larger" because changing from a
|
2012-01-03 13:56:50 +01:00
|
|
|
// relative width to an absolute width by resizing would lead
|
|
|
|
// to an infinite loop.
|
|
|
|
//
|
|
|
|
// Because we do not call resize for tables in frames if the
|
|
|
|
// frame has a non-relative width, we cannot play such games.
|
|
|
|
//
|
|
|
|
// Let's play such games now anyway. We had a graphic in a 1% wide
|
|
|
|
// table and it didn't fit in of course.
|
2011-01-17 15:06:54 +01:00
|
|
|
nAbsTabWidth = (sal_uInt16)( ((sal_uLong)nAbsAvail * nWidthOption) / 100 );
|
2000-09-18 23:08:29 +00:00
|
|
|
if( IsTopTable() &&
|
2011-01-17 15:06:54 +01:00
|
|
|
( /*MayBeInFlyFrame() ||*/ (sal_uLong)nAbsTabWidth > nMin ) )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
nRelAvail = USHRT_MAX;
|
2012-11-13 06:13:47 +09:00
|
|
|
bUseRelWidth = true;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nAbsTabWidth = nWidthOption;
|
|
|
|
if( nAbsTabWidth > MAX_TABWIDTH )
|
|
|
|
nAbsTabWidth = MAX_TABWIDTH;
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// Tables within tables must never get wider than the available
|
|
|
|
// space.
|
2000-09-18 23:08:29 +00:00
|
|
|
if( !IsTopTable() && nAbsTabWidth > nAbsAvail )
|
|
|
|
nAbsTabWidth = nAbsAvail;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-25 17:08:45 +01:00
|
|
|
OSL_ENSURE( IsTopTable() || nAbsTabWidth<=nAbsAvail,
|
2012-01-03 13:56:50 +01:00
|
|
|
"AutoLayout pass 2: nAbsTabWidth > nAbsAvail for table in table" );
|
2010-11-25 17:08:45 +01:00
|
|
|
OSL_ENSURE( !nRelAvail || nAbsTabWidth<=nAbsAvail,
|
2012-01-03 13:56:50 +01:00
|
|
|
"AutoLayout pass 2: nAbsTabWidth > nAbsAvail for relative width" );
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// Catch for the two asserts above (we never know!)
|
2000-09-18 23:08:29 +00:00
|
|
|
if( (!IsTopTable() || nRelAvail>0) && nAbsTabWidth>nAbsAvail )
|
|
|
|
nAbsTabWidth = nAbsAvail;
|
|
|
|
|
|
|
|
|
2012-01-04 13:50:06 +01:00
|
|
|
// Step 3: Identify the column width and, if applicable, the absolute
|
|
|
|
// and relative table widths.
|
2011-01-17 15:06:54 +01:00
|
|
|
if( (!IsTopTable() && nMin > (sal_uLong)nAbsAvail) ||
|
2000-09-18 23:08:29 +00:00
|
|
|
nMin > MAX_TABWIDTH )
|
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// If
|
2012-01-04 13:50:06 +01:00
|
|
|
// - a inner table's minimum is larger than the available space, or
|
2012-01-03 13:56:50 +01:00
|
|
|
// - a top table's minimum is larger than USHORT_MAX the table
|
|
|
|
// has to be adapted to the available space or USHORT_MAX.
|
|
|
|
// We preserve the widths' ratio amongst themselves, however.
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
nAbsTabWidth = IsTopTable() ? MAX_TABWIDTH : nAbsAvail;
|
|
|
|
nRelTabWidth = (nRelAvail ? nRelAvail : nAbsTabWidth );
|
|
|
|
|
2012-02-18 12:37:04 +08:00
|
|
|
// First of all, we check whether we can fit the layout constrains,
|
2012-01-03 13:56:50 +01:00
|
|
|
// which are: Every cell's width excluding the borders must be at least
|
2001-07-11 09:09:32 +00:00
|
|
|
// MINLAY:
|
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nRealMin = 0;
|
|
|
|
for( sal_uInt16 i=0; i<nCols; i++ )
|
2001-07-11 09:09:32 +00:00
|
|
|
{
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nRealColMin = MINLAY, nDummy1, nDummy2;
|
2001-07-11 09:09:32 +00:00
|
|
|
AddBorderWidth( nRealColMin, nDummy1, nDummy2, i, 1 );
|
|
|
|
nRealMin += nRealColMin;
|
|
|
|
}
|
|
|
|
if( (nRealMin >= nAbsTabWidth) || (nRealMin >= nMin) )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// "Rien ne va plus": we cannot get the minimum column widths
|
2001-07-11 09:09:32 +00:00
|
|
|
// the layout wants to have.
|
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 nAbs = 0, nRel = 0;
|
2001-07-11 09:09:32 +00:00
|
|
|
SwHTMLTableLayoutColumn *pColumn;
|
2011-01-17 15:06:54 +01:00
|
|
|
for( sal_uInt16 i=0; i<nCols-1; i++ )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2001-07-11 09:09:32 +00:00
|
|
|
pColumn = GetColumn( i );
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nColMin = pColumn->GetMin();
|
2001-07-11 09:09:32 +00:00
|
|
|
if( nColMin <= USHRT_MAX )
|
|
|
|
{
|
|
|
|
pColumn->SetAbsColWidth(
|
2011-01-17 15:06:54 +01:00
|
|
|
(sal_uInt16)((nColMin * nAbsTabWidth) / nMin) );
|
2001-07-11 09:09:32 +00:00
|
|
|
pColumn->SetRelColWidth(
|
2011-01-17 15:06:54 +01:00
|
|
|
(sal_uInt16)((nColMin * nRelTabWidth) / nMin) );
|
2001-07-11 09:09:32 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
double nColMinD = nColMin;
|
|
|
|
pColumn->SetAbsColWidth(
|
2011-01-17 15:06:54 +01:00
|
|
|
(sal_uInt16)((nColMinD * nAbsTabWidth) / nMin) );
|
2001-07-11 09:09:32 +00:00
|
|
|
pColumn->SetRelColWidth(
|
2011-01-17 15:06:54 +01:00
|
|
|
(sal_uInt16)((nColMinD * nRelTabWidth) / nMin) );
|
2001-07-11 09:09:32 +00:00
|
|
|
}
|
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
nAbs = nAbs + (sal_uInt16)pColumn->GetAbsColWidth();
|
|
|
|
nRel = nRel + (sal_uInt16)pColumn->GetRelColWidth();
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
2001-07-11 09:09:32 +00:00
|
|
|
pColumn = GetColumn( nCols-1 );
|
|
|
|
pColumn->SetAbsColWidth( nAbsTabWidth - nAbs );
|
|
|
|
pColumn->SetRelColWidth( nRelTabWidth - nRel );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nDistAbs = nAbsTabWidth - nRealMin;
|
|
|
|
sal_uLong nDistRel = nRelTabWidth - nRealMin;
|
|
|
|
sal_uLong nDistMin = nMin - nRealMin;
|
|
|
|
sal_uInt16 nAbs = 0, nRel = 0;
|
2001-07-11 09:09:32 +00:00
|
|
|
SwHTMLTableLayoutColumn *pColumn;
|
2011-01-17 15:06:54 +01:00
|
|
|
for( sal_uInt16 i=0; i<nCols-1; i++ )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2001-07-11 09:09:32 +00:00
|
|
|
pColumn = GetColumn( i );
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nColMin = pColumn->GetMin();
|
|
|
|
sal_uLong nRealColMin = MINLAY, nDummy1, nDummy2;
|
2001-07-11 09:09:32 +00:00
|
|
|
AddBorderWidth( nRealColMin, nDummy1, nDummy2, i, 1 );
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2001-07-11 09:09:32 +00:00
|
|
|
if( nColMin <= USHRT_MAX )
|
|
|
|
{
|
|
|
|
pColumn->SetAbsColWidth(
|
2011-01-17 15:06:54 +01:00
|
|
|
(sal_uInt16)((((nColMin-nRealColMin) * nDistAbs) / nDistMin) + nRealColMin) );
|
2001-07-11 09:09:32 +00:00
|
|
|
pColumn->SetRelColWidth(
|
2011-01-17 15:06:54 +01:00
|
|
|
(sal_uInt16)((((nColMin-nRealColMin) * nDistRel) / nDistMin) + nRealColMin) );
|
2001-07-11 09:09:32 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
double nColMinD = nColMin;
|
|
|
|
pColumn->SetAbsColWidth(
|
2011-01-17 15:06:54 +01:00
|
|
|
(sal_uInt16)((((nColMinD-nRealColMin) * nDistAbs) / nDistMin) + nRealColMin) );
|
2001-07-11 09:09:32 +00:00
|
|
|
pColumn->SetRelColWidth(
|
2011-01-17 15:06:54 +01:00
|
|
|
(sal_uInt16)((((nColMinD-nRealColMin) * nDistRel) / nDistMin) + nRealColMin) );
|
2001-07-11 09:09:32 +00:00
|
|
|
}
|
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
nAbs = nAbs + (sal_uInt16)pColumn->GetAbsColWidth();
|
|
|
|
nRel = nRel + (sal_uInt16)pColumn->GetRelColWidth();
|
2001-07-11 09:09:32 +00:00
|
|
|
}
|
|
|
|
pColumn = GetColumn( nCols-1 );
|
|
|
|
pColumn->SetAbsColWidth( nAbsTabWidth - nAbs );
|
|
|
|
pColumn->SetRelColWidth( nRelTabWidth - nRel );
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
}
|
2011-01-17 15:06:54 +01:00
|
|
|
else if( nMax <= (sal_uLong)(nAbsTabWidth ? nAbsTabWidth : nAbsAvail) )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// If
|
|
|
|
// - the table has a fixed width and the table's maximum is
|
|
|
|
// smaller, or
|
|
|
|
//- the maximum is smaller than the available space,
|
|
|
|
// we can take over the maximum as it is. Respectively
|
|
|
|
// the table can only be adapted to the fixed width by
|
|
|
|
// respecting the maximum.
|
|
|
|
|
|
|
|
// No fixed width, use the maximum.
|
2000-09-18 23:08:29 +00:00
|
|
|
if( !nAbsTabWidth )
|
2011-01-17 15:06:54 +01:00
|
|
|
nAbsTabWidth = (sal_uInt16)nMax;
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// A top table may also get wider then the available space.
|
2000-09-18 23:08:29 +00:00
|
|
|
if( nAbsTabWidth > nAbsAvail )
|
|
|
|
{
|
2010-11-25 17:08:45 +01:00
|
|
|
OSL_ENSURE( IsTopTable(),
|
2012-01-03 13:56:50 +01:00
|
|
|
"Table in table should get wider than the surrounding cell." );
|
2000-09-18 23:08:29 +00:00
|
|
|
nAbsAvail = nAbsTabWidth;
|
|
|
|
}
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// Only use the relative widths' fraction, that is used for the
|
|
|
|
// absolute width.
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nAbsTabWidthL = nAbsTabWidth;
|
2000-09-18 23:08:29 +00:00
|
|
|
nRelTabWidth =
|
2011-01-17 15:06:54 +01:00
|
|
|
( nRelAvail ? (sal_uInt16)((nAbsTabWidthL * nRelAvail) / nAbsAvail)
|
2000-09-18 23:08:29 +00:00
|
|
|
: nAbsTabWidth );
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// Are there columns width a percentage setting and some without one?
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nFixMax = nMax;
|
|
|
|
for( sal_uInt16 i=0; i<nCols; i++ )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
const SwHTMLTableLayoutColumn *pColumn = GetColumn( i );
|
|
|
|
if( pColumn->IsRelWidthOption() && pColumn->GetWidthOption()>0 )
|
|
|
|
nFixMax -= pColumn->GetMax();
|
|
|
|
}
|
|
|
|
|
|
|
|
if( nFixMax > 0 && nFixMax < nMax )
|
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// Yes, distribute the to-be-distributed space only to the
|
|
|
|
// columns with a percentage setting.
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// In this case (and in this case only) there are columns
|
|
|
|
// that exactly keep their maximum width, that is they neither
|
|
|
|
// get smaller nor wider. When calculating the absolute width
|
|
|
|
// from the relative width we can get rounding errors.
|
|
|
|
// To correct this, we first make the fixed widths compensate for
|
|
|
|
// this error. We then fix the relative widths the same way.
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 nAbs = 0, nRel = 0;
|
|
|
|
sal_uInt16 nFixedCols = 0;
|
|
|
|
sal_uInt16 i;
|
2003-12-01 15:36:04 +00:00
|
|
|
|
|
|
|
for( i = 0; i < nCols; i++ )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
SwHTMLTableLayoutColumn *pColumn = GetColumn( i );
|
|
|
|
if( !pColumn->IsRelWidthOption() || !pColumn->GetWidthOption() )
|
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// The column keeps it's width.
|
2000-09-18 23:08:29 +00:00
|
|
|
nFixedCols++;
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nColMax = pColumn->GetMax();
|
|
|
|
pColumn->SetAbsColWidth( (sal_uInt16)nColMax );
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nRelColWidth =
|
2000-09-18 23:08:29 +00:00
|
|
|
(nColMax * nRelTabWidth) / nAbsTabWidth;
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nChkWidth =
|
2000-09-18 23:08:29 +00:00
|
|
|
(nRelColWidth * nAbsTabWidth) / nRelTabWidth;
|
|
|
|
if( nChkWidth < nColMax )
|
|
|
|
nRelColWidth++;
|
|
|
|
else if( nChkWidth > nColMax )
|
|
|
|
nRelColWidth--;
|
2011-01-17 15:06:54 +01:00
|
|
|
pColumn->SetRelColWidth( (sal_uInt16)nRelColWidth );
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
nAbs = nAbs + (sal_uInt16)nColMax;
|
|
|
|
nRel = nRel + (sal_uInt16)nRelColWidth;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// The to-be-distributed percentage of the maximum, the
|
|
|
|
// relative and absolute widths. Here, nFixMax corresponds
|
|
|
|
// to nAbs, so that we could've called it nAbs.
|
|
|
|
// The code is, however, more readable like that.
|
|
|
|
OSL_ENSURE( nFixMax == nAbs, "Two loops, two sums?" );
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nDistMax = nMax - nFixMax;
|
|
|
|
sal_uInt16 nDistAbsTabWidth = nAbsTabWidth - nAbs;
|
|
|
|
sal_uInt16 nDistRelTabWidth = nRelTabWidth - nRel;
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
for( i=0; i<nCols; i++ )
|
|
|
|
{
|
|
|
|
SwHTMLTableLayoutColumn *pColumn = GetColumn( i );
|
|
|
|
if( pColumn->IsRelWidthOption() && pColumn->GetWidthOption() > 0 )
|
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// The column gets proportionately wider.
|
2000-09-18 23:08:29 +00:00
|
|
|
nFixedCols++;
|
|
|
|
if( nFixedCols == nCols )
|
|
|
|
{
|
|
|
|
pColumn->SetAbsColWidth( nAbsTabWidth-nAbs );
|
|
|
|
pColumn->SetRelColWidth( nRelTabWidth-nRel );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nColMax = pColumn->GetMax();
|
2000-09-18 23:08:29 +00:00
|
|
|
pColumn->SetAbsColWidth(
|
2011-01-17 15:06:54 +01:00
|
|
|
(sal_uInt16)((nColMax * nDistAbsTabWidth) / nDistMax) );
|
2000-09-18 23:08:29 +00:00
|
|
|
pColumn->SetRelColWidth(
|
2011-01-17 15:06:54 +01:00
|
|
|
(sal_uInt16)((nColMax * nDistRelTabWidth) / nDistMax) );
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
2007-09-27 07:38:17 +00:00
|
|
|
nAbs = nAbs + pColumn->GetAbsColWidth();
|
|
|
|
nRel = nRel + pColumn->GetRelColWidth();
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
}
|
2012-01-03 13:56:50 +01:00
|
|
|
OSL_ENSURE( nCols==nFixedCols, "Missed a column!" );
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// No. So distribute the space regularily among all columns.
|
2011-01-17 15:06:54 +01:00
|
|
|
for( sal_uInt16 i=0; i<nCols; i++ )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nColMax = GetColumn( i )->GetMax();
|
2000-09-18 23:08:29 +00:00
|
|
|
GetColumn( i )->SetAbsColWidth(
|
2011-01-17 15:06:54 +01:00
|
|
|
(sal_uInt16)((nColMax * nAbsTabWidth) / nMax) );
|
2000-09-18 23:08:29 +00:00
|
|
|
GetColumn( i )->SetRelColWidth(
|
2011-01-17 15:06:54 +01:00
|
|
|
(sal_uInt16)((nColMax * nRelTabWidth) / nMax) );
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-01-04 13:50:06 +01:00
|
|
|
// Proportionately distribute the space that extends over the minimum
|
|
|
|
// width among the columns.
|
2000-09-18 23:08:29 +00:00
|
|
|
if( !nAbsTabWidth )
|
|
|
|
nAbsTabWidth = nAbsAvail;
|
|
|
|
if( nAbsTabWidth < nMin )
|
2011-01-17 15:06:54 +01:00
|
|
|
nAbsTabWidth = (sal_uInt16)nMin;
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
if( nAbsTabWidth > nAbsAvail )
|
|
|
|
{
|
2010-11-25 17:08:45 +01:00
|
|
|
OSL_ENSURE( IsTopTable(),
|
2012-01-03 13:56:50 +01:00
|
|
|
"A nested table should become wider than the available space." );
|
2000-09-18 23:08:29 +00:00
|
|
|
nAbsAvail = nAbsTabWidth;
|
|
|
|
}
|
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nAbsTabWidthL = nAbsTabWidth;
|
2000-09-18 23:08:29 +00:00
|
|
|
nRelTabWidth =
|
2011-01-17 15:06:54 +01:00
|
|
|
( nRelAvail ? (sal_uInt16)((nAbsTabWidthL * nRelAvail) / nAbsAvail)
|
2000-09-18 23:08:29 +00:00
|
|
|
: nAbsTabWidth );
|
|
|
|
double nW = nAbsTabWidth - nMin;
|
|
|
|
double nD = (nMax==nMin ? 1 : nMax-nMin);
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 nAbs = 0, nRel = 0;
|
|
|
|
for( sal_uInt16 i=0; i<nCols-1; i++ )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
double nd = GetColumn( i )->GetMax() - GetColumn( i )->GetMin();
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uLong nAbsColWidth = GetColumn( i )->GetMin() + (sal_uLong)((nd*nW)/nD);
|
|
|
|
sal_uLong nRelColWidth = nRelAvail
|
2000-09-18 23:08:29 +00:00
|
|
|
? (nAbsColWidth * nRelTabWidth) / nAbsTabWidth
|
|
|
|
: nAbsColWidth;
|
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
GetColumn( i )->SetAbsColWidth( (sal_uInt16)nAbsColWidth );
|
|
|
|
GetColumn( i )->SetRelColWidth( (sal_uInt16)nRelColWidth );
|
|
|
|
nAbs = nAbs + (sal_uInt16)nAbsColWidth;
|
|
|
|
nRel = nRel + (sal_uInt16)nRelColWidth;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
GetColumn( nCols-1 )->SetAbsColWidth( nAbsTabWidth - nAbs );
|
|
|
|
GetColumn( nCols-1 )->SetRelColWidth( nRelTabWidth - nRel );
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// Step 4: For nested tables we can have balancing cells on the
|
|
|
|
// left or right. Here we calculate their width.
|
2000-09-18 23:08:29 +00:00
|
|
|
nInhAbsLeftSpace = 0;
|
|
|
|
nInhAbsRightSpace = 0;
|
|
|
|
if( !IsTopTable() && (nRelLeftFill>0 || nRelRightFill>0 ||
|
|
|
|
nAbsTabWidth<nAbsAvail) )
|
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// Calculate the width of additional cells we use for
|
|
|
|
// aligning inner tables.
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 nAbsDist = (sal_uInt16)(nAbsAvail-nAbsTabWidth);
|
|
|
|
sal_uInt16 nRelDist = (sal_uInt16)(nRelAvail-nRelTabWidth);
|
|
|
|
sal_uInt16 nParentInhAbsLeftSpace = 0, nParentInhAbsRightSpace = 0;
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// Calculate the size and position of the additional cells.
|
2000-09-18 23:08:29 +00:00
|
|
|
switch( eTableAdjust )
|
|
|
|
{
|
|
|
|
case SVX_ADJUST_RIGHT:
|
2007-09-27 07:38:17 +00:00
|
|
|
nAbsLeftFill = nAbsLeftFill + nAbsDist;
|
|
|
|
nRelLeftFill = nRelLeftFill + nRelDist;
|
2000-09-18 23:08:29 +00:00
|
|
|
nParentInhAbsLeftSpace = nParentInhAbsSpace;
|
|
|
|
break;
|
|
|
|
case SVX_ADJUST_CENTER:
|
|
|
|
{
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 nAbsLeftDist = nAbsDist / 2;
|
2007-09-27 07:38:17 +00:00
|
|
|
nAbsLeftFill = nAbsLeftFill + nAbsLeftDist;
|
2000-09-18 23:08:29 +00:00
|
|
|
nAbsRightFill += nAbsDist - nAbsLeftDist;
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 nRelLeftDist = nRelDist / 2;
|
2007-09-27 07:38:17 +00:00
|
|
|
nRelLeftFill = nRelLeftFill + nRelLeftDist;
|
2000-09-18 23:08:29 +00:00
|
|
|
nRelRightFill += nRelDist - nRelLeftDist;
|
|
|
|
nParentInhAbsLeftSpace = nParentInhAbsSpace / 2;
|
|
|
|
nParentInhAbsRightSpace = nParentInhAbsSpace -
|
|
|
|
nParentInhAbsLeftSpace;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SVX_ADJUST_LEFT:
|
|
|
|
default:
|
2007-09-27 07:38:17 +00:00
|
|
|
nAbsRightFill = nAbsRightFill + nAbsDist;
|
|
|
|
nRelRightFill = nRelRightFill + nRelDist;
|
2000-09-18 23:08:29 +00:00
|
|
|
nParentInhAbsRightSpace = nParentInhAbsSpace;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-11-25 17:08:45 +01:00
|
|
|
OSL_ENSURE( !pLeftFillerBox || nRelLeftFill>0,
|
2012-01-03 13:56:50 +01:00
|
|
|
"We don't have a width for the left filler box!" );
|
2010-11-25 17:08:45 +01:00
|
|
|
OSL_ENSURE( !pRightFillerBox || nRelRightFill>0,
|
2012-01-03 13:56:50 +01:00
|
|
|
"We don't have a width for the right filler box!" );
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// Filler widths are added to the outer columns, if there are no boxes
|
|
|
|
// for them after the first pass (nWidth>0) or their width would become
|
|
|
|
// too small or if there are COL tags and the filler width corresponds
|
|
|
|
// to the border width.
|
|
|
|
// In the last case we probably exported the table ourselves.
|
2000-09-18 23:08:29 +00:00
|
|
|
if( nRelLeftFill && !pLeftFillerBox &&
|
|
|
|
( nWidthSet>0 || nAbsLeftFill<MINLAY+nInhLeftBorderWidth ||
|
|
|
|
(HasColTags() && nAbsLeftFill < nAbsLeftSpace+nParentInhAbsLeftSpace+20) ) )
|
|
|
|
{
|
|
|
|
SwHTMLTableLayoutColumn *pColumn = GetColumn( 0 );
|
|
|
|
pColumn->SetAbsColWidth( pColumn->GetAbsColWidth()+nAbsLeftFill );
|
|
|
|
pColumn->SetRelColWidth( pColumn->GetRelColWidth()+nRelLeftFill );
|
|
|
|
nRelLeftFill = 0;
|
|
|
|
nInhAbsLeftSpace = nAbsLeftSpace + nParentInhAbsLeftSpace;
|
|
|
|
}
|
|
|
|
if( nRelRightFill && !pRightFillerBox &&
|
|
|
|
( nWidthSet>0 || nAbsRightFill<MINLAY+nInhRightBorderWidth ||
|
|
|
|
(HasColTags() && nAbsRightFill < nAbsRightSpace+nParentInhAbsRightSpace+20) ) )
|
|
|
|
{
|
|
|
|
SwHTMLTableLayoutColumn *pColumn = GetColumn( nCols-1 );
|
|
|
|
pColumn->SetAbsColWidth( pColumn->GetAbsColWidth()+nAbsRightFill );
|
|
|
|
pColumn->SetRelColWidth( pColumn->GetRelColWidth()+nRelRightFill );
|
|
|
|
nRelRightFill = 0;
|
|
|
|
nInhAbsRightSpace = nAbsRightSpace + nParentInhAbsRightSpace;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-18 18:04:44 +02:00
|
|
|
static void lcl_ResizeLine( const SwTableLine* pLine, sal_uInt16 *pWidth );
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2012-06-18 18:04:44 +02:00
|
|
|
static void lcl_ResizeBox( const SwTableBox* pBox, sal_uInt16* pWidth )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2012-05-10 17:42:10 +02:00
|
|
|
if( !pBox->GetSttNd() )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 nWidth = 0;
|
2012-06-18 18:04:44 +02:00
|
|
|
BOOST_FOREACH( const SwTableLine *pLine, pBox->GetTabLines() )
|
|
|
|
lcl_ResizeLine( pLine, &nWidth );
|
2012-05-10 17:42:10 +02:00
|
|
|
pBox->GetFrmFmt()->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, nWidth, 0 ));
|
2007-09-27 07:38:17 +00:00
|
|
|
*pWidth = *pWidth + nWidth;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-05-10 17:42:10 +02:00
|
|
|
*pWidth = *pWidth + (sal_uInt16)pBox->GetFrmFmt()->GetFrmSize().GetSize().Width();
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-18 18:04:44 +02:00
|
|
|
static void lcl_ResizeLine( const SwTableLine* pLine, sal_uInt16 *pWidth )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2011-11-24 00:52:07 +01:00
|
|
|
#if OSL_DEBUG_LEVEL > 0
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 nOldWidth = *pWidth;
|
2004-08-12 11:18:49 +00:00
|
|
|
#endif
|
2000-09-18 23:08:29 +00:00
|
|
|
*pWidth = 0;
|
2012-06-18 18:04:44 +02:00
|
|
|
BOOST_FOREACH( const SwTableBox* pBox, pLine->GetTabBoxes() )
|
|
|
|
lcl_ResizeBox(pBox, pWidth );
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2011-11-24 00:52:07 +01:00
|
|
|
#if OSL_DEBUG_LEVEL > 0
|
2010-11-25 17:08:45 +01:00
|
|
|
OSL_ENSURE( !nOldWidth || Abs(*pWidth-nOldWidth) < COLFUZZY,
|
2012-01-03 13:56:50 +01:00
|
|
|
"A box's rows have all a different length." );
|
2004-08-12 11:18:49 +00:00
|
|
|
#endif
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
void SwHTMLTableLayout::SetWidths( sal_Bool bCallPass2, sal_uInt16 nAbsAvail,
|
|
|
|
sal_uInt16 nRelAvail, sal_uInt16 nAbsLeftSpace,
|
|
|
|
sal_uInt16 nAbsRightSpace,
|
|
|
|
sal_uInt16 nParentInhAbsSpace )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// SetWidth must have been passed through once more for every cell in the
|
|
|
|
// end.
|
2000-09-18 23:08:29 +00:00
|
|
|
nWidthSet++;
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// Step 0: If necessary, we call the layout algorithm of Pass2.
|
2000-09-18 23:08:29 +00:00
|
|
|
if( bCallPass2 )
|
|
|
|
AutoLayoutPass2( nAbsAvail, nRelAvail, nAbsLeftSpace, nAbsRightSpace,
|
|
|
|
nParentInhAbsSpace );
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// Step 1: Set the new width in all content boxes.
|
|
|
|
// Because the boxes don't know anything about the HTML table structure,
|
|
|
|
// we iterate over the HTML table structure.
|
|
|
|
// For tables in tables in tables we call SetWidth recursively.
|
2011-01-17 15:06:54 +01:00
|
|
|
for( sal_uInt16 i=0; i<nRows; i++ )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2011-01-17 15:06:54 +01:00
|
|
|
for( sal_uInt16 j=0; j<nCols; j++ )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
SwHTMLTableLayoutCell *pCell = GetCell( i, j );
|
|
|
|
|
|
|
|
SwHTMLTableLayoutCnts* pCntnts = pCell->GetContents();
|
|
|
|
while( pCntnts && !pCntnts->IsWidthSet(nWidthSet) )
|
|
|
|
{
|
|
|
|
SwTableBox *pBox = pCntnts->GetTableBox();
|
|
|
|
if( pBox )
|
|
|
|
{
|
|
|
|
SetBoxWidth( pBox, j, pCell->GetColSpan() );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 nAbs = 0, nRel = 0, nLSpace = 0, nRSpace = 0,
|
2000-09-18 23:08:29 +00:00
|
|
|
nInhSpace = 0;
|
|
|
|
if( bCallPass2 )
|
|
|
|
{
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 nColSpan = pCell->GetColSpan();
|
2000-09-18 23:08:29 +00:00
|
|
|
GetAvail( j, nColSpan, nAbs, nRel );
|
|
|
|
nLSpace = GetLeftCellSpace( j, nColSpan );
|
|
|
|
nRSpace = GetRightCellSpace( j, nColSpan );
|
|
|
|
nInhSpace = GetInhCellSpace( j, nColSpan );
|
|
|
|
}
|
|
|
|
pCntnts->GetTable()->SetWidths( bCallPass2, nAbs, nRel,
|
|
|
|
nLSpace, nRSpace,
|
|
|
|
nInhSpace );
|
|
|
|
}
|
|
|
|
|
|
|
|
pCntnts->SetWidthSet( nWidthSet );
|
|
|
|
pCntnts = pCntnts->GetNext();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// Step 2: If we have a top table, we adapt the formats of the
|
2012-01-04 13:50:06 +01:00
|
|
|
// non-content-boxes. Because they are not known in the HTML table
|
2012-01-03 13:56:50 +01:00
|
|
|
// due to garbage collection there, we need the iterate over the
|
|
|
|
// whole table.
|
|
|
|
// We also adapt the table frame format. For nested tables we set the
|
|
|
|
// filler cell's width instead.
|
2000-09-18 23:08:29 +00:00
|
|
|
if( IsTopTable() )
|
|
|
|
{
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_uInt16 nCalcTabWidth = 0;
|
2012-06-18 18:04:44 +02:00
|
|
|
BOOST_FOREACH( const SwTableLine *pLine, pSwTable->GetTabLines() )
|
|
|
|
lcl_ResizeLine( pLine, &nCalcTabWidth );
|
2010-11-25 17:08:45 +01:00
|
|
|
OSL_ENSURE( Abs( nRelTabWidth-nCalcTabWidth ) < COLFUZZY,
|
2012-01-03 13:56:50 +01:00
|
|
|
"Table width is not equal to the row width." );
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// Lock the table format when altering it, or else the box formats
|
|
|
|
// are altered again.
|
2012-01-04 13:50:06 +01:00
|
|
|
// Also, we need to preserve a percent setting if it exists.
|
2000-09-18 23:08:29 +00:00
|
|
|
SwFrmFmt *pFrmFmt = pSwTable->GetFrmFmt();
|
|
|
|
((SwTable *)pSwTable)->LockModify();
|
|
|
|
SwFmtFrmSize aFrmSize( pFrmFmt->GetFrmSize() );
|
|
|
|
aFrmSize.SetWidth( nRelTabWidth );
|
2012-11-13 06:13:47 +09:00
|
|
|
bool bRel = bUseRelWidth &&
|
2007-09-27 07:38:17 +00:00
|
|
|
text::HoriOrientation::FULL!=pFrmFmt->GetHoriOrient().GetHoriOrient();
|
2011-01-17 15:06:54 +01:00
|
|
|
aFrmSize.SetWidthPercent( (sal_uInt8)(bRel ? nWidthOption : 0) );
|
2008-06-13 08:37:06 +00:00
|
|
|
pFrmFmt->SetFmtAttr( aFrmSize );
|
2000-09-18 23:08:29 +00:00
|
|
|
((SwTable *)pSwTable)->UnlockModify();
|
|
|
|
|
2012-01-04 13:50:06 +01:00
|
|
|
// If the table is located in a frame, we also need to adapt the
|
|
|
|
// frame's width.
|
2000-09-18 23:08:29 +00:00
|
|
|
if( MayBeInFlyFrame() )
|
|
|
|
{
|
|
|
|
SwFrmFmt *pFlyFrmFmt = FindFlyFrmFmt();
|
|
|
|
if( pFlyFrmFmt )
|
|
|
|
{
|
|
|
|
SwFmtFrmSize aFlyFrmSize( ATT_VAR_SIZE, nRelTabWidth, MINLAY );
|
|
|
|
|
|
|
|
if( bUseRelWidth )
|
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// For percentage settings we set the width to the minimum.
|
2000-09-18 23:08:29 +00:00
|
|
|
aFlyFrmSize.SetWidth( nMin > USHRT_MAX ? USHRT_MAX
|
|
|
|
: nMin );
|
2011-01-17 15:06:54 +01:00
|
|
|
aFlyFrmSize.SetWidthPercent( (sal_uInt8)nWidthOption );
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
2008-06-13 08:37:06 +00:00
|
|
|
pFlyFrmFmt->SetFmtAttr( aFlyFrmSize );
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-11-24 00:52:07 +01:00
|
|
|
#ifdef DBG_UTIL
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// is located in tblrwcl.cxx
|
2000-09-18 23:08:29 +00:00
|
|
|
extern void _CheckBoxWidth( const SwTableLine&, SwTwips );
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// check if the tables have correct widths
|
2000-09-18 23:08:29 +00:00
|
|
|
SwTwips nSize = pSwTable->GetFrmFmt()->GetFrmSize().GetWidth();
|
|
|
|
const SwTableLines& rLines = pSwTable->GetTabLines();
|
2012-06-20 19:45:46 +02:00
|
|
|
for (size_t n = 0; n < rLines.size(); ++n)
|
|
|
|
{
|
2000-09-18 23:08:29 +00:00
|
|
|
_CheckBoxWidth( *rLines[ n ], nSize );
|
2012-06-20 19:45:46 +02:00
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if( pLeftFillerBox )
|
|
|
|
{
|
2008-06-13 08:37:06 +00:00
|
|
|
pLeftFillerBox->GetFrmFmt()->SetFmtAttr(
|
2000-09-18 23:08:29 +00:00
|
|
|
SwFmtFrmSize( ATT_VAR_SIZE, nRelLeftFill, 0 ));
|
|
|
|
}
|
|
|
|
if( pRightFillerBox )
|
|
|
|
{
|
2008-06-13 08:37:06 +00:00
|
|
|
pRightFillerBox->GetFrmFmt()->SetFmtAttr(
|
2000-09-18 23:08:29 +00:00
|
|
|
SwFmtFrmSize( ATT_VAR_SIZE, nRelRightFill, 0 ));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
void SwHTMLTableLayout::_Resize( sal_uInt16 nAbsAvail, sal_Bool bRecalc )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// If bRecalc is set, the table's content changed.
|
|
|
|
// We need to execute pass 1 again.
|
2000-09-18 23:08:29 +00:00
|
|
|
if( bRecalc )
|
|
|
|
AutoLayoutPass1();
|
|
|
|
|
2010-06-13 15:22:56 +02:00
|
|
|
SwRootFrm *pRoot = (SwRootFrm*)GetDoc()->GetCurrentViewShell()->GetLayout();
|
2000-09-18 23:08:29 +00:00
|
|
|
if ( pRoot && pRoot->IsCallbackActionEnabled() )
|
2010-06-13 15:22:56 +02:00
|
|
|
pRoot->StartAllAction(); //swmod 071108//swmod 071225
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// Else we can set the widths, in which we have to run Pass 2 in each case.
|
2011-01-17 15:06:54 +01:00
|
|
|
SetWidths( sal_True, nAbsAvail );
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
if ( pRoot && pRoot->IsCallbackActionEnabled() )
|
2012-01-03 13:56:50 +01:00
|
|
|
pRoot->EndAllAction( sal_True ); //True per VirDev (browsing is calmer) //swmod 071108//swmod 071225
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
IMPL_STATIC_LINK( SwHTMLTableLayout, DelayedResize_Impl, void*, EMPTYARG )
|
|
|
|
{
|
|
|
|
pThis->aResizeTimer.Stop();
|
|
|
|
pThis->_Resize( pThis->nDelayedResizeAbsAvail,
|
|
|
|
pThis->bDelayedResizeRecalc );
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
sal_Bool SwHTMLTableLayout::Resize( sal_uInt16 nAbsAvail, sal_Bool bRecalc,
|
|
|
|
sal_Bool bForce, sal_uLong nDelay )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2007-07-31 16:40:36 +00:00
|
|
|
if( 0 == nAbsAvail )
|
2011-01-17 15:06:54 +01:00
|
|
|
return sal_False;
|
2012-01-03 13:56:50 +01:00
|
|
|
OSL_ENSURE( IsTopTable(), "Resize must only be called for top tables!" );
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// May the table be resized at all? Or is it forced?
|
2000-09-18 23:08:29 +00:00
|
|
|
if( bMustNotResize && !bForce )
|
2011-01-17 15:06:54 +01:00
|
|
|
return sal_False;
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// May the table be recalculated? Or is it forced?
|
2000-09-18 23:08:29 +00:00
|
|
|
if( bMustNotRecalc && !bForce )
|
2011-01-17 15:06:54 +01:00
|
|
|
bRecalc = sal_False;
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
const SwDoc *pDoc = GetDoc();
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// If there is a layout, the root frame's size instead of the
|
|
|
|
// VisArea's size was potentially passed.
|
|
|
|
// If we're not in a frame we need to calculate the table for the VisArea,
|
|
|
|
// because switching from relative to absolute wouldn't work.
|
2010-06-13 15:22:56 +02:00
|
|
|
if( pDoc->GetCurrentViewShell() && pDoc->GetCurrentViewShell()->GetViewOptions()->getBrowseMode() )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2011-01-17 15:06:54 +01:00
|
|
|
const sal_uInt16 nVisAreaWidth = GetBrowseWidthByVisArea( *pDoc );
|
2000-09-18 23:08:29 +00:00
|
|
|
if( nVisAreaWidth < nAbsAvail && !FindFlyFrmFmt() )
|
|
|
|
nAbsAvail = nVisAreaWidth;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( nDelay==0 && aResizeTimer.IsActive() )
|
|
|
|
{
|
2012-01-03 13:56:50 +01:00
|
|
|
// If there is an asynchronous resize left to process when we call
|
|
|
|
// a synchronous resize, we only take over the new values.
|
2000-09-18 23:08:29 +00:00
|
|
|
bRecalc |= bDelayedResizeRecalc;
|
|
|
|
nDelayedResizeAbsAvail = nAbsAvail;
|
2011-01-17 15:06:54 +01:00
|
|
|
return sal_False;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
2012-01-03 13:56:50 +01:00
|
|
|
// Optimisation:
|
|
|
|
// If the minimums or maximums should not be recalculated and
|
|
|
|
// - the table's width never needs to be recalculated, or
|
|
|
|
// - the table was already calculated for the passed width, or
|
|
|
|
// - the available space is less or equal to the minimum width
|
|
|
|
// and the table already has the minimum width, or
|
|
|
|
// - the available space is larger than the maximum width and
|
|
|
|
// the table already has the maximum width
|
|
|
|
// nothing will happen to the table.
|
2000-09-18 23:08:29 +00:00
|
|
|
if( !bRecalc && ( !bMustResize ||
|
|
|
|
(nLastResizeAbsAvail==nAbsAvail) ||
|
|
|
|
(nAbsAvail<=nMin && nRelTabWidth==nMin) ||
|
|
|
|
(!bPrcWidthOption && nAbsAvail>=nMax && nRelTabWidth==nMax) ) )
|
2011-01-17 15:06:54 +01:00
|
|
|
return sal_False;
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
if( nDelay==HTMLTABLE_RESIZE_NOW )
|
|
|
|
{
|
|
|
|
if( aResizeTimer.IsActive() )
|
|
|
|
aResizeTimer.Stop();
|
|
|
|
_Resize( nAbsAvail, bRecalc );
|
|
|
|
}
|
|
|
|
else if( nDelay > 0 )
|
|
|
|
{
|
|
|
|
nDelayedResizeAbsAvail = nAbsAvail;
|
|
|
|
bDelayedResizeRecalc = bRecalc;
|
|
|
|
aResizeTimer.SetTimeout( nDelay );
|
|
|
|
aResizeTimer.Start();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_Resize( nAbsAvail, bRecalc );
|
|
|
|
}
|
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
return sal_True;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
2011-01-17 15:06:54 +01:00
|
|
|
void SwHTMLTableLayout::BordersChanged( sal_uInt16 nAbsAvail, sal_Bool bRecalc )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2011-01-17 15:06:54 +01:00
|
|
|
bBordersChanged = sal_True;
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
Resize( nAbsAvail, bRecalc );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-10-14 08:30:41 +02:00
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|