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

Generated by: LCOV version 1.10