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

Generated by: LCOV version 1.10