LCOV - code coverage report
Current view: top level - sw/source/filter/html - htmltabw.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 316 575 55.0 %
Date: 2015-06-13 12:38:46 Functions: 11 17 64.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <hintids.hxx>
      21             : #include <vcl/svapp.hxx>
      22             : #include <svtools/htmlout.hxx>
      23             : #include <svtools/htmltokn.h>
      24             : #include <svtools/htmlkywd.hxx>
      25             : #include <vcl/wrkwin.hxx>
      26             : #include <editeng/ulspitem.hxx>
      27             : #include <editeng/lrspitem.hxx>
      28             : #include <editeng/brushitem.hxx>
      29             : #include <editeng/boxitem.hxx>
      30             : #include <com/sun/star/form/XFormsSupplier.hpp>
      31             : #include <com/sun/star/form/XForm.hpp>
      32             : #include <com/sun/star/form/XImageProducerSupplier.hpp>
      33             : #include <com/sun/star/form/XFormController.hpp>
      34             : #include <com/sun/star/container/XContainer.hpp>
      35             : #include <com/sun/star/container/XIndexContainer.hpp>
      36             : #include <com/sun/star/container/XSet.hpp>
      37             : #include <fmtornt.hxx>
      38             : #include <frmfmt.hxx>
      39             : #include <fmtfsize.hxx>
      40             : #include <fmtsrnd.hxx>
      41             : #include <frmatr.hxx>
      42             : #include <doc.hxx>
      43             : #include <IDocumentLayoutAccess.hxx>
      44             : #include <pam.hxx>
      45             : #include <ndtxt.hxx>
      46             : #include <swrect.hxx>
      47             : #include <cellatr.hxx>
      48             : #include <poolfmt.hxx>
      49             : #include <swtable.hxx>
      50             : #include <htmltbl.hxx>
      51             : #include <htmlnum.hxx>
      52             : #include <wrthtml.hxx>
      53             : #include <wrtswtbl.hxx>
      54             : #ifdef DBG_UTIL
      55             : #include <viewsh.hxx>
      56             : #include <viewopt.hxx>
      57             : #endif
      58             : #include <rtl/strbuf.hxx>
      59             : #include <sal/types.h>
      60             : 
      61             : #define MAX_DEPTH (3)
      62             : 
      63             : using namespace ::com::sun::star;
      64             : 
      65           2 : class SwHTMLWrtTable : public SwWriteTable
      66             : {
      67             :     static void Pixelize( sal_uInt16& rValue );
      68             :     void PixelizeBorders();
      69             : 
      70             :     void OutTableCell( SwHTMLWriter& rWrt, const SwWriteTableCell *pCell,
      71             :                        bool bOutVAlign ) const;
      72             : 
      73             :     void OutTableCells( SwHTMLWriter& rWrt,
      74             :                         const SwWriteTableCells& rCells,
      75             :                         const SvxBrushItem *pBrushItem ) const;
      76             : 
      77             :     virtual bool ShouldExpandSub( const SwTableBox *pBox,
      78             :                             bool bExpandedBefore, sal_uInt16 nDepth ) const SAL_OVERRIDE;
      79             : 
      80             :     static bool HasTabBackground( const SwTableLine& rLine,
      81             :                         bool bTop, bool bBottom, bool bLeft, bool bRight );
      82             :     static bool HasTabBackground( const SwTableBox& rBox,
      83             :                         bool bTop, bool bBottom, bool bLeft, bool bRight );
      84             : 
      85             : public:
      86             :     SwHTMLWrtTable( const SwTableLines& rLines, long nWidth, sal_uInt32 nBWidth,
      87             :                     bool bRel, sal_uInt16 nLeftSub=0, sal_uInt16 nRightSub=0,
      88             :                     sal_uInt16 nNumOfRowsToRepeat = 0 );
      89             :     explicit SwHTMLWrtTable( const SwHTMLTableLayout *pLayoutInfo );
      90             : 
      91             :     void Write( SwHTMLWriter& rWrt, sal_Int16 eAlign=text::HoriOrientation::NONE,
      92             :                 bool bTHead=false, const SwFrameFormat *pFrameFormat=0,
      93             :                 const OUString *pCaption=0, bool bTopCaption=false,
      94             :                 sal_uInt16 nHSpace=0, sal_uInt16 nVSpace=0 ) const;
      95             : };
      96             : 
      97           1 : SwHTMLWrtTable::SwHTMLWrtTable( const SwTableLines& rLines, long nWidth,
      98             :                                 sal_uInt32 nBWidth, bool bRel,
      99             :                                 sal_uInt16 nLSub, sal_uInt16 nRSub,
     100             :                                 sal_uInt16 nNumOfRowsToRepeat )
     101           1 :     : SwWriteTable(NULL, rLines, nWidth, nBWidth, bRel, MAX_DEPTH, nLSub, nRSub, nNumOfRowsToRepeat)
     102             : {
     103           1 :     PixelizeBorders();
     104           1 : }
     105             : 
     106           1 : SwHTMLWrtTable::SwHTMLWrtTable( const SwHTMLTableLayout *pLayoutInfo )
     107           1 :     : SwWriteTable(NULL, pLayoutInfo)
     108             : {
     109             :     // Einige Twip-Werte an Pixel-Grenzen anpassen
     110           1 :     if( bCollectBorderWidth )
     111           0 :         PixelizeBorders();
     112           1 : }
     113             : 
     114           3 : void SwHTMLWrtTable::Pixelize( sal_uInt16& rValue )
     115             : {
     116           3 :     if( rValue && Application::GetDefaultDevice() )
     117             :     {
     118           2 :         Size aSz( rValue, 0 );
     119           2 :         aSz = Application::GetDefaultDevice()->LogicToPixel( aSz, MapMode(MAP_TWIP) );
     120           2 :         if( !aSz.Width() )
     121           1 :             aSz.Width() = 1;
     122           2 :         aSz = Application::GetDefaultDevice()->PixelToLogic( aSz, MapMode(MAP_TWIP) );
     123           2 :         rValue = (sal_uInt16)aSz.Width();
     124             :     }
     125           3 : }
     126             : 
     127           1 : void SwHTMLWrtTable::PixelizeBorders()
     128             : {
     129           1 :     Pixelize( nBorder );
     130           1 :     Pixelize( nCellSpacing );
     131           1 :     Pixelize( nCellPadding );
     132           1 : }
     133             : 
     134           0 : bool SwHTMLWrtTable::HasTabBackground( const SwTableBox& rBox,
     135             :                         bool bTop, bool bBottom, bool bLeft, bool bRight )
     136             : {
     137             :     OSL_ENSURE( bTop || bBottom || bLeft || bRight,
     138             :             "HasTabBackground: darf nicht aufgerufen werden" );
     139             : 
     140           0 :     bool bRet = false;
     141           0 :     if( rBox.GetSttNd() )
     142             :     {
     143             :         SvxBrushItem aBrushItem =
     144           0 :             rBox.GetFrameFormat()->makeBackgroundBrushItem();
     145             : 
     146             :         /// The table box has a background, if its background color is not "no fill"/
     147             :         /// "auto fill" or it has a background graphic.
     148           0 :         bRet = aBrushItem.GetColor() != COL_TRANSPARENT ||
     149           0 :                !aBrushItem.GetGraphicLink().isEmpty() || aBrushItem.GetGraphic();
     150             :     }
     151             :     else
     152             :     {
     153           0 :         const SwTableLines& rLines = rBox.GetTabLines();
     154           0 :         const SwTableLines::size_type nCount = rLines.size();
     155           0 :         bool bLeftRight = bLeft || bRight;
     156           0 :         for( SwTableLines::size_type i=0; !bRet && i<nCount; ++i )
     157             :         {
     158           0 :             bool bT = bTop && 0 == i;
     159           0 :             bool bB = bBottom && nCount-1 == i;
     160           0 :             if( bT || bB || bLeftRight )
     161           0 :                 bRet = HasTabBackground( *rLines[i], bT, bB, bLeft, bRight);
     162             :         }
     163             :     }
     164             : 
     165           0 :     return bRet;
     166             : }
     167             : 
     168           0 : bool SwHTMLWrtTable::HasTabBackground( const SwTableLine& rLine,
     169             :                         bool bTop, bool bBottom, bool bLeft, bool bRight )
     170             : {
     171             :     OSL_ENSURE( bTop || bBottom || bLeft || bRight,
     172             :             "HasTabBackground: darf nicht aufgerufen werden" );
     173             : 
     174           0 :     SvxBrushItem aBrushItem = rLine.GetFrameFormat()->makeBackgroundBrushItem();
     175             :     /// The table line has a background, if its background color is not "no fill"/
     176             :     /// "auto fill" or it has a background graphic.
     177           0 :     bool bRet = aBrushItem.GetColor() != COL_TRANSPARENT ||
     178           0 :            !aBrushItem.GetGraphicLink().isEmpty() || aBrushItem.GetGraphic();
     179             : 
     180           0 :     if( !bRet )
     181             :     {
     182           0 :         const SwTableBoxes& rBoxes = rLine.GetTabBoxes();
     183           0 :         const SwTableBoxes::size_type nCount = rBoxes.size();
     184           0 :         bool bTopBottom = bTop || bBottom;
     185           0 :         for( SwTableBoxes::size_type i=0; !bRet && i<nCount; ++i )
     186             :         {
     187           0 :             bool bL = bLeft && 0 == i;
     188           0 :             bool bR = bRight && nCount-1 == i;
     189           0 :             if( bTopBottom || bL || bR )
     190           0 :                 bRet = HasTabBackground( *rBoxes[i], bTop, bBottom, bL, bR );
     191             :         }
     192             :     }
     193             : 
     194           0 :     return bRet;
     195             : }
     196             : 
     197             : static bool lcl_TableLine_HasTabBorders( const SwTableLine* pLine, bool *pBorders );
     198             : 
     199           0 : static bool lcl_TableBox_HasTabBorders( const SwTableBox* pBox, bool *pBorders )
     200             : {
     201           0 :     if( *pBorders )
     202           0 :         return false;
     203             : 
     204           0 :     if( !pBox->GetSttNd() )
     205             :     {
     206           0 :         for( SwTableLines::const_iterator it = pBox->GetTabLines().begin();
     207           0 :                  it != pBox->GetTabLines().end(); ++it)
     208             :         {
     209           0 :             if ( lcl_TableLine_HasTabBorders( *it, pBorders ) )
     210           0 :                 break;
     211             :         }
     212             :     }
     213             :     else
     214             :     {
     215             :         const SvxBoxItem& rBoxItem =
     216           0 :             static_cast<const SvxBoxItem&>(pBox->GetFrameFormat()->GetFormatAttr( RES_BOX ));
     217             : 
     218           0 :         *pBorders = rBoxItem.GetTop() || rBoxItem.GetBottom() ||
     219           0 :                     rBoxItem.GetLeft() || rBoxItem.GetRight();
     220             :     }
     221             : 
     222           0 :     return !*pBorders;
     223             : }
     224             : 
     225           0 : static bool lcl_TableLine_HasTabBorders( const SwTableLine* pLine, bool *pBorders )
     226             : {
     227           0 :     if( *pBorders )
     228           0 :         return false;
     229             : 
     230           0 :     for( SwTableBoxes::const_iterator it = pLine->GetTabBoxes().begin();
     231           0 :              it != pLine->GetTabBoxes().end(); ++it)
     232             :     {
     233           0 :         if ( lcl_TableBox_HasTabBorders( *it, pBorders ) )
     234           0 :             break;
     235             :     }
     236           0 :     return !*pBorders;
     237             : }
     238             : 
     239           0 : bool SwHTMLWrtTable::ShouldExpandSub( const SwTableBox *pBox,
     240             :                                       bool bExpandedBefore,
     241             :                                       sal_uInt16 nDepth ) const
     242             : {
     243           0 :     bool bExpand = !pBox->GetSttNd() && nDepth>0;
     244           0 :     if( bExpand && bExpandedBefore )
     245             :     {
     246             :         // MIB 30.6.97: Wenn schon eine Box expandiert wurde, wird eine
     247             :         // weitere nur expandiert, wenn sie Umrandungen besitzt.
     248           0 :         bool bBorders = false;
     249           0 :         lcl_TableBox_HasTabBorders( pBox, &bBorders );
     250           0 :         if( !bBorders )
     251           0 :             bBorders = HasTabBackground( *pBox, true, true, true, true );
     252           0 :         bExpand = bBorders;
     253             :     }
     254             : 
     255           0 :     return bExpand;
     256             : }
     257             : 
     258             : // Eine Box als einzelne Zelle schreiben
     259         261 : void SwHTMLWrtTable::OutTableCell( SwHTMLWriter& rWrt,
     260             :                                    const SwWriteTableCell *pCell,
     261             :                                    bool bOutVAlign ) const
     262             : {
     263         261 :     const SwTableBox *pBox = pCell->GetBox();
     264         261 :     sal_uInt16 nRow = pCell->GetRow();
     265         261 :     sal_uInt16 nCol = pCell->GetCol();
     266         261 :     sal_uInt16 nRowSpan = pCell->GetRowSpan();
     267         261 :     sal_uInt16 nColSpan = pCell->GetColSpan();
     268             : 
     269         261 :     if ( !nRowSpan )
     270         261 :         return;
     271             : 
     272         261 :     SwWriteTableCol *pCol = aCols[nCol];
     273         261 :     bool bOutWidth = true;
     274             : 
     275         261 :     const SwStartNode* pSttNd = pBox->GetSttNd();
     276         261 :     bool bHead = false;
     277         261 :     if( pSttNd )
     278             :     {
     279         261 :         sal_uLong nNdPos = pSttNd->GetIndex()+1;
     280             : 
     281             :         // Art der Zelle (TD/TH) bestimmen
     282             :         SwNode* pNd;
     283         783 :         while( !( pNd = rWrt.pDoc->GetNodes()[nNdPos])->IsEndNode() )
     284             :         {
     285         262 :             if( pNd->IsTextNode() )
     286             :             {
     287             :                 // nur Absaetzte betrachten, an denen man was erkennt
     288             :                 // Das ist der Fall, wenn die Vorlage eine der Tabellen-Vorlagen
     289             :                 // ist oder von einer der beiden abgelitten ist.
     290         262 :                 const SwFormat *pFormat = &static_cast<SwTextNode*>(pNd)->GetAnyFormatColl();
     291         262 :                 sal_uInt16 nPoolId = pFormat->GetPoolFormatId();
     292        2200 :                 while( !pFormat->IsDefault() &&
     293        1205 :                        RES_POOLCOLL_TABLE_HDLN!=nPoolId &&
     294             :                        RES_POOLCOLL_TABLE!=nPoolId )
     295             :                 {
     296         471 :                     pFormat = pFormat->DerivedFrom();
     297         471 :                     nPoolId = pFormat->GetPoolFormatId();
     298             :                 }
     299             : 
     300         262 :                 if( !pFormat->IsDefault() )
     301             :                 {
     302           1 :                     bHead = (RES_POOLCOLL_TABLE_HDLN==nPoolId);
     303           1 :                     break;
     304             :                 }
     305             :             }
     306         261 :             nNdPos++;
     307             :         }
     308             :     }
     309             : 
     310         261 :     rWrt.OutNewLine();  // <TH>/<TD> in neue Zeile
     311         261 :     OStringBuffer sOut;
     312         261 :     sOut.append('<');
     313         261 :     sOut.append(bHead ? OOO_STRING_SVTOOLS_HTML_tableheader : OOO_STRING_SVTOOLS_HTML_tabledata);
     314             : 
     315             :     // ROW- und COLSPAN ausgeben
     316         261 :     if( nRowSpan>1 )
     317             :     {
     318           0 :         sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_rowspan).
     319           0 :             append("=\"").append(static_cast<sal_Int32>(nRowSpan)).append("\"");
     320             :     }
     321         261 :     if( nColSpan > 1 )
     322             :     {
     323           0 :         sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_colspan).
     324           0 :             append("=\"").append(static_cast<sal_Int32>(nColSpan)).append("\"");
     325             :     }
     326             : 
     327         261 :     long nWidth = 0;
     328         261 :     sal_uInt32 nPrcWidth = SAL_MAX_UINT32;
     329         261 :     if( bOutWidth )
     330             :     {
     331         261 :         if( bLayoutExport )
     332             :         {
     333           1 :             if( pCell->HasPrcWidthOpt() )
     334             :             {
     335           1 :                 nPrcWidth = pCell->GetWidthOpt();
     336             :             }
     337             :             else
     338             :             {
     339           0 :                 nWidth = pCell->GetWidthOpt();
     340           0 :                 if( !nWidth )
     341           0 :                     bOutWidth = false;
     342             :             }
     343             :         }
     344             :         else
     345             :         {
     346         260 :             if( HasRelWidths() )
     347         260 :                 nPrcWidth = GetPrcWidth(nCol, nColSpan);
     348             :             else
     349           0 :                 nWidth = GetAbsWidth( nCol, nColSpan );
     350             :         }
     351             :     }
     352             : 
     353         261 :     long nHeight = pCell->GetHeight() > 0
     354           0 :                         ? GetAbsHeight( pCell->GetHeight(), nRow, nRowSpan )
     355         261 :                         : 0;
     356         261 :     Size aPixelSz( nWidth, nHeight );
     357             : 
     358             :     // WIDTH ausgeben (Grrr: nur fuer Netscape)
     359         261 :     if( (aPixelSz.Width() || aPixelSz.Height()) && Application::GetDefaultDevice() )
     360             :     {
     361           0 :         Size aOldSz( aPixelSz );
     362             :         aPixelSz = Application::GetDefaultDevice()->LogicToPixel( aPixelSz,
     363           0 :                                                         MapMode(MAP_TWIP) );
     364           0 :         if( aOldSz.Width() && !aPixelSz.Width() )
     365           0 :             aPixelSz.Width() = 1;
     366           0 :         if( aOldSz.Height() && !aPixelSz.Height() )
     367           0 :             aPixelSz.Height() = 1;
     368             :     }
     369             : 
     370             :     // WIDTH ausgeben: Aus Layout oder berechnet
     371         261 :     if( bOutWidth )
     372             :     {
     373         261 :         sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_width).
     374         261 :             append("=\"");
     375         261 :         if( nPrcWidth != SAL_MAX_UINT32 )
     376             :         {
     377         261 :             sOut.append(static_cast<sal_Int32>(nPrcWidth)).append('%');
     378             :         }
     379             :         else
     380             :         {
     381           0 :             sOut.append(static_cast<sal_Int32>(aPixelSz.Width()));
     382             :         }
     383         261 :         sOut.append("\"");
     384         261 :         if( !bLayoutExport && nColSpan==1 )
     385         260 :             pCol->SetOutWidth( false );
     386             :     }
     387             : 
     388         261 :     if( nHeight )
     389             :     {
     390           0 :         sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_height)
     391           0 :             .append("=\"").append(static_cast<sal_Int32>(aPixelSz.Height())).append("\"");
     392             :     }
     393             : 
     394         261 :     const SfxItemSet& rItemSet = pBox->GetFrameFormat()->GetAttrSet();
     395             :     const SfxPoolItem *pItem;
     396             : 
     397             :     // ALIGN wird jetzt nur noch an den Absaetzen ausgegeben
     398             : 
     399             :     // VALIGN ausgeben
     400         261 :     if( bOutVAlign )
     401             :     {
     402           1 :         sal_Int16 eVertOri = pCell->GetVertOri();
     403           1 :         if( text::VertOrientation::TOP==eVertOri || text::VertOrientation::BOTTOM==eVertOri )
     404             :         {
     405           1 :             sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_valign)
     406           1 :                 .append("=\"").append(text::VertOrientation::TOP==eVertOri ?
     407             :                     OOO_STRING_SVTOOLS_HTML_VA_top :
     408           3 :                     OOO_STRING_SVTOOLS_HTML_VA_bottom)
     409           1 :                 .append("\"");
     410             :         }
     411             :     }
     412             : 
     413         261 :     rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
     414             : 
     415         261 :     rWrt.bTextAttr = false;
     416         261 :     rWrt.bOutOpts = true;
     417         261 :     const SvxBrushItem *pBrushItem = 0;
     418         261 :     if( SfxItemState::SET==rItemSet.GetItemState( RES_BACKGROUND, false, &pItem ) )
     419             :     {
     420         261 :         pBrushItem = static_cast<const SvxBrushItem *>(pItem);
     421             :     }
     422         261 :     if( !pBrushItem )
     423           0 :         pBrushItem = pCell->GetBackground();
     424             : 
     425         261 :     if( pBrushItem )
     426             :     {
     427             :         // Hintergrund ausgeben
     428         261 :         rWrt.OutBackground( pBrushItem, false );
     429             : 
     430         261 :         if( rWrt.bCfgOutStyles )
     431         261 :             OutCSS1_TableBGStyleOpt( rWrt, *pBrushItem );
     432             :     }
     433             : 
     434         261 :     rWrt.OutCSS1_TableCellBorderHack(*pBox->GetFrameFormat());
     435             : 
     436         261 :     sal_uInt32 nNumFormat = 0;
     437         261 :     double nValue = 0.0;
     438         261 :     bool bNumFormat = false, bValue = false;
     439         261 :     if( SfxItemState::SET==rItemSet.GetItemState( RES_BOXATR_FORMAT, false, &pItem ) )
     440             :     {
     441           0 :         nNumFormat = static_cast<const SwTableBoxNumFormat *>(pItem)->GetValue();
     442           0 :         bNumFormat = true;
     443             :     }
     444         261 :     if( SfxItemState::SET==rItemSet.GetItemState( RES_BOXATR_VALUE, false, &pItem ) )
     445             :     {
     446           0 :         nValue = static_cast<const SwTableBoxValue *>(pItem)->GetValue();
     447           0 :         bValue = true;
     448           0 :         if( !bNumFormat )
     449           0 :             nNumFormat = pBox->GetFrameFormat()->GetTableBoxNumFormat().GetValue();
     450             :     }
     451             : 
     452         261 :     if( bNumFormat || bValue )
     453             :     {
     454             :         sOut.append(HTMLOutFuncs::CreateTableDataOptionsValNum(bValue, nValue,
     455           0 :             nNumFormat, *rWrt.pDoc->GetNumberFormatter(), rWrt.eDestEnc,
     456           0 :             &rWrt.aNonConvertableCharacters));
     457             :     }
     458         261 :     sOut.append('>');
     459         261 :     rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
     460         261 :     rWrt.bLFPossible = true;
     461             : 
     462         261 :     rWrt.IncIndentLevel();  // den Inhalt von <TD>...</TD> einruecken
     463             : 
     464         261 :     if( pSttNd )
     465             :     {
     466         261 :         HTMLSaveData aSaveData( rWrt, pSttNd->GetIndex()+1,
     467         522 :                                 pSttNd->EndOfSectionIndex() );
     468         261 :         rWrt.Out_SwDoc( rWrt.pCurPam );
     469             :     }
     470             :     else
     471             :     {
     472             :         sal_uInt16 nTWidth;
     473             :         sal_uInt32 nBWidth;
     474             :         sal_uInt16 nLSub, nRSub;
     475           0 :         if( HasRelWidths() )
     476             :         {
     477           0 :             nTWidth = 100;
     478           0 :             nBWidth = GetRawWidth( nCol, nColSpan );
     479           0 :             nLSub = 0;
     480           0 :             nRSub = 0;
     481             :         }
     482             :         else
     483             :         {
     484           0 :             nTWidth = GetAbsWidth( nCol, nColSpan );
     485           0 :             nBWidth = nTWidth;
     486           0 :             nLSub = GetLeftSpace( nCol );
     487           0 :             nRSub = GetRightSpace( nCol, nColSpan );
     488             :         }
     489             : 
     490           0 :         SwHTMLWrtTable aTableWrt( pBox->GetTabLines(), nTWidth,
     491           0 :                                   nBWidth, HasRelWidths(), nLSub, nRSub );
     492           0 :         aTableWrt.Write( rWrt );
     493             :     }
     494             : 
     495         261 :     rWrt.DecIndentLevel();  // den Inhalt von <TD>...</TD> einruecken
     496             : 
     497         261 :     if( rWrt.bLFPossible )
     498         261 :         rWrt.OutNewLine();
     499         261 :     HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), bHead ? OOO_STRING_SVTOOLS_HTML_tableheader
     500             :                                                      : OOO_STRING_SVTOOLS_HTML_tabledata,
     501         522 :                                 false );
     502         261 :     rWrt.bLFPossible = true;
     503             : }
     504             : 
     505             : // Eine Line als Zeilen ausgeben
     506          53 : void SwHTMLWrtTable::OutTableCells( SwHTMLWriter& rWrt,
     507             :                                     const SwWriteTableCells& rCells,
     508             :                                     const SvxBrushItem *pBrushItem ) const
     509             : {
     510             :     // Wenn die Zeile mehr als eine Zelle nethaelt und alle Zellen
     511             :     // die gleiche Ausrichtung besitzen, das VALIGN an der Zeile statt der
     512             :     // Zelle ausgeben
     513          53 :     sal_Int16 eRowVertOri = text::VertOrientation::NONE;
     514          53 :     if( rCells.size() > 1 )
     515             :     {
     516         312 :         for( SwWriteTableCells::size_type nCell = 0; nCell<rCells.size(); ++nCell )
     517             :         {
     518         260 :             sal_Int16 eCellVertOri = rCells[nCell].GetVertOri();
     519         260 :             if( 0==nCell )
     520             :             {
     521          52 :                 eRowVertOri = eCellVertOri;
     522             :             }
     523         208 :             else if( eRowVertOri != eCellVertOri )
     524             :             {
     525           0 :                 eRowVertOri = text::VertOrientation::NONE;
     526           0 :                 break;
     527             :             }
     528             :         }
     529             :     }
     530             : 
     531          53 :     rWrt.OutNewLine();  // <TR> in neuer Zeile
     532          53 :     rWrt.Strm().WriteChar( '<' ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_tablerow );
     533          53 :     if( pBrushItem )
     534             :     {
     535           0 :         rWrt.OutBackground( pBrushItem, false );
     536             : 
     537           0 :         rWrt.bTextAttr = false;
     538           0 :         rWrt.bOutOpts = true;
     539           0 :         if( rWrt.bCfgOutStyles )
     540           0 :             OutCSS1_TableBGStyleOpt( rWrt, *pBrushItem );
     541             :     }
     542             : 
     543          53 :     if( text::VertOrientation::TOP==eRowVertOri || text::VertOrientation::BOTTOM==eRowVertOri )
     544             :     {
     545          52 :         OStringBuffer sOut;
     546          52 :         sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_valign)
     547         156 :             .append("=\"").append(text::VertOrientation::TOP==eRowVertOri ? OOO_STRING_SVTOOLS_HTML_VA_top : OOO_STRING_SVTOOLS_HTML_VA_bottom)
     548          52 :             .append("\"");
     549          52 :         rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
     550             :     }
     551             : 
     552          53 :     rWrt.Strm().WriteChar( '>' );
     553             : 
     554          53 :     rWrt.IncIndentLevel(); // Inhalt von <TR>...</TR> einruecken
     555             : 
     556         314 :     for( const auto &rCell : rCells )
     557         261 :         OutTableCell( rWrt, &rCell, text::VertOrientation::NONE==eRowVertOri );
     558             : 
     559          53 :     rWrt.DecIndentLevel(); // Inhalt von <TR>...</TR> einruecken
     560             : 
     561          53 :     rWrt.OutNewLine();  // </TR> in neuer Zeile
     562          53 :     HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_tablerow, false );
     563          53 : }
     564             : 
     565           2 : void SwHTMLWrtTable::Write( SwHTMLWriter& rWrt, sal_Int16 eAlign,
     566             :                             bool bTHead, const SwFrameFormat *pFrameFormat,
     567             :                             const OUString *pCaption, bool bTopCaption,
     568             :                             sal_uInt16 nHSpace, sal_uInt16 nVSpace ) const
     569             : {
     570             :     // Wert fuer FRAME bestimmen
     571           2 :     sal_uInt16 nFrameMask = 15;
     572           2 :     if( !(aRows.front())->bTopBorder )
     573           0 :         nFrameMask &= ~1;
     574           2 :     if( !(aRows.back())->bBottomBorder )
     575           0 :         nFrameMask &= ~2;
     576           2 :     if( !(aCols.front())->bLeftBorder )
     577           0 :         nFrameMask &= ~4;
     578           2 :     if( !(aCols.back())->bRightBorder )
     579           0 :         nFrameMask &= ~8;
     580             : 
     581             :     // Wert fur RULES bestimmen
     582           2 :     bool bRowsHaveBorder = false;
     583           2 :     bool bRowsHaveBorderOnly = true;
     584           2 :     SwWriteTableRow *pRow = aRows[0];
     585          53 :     for( SwWriteTableRows::size_type nRow=1; nRow < aRows.size(); ++nRow )
     586             :     {
     587          51 :         SwWriteTableRow *pNextRow = aRows[nRow];
     588          51 :         bool bBorder = ( pRow->bBottomBorder || pNextRow->bTopBorder );
     589          51 :         bRowsHaveBorder |= bBorder;
     590          51 :         bRowsHaveBorderOnly &= bBorder;
     591             : 
     592          51 :         sal_uInt16 nBorder2 = pRow->bBottomBorder ? pRow->nBottomBorder : USHRT_MAX;
     593          51 :         if( pNextRow->bTopBorder && pNextRow->nTopBorder < nBorder2 )
     594           0 :             nBorder2 = pNextRow->nTopBorder;
     595             : 
     596          51 :         pRow->bBottomBorder = bBorder;
     597          51 :         pRow->nBottomBorder = nBorder2;
     598             : 
     599          51 :         pNextRow->bTopBorder = bBorder;
     600          51 :         pNextRow->nTopBorder = nBorder2;
     601             : 
     602          51 :         pRow = pNextRow;
     603             :     }
     604             : 
     605           2 :     bool bColsHaveBorder = false;
     606           2 :     bool bColsHaveBorderOnly = true;
     607           2 :     SwWriteTableCol *pCol = aCols[0];
     608           6 :     for( SwWriteTableCols::size_type nCol=1; nCol<aCols.size(); ++nCol )
     609             :     {
     610           4 :         SwWriteTableCol *pNextCol = aCols[nCol];
     611           4 :         bool bBorder = ( pCol->bRightBorder || pNextCol->bLeftBorder );
     612           4 :         bColsHaveBorder |= bBorder;
     613           4 :         bColsHaveBorderOnly &= bBorder;
     614           4 :         pCol->bRightBorder = bBorder;
     615           4 :         pNextCol->bLeftBorder = bBorder;
     616           4 :         pCol = pNextCol;
     617             :     }
     618             : 
     619             :     // vorhergende Aufzaehlung etc. beenden
     620           2 :     rWrt.ChangeParaToken( 0 );
     621             : 
     622           2 :     if( rWrt.bLFPossible )
     623           2 :         rWrt.OutNewLine();  // <TABLE> in neue Zeile
     624           2 :     OStringBuffer sOut;
     625           2 :     sOut.append('<').append(OOO_STRING_SVTOOLS_HTML_table);
     626             : 
     627           2 :     const sal_uInt16 nOldDirection = rWrt.nDirection;
     628           2 :     if( pFrameFormat )
     629           2 :         rWrt.nDirection = rWrt.GetHTMLDirection( pFrameFormat->GetAttrSet() );
     630           2 :     if( rWrt.bOutFlyFrame || nOldDirection != rWrt.nDirection )
     631             :     {
     632           0 :         rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
     633           0 :         rWrt.OutDirection( rWrt.nDirection );
     634             :     }
     635             : 
     636             :     // ALIGN= ausgeben
     637           2 :     if( text::HoriOrientation::RIGHT == eAlign )
     638             :     {
     639           0 :         sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_align).
     640           0 :             append("=\"").append(OOO_STRING_SVTOOLS_HTML_AL_right).append("\"");
     641             :     }
     642           2 :     else if( text::HoriOrientation::CENTER == eAlign )
     643             :     {
     644           0 :         sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_align).
     645           0 :             append("=\"").append(OOO_STRING_SVTOOLS_HTML_AL_center).append("\"");
     646             :     }
     647           2 :     else if( text::HoriOrientation::LEFT == eAlign )
     648             :     {
     649           0 :         sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_align).
     650           0 :             append("=\"").append(OOO_STRING_SVTOOLS_HTML_AL_left).append("\"");
     651             :     }
     652             : 
     653             :     // WIDTH ausgeben: Stammt aus Layout oder ist berechnet
     654           2 :     if( nTabWidth )
     655             :     {
     656           2 :         sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_width).
     657           2 :             append("=\"");
     658           2 :         if( HasRelWidths() )
     659           2 :             sOut.append(static_cast<sal_Int32>(nTabWidth)).append('%');
     660           0 :         else if( Application::GetDefaultDevice() )
     661             :         {
     662             :             sal_Int32 nPixWidth = Application::GetDefaultDevice()->LogicToPixel(
     663           0 :                         Size(nTabWidth,0), MapMode(MAP_TWIP) ).Width();
     664           0 :             if( !nPixWidth )
     665           0 :                 nPixWidth = 1;
     666             : 
     667           0 :             sOut.append(nPixWidth);
     668             :         }
     669             :         else
     670             :         {
     671             :             OSL_ENSURE( Application::GetDefaultDevice(), "kein Application-Window!?" );
     672           0 :             sOut.append("100%");
     673             :         }
     674           2 :         sOut.append("\"");
     675             :     }
     676             : 
     677           2 :     if( (nHSpace || nVSpace) && Application::GetDefaultDevice())
     678             :     {
     679             :         Size aPixelSpc =
     680             :             Application::GetDefaultDevice()->LogicToPixel( Size(nHSpace,nVSpace),
     681           0 :                                                    MapMode(MAP_TWIP) );
     682           0 :         if( !aPixelSpc.Width() && nHSpace )
     683           0 :             aPixelSpc.Width() = 1;
     684           0 :         if( !aPixelSpc.Height() && nVSpace )
     685           0 :             aPixelSpc.Height() = 1;
     686             : 
     687           0 :         if( aPixelSpc.Width() )
     688             :         {
     689           0 :             sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_hspace).
     690           0 :                 append("=\"").append(static_cast<sal_Int32>(aPixelSpc.Width())).append("\"");
     691             :         }
     692             : 
     693           0 :         if( aPixelSpc.Height() )
     694             :         {
     695           0 :             sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_vspace).
     696           0 :                 append("=\"").append(static_cast<sal_Int32>(aPixelSpc.Height())).append("\"");
     697             :         }
     698             :     }
     699             : 
     700             :     // CELLPADDING ausgeben: Stammt aus Layout oder ist berechnet
     701           2 :     sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_cellpadding).
     702           4 :         append("=\"").append(static_cast<sal_Int32>(SwHTMLWriter::ToPixel(nCellPadding,false))).append("\"");
     703             : 
     704             :     // CELLSPACING ausgeben: Stammt aus Layout oder ist berechnet
     705           2 :     sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_cellspacing).
     706           4 :         append("=\"").append(static_cast<sal_Int32>(SwHTMLWriter::ToPixel(nCellSpacing,false))).append("\"");
     707             : 
     708           2 :     rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
     709             : 
     710             :     // Hintergrund ausgeben
     711           2 :     if( pFrameFormat )
     712             :     {
     713           2 :         rWrt.OutBackground( pFrameFormat->GetAttrSet(), false );
     714             : 
     715           2 :         if( rWrt.bCfgOutStyles && pFrameFormat )
     716           2 :             rWrt.OutCSS1_TableFrameFormatOptions( *pFrameFormat );
     717             :     }
     718             : 
     719           2 :     sOut.append('>');
     720           2 :     rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
     721             : 
     722           2 :     rWrt.IncIndentLevel(); // Inhalte von Table einruecken
     723             : 
     724             :     // Ueberschrift ausgeben
     725           2 :     if( pCaption && !pCaption->isEmpty() )
     726             :     {
     727           0 :         rWrt.OutNewLine(); // <CAPTION> in neue Zeile
     728           0 :         OStringBuffer sOutStr(OOO_STRING_SVTOOLS_HTML_caption);
     729           0 :         sOutStr.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_align).append("=\"")
     730           0 :                .append(bTopCaption ? OOO_STRING_SVTOOLS_HTML_VA_top : OOO_STRING_SVTOOLS_HTML_VA_bottom)
     731           0 :                .append("\"");
     732           0 :         HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), sOutStr.getStr(), true );
     733           0 :         HTMLOutFuncs::Out_String( rWrt.Strm(), *pCaption, rWrt.eDestEnc, &rWrt.aNonConvertableCharacters );
     734           0 :         HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_caption, false );
     735             :     }
     736             : 
     737           2 :     const SwWriteTableCols::size_type nCols = aCols.size();
     738             : 
     739             :     // <COLGRP>/<COL> ausgeben: Bei Export ueber Layout nur wenn beim
     740             :     // Import welche da waren, sonst immer.
     741           2 :     bool bColGroups = (bColsHaveBorder && !bColsHaveBorderOnly);
     742           2 :     if( bColTags )
     743             :     {
     744           2 :         if( bColGroups )
     745             :         {
     746           0 :             rWrt.OutNewLine(); // <COLGRP> in neue Zeile
     747           0 :             HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_colgroup, true );
     748             : 
     749           0 :             rWrt.IncIndentLevel(); // Inhalt von <COLGRP> einruecken
     750             :         }
     751             : 
     752           8 :         for( SwWriteTableCols::size_type nCol=0; nCol<nCols; ++nCol )
     753             :         {
     754           6 :             rWrt.OutNewLine(); // <COL> in neue Zeile
     755             : 
     756           6 :             const SwWriteTableCol *pColumn = aCols[nCol];
     757             : 
     758           6 :             OStringBuffer sOutStr;
     759           6 :             sOutStr.append('<').append(OOO_STRING_SVTOOLS_HTML_col);
     760             : 
     761             :             sal_uInt32 nWidth;
     762             :             bool bRel;
     763           6 :             if( bLayoutExport )
     764             :             {
     765           1 :                 bRel = pColumn->HasRelWidthOpt();
     766           1 :                 nWidth = pColumn->GetWidthOpt();
     767             :             }
     768             :             else
     769             :             {
     770           5 :                 bRel = HasRelWidths();
     771           5 :                 nWidth = bRel ? GetRelWidth(nCol,1) : GetAbsWidth(nCol,1);
     772             :             }
     773             : 
     774           6 :             sOutStr.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_width).
     775           6 :                 append("=\"");
     776           6 :             if( bRel )
     777           6 :                 sOutStr.append(static_cast<sal_Int32>(nWidth)).append('*');
     778             :             else
     779           0 :                 sOutStr.append(static_cast<sal_Int32>(SwHTMLWriter::ToPixel(nWidth,false)));
     780           6 :             sOutStr.append("\">");
     781           6 :             rWrt.Strm().WriteCharPtr( sOutStr.makeStringAndClear().getStr() );
     782             : 
     783           6 :             if( bColGroups && pColumn->bRightBorder && nCol<nCols-1 )
     784             :             {
     785           0 :                 rWrt.DecIndentLevel(); // Inhalt von <COLGRP> einruecken
     786           0 :                 rWrt.OutNewLine(); // </COLGRP> in neue Zeile
     787           0 :                 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_colgroup,
     788           0 :                                             false );
     789           0 :                 rWrt.OutNewLine(); // <COLGRP> in neue Zeile
     790           0 :                 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_colgroup,
     791           0 :                                             true );
     792           0 :                 rWrt.IncIndentLevel(); // Inhalt von <COLGRP> einruecken
     793             :             }
     794           6 :         }
     795           2 :         if( bColGroups )
     796             :         {
     797           0 :             rWrt.DecIndentLevel(); // Inhalt von <COLGRP> einruecken
     798             : 
     799           0 :             rWrt.OutNewLine(); // </COLGRP> in neue Zeile
     800           0 :             HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_colgroup,
     801           0 :                                         false );
     802             :         }
     803             :     }
     804             : 
     805             :     // die Lines als Tabellenzeilen rausschreiben
     806             : 
     807             :     // <TBODY> ausgeben?
     808           2 :     bool bTSections = (bRowsHaveBorder && !bRowsHaveBorderOnly);
     809           2 :     bool bTBody = bTSections;
     810             : 
     811             :     // Wenn Sections ausgegeben werden muessen darf ein THEAD um die erste
     812             :     // Zeile nur ausgegeben werden, wenn unter der Zeile eine Linie ist
     813           2 :     if( bTHead &&
     814           0 :         (bTSections || bColGroups) &&
     815           2 :         nHeadEndRow<aRows.size()-1 && !aRows[nHeadEndRow]->bBottomBorder )
     816           0 :         bTHead = false;
     817             : 
     818             :     // <TBODY> aus ausgeben, wenn <THEAD> ausgegeben wird.
     819           2 :     bTSections |= bTHead;
     820             : 
     821           2 :     if( bTSections )
     822             :     {
     823           0 :         rWrt.OutNewLine(); // <THEAD>/<TDATA> in neue Zeile
     824           0 :         HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(),
     825           0 :                             bTHead ? OOO_STRING_SVTOOLS_HTML_thead : OOO_STRING_SVTOOLS_HTML_tbody, true );
     826             : 
     827           0 :         rWrt.IncIndentLevel(); // Inhalt von <THEAD>/<TDATA> einr.
     828             :     }
     829             : 
     830          55 :     for( SwWriteTableRows::size_type nRow = 0; nRow < aRows.size(); ++nRow )
     831             :     {
     832          53 :         const SwWriteTableRow *pRow2 = aRows[nRow];
     833             : 
     834          53 :         OutTableCells( rWrt, pRow2->GetCells(), pRow2->GetBackground() );
     835         104 :         if( !nCellSpacing && nRow < aRows.size()-1 && pRow2->bBottomBorder &&
     836          51 :             pRow2->nBottomBorder > DEF_LINE_WIDTH_1 )
     837             :         {
     838           0 :             for( auto nCnt = (pRow2->nBottomBorder / DEF_LINE_WIDTH_1) - 1; nCnt; --nCnt )
     839             :             {
     840           0 :                 rWrt.OutNewLine();
     841           0 :                 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_tablerow,
     842           0 :                                             true );
     843           0 :                 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_tablerow,
     844           0 :                                             false );
     845             :             }
     846             :         }
     847          53 :         if( ( (bTHead && nRow==nHeadEndRow) ||
     848          53 :               (bTBody && pRow2->bBottomBorder) ) &&
     849           0 :             nRow < aRows.size()-1 )
     850             :         {
     851           0 :             rWrt.DecIndentLevel(); // Inhalt von <THEAD>/<TDATA> einr.
     852           0 :             rWrt.OutNewLine(); // </THEAD>/</TDATA> in neue Zeile
     853           0 :             HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(),
     854           0 :                             bTHead ? OOO_STRING_SVTOOLS_HTML_thead : OOO_STRING_SVTOOLS_HTML_tbody, false );
     855           0 :             rWrt.OutNewLine(); // <THEAD>/<TDATA> in neue Zeile
     856             : 
     857           0 :             if( bTHead && nRow==nHeadEndRow )
     858           0 :                 bTHead = false;
     859             : 
     860           0 :             HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(),
     861           0 :                             bTHead ? OOO_STRING_SVTOOLS_HTML_thead : OOO_STRING_SVTOOLS_HTML_tbody, true );
     862           0 :             rWrt.IncIndentLevel(); // Inhalt von <THEAD>/<TDATA> einr.
     863             :         }
     864             :     }
     865             : 
     866           2 :     if( bTSections )
     867             :     {
     868           0 :         rWrt.DecIndentLevel(); // Inhalt von <THEAD>/<TDATA> einr.
     869             : 
     870           0 :         rWrt.OutNewLine(); // </THEAD>/</TDATA> in neue Zeile
     871           0 :         HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(),
     872           0 :                             bTHead ? OOO_STRING_SVTOOLS_HTML_thead : OOO_STRING_SVTOOLS_HTML_tbody, false );
     873             :     }
     874             : 
     875           2 :     rWrt.DecIndentLevel(); // Inhalt von <TABLE> einr.
     876             : 
     877           2 :     rWrt.OutNewLine(); // </TABLE> in neue Zeile
     878           2 :     HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_table, false );
     879             : 
     880           2 :     rWrt.nDirection = nOldDirection;
     881           2 : }
     882             : 
     883           2 : Writer& OutHTML_SwTableNode( Writer& rWrt, SwTableNode & rNode,
     884             :                            const SwFrameFormat *pFlyFrameFormat,
     885             :                            const OUString *pCaption, bool bTopCaption )
     886             : {
     887             : 
     888           2 :     SwTable& rTable = rNode.GetTable();
     889             : 
     890           2 :     SwHTMLWriter & rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
     891           2 :     rHTMLWrt.bOutTable = true;
     892             : 
     893             :     // die horizontale Ausrichtung des Rahmens hat (falls vorhanden)
     894             :     // Prioritaet. NONE bedeutet, dass keine horizontale
     895             :     // Ausrichtung geschrieben wird.
     896           2 :     sal_Int16 eFlyHoriOri = text::HoriOrientation::NONE;
     897           2 :     SwSurround eSurround = SURROUND_NONE;
     898           2 :     sal_uInt8 nFlyPrcWidth = 0;
     899           2 :     long nFlyWidth = 0;
     900           2 :     sal_uInt16 nFlyHSpace = 0;
     901           2 :     sal_uInt16 nFlyVSpace = 0;
     902           2 :     if( pFlyFrameFormat )
     903             :     {
     904           0 :         eSurround = pFlyFrameFormat->GetSurround().GetSurround();
     905           0 :         const SwFormatFrmSize& rFrmSize = pFlyFrameFormat->GetFrmSize();
     906           0 :         nFlyPrcWidth = rFrmSize.GetWidthPercent();
     907           0 :         nFlyWidth = rFrmSize.GetSize().Width();
     908             : 
     909           0 :         eFlyHoriOri = pFlyFrameFormat->GetHoriOrient().GetHoriOrient();
     910           0 :         if( text::HoriOrientation::NONE == eFlyHoriOri )
     911           0 :             eFlyHoriOri = text::HoriOrientation::LEFT;
     912             : 
     913           0 :         const SvxLRSpaceItem& rLRSpace = pFlyFrameFormat->GetLRSpace();
     914           0 :         nFlyHSpace = static_cast< sal_uInt16 >((rLRSpace.GetLeft() + rLRSpace.GetRight()) / 2);
     915             : 
     916           0 :         const SvxULSpaceItem& rULSpace = pFlyFrameFormat->GetULSpace();
     917           0 :         nFlyVSpace = (rULSpace.GetUpper() + rULSpace.GetLower()) / 2;
     918             :     }
     919             : 
     920             :     // ggf. eine FORM oeffnen
     921           2 :     bool bPreserveForm = false;
     922           2 :     if( !rHTMLWrt.bPreserveForm )
     923             :     {
     924           2 :         rHTMLWrt.OutForm( true, &rNode );
     925           2 :         bPreserveForm = (rHTMLWrt.pxFormComps && rHTMLWrt.pxFormComps->is() );
     926           2 :         rHTMLWrt.bPreserveForm = bPreserveForm;
     927             :     }
     928             : 
     929           2 :     SwFrameFormat *pFormat = rTable.GetFrameFormat();
     930             : 
     931           2 :     const SwFormatFrmSize& rFrmSize = pFormat->GetFrmSize();
     932           2 :     long nWidth = rFrmSize.GetSize().Width();
     933           2 :     sal_uInt8 nPrcWidth = rFrmSize.GetWidthPercent();
     934           2 :     sal_uInt16 nBaseWidth = (sal_uInt16)nWidth;
     935             : 
     936           2 :     sal_Int16 eTabHoriOri = pFormat->GetHoriOrient().GetHoriOrient();
     937             : 
     938             :     // text::HoriOrientation::NONE und text::HoriOrientation::FULL Tabellen benoetigen relative Breiten
     939           2 :     sal_uInt16 nNewDefListLvl = 0;
     940           2 :     bool bRelWidths = false;
     941           2 :     bool bCheckDefList = false;
     942           2 :     switch( eTabHoriOri )
     943             :     {
     944             :     case text::HoriOrientation::FULL:
     945             :         // Tabellen mit automatischer Ausrichtung werden zu Tabellen
     946             :         // mit 100%-Breite
     947           0 :         bRelWidths = true;
     948           0 :         nWidth = 100;
     949           0 :         eTabHoriOri = text::HoriOrientation::LEFT;
     950           0 :         break;
     951             :     case text::HoriOrientation::NONE:
     952             :         {
     953           0 :             const SvxLRSpaceItem& aLRItem = pFormat->GetLRSpace();
     954           0 :             if( aLRItem.GetRight() )
     955             :             {
     956             :                 // Die Tabellenbreite wird anhand des linken und rechten
     957             :                 // Abstandes bestimmt. Deshalb versuchen wir die
     958             :                 // tatsaechliche Breite der Tabelle zu bestimmen. Wenn
     959             :                 // das nicht geht, machen wir eine 100% breite Tabelle
     960             :                 // draus.
     961           0 :                 nWidth = pFormat->FindLayoutRect(true).Width();
     962           0 :                 if( !nWidth )
     963             :                 {
     964           0 :                     bRelWidths = true;
     965           0 :                     nWidth = 100;
     966             :                 }
     967             : 
     968             :             }
     969           0 :             else if( nPrcWidth  )
     970             :             {
     971             :                 // Ohne rechten Rand bleibt die %-Breite erhalten
     972           0 :                 nWidth = nPrcWidth;
     973           0 :                 bRelWidths = true;
     974             :             }
     975             :             else
     976             :             {
     977             :                 // Ohne rechten Rand bleibt auch eine absolute Breite erhalten
     978             :                 // Wir versuchen aber trotzdem ueber das Layout die
     979             :                 // tatsachliche Breite zu ermitteln.
     980           0 :                 long nRealWidth = pFormat->FindLayoutRect(true).Width();
     981           0 :                 if( nRealWidth )
     982           0 :                     nWidth = nRealWidth;
     983             :             }
     984           0 :             bCheckDefList = true;
     985             :         }
     986           0 :         break;
     987             :     case text::HoriOrientation::LEFT_AND_WIDTH:
     988           1 :         eTabHoriOri = text::HoriOrientation::LEFT;
     989           1 :         bCheckDefList = true;
     990             :         // no break
     991             :     default:
     992             :         // In allen anderen Faellen kann eine absolute oder relative
     993             :         // Breite direkt uebernommen werden.
     994           2 :         if( nPrcWidth )
     995             :         {
     996           2 :             bRelWidths = true;
     997           2 :             nWidth = nPrcWidth;
     998             :         }
     999           2 :         break;
    1000             :     }
    1001             : 
    1002           2 :     if( bCheckDefList )
    1003             :     {
    1004             :         OSL_ENSURE( !rHTMLWrt.GetNumInfo().GetNumRule() ||
    1005             :                 rHTMLWrt.GetNextNumInfo(),
    1006             :                 "NumInfo fuer naechsten Absatz fehlt!" );
    1007           1 :         const SvxLRSpaceItem& aLRItem = pFormat->GetLRSpace();
    1008           1 :         if( aLRItem.GetLeft() > 0 && rHTMLWrt.nDefListMargin > 0 &&
    1009           0 :             ( !rHTMLWrt.GetNumInfo().GetNumRule() ||
    1010           0 :               ( rHTMLWrt.GetNextNumInfo() &&
    1011           0 :                 (rHTMLWrt.GetNextNumInfo()->IsRestart() ||
    1012           0 :                  rHTMLWrt.GetNumInfo().GetNumRule() !=
    1013           0 :                     rHTMLWrt.GetNextNumInfo()->GetNumRule()) ) ) )
    1014             :         {
    1015             :             // Wenn der Absatz vor der Tabelle nicht numeriert ist oder
    1016             :             // der Absatz nach der Tabelle mit einer anderen oder
    1017             :             // (gar keiner) Regel numeriert ist, koennen wir
    1018             :             // die Einrueckung ueber eine DL regeln. Sonst behalten wir
    1019             :             // die Einrueckung der Numerierung bei.
    1020             :             nNewDefListLvl = static_cast< sal_uInt16 >(
    1021           0 :                 (aLRItem.GetLeft() + (rHTMLWrt.nDefListMargin/2)) /
    1022           0 :                 rHTMLWrt.nDefListMargin );
    1023             :         }
    1024             :     }
    1025             : 
    1026           2 :     if( !pFlyFrameFormat && nNewDefListLvl != rHTMLWrt.nDefListLvl )
    1027           0 :         rHTMLWrt.OutAndSetDefList( nNewDefListLvl );
    1028             : 
    1029           2 :     if( nNewDefListLvl )
    1030             :     {
    1031           0 :         if( rHTMLWrt.bLFPossible )
    1032           0 :             rHTMLWrt.OutNewLine();
    1033           0 :         HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_dd );
    1034             :     }
    1035             : 
    1036             :     // eFlyHoriOri und eTabHoriOri besitzen nun nur noch die Werte
    1037             :     // LEFT/CENTER und RIGHT!
    1038           2 :     if( eFlyHoriOri!=text::HoriOrientation::NONE )
    1039             :     {
    1040           0 :         eTabHoriOri = eFlyHoriOri;
    1041             :         // MIB 4.7.97: Wenn die Tabelle eine relative Breite besitzt,
    1042             :         // dann richtet sich ihre Breite nach der des Rahmens, also
    1043             :         // exportieren wir dessen Breite. Bei fixer Breite ist die Breite
    1044             :         // der Tabelle massgeblich. Wer Tabellen mit relativer Breite <100%
    1045             :         // in Rahmen steckt, ist selber schuld wenn nix Gutes bei rauskommt.
    1046           0 :         if( bRelWidths )
    1047             :         {
    1048           0 :             nWidth = nFlyPrcWidth ? nFlyPrcWidth : nFlyWidth;
    1049           0 :             bRelWidths = nFlyPrcWidth > 0;
    1050             :         }
    1051             :     }
    1052             : 
    1053           2 :     sal_Int16 eDivHoriOri = text::HoriOrientation::NONE;
    1054           2 :     switch( eTabHoriOri )
    1055             :     {
    1056             :     case text::HoriOrientation::LEFT:
    1057             :         // Wenn eine linksbuendigeTabelle keinen rechtsseiigen Durchlauf
    1058             :         // hat, brauchen wir auch kein ALIGN=LEFT in der Tabelle.
    1059           2 :         if( eSurround==SURROUND_NONE || eSurround==SURROUND_LEFT )
    1060           2 :             eTabHoriOri = text::HoriOrientation::NONE;
    1061           2 :         break;
    1062             :     case text::HoriOrientation::RIGHT:
    1063             :         // Aehnliches gilt fuer rechtsbuendigeTabelle, hier nehmen wir
    1064             :         // stattdessen ein <DIV ALIGN=RIGHT>.
    1065           0 :         if( eSurround==SURROUND_NONE || eSurround==SURROUND_RIGHT )
    1066             :         {
    1067           0 :             eDivHoriOri = text::HoriOrientation::RIGHT;
    1068           0 :             eTabHoriOri = text::HoriOrientation::NONE;
    1069             :         }
    1070           0 :         break;
    1071             :     case text::HoriOrientation::CENTER:
    1072             :         // ALIGN=CENTER versteht so gut wie keiner, deshalb verzichten wir
    1073             :         // daruf und nehmen ein <CENTER>.
    1074           0 :         eDivHoriOri = text::HoriOrientation::CENTER;
    1075           0 :         eTabHoriOri = text::HoriOrientation::NONE;
    1076           0 :         break;
    1077             :     default:
    1078             :         ;
    1079             :     }
    1080           2 :     if( text::HoriOrientation::NONE==eTabHoriOri )
    1081           2 :         nFlyHSpace = nFlyVSpace = 0;
    1082             : 
    1083           2 :     if( !pFormat->GetName().isEmpty() )
    1084           2 :         rHTMLWrt.OutImplicitMark( pFormat->GetName(), "table" );
    1085             : 
    1086           2 :     if( text::HoriOrientation::NONE!=eDivHoriOri )
    1087             :     {
    1088           0 :         if( rHTMLWrt.bLFPossible )
    1089           0 :             rHTMLWrt.OutNewLine();  // <CENTER> in neuer Zeile
    1090           0 :         if( text::HoriOrientation::CENTER==eDivHoriOri )
    1091           0 :             HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_center, true );
    1092             :         else
    1093             :         {
    1094           0 :             OStringBuffer sOut(OOO_STRING_SVTOOLS_HTML_division);
    1095           0 :             sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_align).append("=\"")
    1096           0 :                 .append(OOO_STRING_SVTOOLS_HTML_AL_right).append("\"");
    1097           0 :             HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), sOut.getStr(), true );
    1098             :         }
    1099           0 :         rHTMLWrt.IncIndentLevel();  // Inhalt von <CENTER> einruecken
    1100           0 :         rHTMLWrt.bLFPossible = true;
    1101             :     }
    1102             : 
    1103             :     // Wenn die Tabelle in keinem Rahmen ist kann man immer ein LF ausgeben.
    1104           2 :     if( text::HoriOrientation::NONE==eTabHoriOri )
    1105           2 :         rHTMLWrt.bLFPossible = true;
    1106             : 
    1107           2 :     const SwHTMLTableLayout *pLayout = rTable.GetHTMLTableLayout();
    1108             : 
    1109             : #ifdef DBG_UTIL
    1110             :     {
    1111             :     SwViewShell *pSh = rWrt.pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
    1112             :     if ( pSh && pSh->GetViewOptions()->IsTest1() )
    1113             :         pLayout = 0;
    1114             :     }
    1115             : #endif
    1116             : 
    1117           2 :     if( pLayout && pLayout->IsExportable() )
    1118             :     {
    1119           1 :         SwHTMLWrtTable aTableWrt( pLayout );
    1120           1 :         aTableWrt.Write( rHTMLWrt, eTabHoriOri, rTable.GetRowsToRepeat() > 0,
    1121             :                          pFormat, pCaption, bTopCaption,
    1122           2 :                          nFlyHSpace, nFlyVSpace );
    1123             :     }
    1124             :     else
    1125             :     {
    1126           1 :         SwHTMLWrtTable aTableWrt( rTable.GetTabLines(), nWidth,
    1127           2 :                                   nBaseWidth, bRelWidths, 0, 0, rTable.GetRowsToRepeat() );
    1128           1 :         aTableWrt.Write( rHTMLWrt, eTabHoriOri, rTable.GetRowsToRepeat() > 0,
    1129             :                          pFormat, pCaption, bTopCaption,
    1130           2 :                          nFlyHSpace, nFlyVSpace );
    1131             :     }
    1132             : 
    1133             :     // Wenn die Tabelle in keinem Rahmen war kann man immer ein LF ausgeben.
    1134           2 :     if( text::HoriOrientation::NONE==eTabHoriOri )
    1135           2 :         rHTMLWrt.bLFPossible = true;
    1136             : 
    1137           2 :     if( text::HoriOrientation::NONE!=eDivHoriOri )
    1138             :     {
    1139           0 :         rHTMLWrt.DecIndentLevel();  // Inhalt von <CENTER> einruecken
    1140           0 :         rHTMLWrt.OutNewLine();      // </CENTER> in neue Teile
    1141           0 :         HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(),
    1142             :                                text::HoriOrientation::CENTER==eDivHoriOri ? OOO_STRING_SVTOOLS_HTML_center
    1143           0 :                                                         : OOO_STRING_SVTOOLS_HTML_division, false );
    1144           0 :         rHTMLWrt.bLFPossible = true;
    1145             :     }
    1146             : 
    1147             :     // Pam hinter die Tabelle verschieben
    1148           2 :     rHTMLWrt.pCurPam->GetPoint()->nNode = *rNode.EndOfSectionNode();
    1149             : 
    1150           2 :     if( bPreserveForm )
    1151             :     {
    1152           0 :         rHTMLWrt.bPreserveForm = false;
    1153           0 :         rHTMLWrt.OutForm( false );
    1154             :     }
    1155             : 
    1156           2 :     rHTMLWrt.bOutTable = false;
    1157             : 
    1158           4 :     if( rHTMLWrt.GetNextNumInfo() &&
    1159           2 :         !rHTMLWrt.GetNextNumInfo()->IsRestart() &&
    1160           0 :         rHTMLWrt.GetNextNumInfo()->GetNumRule() ==
    1161           0 :             rHTMLWrt.GetNumInfo().GetNumRule() )
    1162             :     {
    1163             :         // Wenn der Absatz hinter der Tabelle mit der gleichen Regel
    1164             :         // numeriert ist wie der Absatz vor der Tabelle, dann steht in
    1165             :         // der NumInfo des naechsten Absatzes noch die Ebene des Absatzes
    1166             :         // vor der Tabelle. Es muss deshalb die NumInfo noch einmal geholt
    1167             :         // werden um ggf. die Num-Liste noch zu beenden.
    1168           0 :         rHTMLWrt.ClearNextNumInfo();
    1169           0 :         rHTMLWrt.FillNextNumInfo();
    1170           0 :         OutHTML_NumBulListEnd( rHTMLWrt, *rHTMLWrt.GetNextNumInfo() );
    1171             :     }
    1172           2 :     return rWrt;
    1173         177 : }
    1174             : 
    1175             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11