LCOV - code coverage report
Current view: top level - sw/source/filter/html - htmltabw.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 297 576 51.6 %
Date: 2014-11-03 Functions: 10 17 58.8 %
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             :     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             :     SwHTMLWrtTable( const SwHTMLTableLayout *pLayoutInfo );
      90             : 
      91             :     void Write( SwHTMLWriter& rWrt, sal_Int16 eAlign=text::HoriOrientation::NONE,
      92             :                 bool bTHead=false, const SwFrmFmt *pFrmFmt=0,
      93             :                 const OUString *pCaption=0, bool bTopCaption=false,
      94             :                 sal_uInt16 nHSpace=0, sal_uInt16 nVSpace=0 ) const;
      95             : };
      96             : 
      97           2 : 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           2 :     : SwWriteTable( rLines, nWidth, nBWidth, bRel, MAX_DEPTH, nLSub, nRSub, nNumOfRowsToRepeat )
     102             : {
     103           2 :     PixelizeBorders();
     104           2 : }
     105             : 
     106           0 : SwHTMLWrtTable::SwHTMLWrtTable( const SwHTMLTableLayout *pLayoutInfo )
     107           0 :     : SwWriteTable( pLayoutInfo )
     108             : {
     109             :     // Einige Twip-Werte an Pixel-Grenzen anpassen
     110           0 :     if( bCollectBorderWidth )
     111           0 :         PixelizeBorders();
     112           0 : }
     113             : 
     114           6 : void SwHTMLWrtTable::Pixelize( sal_uInt16& rValue )
     115             : {
     116           6 :     if( rValue && Application::GetDefaultDevice() )
     117             :     {
     118           4 :         Size aSz( rValue, 0 );
     119           4 :         aSz = Application::GetDefaultDevice()->LogicToPixel( aSz, MapMode(MAP_TWIP) );
     120           4 :         if( !aSz.Width() )
     121           2 :             aSz.Width() = 1;
     122           4 :         aSz = Application::GetDefaultDevice()->PixelToLogic( aSz, MapMode(MAP_TWIP) );
     123           4 :         rValue = (sal_uInt16)aSz.Width();
     124             :     }
     125           6 : }
     126             : 
     127           2 : void SwHTMLWrtTable::PixelizeBorders()
     128             : {
     129           2 :     Pixelize( nBorder );
     130           2 :     Pixelize( nCellSpacing );
     131           2 :     Pixelize( nCellPadding );
     132           2 : }
     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.GetFrmFmt()->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 :         sal_uInt16 nCount = rLines.size();
     155           0 :         bool bLeftRight = bLeft || bRight;
     156           0 :         for( sal_uInt16 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.GetFrmFmt()->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 :         sal_uInt16 nCount = rBoxes.size();
     184           0 :         bool bTopBottom = bTop || bBottom;
     185           0 :         for( sal_uInt16 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, sal_Bool *pBorders );
     198             : 
     199           0 : static bool lcl_TableBox_HasTabBorders( const SwTableBox* pBox, sal_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 :             (const SvxBoxItem&)pBox->GetFrmFmt()->GetFmtAttr( 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, sal_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 :         sal_Bool bBorders = sal_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         520 : void SwHTMLWrtTable::OutTableCell( SwHTMLWriter& rWrt,
     260             :                                    const SwWriteTableCell *pCell,
     261             :                                    bool bOutVAlign ) const
     262             : {
     263         520 :     const SwTableBox *pBox = pCell->GetBox();
     264         520 :     sal_uInt16 nRow = pCell->GetRow();
     265         520 :     sal_uInt16 nCol = pCell->GetCol();
     266         520 :     sal_uInt16 nRowSpan = pCell->GetRowSpan();
     267         520 :     sal_uInt16 nColSpan = pCell->GetColSpan();
     268             : 
     269         520 :     if ( !nRowSpan )
     270         520 :         return;
     271             : 
     272         520 :     SwWriteTableCol *pCol = aCols[nCol];
     273         520 :     bool bOutWidth = true;
     274             : 
     275         520 :     const SwStartNode* pSttNd = pBox->GetSttNd();
     276         520 :     bool bHead = false;
     277         520 :     if( pSttNd )
     278             :     {
     279         520 :         sal_uLong nNdPos = pSttNd->GetIndex()+1;
     280             : 
     281             :         // Art der Zelle (TD/TH) bestimmen
     282             :         SwNode* pNd;
     283        1562 :         while( !( pNd = rWrt.pDoc->GetNodes()[nNdPos])->IsEndNode() )
     284             :         {
     285         522 :             if( pNd->IsTxtNode() )
     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         522 :                 const SwFmt *pFmt = &((SwTxtNode*)pNd)->GetAnyFmtColl();
     291         522 :                 sal_uInt16 nPoolId = pFmt->GetPoolFmtId();
     292        4392 :                 while( !pFmt->IsDefault() &&
     293        2406 :                        RES_POOLCOLL_TABLE_HDLN!=nPoolId &&
     294             :                        RES_POOLCOLL_TABLE!=nPoolId )
     295             :                 {
     296         942 :                     pFmt = pFmt->DerivedFrom();
     297         942 :                     nPoolId = pFmt->GetPoolFmtId();
     298             :                 }
     299             : 
     300         522 :                 if( !pFmt->IsDefault() )
     301             :                 {
     302           0 :                     bHead = (RES_POOLCOLL_TABLE_HDLN==nPoolId);
     303           0 :                     break;
     304             :                 }
     305             :             }
     306         522 :             nNdPos++;
     307             :         }
     308             :     }
     309             : 
     310         520 :     rWrt.OutNewLine();  // <TH>/<TD> in neue Zeile
     311         520 :     OStringBuffer sOut;
     312         520 :     sOut.append('<');
     313         520 :     sOut.append(bHead ? OOO_STRING_SVTOOLS_HTML_tableheader : OOO_STRING_SVTOOLS_HTML_tabledata);
     314             : 
     315             :     // ROW- und COLSPAN ausgeben
     316         520 :     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         520 :     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         520 :     long nWidth = 0;
     328         520 :     sal_uInt32 nPrcWidth = USHRT_MAX;
     329         520 :     if( bOutWidth )
     330             :     {
     331         520 :         if( bLayoutExport )
     332             :         {
     333           0 :             if( pCell->HasPrcWidthOpt() )
     334             :             {
     335           0 :                 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         520 :             if( HasRelWidths() )
     347         520 :                 nPrcWidth = (sal_uInt16)GetPrcWidth(nCol,nColSpan);
     348             :             else
     349           0 :                 nWidth = GetAbsWidth( nCol, nColSpan );
     350             :         }
     351             :     }
     352             : 
     353         520 :     long nHeight = pCell->GetHeight() > 0
     354           0 :                         ? GetAbsHeight( pCell->GetHeight(), nRow, nRowSpan )
     355         520 :                         : 0;
     356         520 :     Size aPixelSz( nWidth, nHeight );
     357             : 
     358             :     // WIDTH ausgeben (Grrr: nur fuer Netscape)
     359         520 :     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         520 :     if( bOutWidth )
     372             :     {
     373         520 :         sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_width).
     374         520 :             append("=\"");
     375         520 :         if( nPrcWidth != USHRT_MAX )
     376             :         {
     377         520 :             sOut.append(static_cast<sal_Int32>(nPrcWidth)).append('%');
     378             :         }
     379             :         else
     380             :         {
     381           0 :             sOut.append(static_cast<sal_Int32>(aPixelSz.Width()));
     382             :         }
     383         520 :         sOut.append("\"");
     384         520 :         if( !bLayoutExport && nColSpan==1 )
     385         520 :             pCol->SetOutWidth( false );
     386             :     }
     387             : 
     388         520 :     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         520 :     const SfxItemSet& rItemSet = pBox->GetFrmFmt()->GetAttrSet();
     395             :     const SfxPoolItem *pItem;
     396             : 
     397             :     // ALIGN wird jetzt nur noch an den Absaetzen ausgegeben
     398             : 
     399             :     // VALIGN ausgeben
     400         520 :     if( bOutVAlign )
     401             :     {
     402           0 :         sal_Int16 eVertOri = pCell->GetVertOri();
     403           0 :         if( text::VertOrientation::TOP==eVertOri || text::VertOrientation::BOTTOM==eVertOri )
     404             :         {
     405           0 :             sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_valign)
     406           0 :                 .append("=\"").append(text::VertOrientation::TOP==eVertOri ?
     407             :                     OOO_STRING_SVTOOLS_HTML_VA_top :
     408           0 :                     OOO_STRING_SVTOOLS_HTML_VA_bottom)
     409           0 :                 .append("\"");
     410             :         }
     411             :     }
     412             : 
     413         520 :     rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
     414             : 
     415         520 :     rWrt.bTxtAttr = false;
     416         520 :     rWrt.bOutOpts = true;
     417         520 :     const SvxBrushItem *pBrushItem = 0;
     418         520 :     if( SfxItemState::SET==rItemSet.GetItemState( RES_BACKGROUND, false, &pItem ) )
     419             :     {
     420         520 :         pBrushItem = (const SvxBrushItem *)pItem;
     421             :     }
     422         520 :     if( !pBrushItem )
     423           0 :         pBrushItem = pCell->GetBackground();
     424             : 
     425         520 :     if( pBrushItem )
     426             :     {
     427             :         // Hintergrund ausgeben
     428         520 :         rWrt.OutBackground( pBrushItem, false );
     429             : 
     430         520 :         if( rWrt.bCfgOutStyles )
     431         520 :             OutCSS1_TableBGStyleOpt( rWrt, *pBrushItem );
     432             :     }
     433             : 
     434         520 :     rWrt.OutCSS1_TableCellBorderHack(*pBox->GetFrmFmt());
     435             : 
     436         520 :     sal_uInt32 nNumFmt = 0;
     437         520 :     double nValue = 0.0;
     438         520 :     bool bNumFmt = false, bValue = false;
     439         520 :     if( SfxItemState::SET==rItemSet.GetItemState( RES_BOXATR_FORMAT, false, &pItem ) )
     440             :     {
     441           0 :         nNumFmt = ((const SwTblBoxNumFormat *)pItem)->GetValue();
     442           0 :         bNumFmt = true;
     443             :     }
     444         520 :     if( SfxItemState::SET==rItemSet.GetItemState( RES_BOXATR_VALUE, false, &pItem ) )
     445             :     {
     446           0 :         nValue = ((const SwTblBoxValue *)pItem)->GetValue();
     447           0 :         bValue = true;
     448           0 :         if( !bNumFmt )
     449           0 :             nNumFmt = pBox->GetFrmFmt()->GetTblBoxNumFmt().GetValue();
     450             :     }
     451             : 
     452         520 :     if( bNumFmt || bValue )
     453             :     {
     454             :         sOut.append(HTMLOutFuncs::CreateTableDataOptionsValNum(bValue, nValue,
     455           0 :             nNumFmt, *rWrt.pDoc->GetNumberFormatter(), rWrt.eDestEnc,
     456           0 :             &rWrt.aNonConvertableCharacters));
     457             :     }
     458         520 :     sOut.append('>');
     459         520 :     rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
     460         520 :     rWrt.bLFPossible = true;
     461             : 
     462         520 :     rWrt.IncIndentLevel();  // den Inhalt von <TD>...</TD> einruecken
     463             : 
     464         520 :     if( pSttNd )
     465             :     {
     466         520 :         HTMLSaveData aSaveData( rWrt, pSttNd->GetIndex()+1,
     467        1040 :                                 pSttNd->EndOfSectionIndex() );
     468         520 :         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         520 :     rWrt.DecIndentLevel();  // den Inhalt von <TD>...</TD> einruecken
     496             : 
     497         520 :     if( rWrt.bLFPossible )
     498         520 :         rWrt.OutNewLine();
     499         520 :     HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), bHead ? OOO_STRING_SVTOOLS_HTML_tableheader
     500             :                                                      : OOO_STRING_SVTOOLS_HTML_tabledata,
     501        1040 :                                 false );
     502         520 :     rWrt.bLFPossible = true;
     503             : }
     504             : 
     505             : // Eine Line als Zeilen ausgeben
     506         104 : 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         104 :     sal_Int16 eRowVertOri = text::VertOrientation::NONE;
     514         104 :     if( rCells.size() > 1 )
     515             :     {
     516         624 :         for( sal_uInt16 nCell = 0; nCell<rCells.size(); nCell++ )
     517             :         {
     518         520 :             sal_Int16 eCellVertOri = rCells[nCell].GetVertOri();
     519         520 :             if( 0==nCell )
     520             :             {
     521         104 :                 eRowVertOri = eCellVertOri;
     522             :             }
     523         416 :             else if( eRowVertOri != eCellVertOri )
     524             :             {
     525           0 :                 eRowVertOri = text::VertOrientation::NONE;
     526           0 :                 break;
     527             :             }
     528             :         }
     529             :     }
     530             : 
     531         104 :     rWrt.OutNewLine();  // <TR> in neuer Zeile
     532         104 :     rWrt.Strm().WriteChar( '<' ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_tablerow );
     533         104 :     if( pBrushItem )
     534             :     {
     535           0 :         rWrt.OutBackground( pBrushItem, false );
     536             : 
     537           0 :         rWrt.bTxtAttr = false;
     538           0 :         rWrt.bOutOpts = true;
     539           0 :         if( rWrt.bCfgOutStyles )
     540           0 :             OutCSS1_TableBGStyleOpt( rWrt, *pBrushItem );
     541             :     }
     542             : 
     543         104 :     if( text::VertOrientation::TOP==eRowVertOri || text::VertOrientation::BOTTOM==eRowVertOri )
     544             :     {
     545         104 :         OStringBuffer sOut;
     546         104 :         sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_valign)
     547         312 :             .append("=\"").append(text::VertOrientation::TOP==eRowVertOri ? OOO_STRING_SVTOOLS_HTML_VA_top : OOO_STRING_SVTOOLS_HTML_VA_bottom)
     548         104 :             .append("\"");
     549         104 :         rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
     550             :     }
     551             : 
     552         104 :     rWrt.Strm().WriteChar( '>' );
     553             : 
     554         104 :     rWrt.IncIndentLevel(); // Inhalt von <TR>...</TR> einruecken
     555             : 
     556         624 :     for( sal_uInt16 nCell = 0; nCell<rCells.size(); nCell++ )
     557         520 :         OutTableCell( rWrt, &rCells[nCell], text::VertOrientation::NONE==eRowVertOri );
     558             : 
     559         104 :     rWrt.DecIndentLevel(); // Inhalt von <TR>...</TR> einruecken
     560             : 
     561         104 :     rWrt.OutNewLine();  // </TR> in neuer Zeile
     562         104 :     HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_tablerow, false );
     563         104 : }
     564             : 
     565           2 : void SwHTMLWrtTable::Write( SwHTMLWriter& rWrt, sal_Int16 eAlign,
     566             :                             bool bTHead, const SwFrmFmt *pFrmFmt,
     567             :                             const OUString *pCaption, bool bTopCaption,
     568             :                             sal_uInt16 nHSpace, sal_uInt16 nVSpace ) const
     569             : {
     570             :     sal_uInt16 nRow;
     571             : 
     572             :     // Wert fuer FRAME bestimmen
     573           2 :     sal_uInt16 nFrameMask = 15;
     574           2 :     if( !(aRows.front())->bTopBorder )
     575           0 :         nFrameMask &= ~1;
     576           2 :     if( !(aRows.back())->bBottomBorder )
     577           0 :         nFrameMask &= ~2;
     578           2 :     if( !(aCols.front())->bLeftBorder )
     579           0 :         nFrameMask &= ~4;
     580           2 :     if( !(aCols.back())->bRightBorder )
     581           0 :         nFrameMask &= ~8;
     582             : 
     583             :     // Wert fur RULES bestimmen
     584           2 :     bool bRowsHaveBorder = false;
     585           2 :     bool bRowsHaveBorderOnly = true;
     586           2 :     SwWriteTableRow *pRow = aRows[0];
     587         104 :     for( nRow=1; nRow < aRows.size(); nRow++ )
     588             :     {
     589         102 :         SwWriteTableRow *pNextRow = aRows[nRow];
     590         102 :         bool bBorder = ( pRow->bBottomBorder || pNextRow->bTopBorder );
     591         102 :         bRowsHaveBorder |= bBorder;
     592         102 :         bRowsHaveBorderOnly &= bBorder;
     593             : 
     594         102 :         sal_uInt16 nBorder2 = pRow->bBottomBorder ? pRow->nBottomBorder : USHRT_MAX;
     595         102 :         if( pNextRow->bTopBorder && pNextRow->nTopBorder < nBorder2 )
     596           0 :             nBorder2 = pNextRow->nTopBorder;
     597             : 
     598         102 :         pRow->bBottomBorder = bBorder;
     599         102 :         pRow->nBottomBorder = nBorder2;
     600             : 
     601         102 :         pNextRow->bTopBorder = bBorder;
     602         102 :         pNextRow->nTopBorder = nBorder2;
     603             : 
     604         102 :         pRow = pNextRow;
     605             :     }
     606             : 
     607           2 :     bool bColsHaveBorder = false;
     608           2 :     bool bColsHaveBorderOnly = true;
     609           2 :     SwWriteTableCol *pCol = aCols[0];
     610             :     sal_uInt16 nCol;
     611          10 :     for( nCol=1; nCol<aCols.size(); nCol++ )
     612             :     {
     613           8 :         SwWriteTableCol *pNextCol = aCols[nCol];
     614           8 :         bool bBorder = ( pCol->bRightBorder || pNextCol->bLeftBorder );
     615           8 :         bColsHaveBorder |= bBorder;
     616           8 :         bColsHaveBorderOnly &= bBorder;
     617           8 :         pCol->bRightBorder = bBorder;
     618           8 :         pNextCol->bLeftBorder = bBorder;
     619           8 :         pCol = pNextCol;
     620             :     }
     621             : 
     622             :     // vorhergende Aufzaehlung etc. beenden
     623           2 :     rWrt.ChangeParaToken( 0 );
     624             : 
     625           2 :     if( rWrt.bLFPossible )
     626           2 :         rWrt.OutNewLine();  // <TABLE> in neue Zeile
     627           2 :     OStringBuffer sOut;
     628           2 :     sOut.append('<').append(OOO_STRING_SVTOOLS_HTML_table);
     629             : 
     630           2 :     sal_uInt16 nOldDirection = rWrt.nDirection;
     631           2 :     if( pFrmFmt )
     632           2 :         rWrt.nDirection = rWrt.GetHTMLDirection( pFrmFmt->GetAttrSet() );
     633           2 :     if( rWrt.bOutFlyFrame || nOldDirection != rWrt.nDirection )
     634             :     {
     635           0 :         rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
     636           0 :         rWrt.OutDirection( rWrt.nDirection );
     637             :     }
     638             : 
     639             :     // ALIGN= ausgeben
     640           2 :     if( text::HoriOrientation::RIGHT == eAlign )
     641             :     {
     642           0 :         sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_align).
     643           0 :             append("=\"").append(OOO_STRING_SVTOOLS_HTML_AL_right).append("\"");
     644             :     }
     645           2 :     else if( text::HoriOrientation::CENTER == eAlign )
     646             :     {
     647           0 :         sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_align).
     648           0 :             append("=\"").append(OOO_STRING_SVTOOLS_HTML_AL_center).append("\"");
     649             :     }
     650           2 :     else if( text::HoriOrientation::LEFT == eAlign )
     651             :     {
     652           0 :         sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_align).
     653           0 :             append("=\"").append(OOO_STRING_SVTOOLS_HTML_AL_left).append("\"");
     654             :     }
     655             : 
     656             :     // WIDTH ausgeben: Stammt aus Layout oder ist berechnet
     657           2 :     if( nTabWidth )
     658             :     {
     659           2 :         sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_width).
     660           2 :             append("=\"");
     661           2 :         if( HasRelWidths() )
     662           2 :             sOut.append(static_cast<sal_Int32>(nTabWidth)).append('%');
     663           0 :         else if( Application::GetDefaultDevice() )
     664             :         {
     665             :             sal_Int32 nPixWidth = Application::GetDefaultDevice()->LogicToPixel(
     666           0 :                         Size(nTabWidth,0), MapMode(MAP_TWIP) ).Width();
     667           0 :             if( !nPixWidth )
     668           0 :                 nPixWidth = 1;
     669             : 
     670           0 :             sOut.append(nPixWidth);
     671             :         }
     672             :         else
     673             :         {
     674             :             OSL_ENSURE( Application::GetDefaultDevice(), "kein Application-Window!?" );
     675           0 :             sOut.append("100%");
     676             :         }
     677           2 :         sOut.append("\"");
     678             :     }
     679             : 
     680           2 :     if( (nHSpace || nVSpace) && Application::GetDefaultDevice())
     681             :     {
     682             :         Size aPixelSpc =
     683             :             Application::GetDefaultDevice()->LogicToPixel( Size(nHSpace,nVSpace),
     684           0 :                                                    MapMode(MAP_TWIP) );
     685           0 :         if( !aPixelSpc.Width() && nHSpace )
     686           0 :             aPixelSpc.Width() = 1;
     687           0 :         if( !aPixelSpc.Height() && nVSpace )
     688           0 :             aPixelSpc.Height() = 1;
     689             : 
     690           0 :         if( aPixelSpc.Width() )
     691             :         {
     692           0 :             sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_hspace).
     693           0 :                 append("=\"").append(static_cast<sal_Int32>(aPixelSpc.Width())).append("\"");
     694             :         }
     695             : 
     696           0 :         if( aPixelSpc.Height() )
     697             :         {
     698           0 :             sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_vspace).
     699           0 :                 append("=\"").append(static_cast<sal_Int32>(aPixelSpc.Height())).append("\"");
     700             :         }
     701             :     }
     702             : 
     703             :     // CELLPADDING ausgeben: Stammt aus Layout oder ist berechnet
     704           2 :     sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_cellpadding).
     705           4 :         append("=\"").append(static_cast<sal_Int32>(rWrt.ToPixel(nCellPadding,false))).append("\"");
     706             : 
     707             :     // CELLSPACING ausgeben: Stammt aus Layout oder ist berechnet
     708           2 :     sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_cellspacing).
     709           4 :         append("=\"").append(static_cast<sal_Int32>(rWrt.ToPixel(nCellSpacing,false))).append("\"");
     710             : 
     711           2 :     rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
     712             : 
     713             :     // Hintergrund ausgeben
     714           2 :     if( pFrmFmt )
     715             :     {
     716           2 :         rWrt.OutBackground( pFrmFmt->GetAttrSet(), false );
     717             : 
     718           2 :         if( rWrt.bCfgOutStyles && pFrmFmt )
     719           2 :             rWrt.OutCSS1_TableFrmFmtOptions( *pFrmFmt );
     720             :     }
     721             : 
     722           2 :     sOut.append('>');
     723           2 :     rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
     724             : 
     725           2 :     rWrt.IncIndentLevel(); // Inhalte von Table einruecken
     726             : 
     727             :     // Ueberschrift ausgeben
     728           2 :     if( pCaption && !pCaption->isEmpty() )
     729             :     {
     730           0 :         rWrt.OutNewLine(); // <CAPTION> in neue Zeile
     731           0 :         OStringBuffer sOutStr(OOO_STRING_SVTOOLS_HTML_caption);
     732           0 :         sOutStr.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_align).append("=\"")
     733           0 :                .append(bTopCaption ? OOO_STRING_SVTOOLS_HTML_VA_top : OOO_STRING_SVTOOLS_HTML_VA_bottom)
     734           0 :                .append("\"");
     735           0 :         HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), sOutStr.getStr(), true );
     736           0 :         HTMLOutFuncs::Out_String( rWrt.Strm(), *pCaption, rWrt.eDestEnc, &rWrt.aNonConvertableCharacters );
     737           0 :         HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_caption, false );
     738             :     }
     739             : 
     740           2 :     sal_uInt16 nCols = aCols.size();
     741             : 
     742             :     // <COLGRP>/<COL> ausgeben: Bei Export ueber Layout nur wenn beim
     743             :     // Import welche da waren, sonst immer.
     744           2 :     bool bColGroups = (bColsHaveBorder && !bColsHaveBorderOnly);
     745           2 :     if( bColTags )
     746             :     {
     747           2 :         if( bColGroups )
     748             :         {
     749           0 :             rWrt.OutNewLine(); // <COLGRP> in neue Zeile
     750           0 :             HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_colgroup, true );
     751             : 
     752           0 :             rWrt.IncIndentLevel(); // Inhalt von <COLGRP> einruecken
     753             :         }
     754             : 
     755          12 :         for( nCol=0; nCol<nCols; nCol++ )
     756             :         {
     757          10 :             rWrt.OutNewLine(); // <COL> in neue Zeile
     758             : 
     759          10 :             const SwWriteTableCol *pColumn = aCols[nCol];
     760             : 
     761          10 :             OStringBuffer sOutStr;
     762          10 :             sOutStr.append('<').append(OOO_STRING_SVTOOLS_HTML_col);
     763             : 
     764             :             sal_uInt32 nWidth;
     765             :             bool bRel;
     766          10 :             if( bLayoutExport )
     767             :             {
     768           0 :                 bRel = pColumn->HasRelWidthOpt();
     769           0 :                 nWidth = pColumn->GetWidthOpt();
     770             :             }
     771             :             else
     772             :             {
     773          10 :                 bRel = HasRelWidths();
     774          10 :                 nWidth = bRel ? GetRelWidth(nCol,1) : GetAbsWidth(nCol,1);
     775             :             }
     776             : 
     777          10 :             sOutStr.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_width).
     778          10 :                 append("=\"");
     779          10 :             if( bRel )
     780          10 :                 sOutStr.append(static_cast<sal_Int32>(nWidth)).append('*');
     781             :             else
     782           0 :                 sOutStr.append(static_cast<sal_Int32>(rWrt.ToPixel(nWidth,false)));
     783          10 :             sOutStr.append("\">");
     784          10 :             rWrt.Strm().WriteCharPtr( sOutStr.makeStringAndClear().getStr() );
     785             : 
     786          10 :             if( bColGroups && pColumn->bRightBorder && nCol<nCols-1 )
     787             :             {
     788           0 :                 rWrt.DecIndentLevel(); // Inhalt von <COLGRP> einruecken
     789           0 :                 rWrt.OutNewLine(); // </COLGRP> in neue Zeile
     790           0 :                 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_colgroup,
     791           0 :                                             false );
     792           0 :                 rWrt.OutNewLine(); // <COLGRP> in neue Zeile
     793           0 :                 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_colgroup,
     794           0 :                                             true );
     795           0 :                 rWrt.IncIndentLevel(); // Inhalt von <COLGRP> einruecken
     796             :             }
     797          10 :         }
     798           2 :         if( bColGroups )
     799             :         {
     800           0 :             rWrt.DecIndentLevel(); // Inhalt von <COLGRP> einruecken
     801             : 
     802           0 :             rWrt.OutNewLine(); // </COLGRP> in neue Zeile
     803           0 :             HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_colgroup,
     804           0 :                                         false );
     805             :         }
     806             :     }
     807             : 
     808             :     // die Lines als Tabellenzeilen rausschreiben
     809             : 
     810             :     // <TBODY> ausgeben?
     811           2 :     bool bTSections = (bRowsHaveBorder && !bRowsHaveBorderOnly);
     812           2 :     bool bTBody = bTSections;
     813             : 
     814             :     // Wenn Sections ausgegeben werden muessen darf ein THEAD um die erste
     815             :     // Zeile nur ausgegeben werden, wenn unter der Zeile eine Linie ist
     816           2 :     if( bTHead &&
     817           0 :         (bTSections || bColGroups) &&
     818           2 :         nHeadEndRow<aRows.size()-1 && !aRows[nHeadEndRow]->bBottomBorder )
     819           0 :         bTHead = false;
     820             : 
     821             :     // <TBODY> aus ausgeben, wenn <THEAD> ausgegeben wird.
     822           2 :     bTSections |= bTHead;
     823             : 
     824           2 :     if( bTSections )
     825             :     {
     826           0 :         rWrt.OutNewLine(); // <THEAD>/<TDATA> in neue Zeile
     827           0 :         HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(),
     828           0 :                             bTHead ? OOO_STRING_SVTOOLS_HTML_thead : OOO_STRING_SVTOOLS_HTML_tbody, true );
     829             : 
     830           0 :         rWrt.IncIndentLevel(); // Inhalt von <THEAD>/<TDATA> einr.
     831             :     }
     832             : 
     833         106 :     for( nRow = 0; nRow < aRows.size(); nRow++ )
     834             :     {
     835         104 :         const SwWriteTableRow *pRow2 = aRows[nRow];
     836             : 
     837         104 :         OutTableCells( rWrt, pRow2->GetCells(), pRow2->GetBackground() );
     838         206 :         if( !nCellSpacing && nRow < aRows.size()-1 && pRow2->bBottomBorder &&
     839         102 :             pRow2->nBottomBorder > DEF_LINE_WIDTH_1 )
     840             :         {
     841           0 :             sal_uInt16 nCnt = (pRow2->nBottomBorder / DEF_LINE_WIDTH_1) - 1;
     842           0 :             for( ; nCnt; nCnt-- )
     843             :             {
     844           0 :                 rWrt.OutNewLine();
     845           0 :                 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_tablerow,
     846           0 :                                             true );
     847           0 :                 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_tablerow,
     848           0 :                                             false );
     849             :             }
     850             :         }
     851         104 :         if( ( (bTHead && nRow==nHeadEndRow) ||
     852         104 :               (bTBody && pRow2->bBottomBorder) ) &&
     853           0 :             nRow < aRows.size()-1 )
     854             :         {
     855           0 :             rWrt.DecIndentLevel(); // Inhalt von <THEAD>/<TDATA> einr.
     856           0 :             rWrt.OutNewLine(); // </THEAD>/</TDATA> in neue Zeile
     857           0 :             HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(),
     858           0 :                             bTHead ? OOO_STRING_SVTOOLS_HTML_thead : OOO_STRING_SVTOOLS_HTML_tbody, false );
     859           0 :             rWrt.OutNewLine(); // <THEAD>/<TDATA> in neue Zeile
     860             : 
     861           0 :             if( bTHead && nRow==nHeadEndRow )
     862           0 :                 bTHead = false;
     863             : 
     864           0 :             HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(),
     865           0 :                             bTHead ? OOO_STRING_SVTOOLS_HTML_thead : OOO_STRING_SVTOOLS_HTML_tbody, true );
     866           0 :             rWrt.IncIndentLevel(); // Inhalt von <THEAD>/<TDATA> einr.
     867             :         }
     868             :     }
     869             : 
     870           2 :     if( bTSections )
     871             :     {
     872           0 :         rWrt.DecIndentLevel(); // Inhalt von <THEAD>/<TDATA> einr.
     873             : 
     874           0 :         rWrt.OutNewLine(); // </THEAD>/</TDATA> in neue Zeile
     875           0 :         HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(),
     876           0 :                             bTHead ? OOO_STRING_SVTOOLS_HTML_thead : OOO_STRING_SVTOOLS_HTML_tbody, false );
     877             :     }
     878             : 
     879           2 :     rWrt.DecIndentLevel(); // Inhalt von <TABLE> einr.
     880             : 
     881           2 :     rWrt.OutNewLine(); // </TABLE> in neue Zeile
     882           2 :     HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_table, false );
     883             : 
     884           2 :     rWrt.nDirection = nOldDirection;
     885           2 : }
     886             : 
     887           2 : Writer& OutHTML_SwTblNode( Writer& rWrt, SwTableNode & rNode,
     888             :                            const SwFrmFmt *pFlyFrmFmt,
     889             :                            const OUString *pCaption, bool bTopCaption )
     890             : {
     891             : 
     892           2 :     SwTable& rTbl = rNode.GetTable();
     893             : 
     894           2 :     SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
     895           2 :     rHTMLWrt.bOutTable = true;
     896             : 
     897             :     // die horizontale Ausrichtung des Rahmens hat (falls vorhanden)
     898             :     // Prioritaet. NONE bedeutet, dass keine horizontale
     899             :     // Ausrichtung geschrieben wird.
     900           2 :     sal_Int16 eFlyHoriOri = text::HoriOrientation::NONE;
     901           2 :     SwSurround eSurround = SURROUND_NONE;
     902           2 :     sal_uInt8 nFlyPrcWidth = 0;
     903           2 :     long nFlyWidth = 0;
     904           2 :     sal_uInt16 nFlyHSpace = 0;
     905           2 :     sal_uInt16 nFlyVSpace = 0;
     906           2 :     if( pFlyFrmFmt )
     907             :     {
     908           0 :         eSurround = pFlyFrmFmt->GetSurround().GetSurround();
     909           0 :         const SwFmtFrmSize& rFrmSize = pFlyFrmFmt->GetFrmSize();
     910           0 :         nFlyPrcWidth = rFrmSize.GetWidthPercent();
     911           0 :         nFlyWidth = rFrmSize.GetSize().Width();
     912             : 
     913           0 :         eFlyHoriOri = pFlyFrmFmt->GetHoriOrient().GetHoriOrient();
     914           0 :         if( text::HoriOrientation::NONE == eFlyHoriOri )
     915           0 :             eFlyHoriOri = text::HoriOrientation::LEFT;
     916             : 
     917           0 :         const SvxLRSpaceItem& rLRSpace = pFlyFrmFmt->GetLRSpace();
     918           0 :         nFlyHSpace = static_cast< sal_uInt16 >((rLRSpace.GetLeft() + rLRSpace.GetRight()) / 2);
     919             : 
     920           0 :         const SvxULSpaceItem& rULSpace = pFlyFrmFmt->GetULSpace();
     921           0 :         nFlyVSpace = (rULSpace.GetUpper() + rULSpace.GetLower()) / 2;
     922             :     }
     923             : 
     924             :     // ggf. eine FORM oeffnen
     925           2 :     bool bPreserveForm = false;
     926           2 :     if( !rHTMLWrt.bPreserveForm )
     927             :     {
     928           2 :         rHTMLWrt.OutForm( true, &rNode );
     929           2 :         bPreserveForm = (rHTMLWrt.pxFormComps && rHTMLWrt.pxFormComps->is() );
     930           2 :         rHTMLWrt.bPreserveForm = bPreserveForm;
     931             :     }
     932             : 
     933           2 :     SwFrmFmt *pFmt = rTbl.GetFrmFmt();
     934             : 
     935           2 :     const SwFmtFrmSize& rFrmSize = pFmt->GetFrmSize();
     936           2 :     long nWidth = rFrmSize.GetSize().Width();
     937           2 :     sal_uInt8 nPrcWidth = rFrmSize.GetWidthPercent();
     938           2 :     sal_uInt16 nBaseWidth = (sal_uInt16)nWidth;
     939             : 
     940           2 :     sal_Int16 eTabHoriOri = pFmt->GetHoriOrient().GetHoriOrient();
     941             : 
     942             :     // text::HoriOrientation::NONE und text::HoriOrientation::FULL Tabellen benoetigen relative Breiten
     943           2 :     sal_uInt16 nNewDefListLvl = 0;
     944           2 :     bool bRelWidths = false;
     945           2 :     bool bCheckDefList = false;
     946           2 :     switch( eTabHoriOri )
     947             :     {
     948             :     case text::HoriOrientation::FULL:
     949             :         // Tabellen mit automatischer Ausrichtung werden zu Tabellen
     950             :         // mit 100%-Breite
     951           0 :         bRelWidths = true;
     952           0 :         nWidth = 100;
     953           0 :         eTabHoriOri = text::HoriOrientation::LEFT;
     954           0 :         break;
     955             :     case text::HoriOrientation::NONE:
     956             :         {
     957           0 :             const SvxLRSpaceItem& aLRItem = pFmt->GetLRSpace();
     958           0 :             if( aLRItem.GetRight() )
     959             :             {
     960             :                 // Die Tabellenbreite wird anhand des linken und rechten
     961             :                 // Abstandes bestimmt. Deshalb versuchen wir die
     962             :                 // tatsaechliche Breite der Tabelle zu bestimmen. Wenn
     963             :                 // das nicht geht, machen wir eine 100% breite Tabelle
     964             :                 // draus.
     965           0 :                 nWidth = pFmt->FindLayoutRect(true).Width();
     966           0 :                 if( !nWidth )
     967             :                 {
     968           0 :                     bRelWidths = true;
     969           0 :                     nWidth = 100;
     970             :                 }
     971             : 
     972             :             }
     973           0 :             else if( nPrcWidth  )
     974             :             {
     975             :                 // Ohne rechten Rand bleibt die %-Breite erhalten
     976           0 :                 nWidth = nPrcWidth;
     977           0 :                 bRelWidths = true;
     978             :             }
     979             :             else
     980             :             {
     981             :                 // Ohne rechten Rand bleibt auch eine absolute Breite erhalten
     982             :                 // Wir versuchen aber trotzdem ueber das Layout die
     983             :                 // tatsachliche Breite zu ermitteln.
     984           0 :                 long nRealWidth = pFmt->FindLayoutRect(true).Width();
     985           0 :                 if( nRealWidth )
     986           0 :                     nWidth = nRealWidth;
     987             :             }
     988           0 :             bCheckDefList = true;
     989             :         }
     990           0 :         break;
     991             :     case text::HoriOrientation::LEFT_AND_WIDTH:
     992           2 :         eTabHoriOri = text::HoriOrientation::LEFT;
     993           2 :         bCheckDefList = true;
     994             :         // no break
     995             :     default:
     996             :         // In allen anderen Faellen kann eine absolute oder relative
     997             :         // Breite direkt uebernommen werden.
     998           2 :         if( nPrcWidth )
     999             :         {
    1000           2 :             bRelWidths = true;
    1001           2 :             nWidth = nPrcWidth;
    1002             :         }
    1003           2 :         break;
    1004             :     }
    1005             : 
    1006           2 :     if( bCheckDefList )
    1007             :     {
    1008             :         OSL_ENSURE( !rHTMLWrt.GetNumInfo().GetNumRule() ||
    1009             :                 rHTMLWrt.GetNextNumInfo(),
    1010             :                 "NumInfo fuer naechsten Absatz fehlt!" );
    1011           2 :         const SvxLRSpaceItem& aLRItem = pFmt->GetLRSpace();
    1012           2 :         if( aLRItem.GetLeft() > 0 && rHTMLWrt.nDefListMargin > 0 &&
    1013           0 :             ( !rHTMLWrt.GetNumInfo().GetNumRule() ||
    1014           0 :               ( rHTMLWrt.GetNextNumInfo() &&
    1015           0 :                 (rHTMLWrt.GetNextNumInfo()->IsRestart() ||
    1016           0 :                  rHTMLWrt.GetNumInfo().GetNumRule() !=
    1017           0 :                     rHTMLWrt.GetNextNumInfo()->GetNumRule()) ) ) )
    1018             :         {
    1019             :             // Wenn der Absatz vor der Tabelle nicht numeriert ist oder
    1020             :             // der Absatz nach der Tabelle mit einer anderen oder
    1021             :             // (gar keiner) Regel numeriert ist, koennen wir
    1022             :             // die Einrueckung ueber eine DL regeln. Sonst behalten wir
    1023             :             // die Einrueckung der Numerierung bei.
    1024             :             nNewDefListLvl = static_cast< sal_uInt16 >(
    1025           0 :                 (aLRItem.GetLeft() + (rHTMLWrt.nDefListMargin/2)) /
    1026           0 :                 rHTMLWrt.nDefListMargin );
    1027             :         }
    1028             :     }
    1029             : 
    1030           2 :     if( !pFlyFrmFmt && nNewDefListLvl != rHTMLWrt.nDefListLvl )
    1031           0 :         rHTMLWrt.OutAndSetDefList( nNewDefListLvl );
    1032             : 
    1033           2 :     if( nNewDefListLvl )
    1034             :     {
    1035           0 :         if( rHTMLWrt.bLFPossible )
    1036           0 :             rHTMLWrt.OutNewLine();
    1037           0 :         HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_dd );
    1038             :     }
    1039             : 
    1040             :     // eFlyHoriOri und eTabHoriOri besitzen nun nur noch die Werte
    1041             :     // LEFT/CENTER und RIGHT!
    1042           2 :     if( eFlyHoriOri!=text::HoriOrientation::NONE )
    1043             :     {
    1044           0 :         eTabHoriOri = eFlyHoriOri;
    1045             :         // MIB 4.7.97: Wenn die Tabelle eine relative Breite besitzt,
    1046             :         // dann richtet sich ihre Breite nach der des Rahmens, also
    1047             :         // exportieren wir dessen Breite. Bei fixer Breite ist die Breite
    1048             :         // der Tabelle massgeblich. Wer Tabellen mit relativer Breite <100%
    1049             :         // in Rahmen steckt, ist selber schuld wenn nix Gutes bei rauskommt.
    1050           0 :         if( bRelWidths )
    1051             :         {
    1052           0 :             nWidth = nFlyPrcWidth ? nFlyPrcWidth : nFlyWidth;
    1053           0 :             bRelWidths = nFlyPrcWidth > 0;
    1054             :         }
    1055             :     }
    1056             : 
    1057           2 :     sal_Int16 eDivHoriOri = text::HoriOrientation::NONE;
    1058           2 :     switch( eTabHoriOri )
    1059             :     {
    1060             :     case text::HoriOrientation::LEFT:
    1061             :         // Wenn eine linksbuendigeTabelle keinen rechtsseiigen Durchlauf
    1062             :         // hat, brauchen wir auch kein ALIGN=LEFT in der Tabelle.
    1063           2 :         if( eSurround==SURROUND_NONE || eSurround==SURROUND_LEFT )
    1064           2 :             eTabHoriOri = text::HoriOrientation::NONE;
    1065           2 :         break;
    1066             :     case text::HoriOrientation::RIGHT:
    1067             :         // Aehnliches gilt fuer rechtsbuendigeTabelle, hier nehmen wir
    1068             :         // stattdessen ein <DIV ALIGN=RIGHT>.
    1069           0 :         if( eSurround==SURROUND_NONE || eSurround==SURROUND_RIGHT )
    1070             :         {
    1071           0 :             eDivHoriOri = text::HoriOrientation::RIGHT;
    1072           0 :             eTabHoriOri = text::HoriOrientation::NONE;
    1073             :         }
    1074           0 :         break;
    1075             :     case text::HoriOrientation::CENTER:
    1076             :         // ALIGN=CENTER versteht so gut wie keiner, deshalb verzichten wir
    1077             :         // daruf und nehmen ein <CENTER>.
    1078           0 :         eDivHoriOri = text::HoriOrientation::CENTER;
    1079           0 :         eTabHoriOri = text::HoriOrientation::NONE;
    1080           0 :         break;
    1081             :     default:
    1082             :         ;
    1083             :     }
    1084           2 :     if( text::HoriOrientation::NONE==eTabHoriOri )
    1085           2 :         nFlyHSpace = nFlyVSpace = 0;
    1086             : 
    1087           2 :     if( !pFmt->GetName().isEmpty() )
    1088           2 :         rHTMLWrt.OutImplicitMark( pFmt->GetName(), "table" );
    1089             : 
    1090           2 :     if( text::HoriOrientation::NONE!=eDivHoriOri )
    1091             :     {
    1092           0 :         if( rHTMLWrt.bLFPossible )
    1093           0 :             rHTMLWrt.OutNewLine();  // <CENTER> in neuer Zeile
    1094           0 :         if( text::HoriOrientation::CENTER==eDivHoriOri )
    1095           0 :             HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_center, true );
    1096             :         else
    1097             :         {
    1098           0 :             OStringBuffer sOut(OOO_STRING_SVTOOLS_HTML_division);
    1099           0 :             sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_align).append("=\"")
    1100           0 :                 .append(OOO_STRING_SVTOOLS_HTML_AL_right).append("\"");
    1101           0 :             HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), sOut.getStr(), true );
    1102             :         }
    1103           0 :         rHTMLWrt.IncIndentLevel();  // Inhalt von <CENTER> einruecken
    1104           0 :         rHTMLWrt.bLFPossible = true;
    1105             :     }
    1106             : 
    1107             :     // Wenn die Tabelle in keinem Rahmen ist kann man immer ein LF ausgeben.
    1108           2 :     if( text::HoriOrientation::NONE==eTabHoriOri )
    1109           2 :         rHTMLWrt.bLFPossible = true;
    1110             : 
    1111           2 :     const SwHTMLTableLayout *pLayout = rTbl.GetHTMLTableLayout();
    1112             : 
    1113             : #ifdef DBG_UTIL
    1114             :     {
    1115             :     SwViewShell *pSh = rWrt.pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
    1116             :     if ( pSh && pSh->GetViewOptions()->IsTest1() )
    1117             :         pLayout = 0;
    1118             :     }
    1119             : #endif
    1120             : 
    1121           2 :     if( pLayout && pLayout->IsExportable() )
    1122             :     {
    1123           0 :         SwHTMLWrtTable aTableWrt( pLayout );
    1124           0 :         aTableWrt.Write( rHTMLWrt, eTabHoriOri, rTbl.GetRowsToRepeat() > 0,
    1125             :                          pFmt, pCaption, bTopCaption,
    1126           0 :                          nFlyHSpace, nFlyVSpace );
    1127             :     }
    1128             :     else
    1129             :     {
    1130           2 :         SwHTMLWrtTable aTableWrt( rTbl.GetTabLines(), nWidth,
    1131           4 :                                   nBaseWidth, bRelWidths, 0, 0, rTbl.GetRowsToRepeat() );
    1132           2 :         aTableWrt.Write( rHTMLWrt, eTabHoriOri, rTbl.GetRowsToRepeat() > 0,
    1133             :                          pFmt, pCaption, bTopCaption,
    1134           4 :                          nFlyHSpace, nFlyVSpace );
    1135             :     }
    1136             : 
    1137             :     // Wenn die Tabelle in keinem Rahmen war kann man immer ein LF ausgeben.
    1138           2 :     if( text::HoriOrientation::NONE==eTabHoriOri )
    1139           2 :         rHTMLWrt.bLFPossible = true;
    1140             : 
    1141           2 :     if( text::HoriOrientation::NONE!=eDivHoriOri )
    1142             :     {
    1143           0 :         rHTMLWrt.DecIndentLevel();  // Inhalt von <CENTER> einruecken
    1144           0 :         rHTMLWrt.OutNewLine();      // </CENTER> in neue Teile
    1145           0 :         HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(),
    1146             :                                text::HoriOrientation::CENTER==eDivHoriOri ? OOO_STRING_SVTOOLS_HTML_center
    1147           0 :                                                         : OOO_STRING_SVTOOLS_HTML_division, false );
    1148           0 :         rHTMLWrt.bLFPossible = true;
    1149             :     }
    1150             : 
    1151             :     // Pam hinter die Tabelle verschieben
    1152           2 :     rHTMLWrt.pCurPam->GetPoint()->nNode = *rNode.EndOfSectionNode();
    1153             : 
    1154           2 :     if( bPreserveForm )
    1155             :     {
    1156           0 :         rHTMLWrt.bPreserveForm = false;
    1157           0 :         rHTMLWrt.OutForm( false );
    1158             :     }
    1159             : 
    1160           2 :     rHTMLWrt.bOutTable = false;
    1161             : 
    1162           4 :     if( rHTMLWrt.GetNextNumInfo() &&
    1163           2 :         !rHTMLWrt.GetNextNumInfo()->IsRestart() &&
    1164           0 :         rHTMLWrt.GetNextNumInfo()->GetNumRule() ==
    1165           0 :             rHTMLWrt.GetNumInfo().GetNumRule() )
    1166             :     {
    1167             :         // Wenn der Absatz hinter der Tabelle mit der gleichen Regel
    1168             :         // numeriert ist wie der Absatz vor der Tabelle, dann steht in
    1169             :         // der NumInfo des naechsten Absatzes noch die Ebene des Absatzes
    1170             :         // vor der Tabelle. Es muss deshalb die NumInfo noch einmal geholt
    1171             :         // werden um ggf. die Num-Liste noch zu beenden.
    1172           0 :         rHTMLWrt.ClearNextNumInfo();
    1173           0 :         rHTMLWrt.FillNextNumInfo();
    1174           0 :         OutHTML_NumBulListEnd( rHTMLWrt, *rHTMLWrt.GetNextNumInfo() );
    1175             :     }
    1176           2 :     return rWrt;
    1177         270 : }
    1178             : 
    1179             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10