| /************************************************************** |
| * |
| * 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; |
| } |
| |
| |