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

Generated by: LCOV version 1.10