blob: d6efd3628ab191c31bb278a20d6ccf4a7906cdd3 [file] [log] [blame]
/**************************************************************
*
* 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
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"
#include <hintids.hxx>
#include <vcl/svapp.hxx>
#include <svtools/htmlout.hxx>
#include <svtools/htmltokn.h>
#include <svtools/htmlkywd.hxx>
#ifndef _WRKWIN_HXX //autogen
#include <vcl/wrkwin.hxx>
#endif
#include <editeng/ulspitem.hxx>
#include <editeng/lrspitem.hxx>
#include <editeng/brshitem.hxx>
#include <editeng/boxitem.hxx>
#include <com/sun/star/form/XFormsSupplier.hpp>
#include <com/sun/star/form/XForm.hpp>
#include <com/sun/star/form/XImageProducerSupplier.hpp>
#include <com/sun/star/form/XFormController.hpp>
#include <com/sun/star/container/XContainer.hpp>
#include <com/sun/star/container/XIndexContainer.hpp>
#include <com/sun/star/container/XSet.hpp>
#include <fmtornt.hxx>
#include <frmfmt.hxx>
#include <fmtfsize.hxx>
#include <fmtsrnd.hxx>
#include <frmatr.hxx>
#include <doc.hxx>
#include <pam.hxx>
#include <ndtxt.hxx>
#include <swrect.hxx>
#include <cellatr.hxx>
#include <poolfmt.hxx>
#include <swtable.hxx>
#include <htmltbl.hxx>
#include <htmlnum.hxx>
#include <wrthtml.hxx>
#include <wrtswtbl.hxx>
#ifdef DBG_UTIL
#ifndef _VIEWSH_HXX
#include <viewsh.hxx>
#endif
#include <viewopt.hxx>
#endif
#include <sal/types.h>
//#define MAX_DEPTH (USHRT_MAX)
#define MAX_DEPTH (3)
using namespace ::com::sun::star;
class SwHTMLWrtTable : public SwWriteTable
{
void Pixelize( sal_uInt16& rValue );
void PixelizeBorders();
void OutTableCell( SwHTMLWriter& rWrt, const SwWriteTableCell *pCell,
sal_Bool bOutVAlign ) const;
void OutTableCells( SwHTMLWriter& rWrt,
const SwWriteTableCells& rCells,
const SvxBrushItem *pBrushItem ) const;
virtual sal_Bool ShouldExpandSub( const SwTableBox *pBox,
sal_Bool bExpandedBefore, sal_uInt16 nDepth ) const;
static sal_Bool HasTabBackground( const SwTableLine& rLine,
sal_Bool bTop, sal_Bool bBottom, sal_Bool bLeft, sal_Bool bRight );
static sal_Bool HasTabBackground( const SwTableBox& rBox,
sal_Bool bTop, sal_Bool bBottom, sal_Bool bLeft, sal_Bool bRight );
public:
SwHTMLWrtTable( const SwTableLines& rLines, long nWidth, sal_uInt32 nBWidth,
sal_Bool bRel, sal_uInt16 nNumOfRowsToRepeat,
sal_uInt16 nLeftSub=0, sal_uInt16 nRightSub=0 );
SwHTMLWrtTable( const SwHTMLTableLayout *pLayoutInfo );
void Write( SwHTMLWriter& rWrt, sal_Int16 eAlign=text::HoriOrientation::NONE,
sal_Bool bTHead=sal_False, const SwFrmFmt *pFrmFmt=0,
const String *pCaption=0, sal_Bool bTopCaption=sal_False,
sal_uInt16 nHSpace=0, sal_uInt16 nVSpace=0 ) const;
};
SwHTMLWrtTable::SwHTMLWrtTable( const SwTableLines& rLines, long nWidth,
sal_uInt32 nBWidth, sal_Bool bRel, sal_uInt16 nNumOfRowsToRepeat,
sal_uInt16 nLSub, sal_uInt16 nRSub )
: SwWriteTable( rLines, nWidth, nBWidth, bRel, MAX_DEPTH, nLSub, nRSub, nNumOfRowsToRepeat )
{
PixelizeBorders();
}
SwHTMLWrtTable::SwHTMLWrtTable( const SwHTMLTableLayout *pLayoutInfo )
: SwWriteTable( pLayoutInfo )
{
// Einige Twip-Werte an Pixel-Grenzen anpassen
if( bCollectBorderWidth )
PixelizeBorders();
}
void SwHTMLWrtTable::Pixelize( sal_uInt16& rValue )
{
if( rValue && Application::GetDefaultDevice() )
{
Size aSz( rValue, 0 );
aSz = Application::GetDefaultDevice()->LogicToPixel( aSz, MapMode(MAP_TWIP) );
if( !aSz.Width() )
aSz.Width() = 1;
aSz = Application::GetDefaultDevice()->PixelToLogic( aSz, MapMode(MAP_TWIP) );
rValue = (sal_uInt16)aSz.Width();
}
}
void SwHTMLWrtTable::PixelizeBorders()
{
Pixelize( nBorder );
Pixelize( nCellSpacing );
Pixelize( nCellPadding );
}
sal_Bool SwHTMLWrtTable::HasTabBackground( const SwTableBox& rBox,
sal_Bool bTop, sal_Bool bBottom, sal_Bool bLeft, sal_Bool bRight )
{
ASSERT( bTop || bBottom || bLeft || bRight,
"HasTabBackground: darf nicht aufgerufen werden" );
sal_Bool bRet = sal_False;
if( rBox.GetSttNd() )
{
const SvxBrushItem& rBrushItem =
rBox.GetFrmFmt()->GetBackground();
/// OD 02.09.2002 #99657#
/// The table box has a background, if its background color is not "no fill"/
/// "auto fill" or it has a background graphic.
bRet = rBrushItem.GetColor() != COL_TRANSPARENT ||
rBrushItem.GetGraphicLink() || rBrushItem.GetGraphic();
}
else
{
const SwTableLines& rLines = rBox.GetTabLines();
sal_uInt16 nCount = rLines.Count();
sal_Bool bLeftRight = bLeft || bRight;
for( sal_uInt16 i=0; !bRet && i<nCount; i++ )
{
sal_Bool bT = bTop && 0 == i;
sal_Bool bB = bBottom && nCount-1 == i;
if( bT || bB || bLeftRight )
bRet = HasTabBackground( *rLines[i], bT, bB, bLeft, bRight);
}
}
return bRet;
}
sal_Bool SwHTMLWrtTable::HasTabBackground( const SwTableLine& rLine,
sal_Bool bTop, sal_Bool bBottom, sal_Bool bLeft, sal_Bool bRight )
{
ASSERT( bTop || bBottom || bLeft || bRight,
"HasTabBackground: darf nicht aufgerufen werden" );
sal_Bool bRet = sal_False;
const SvxBrushItem& rBrushItem = rLine.GetFrmFmt()->GetBackground();
/// OD 02.09.2002 #99657#
/// The table line has a background, if its background color is not "no fill"/
/// "auto fill" or it has a background graphic.
bRet = rBrushItem.GetColor() != COL_TRANSPARENT ||
rBrushItem.GetGraphicLink() || rBrushItem.GetGraphic();
if( !bRet )
{
const SwTableBoxes& rBoxes = rLine.GetTabBoxes();
sal_uInt16 nCount = rBoxes.Count();
sal_Bool bTopBottom = bTop || bBottom;
for( sal_uInt16 i=0; !bRet && i<nCount; i++ )
{
sal_Bool bL = bLeft && 0 == i;
sal_Bool bR = bRight && nCount-1 == i;
if( bTopBottom || bL || bR )
bRet = HasTabBackground( *rBoxes[i], bTop, bBottom, bL, bR );
}
}
return bRet;
}
sal_Bool lcl_WrtHTMLTbl_HasTabBorders( const SwTableLine*& rpLine, void* pPara );
sal_Bool lcl_WrtHTMLTbl_HasTabBorders( const SwTableBox*& rpBox, void* pPara )
{
sal_Bool *pBorders = (sal_Bool *)pPara;
if( *pBorders )
return sal_False;
if( !rpBox->GetSttNd() )
{
((SwTableBox *)rpBox)->GetTabLines().ForEach(
&lcl_WrtHTMLTbl_HasTabBorders, pPara );
}
else
{
const SvxBoxItem& rBoxItem =
(const SvxBoxItem&)rpBox->GetFrmFmt()->GetFmtAttr( RES_BOX );
*pBorders = rBoxItem.GetTop() || rBoxItem.GetBottom() ||
rBoxItem.GetLeft() || rBoxItem.GetRight();
}
return !*pBorders;
}
sal_Bool lcl_WrtHTMLTbl_HasTabBorders( const SwTableLine*& rpLine, void* pPara )
{
sal_Bool *pBorders = (sal_Bool *)pPara;
if( *pBorders )
return sal_False;
((SwTableLine *)rpLine)->GetTabBoxes().ForEach(
&lcl_WrtHTMLTbl_HasTabBorders, pPara );
return !*pBorders;
}
sal_Bool SwHTMLWrtTable::ShouldExpandSub( const SwTableBox *pBox,
sal_Bool bExpandedBefore,
sal_uInt16 nDepth ) const
{
sal_Bool bExpand = !pBox->GetSttNd() && nDepth>0;
if( bExpand && bExpandedBefore )
{
// MIB 30.6.97: Wenn schon eine Box expandiert wurde, wird eine
// weitere nur expandiert, wenn sie Umrandungen besitzt.
sal_Bool bBorders = sal_False;
lcl_WrtHTMLTbl_HasTabBorders( pBox, &bBorders );
if( !bBorders )
bBorders = HasTabBackground( *pBox, sal_True, sal_True, sal_True, sal_True );
bExpand = bBorders;
}
return bExpand;
}
// Eine Box als einzelne Zelle schreiben
void SwHTMLWrtTable::OutTableCell( SwHTMLWriter& rWrt,
const SwWriteTableCell *pCell,
sal_Bool bOutVAlign ) const
{
const SwTableBox *pBox = pCell->GetBox();
sal_uInt16 nRow = pCell->GetRow();
sal_uInt16 nCol = pCell->GetCol();
sal_uInt16 nRowSpan = pCell->GetRowSpan();
sal_uInt16 nColSpan = pCell->GetColSpan();
if ( !nRowSpan )
return;
SwWriteTableCol *pCol = aCols[nCol];
// sal_Bool bOutWidth = nColSpan>1 || pCol->GetOutWidth();
sal_Bool bOutWidth = sal_True; //nColSpan==1 && pCol->GetOutWidth();
const SwStartNode* pSttNd = pBox->GetSttNd();
sal_Bool bHead = sal_False;
if( pSttNd )
{
sal_uLong nNdPos = pSttNd->GetIndex()+1;
// Art der Zelle (TD/TH) bestimmen
SwNode* pNd;
while( !( pNd = rWrt.pDoc->GetNodes()[nNdPos])->IsEndNode() )
{
if( pNd->IsTxtNode() )
{
// nur Absaetzte betrachten, an denen man was erkennt
// Das ist der Fall, wenn die Vorlage eine der Tabellen-Vorlagen
// ist oder von einer der beiden abgelitten ist.
const SwFmt *pFmt = &((SwTxtNode*)pNd)->GetAnyFmtColl();
sal_uInt16 nPoolId = pFmt->GetPoolFmtId();
while( !pFmt->IsDefault() &&
RES_POOLCOLL_TABLE_HDLN!=nPoolId &&
RES_POOLCOLL_TABLE!=nPoolId )
{
pFmt = pFmt->DerivedFrom();
nPoolId = pFmt->GetPoolFmtId();
}
if( !pFmt->IsDefault() )
{
bHead = (RES_POOLCOLL_TABLE_HDLN==nPoolId);
break;
}
}
nNdPos++;
}
}
rWrt.OutNewLine(); // <TH>/<TD> in neue Zeile
ByteString sOut( '<' );
sOut += (bHead ? OOO_STRING_SVTOOLS_HTML_tableheader : OOO_STRING_SVTOOLS_HTML_tabledata );
// ROW- und COLSPAN ausgeben
if( nRowSpan>1 )
(((sOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_rowspan ) += '=')
+= ByteString::CreateFromInt32( nRowSpan );
if( nColSpan > 1 )
(((sOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_colspan ) += '=')
+= ByteString::CreateFromInt32( nColSpan );
#ifndef PURE_HTML
long nWidth = 0;
sal_uInt32 nPrcWidth = USHRT_MAX;
if( bOutWidth )
{
if( bLayoutExport )
{
if( pCell->HasPrcWidthOpt() )
{
nPrcWidth = pCell->GetWidthOpt();
}
else
{
nWidth = pCell->GetWidthOpt();
if( !nWidth )
bOutWidth = sal_False;
}
}
else
{
if( HasRelWidths() )
nPrcWidth = (sal_uInt16)GetPrcWidth(nCol,nColSpan);
else
nWidth = GetAbsWidth( nCol, nColSpan );
}
}
long nHeight = pCell->GetHeight() > 0
? GetAbsHeight( pCell->GetHeight(), nRow, nRowSpan )
: 0;
Size aPixelSz( nWidth, nHeight );
// WIDTH ausgeben (Grrr: nur fuer Netscape)
if( (aPixelSz.Width() || aPixelSz.Height()) && Application::GetDefaultDevice() )
{
Size aOldSz( aPixelSz );
aPixelSz = Application::GetDefaultDevice()->LogicToPixel( aPixelSz,
MapMode(MAP_TWIP) );
if( aOldSz.Width() && !aPixelSz.Width() )
aPixelSz.Width() = 1;
if( aOldSz.Height() && !aPixelSz.Height() )
aPixelSz.Height() = 1;
}
// WIDTH ausgeben: Aus Layout oder berechnet
if( bOutWidth )
{
((sOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_width ) += '=';
if( nPrcWidth != USHRT_MAX )
(sOut += ByteString::CreateFromInt32(nPrcWidth)) += '%';
else
sOut += ByteString::CreateFromInt32(aPixelSz.Width());
if( !bLayoutExport && nColSpan==1 )
pCol->SetOutWidth( sal_False );
}
if( nHeight )
{
(((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_height) += '=')
+= ByteString::CreateFromInt32(aPixelSz.Height());
}
#endif
const SfxItemSet& rItemSet = pBox->GetFrmFmt()->GetAttrSet();
const SfxPoolItem *pItem;
// ALIGN wird jetzt nur noch an den Absaetzen ausgegeben
// VALIGN ausgeben
if( bOutVAlign )
{
sal_Int16 eVertOri = pCell->GetVertOri();
if( text::VertOrientation::TOP==eVertOri || text::VertOrientation::BOTTOM==eVertOri )
{
(((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_valign) += '=')
+= (text::VertOrientation::TOP==eVertOri ? OOO_STRING_SVTOOLS_HTML_VA_top : OOO_STRING_SVTOOLS_HTML_VA_bottom);
}
}
rWrt.Strm() << sOut.GetBuffer();
sOut.Erase();
rWrt.bTxtAttr = sal_False;
rWrt.bOutOpts = sal_True;
const SvxBrushItem *pBrushItem = 0;
if( SFX_ITEM_SET==rItemSet.GetItemState( RES_BACKGROUND, sal_False, &pItem ) )
{
pBrushItem = (const SvxBrushItem *)pItem;
}
if( !pBrushItem )
pBrushItem = pCell->GetBackground();
if( pBrushItem )
{
// Hintergrund ausgeben
String aDummy;
rWrt.OutBackground( pBrushItem, aDummy, sal_False );
if( rWrt.bCfgOutStyles )
OutCSS1_TableBGStyleOpt( rWrt, *pBrushItem );
}
sal_uInt32 nNumFmt = 0;
double nValue = 0.0;
sal_Bool bNumFmt = sal_False, bValue = sal_False;
if( SFX_ITEM_SET==rItemSet.GetItemState( RES_BOXATR_FORMAT, sal_False, &pItem ) )
{
nNumFmt = ((const SwTblBoxNumFormat *)pItem)->GetValue();
bNumFmt = sal_True;
}
if( SFX_ITEM_SET==rItemSet.GetItemState( RES_BOXATR_VALUE, sal_False, &pItem ) )
{
nValue = ((const SwTblBoxValue *)pItem)->GetValue();
bValue = sal_True;
if( !bNumFmt )
nNumFmt = pBox->GetFrmFmt()->GetTblBoxNumFmt().GetValue();
}
if( bNumFmt || bValue )
sOut = HTMLOutFuncs::CreateTableDataOptionsValNum( sOut,
bValue, nValue, nNumFmt, *rWrt.pDoc->GetNumberFormatter(),
rWrt.eDestEnc, &rWrt.aNonConvertableCharacters );
sOut += '>';
rWrt.Strm() << sOut.GetBuffer();
rWrt.bLFPossible = sal_True;
rWrt.IncIndentLevel(); // den Inhalt von <TD>...</TD> einruecken
if( pSttNd )
{
HTMLSaveData aSaveData( rWrt, pSttNd->GetIndex()+1,
pSttNd->EndOfSectionIndex() );
rWrt.Out_SwDoc( rWrt.pCurPam );
}
else
{
sal_uInt16 nTWidth;
sal_uInt32 nBWidth;
sal_uInt16 nLSub, nRSub;
if( HasRelWidths() )
{
nTWidth = 100;
nBWidth = GetRawWidth( nCol, nColSpan );
nLSub = 0;
nRSub = 0;
}
else
{
nTWidth = GetAbsWidth( nCol, nColSpan );
nBWidth = nTWidth;
nLSub = GetLeftSpace( nCol );
nRSub = GetRightSpace( nCol, nColSpan );
}
SwHTMLWrtTable aTableWrt( pBox->GetTabLines(), nTWidth,
nBWidth, HasRelWidths(), nLSub, nRSub );
aTableWrt.Write( rWrt );
}
rWrt.DecIndentLevel(); // den Inhalt von <TD>...</TD> einruecken
if( rWrt.bLFPossible )
rWrt.OutNewLine();
HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), bHead ? OOO_STRING_SVTOOLS_HTML_tableheader
: OOO_STRING_SVTOOLS_HTML_tabledata,
sal_False );
rWrt.bLFPossible = sal_True;
}
// Eine Line als Zeilen ausgeben
void SwHTMLWrtTable::OutTableCells( SwHTMLWriter& rWrt,
const SwWriteTableCells& rCells,
const SvxBrushItem *pBrushItem ) const
{
// Wenn die Zeile mehr als eine Zelle nethaelt und alle Zellen
// die gleiche Ausrichtung besitzen, das VALIGN an der Zeile statt der
// Zelle ausgeben
sal_Int16 eRowVertOri = text::VertOrientation::NONE;
if( rCells.Count() > 1 )
{
for( sal_uInt16 nCell = 0; nCell<rCells.Count(); nCell++ )
{
sal_Int16 eCellVertOri = rCells[nCell]->GetVertOri();
if( 0==nCell )
{
eRowVertOri = eCellVertOri;
}
else if( eRowVertOri != eCellVertOri )
{
eRowVertOri = text::VertOrientation::NONE;
break;
}
}
}
rWrt.OutNewLine(); // <TR> in neuer Zeile
rWrt.Strm() << '<' << OOO_STRING_SVTOOLS_HTML_tablerow;
if( pBrushItem )
{
String aDummy;
rWrt.OutBackground( pBrushItem, aDummy, sal_False );
rWrt.bTxtAttr = sal_False;
rWrt.bOutOpts = sal_True;
if( rWrt.bCfgOutStyles )
OutCSS1_TableBGStyleOpt( rWrt, *pBrushItem );
}
if( text::VertOrientation::TOP==eRowVertOri || text::VertOrientation::BOTTOM==eRowVertOri )
{
ByteString sOut( ' ' );
((sOut += OOO_STRING_SVTOOLS_HTML_O_valign) += '=')
+= (text::VertOrientation::TOP==eRowVertOri ? OOO_STRING_SVTOOLS_HTML_VA_top : OOO_STRING_SVTOOLS_HTML_VA_bottom);
rWrt.Strm() << sOut.GetBuffer();
}
rWrt.Strm() << '>';
rWrt.IncIndentLevel(); // Inhalt von <TR>...</TR> einruecken
for( sal_uInt16 nCell = 0; nCell<rCells.Count(); nCell++ )
OutTableCell( rWrt, rCells[nCell], text::VertOrientation::NONE==eRowVertOri );
rWrt.DecIndentLevel(); // Inhalt von <TR>...</TR> einruecken
rWrt.OutNewLine(); // </TR> in neuer Zeile
HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_tablerow, sal_False );
}
void SwHTMLWrtTable::Write( SwHTMLWriter& rWrt, sal_Int16 eAlign,
sal_Bool bTHead, const SwFrmFmt *pFrmFmt,
const String *pCaption, sal_Bool bTopCaption,
sal_uInt16 nHSpace, sal_uInt16 nVSpace ) const
{
sal_uInt16 nRow;
// Wert fuer FRAME bestimmen
sal_uInt16 nFrameMask = 15;
if( !(aRows[0])->bTopBorder )
nFrameMask &= ~1;
if( !(aRows[aRows.Count()-1])->bBottomBorder )
nFrameMask &= ~2;
if( !(aCols[0])->bLeftBorder )
nFrameMask &= ~4;
if( !(aCols[aCols.Count()-1])->bRightBorder )
nFrameMask &= ~8;
// Wert fur RULES bestimmen
sal_Bool bRowsHaveBorder = sal_False;
sal_Bool bRowsHaveBorderOnly = sal_True;
SwWriteTableRow *pRow = aRows[0];
for( nRow=1; nRow < aRows.Count(); nRow++ )
{
SwWriteTableRow *pNextRow = aRows[nRow];
sal_Bool bBorder = ( pRow->bBottomBorder || pNextRow->bTopBorder );
bRowsHaveBorder |= bBorder;
bRowsHaveBorderOnly &= bBorder;
sal_uInt16 nBorder2 = pRow->bBottomBorder ? pRow->nBottomBorder : USHRT_MAX;
if( pNextRow->bTopBorder && pNextRow->nTopBorder < nBorder2 )
nBorder2 = pNextRow->nTopBorder;
pRow->bBottomBorder = bBorder;
pRow->nBottomBorder = nBorder2;
pNextRow->bTopBorder = bBorder;
pNextRow->nTopBorder = nBorder2;
pRow = pNextRow;
}
sal_Bool bColsHaveBorder = sal_False;
sal_Bool bColsHaveBorderOnly = sal_True;
SwWriteTableCol *pCol = aCols[0];
sal_uInt16 nCol;
for( nCol=1; nCol<aCols.Count(); nCol++ )
{
SwWriteTableCol *pNextCol = aCols[nCol];
sal_Bool bBorder = ( pCol->bRightBorder || pNextCol->bLeftBorder );
bColsHaveBorder |= bBorder;
bColsHaveBorderOnly &= bBorder;
pCol->bRightBorder = bBorder;
pNextCol->bLeftBorder = bBorder;
pCol = pNextCol;
}
// vorhergende Aufzaehlung etc. beenden
rWrt.ChangeParaToken( 0 );
if( rWrt.bLFPossible )
rWrt.OutNewLine(); // <TABLE> in neue Zeile
ByteString sOut( '<' );
sOut += OOO_STRING_SVTOOLS_HTML_table;
sal_uInt16 nOldDirection = rWrt.nDirection;
if( pFrmFmt )
rWrt.nDirection = rWrt.GetHTMLDirection( pFrmFmt->GetAttrSet() );
if( rWrt.bOutFlyFrame || nOldDirection != rWrt.nDirection )
{
rWrt.Strm() << sOut.GetBuffer();
sOut.Erase();
rWrt.OutDirection( rWrt.nDirection );
}
// COLS ausgeben: Nur bei Export ueber Layout, wenn es beim Import
// vorhanden war.
if( bColsOption )
(((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_cols) += '=')
+= ByteString::CreateFromInt32( aCols.Count() );
// ALIGN= ausgeben
if( text::HoriOrientation::RIGHT == eAlign )
(((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_align ) += '=') += OOO_STRING_SVTOOLS_HTML_AL_right;
else if( text::HoriOrientation::CENTER == eAlign )
(((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_align ) += '=') += OOO_STRING_SVTOOLS_HTML_AL_center;
else if( text::HoriOrientation::LEFT == eAlign )
(((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_align ) += '=') += OOO_STRING_SVTOOLS_HTML_AL_left;
// WIDTH ausgeben: Stammt aus Layout oder ist berechnet
if( nTabWidth )
{
((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_width ) += '=';
if( HasRelWidths() )
(sOut += ByteString::CreateFromInt32( nTabWidth )) += '%';
else if( Application::GetDefaultDevice() )
{
long nPixWidth = Application::GetDefaultDevice()->LogicToPixel(
Size(nTabWidth,0), MapMode(MAP_TWIP) ).Width();
if( !nPixWidth )
nPixWidth = 1;
sOut += ByteString::CreateFromInt32( nPixWidth );
}
else
{
ASSERT( Application::GetDefaultDevice(), "kein Application-Window!?" );
sOut += "100%";
}
}
if( (nHSpace || nVSpace) && Application::GetDefaultDevice())
{
Size aPixelSpc =
Application::GetDefaultDevice()->LogicToPixel( Size(nHSpace,nVSpace),
MapMode(MAP_TWIP) );
if( !aPixelSpc.Width() && nHSpace )
aPixelSpc.Width() = 1;
if( !aPixelSpc.Height() && nVSpace )
aPixelSpc.Height() = 1;
if( aPixelSpc.Width() )
{
(((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_hspace) += '=')
+= ByteString::CreateFromInt32( aPixelSpc.Width() );
}
if( aPixelSpc.Height() )
{
(((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_vspace) += '=')
+= ByteString::CreateFromInt32( aPixelSpc.Height() );
}
}
// BORDER ausgeben, aber nur wenn wir die Umrandung selbst berechnet
// haben oder die Umrandung 0 ist oder es irgendwelche Umrandungen gibt.
// Anderenfalls enthaelt nBorder naemlich nur die Breite der Umrandung,
// die genutzt wird, wenn gar kein sheet::Border angegeben ist.
sal_Bool bHasAnyBorders = nFrameMask || bColsHaveBorder || bRowsHaveBorder;
if( bCollectBorderWidth || nBorder==0 || bHasAnyBorders )
(((sOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_border ) += '=')
+= ByteString::CreateFromInt32( rWrt.ToPixel( nBorder ) );
// BORDERCOLOR ausgeben
if( (sal_uInt32)-1 != nBorderColor && rWrt.bCfgOutStyles && bHasAnyBorders )
{
((sOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_bordercolor ) += '=';
rWrt.Strm() << sOut.GetBuffer();
HTMLOutFuncs::Out_Color( rWrt.Strm(), nBorderColor, rWrt.eDestEnc );
sOut.Erase();
}
// CELLPADDING ausgeben: Stammt aus Layout oder ist berechnet
(((sOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_cellpadding ) += '=')
+= ByteString::CreateFromInt32( rWrt.ToPixel( nCellPadding ) );
// CELLSPACING ausgeben: Stammt aus Layout oder ist berechnet
(((sOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_cellspacing ) += '=')
+= ByteString::CreateFromInt32( rWrt.ToPixel( nCellSpacing ) );
// FRAME/RULES ausgeben (nur sinnvoll, wenn border!=0)
if( nBorder!=0 && (bCollectBorderWidth || bHasAnyBorders) )
{
const sal_Char *pFrame = 0;
switch( nFrameMask )
{
case 0: pFrame = OOO_STRING_SVTOOLS_HTML_TF_void ;break;
case 1: pFrame = OOO_STRING_SVTOOLS_HTML_TF_above ;break;
case 2: pFrame = OOO_STRING_SVTOOLS_HTML_TF_below ;break;
case 3: pFrame = OOO_STRING_SVTOOLS_HTML_TF_hsides ;break;
case 4: pFrame = OOO_STRING_SVTOOLS_HTML_TF_lhs ;break;
case 8: pFrame = OOO_STRING_SVTOOLS_HTML_TF_rhs ;break;
case 12: pFrame = OOO_STRING_SVTOOLS_HTML_TF_vsides ;break;
//FRAME=BOX ist der default wenn BORDER>0
//case 15:
//default: pFrame = OOO_STRING_SVTOOLS_HTML_TF_box ;break; // geht nicht
};
if( pFrame )
(((sOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_frame ) += '=') += pFrame;
const sal_Char *pRules = 0;
if( aCols.Count() > 1 && aRows.Count() > 1 )
{
if( !bColsHaveBorder )
{
if( !bRowsHaveBorder )
pRules = OOO_STRING_SVTOOLS_HTML_TR_none;
else if( bRowsHaveBorderOnly )
pRules = OOO_STRING_SVTOOLS_HTML_TR_rows;
else
pRules = OOO_STRING_SVTOOLS_HTML_TR_groups;
}
else if( bColsHaveBorderOnly )
{
if( !bRowsHaveBorder || !bRowsHaveBorderOnly )
pRules = OOO_STRING_SVTOOLS_HTML_TR_cols;
}
else
{
if( !bRowsHaveBorder )
pRules = OOO_STRING_SVTOOLS_HTML_TR_groups;
else if( bRowsHaveBorderOnly )
pRules = OOO_STRING_SVTOOLS_HTML_TR_rows;
else
pRules = OOO_STRING_SVTOOLS_HTML_TR_groups;
}
}
else if( aRows.Count() > 1 )
{
if( !bRowsHaveBorder )
pRules = OOO_STRING_SVTOOLS_HTML_TR_none;
else if( !bRowsHaveBorderOnly )
pRules = OOO_STRING_SVTOOLS_HTML_TR_groups;
}
else if( aCols.Count() > 1 )
{
if( !bColsHaveBorder )
pRules = OOO_STRING_SVTOOLS_HTML_TR_none;
else if( !bColsHaveBorderOnly )
pRules = OOO_STRING_SVTOOLS_HTML_TR_groups;
}
if( pRules )
(((sOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_rules ) += '=') += pRules;
}
rWrt.Strm() << sOut.GetBuffer();
// Hintergrund ausgeben
if( pFrmFmt )
{
String aDummy;
rWrt.OutBackground( pFrmFmt->GetAttrSet(), aDummy, sal_False );
if( rWrt.bCfgOutStyles && pFrmFmt )
rWrt.OutCSS1_TableFrmFmtOptions( *pFrmFmt );
}
sOut = '>';
rWrt.Strm() << sOut.GetBuffer();
rWrt.IncIndentLevel(); // Inhalte von Table einruecken
// Ueberschrift ausgeben
if( pCaption && pCaption->Len() )
{
rWrt.OutNewLine(); // <CAPTION> in neue Zeile
ByteString sOutStr( OOO_STRING_SVTOOLS_HTML_caption );
(((sOutStr += ' ') += OOO_STRING_SVTOOLS_HTML_O_align) += '=')
+= (bTopCaption ? OOO_STRING_SVTOOLS_HTML_VA_top : OOO_STRING_SVTOOLS_HTML_VA_bottom);
HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), sOutStr.GetBuffer(), sal_True );
HTMLOutFuncs::Out_String( rWrt.Strm(), *pCaption, rWrt.eDestEnc, &rWrt.aNonConvertableCharacters );
HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_caption, sal_False );
}
sal_uInt16 nCols = aCols.Count();
// <COLGRP>/<COL> ausgeben: Bei Export ueber Layout nur wenn beim
// Import welche da waren, sonst immer.
sal_Bool bColGroups = (bColsHaveBorder && !bColsHaveBorderOnly);
if( bColTags )
{
if( bColGroups )
{
rWrt.OutNewLine(); // <COLGRP> in neue Zeile
HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_colgroup, sal_True );
rWrt.IncIndentLevel(); // Inhalt von <COLGRP> einruecken
}
for( nCol=0; nCol<nCols; nCol++ )
{
rWrt.OutNewLine(); // <COL> in neue Zeile
const SwWriteTableCol *pColumn = aCols[nCol];
ByteString sOutStr( '<' );
sOutStr += OOO_STRING_SVTOOLS_HTML_col;
sal_uInt32 nWidth;
sal_Bool bRel;
if( bLayoutExport )
{
bRel = pColumn->HasRelWidthOpt();
nWidth = pColumn->GetWidthOpt();
}
else
{
bRel = HasRelWidths();
nWidth = bRel ? GetRelWidth(nCol,1) : GetAbsWidth(nCol,1);
}
((sOutStr += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_width ) += '=';
if( bRel )
{
(sOutStr += ByteString::CreateFromInt32( nWidth ) ) += '*';
}
else
{
sOutStr += ByteString::CreateFromInt32( rWrt.ToPixel( nWidth ) );
}
sOutStr += '>';
rWrt.Strm() << sOutStr.GetBuffer();
if( bColGroups && pColumn->bRightBorder && nCol<nCols-1 )
{
rWrt.DecIndentLevel(); // Inhalt von <COLGRP> einruecken
rWrt.OutNewLine(); // </COLGRP> in neue Zeile
HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_colgroup,
sal_False );
rWrt.OutNewLine(); // <COLGRP> in neue Zeile
HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_colgroup,
sal_True );
rWrt.IncIndentLevel(); // Inhalt von <COLGRP> einruecken
}
}
if( bColGroups )
{
rWrt.DecIndentLevel(); // Inhalt von <COLGRP> einruecken
rWrt.OutNewLine(); // </COLGRP> in neue Zeile
HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_colgroup,
sal_False );
}
}
// die Lines als Tabellenzeilen rausschreiben
// <TBODY> ausgeben?
sal_Bool bTSections = (bRowsHaveBorder && !bRowsHaveBorderOnly);
sal_Bool bTBody = bTSections;
// Wenn Sections ausgegeben werden muessen darf ein THEAD um die erste
// Zeile nur ausgegeben werden, wenn unter der Zeile eine Linie ist
if( bTHead &&
(bTSections || bColGroups) &&
nHeadEndRow<aRows.Count()-1 && !aRows[nHeadEndRow]->bBottomBorder )
bTHead = sal_False;
// <TBODY> aus ausgeben, wenn <THEAD> ausgegeben wird.
bTSections |= bTHead;
if( bTSections )
{
rWrt.OutNewLine(); // <THEAD>/<TDATA> in neue Zeile
HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(),
bTHead ? OOO_STRING_SVTOOLS_HTML_thead : OOO_STRING_SVTOOLS_HTML_tbody, sal_True );
rWrt.IncIndentLevel(); // Inhalt von <THEAD>/<TDATA> einr.
}
for( nRow = 0; nRow < aRows.Count(); nRow++ )
{
const SwWriteTableRow *pRow2 = aRows[nRow];
OutTableCells( rWrt, pRow2->GetCells(), pRow2->GetBackground() );
if( !nCellSpacing && nRow < aRows.Count()-1 && pRow2->bBottomBorder &&
pRow2->nBottomBorder > DEF_LINE_WIDTH_1 )
{
sal_uInt16 nCnt = (pRow2->nBottomBorder / DEF_LINE_WIDTH_1) - 1;
for( ; nCnt; nCnt-- )
{
rWrt.OutNewLine();
HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_tablerow,
sal_True );
HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_tablerow,
sal_False );
}
}
if( ( (bTHead && nRow==nHeadEndRow) ||
(bTBody && pRow2->bBottomBorder) ) &&
nRow < aRows.Count()-1 )
{
rWrt.DecIndentLevel(); // Inhalt von <THEAD>/<TDATA> einr.
rWrt.OutNewLine(); // </THEAD>/</TDATA> in neue Zeile
HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(),
bTHead ? OOO_STRING_SVTOOLS_HTML_thead : OOO_STRING_SVTOOLS_HTML_tbody, sal_False );
rWrt.OutNewLine(); // <THEAD>/<TDATA> in neue Zeile
if( bTHead && nRow==nHeadEndRow )
bTHead = sal_False;
HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(),
bTHead ? OOO_STRING_SVTOOLS_HTML_thead : OOO_STRING_SVTOOLS_HTML_tbody, sal_True );
rWrt.IncIndentLevel(); // Inhalt von <THEAD>/<TDATA> einr.
}
}
if( bTSections )
{
rWrt.DecIndentLevel(); // Inhalt von <THEAD>/<TDATA> einr.
rWrt.OutNewLine(); // </THEAD>/</TDATA> in neue Zeile
HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(),
bTHead ? OOO_STRING_SVTOOLS_HTML_thead : OOO_STRING_SVTOOLS_HTML_tbody, sal_False );
}
rWrt.DecIndentLevel(); // Inhalt von <TABLE> einr.
rWrt.OutNewLine(); // </TABLE> in neue Zeile
HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_table, sal_False );
rWrt.nDirection = nOldDirection;
}
Writer& OutHTML_SwTblNode( Writer& rWrt, SwTableNode & rNode,
const SwFrmFmt *pFlyFrmFmt,
const String *pCaption, sal_Bool bTopCaption )
{
SwTable& rTbl = rNode.GetTable();
SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
rHTMLWrt.bOutTable = sal_True;
// die horizontale Ausrichtung des Rahmens hat (falls vorhanden)
// Prioritaet. NONE bedeutet, dass keine horizontale
// Ausrichtung geschrieben wird.
sal_Int16 eFlyHoriOri = text::HoriOrientation::NONE;
SwSurround eSurround = SURROUND_NONE;
sal_uInt8 nFlyPrcWidth = 0;
long nFlyWidth = 0;
sal_uInt16 nFlyHSpace = 0;
sal_uInt16 nFlyVSpace = 0;
if( pFlyFrmFmt )
{
eSurround = pFlyFrmFmt->GetSurround().GetSurround();
const SwFmtFrmSize& rFrmSize = pFlyFrmFmt->GetFrmSize();
nFlyPrcWidth = rFrmSize.GetWidthPercent();
nFlyWidth = rFrmSize.GetSize().Width();
eFlyHoriOri = pFlyFrmFmt->GetHoriOrient().GetHoriOrient();
if( text::HoriOrientation::NONE == eFlyHoriOri )
eFlyHoriOri = text::HoriOrientation::LEFT;
const SvxLRSpaceItem& rLRSpace = pFlyFrmFmt->GetLRSpace();
nFlyHSpace = static_cast< sal_uInt16 >((rLRSpace.GetLeft() + rLRSpace.GetRight()) / 2);
const SvxULSpaceItem& rULSpace = pFlyFrmFmt->GetULSpace();
nFlyVSpace = (rULSpace.GetUpper() + rULSpace.GetLower()) / 2;
}
// ggf. eine FORM oeffnen
sal_Bool bPreserveForm = sal_False;
if( !rHTMLWrt.bPreserveForm )
{
rHTMLWrt.OutForm( sal_True, &rNode );
bPreserveForm = (rHTMLWrt.pxFormComps && rHTMLWrt.pxFormComps->is() );
rHTMLWrt.bPreserveForm = bPreserveForm;
}
SwFrmFmt *pFmt = rTbl.GetFrmFmt();
const SwFmtFrmSize& rFrmSize = pFmt->GetFrmSize();
long nWidth = rFrmSize.GetSize().Width();
sal_uInt8 nPrcWidth = rFrmSize.GetWidthPercent();
sal_uInt16 nBaseWidth = (sal_uInt16)nWidth;
sal_Int16 eTabHoriOri = pFmt->GetHoriOrient().GetHoriOrient();
// text::HoriOrientation::NONE und text::HoriOrientation::FULL Tabellen benoetigen relative Breiten
sal_uInt16 nNewDefListLvl = 0;
sal_Bool bRelWidths = sal_False;
sal_Bool bCheckDefList = sal_False;
switch( eTabHoriOri )
{
case text::HoriOrientation::FULL:
// Tabellen mit automatischer Ausrichtung werden zu Tabellen
// mit 100%-Breite
bRelWidths = sal_True;
nWidth = 100;
eTabHoriOri = text::HoriOrientation::LEFT;
break;
case text::HoriOrientation::NONE:
{
const SvxLRSpaceItem& aLRItem = pFmt->GetLRSpace();
if( aLRItem.GetRight() )
{
// Die Tabellenbreite wird anhand des linken und rechten
// Abstandes bestimmt. Deshalb versuchen wir die
// tatsaechliche Breite der Tabelle zu bestimmen. Wenn
// das nicht geht, machen wir eine 100% breite Tabelle
// draus.
nWidth = pFmt->FindLayoutRect(sal_True).Width();
if( !nWidth )
{
bRelWidths = sal_True;
nWidth = 100;
}
}
else if( nPrcWidth )
{
// Ohne rechten Rand bleibt die %-Breite erhalten
nWidth = nPrcWidth;
bRelWidths = sal_True;
}
else
{
// Ohne rechten Rand bleibt auch eine absolute Breite erhalten
// Wir versuchen aber trotzdem ueber das Layout die
// tatsachliche Breite zu ermitteln.
long nRealWidth = pFmt->FindLayoutRect(sal_True).Width();
if( nRealWidth )
nWidth = nRealWidth;
}
bCheckDefList = sal_True;
}
break;
case text::HoriOrientation::LEFT_AND_WIDTH:
eTabHoriOri = text::HoriOrientation::LEFT;
bCheckDefList = sal_True;
// no break
default:
// In allen anderen Faellen kann eine absolute oder relative
// Breite direkt uebernommen werden.
if( nPrcWidth )
{
bRelWidths = sal_True;
nWidth = nPrcWidth;
}
break;
}
if( bCheckDefList )
{
ASSERT( !rHTMLWrt.GetNumInfo().GetNumRule() ||
rHTMLWrt.GetNextNumInfo(),
"NumInfo fuer naechsten Absatz fehlt!" );
const SvxLRSpaceItem& aLRItem = pFmt->GetLRSpace();
if( aLRItem.GetLeft() > 0 && rHTMLWrt.nDefListMargin > 0 &&
( !rHTMLWrt.GetNumInfo().GetNumRule() ||
( rHTMLWrt.GetNextNumInfo() &&
(rHTMLWrt.GetNextNumInfo()->IsRestart() ||
rHTMLWrt.GetNumInfo().GetNumRule() !=
rHTMLWrt.GetNextNumInfo()->GetNumRule()) ) ) )
{
// Wenn der Absatz vor der Tabelle nicht numeriert ist oder
// der Absatz nach der Tabelle mit einer anderen oder
// (gar keiner) Regel numeriert ist, koennen wir
// die Einrueckung ueber eine DL regeln. Sonst behalten wir
// die Einrueckung der Numerierung bei.
nNewDefListLvl = static_cast< sal_uInt16 >(
(aLRItem.GetLeft() + (rHTMLWrt.nDefListMargin/2)) /
rHTMLWrt.nDefListMargin );
}
}
if( !pFlyFrmFmt && nNewDefListLvl != rHTMLWrt.nDefListLvl )
rHTMLWrt.OutAndSetDefList( nNewDefListLvl );
if( nNewDefListLvl )
{
if( rHTMLWrt.bLFPossible )
rHTMLWrt.OutNewLine();
HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_dd );
}
// eFlyHoriOri und eTabHoriOri besitzen nun nur noch die Werte
// LEFT/CENTER und RIGHT!
if( eFlyHoriOri!=text::HoriOrientation::NONE )
{
eTabHoriOri = eFlyHoriOri;
// MIB 4.7.97: Wenn die Tabelle eine relative Breite besitzt,
// dann richtet sich ihre Breite nach der des Rahmens, also
// exportieren wir dessen Breite. Bei fixer Breite ist die Breite
// der Tabelle massgeblich. Wer Tabellen mit relativer Breite <100%
// in Rahmen steckt, ist selber schuld wenn nix Gutes bei rauskommt.
if( bRelWidths )
{
nWidth = nFlyPrcWidth ? nFlyPrcWidth : nFlyWidth;
bRelWidths = nFlyPrcWidth > 0;
}
}
sal_Int16 eDivHoriOri = text::HoriOrientation::NONE;
switch( eTabHoriOri )
{
case text::HoriOrientation::LEFT:
// Wenn eine linksbuendigeTabelle keinen rechtsseiigen Durchlauf
// hat, brauchen wir auch kein ALIGN=LEFT in der Tabelle.
if( eSurround==SURROUND_NONE || eSurround==SURROUND_LEFT )
eTabHoriOri = text::HoriOrientation::NONE;
break;
case text::HoriOrientation::RIGHT:
// Aehnliches gilt fuer rechtsbuendigeTabelle, hier nehmen wir
// stattdessen ein <DIV ALIGN=RIGHT>.
if( eSurround==SURROUND_NONE || eSurround==SURROUND_RIGHT )
{
eDivHoriOri = text::HoriOrientation::RIGHT;
eTabHoriOri = text::HoriOrientation::NONE;
}
break;
case text::HoriOrientation::CENTER:
// ALIGN=CENTER versteht so gut wie keiner, deshalb verzichten wir
// daruf und nehmen ein <CENTER>.
eDivHoriOri = text::HoriOrientation::CENTER;
eTabHoriOri = text::HoriOrientation::NONE;
break;
default:
;
}
if( text::HoriOrientation::NONE==eTabHoriOri )
nFlyHSpace = nFlyVSpace = 0;
if( pFmt->GetName().Len() )
rHTMLWrt.OutImplicitMark( pFmt->GetName(), pMarkToTable );
if( text::HoriOrientation::NONE!=eDivHoriOri )
{
if( rHTMLWrt.bLFPossible )
rHTMLWrt.OutNewLine(); // <CENTER> in neuer Zeile
if( text::HoriOrientation::CENTER==eDivHoriOri )
HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_center, sal_True );
else
{
ByteString sOut( OOO_STRING_SVTOOLS_HTML_division );
(((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_align) += '=') += OOO_STRING_SVTOOLS_HTML_AL_right;
HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), sOut.GetBuffer(),
sal_True );
}
rHTMLWrt.IncIndentLevel(); // Inhalt von <CENTER> einruecken
rHTMLWrt.bLFPossible = sal_True;
}
// Wenn die Tabelle in keinem Rahmen ist kann man immer ein LF ausgeben.
if( text::HoriOrientation::NONE==eTabHoriOri )
rHTMLWrt.bLFPossible = sal_True;
const SwHTMLTableLayout *pLayout = rTbl.GetHTMLTableLayout();
#ifdef DBG_UTIL
ViewShell *pSh;
rWrt.pDoc->GetEditShell( &pSh );
if ( pSh && pSh->GetViewOptions()->IsTest1() )
pLayout = 0;
#endif
if( pLayout && pLayout->IsExportable() )
{
SwHTMLWrtTable aTableWrt( pLayout );
aTableWrt.Write( rHTMLWrt, eTabHoriOri, rTbl.GetRowsToRepeat() > 0,
pFmt, pCaption, bTopCaption,
nFlyHSpace, nFlyVSpace );
}
else
{
SwHTMLWrtTable aTableWrt( rTbl.GetTabLines(), nWidth,
nBaseWidth, bRelWidths, rTbl.GetRowsToRepeat() );
aTableWrt.Write( rHTMLWrt, eTabHoriOri, rTbl.GetRowsToRepeat() > 0,
pFmt, pCaption, bTopCaption,
nFlyHSpace, nFlyVSpace );
}
// Wenn die Tabelle in keinem Rahmen war kann man immer ein LF ausgeben.
if( text::HoriOrientation::NONE==eTabHoriOri )
rHTMLWrt.bLFPossible = sal_True;
if( text::HoriOrientation::NONE!=eDivHoriOri )
{
rHTMLWrt.DecIndentLevel(); // Inhalt von <CENTER> einruecken
rHTMLWrt.OutNewLine(); // </CENTER> in neue Teile
HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(),
text::HoriOrientation::CENTER==eDivHoriOri ? OOO_STRING_SVTOOLS_HTML_center
: OOO_STRING_SVTOOLS_HTML_division, sal_False );
rHTMLWrt.bLFPossible = sal_True;
}
// Pam hinter die Tabelle verschieben
rHTMLWrt.pCurPam->GetPoint()->nNode = *rNode.EndOfSectionNode();
if( bPreserveForm )
{
rHTMLWrt.bPreserveForm = sal_False;
rHTMLWrt.OutForm( sal_False );
}
rHTMLWrt.bOutTable = sal_False;
if( rHTMLWrt.GetNextNumInfo() &&
!rHTMLWrt.GetNextNumInfo()->IsRestart() &&
rHTMLWrt.GetNextNumInfo()->GetNumRule() ==
rHTMLWrt.GetNumInfo().GetNumRule() )
{
// Wenn der Absatz hinter der Tabelle mit der gleichen Regel
// numeriert ist wie der Absatz vor der Tabelle, dann steht in
// der NumInfo des naechsten Absatzes noch die Ebene des Absatzes
// vor der Tabelle. Es muss deshalb die NumInfo noch einmal geholt
// werden um ggf. die Num-Liste noch zu beenden.
rHTMLWrt.ClearNextNumInfo();
rHTMLWrt.FillNextNumInfo();
OutHTML_NumBulListEnd( rHTMLWrt, *rHTMLWrt.GetNextNumInfo() );
}
return rWrt;
}