diff options
Diffstat (limited to 'sw/source/filter/html/htmltabw.cxx')
-rw-r--r-- | sw/source/filter/html/htmltabw.cxx | 1253 |
1 files changed, 1253 insertions, 0 deletions
diff --git a/sw/source/filter/html/htmltabw.cxx b/sw/source/filter/html/htmltabw.cxx new file mode 100644 index 000000000000..82628e810b8c --- /dev/null +++ b/sw/source/filter/html/htmltabw.cxx @@ -0,0 +1,1253 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 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> +#include <vcl/wrkwin.hxx> +#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> +#if OSL_DEBUG_LEVEL > 1 +#include <viewsh.hxx> +#include <viewopt.hxx> +#endif +#include <sal/types.h> + +#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 ) +{ + OSL_ENSURE( bTop || bBottom || bLeft || bRight, + "HasTabBackground: darf nicht aufgerufen werden" ); + + sal_Bool bRet = sal_False; + if( rBox.GetSttNd() ) + { + const SvxBrushItem& rBrushItem = + rBox.GetFrmFmt()->GetBackground(); + + /// 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 ) +{ + OSL_ENSURE( bTop || bBottom || bLeft || bRight, + "HasTabBackground: darf nicht aufgerufen werden" ); + + sal_Bool bRet = sal_False; + const SvxBrushItem& rBrushItem = rLine.GetFrmFmt()->GetBackground(); + /// 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; + +#ifndef PURE_HTML + SwWriteTableCol *pCol = aCols[nCol]; +#endif + + sal_Bool bOutWidth = sal_True; + + 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 ); + } + + ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_style ) += "=\""; + rWrt.Strm() << sOut.GetBuffer( ); + OutCSS1_SvxBox( rWrt, pBox->GetFrmFmt()->GetBox() ); + sOut = '"'; + + 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 + { + OSL_ENSURE( 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; + + // 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; + }; + 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 ) + { + OSL_ENSURE( !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(); + +#if OSL_DEBUG_LEVEL > 1 + 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; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |