LCOV - code coverage report
Current view: top level - sw/source/filter/html - htmltab.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 1078 2277 47.3 %
Date: 2014-04-11 Functions: 121 184 65.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 <vcl/wrkwin.hxx>
      23             : #include <editeng/boxitem.hxx>
      24             : #include <editeng/brushitem.hxx>
      25             : #include <editeng/adjustitem.hxx>
      26             : #include <editeng/fhgtitem.hxx>
      27             : #include <editeng/ulspitem.hxx>
      28             : #include <editeng/lrspitem.hxx>
      29             : #include <editeng/formatbreakitem.hxx>
      30             : #include <editeng/spltitem.hxx>
      31             : #include <svtools/htmltokn.h>
      32             : #include <svtools/htmlkywd.hxx>
      33             : #include <svl/urihelper.hxx>
      34             : 
      35             : #include <fmtornt.hxx>
      36             : #include <frmfmt.hxx>
      37             : #include <fmtfsize.hxx>
      38             : #include <fmtsrnd.hxx>
      39             : #include <fmtpdsc.hxx>
      40             : #include <fmtcntnt.hxx>
      41             : #include <fmtanchr.hxx>
      42             : #include <fmtlsplt.hxx>
      43             : #include "frmatr.hxx"
      44             : #include "pam.hxx"
      45             : #include "doc.hxx"
      46             : #include "ndtxt.hxx"
      47             : #include "shellio.hxx"
      48             : #include "poolfmt.hxx"
      49             : #include "swtable.hxx"
      50             : #include "cellatr.hxx"
      51             : #include "htmltbl.hxx"
      52             : #include "swtblfmt.hxx"
      53             : #include "htmlnum.hxx"
      54             : #include "swhtml.hxx"
      55             : #include "swcss1.hxx"
      56             : #include <numrule.hxx>
      57             : 
      58             : #define NETSCAPE_DFLT_BORDER 1
      59             : #define NETSCAPE_DFLT_CELLSPACING 2
      60             : 
      61             : using ::editeng::SvxBorderLine;
      62             : using namespace ::com::sun::star;
      63             : 
      64             : static HTMLOptionEnum aHTMLTblVAlignTable[] =
      65             : {
      66             :     { OOO_STRING_SVTOOLS_HTML_VA_top,         text::VertOrientation::NONE       },
      67             :     { OOO_STRING_SVTOOLS_HTML_VA_middle,      text::VertOrientation::CENTER     },
      68             :     { OOO_STRING_SVTOOLS_HTML_VA_bottom,      text::VertOrientation::BOTTOM     },
      69             :     { 0,                    0               }
      70             : };
      71             : 
      72             : // table tags options
      73             : 
      74           1 : struct HTMLTableOptions
      75             : {
      76             :     sal_uInt16 nCols;
      77             :     sal_uInt16 nWidth;
      78             :     sal_uInt16 nHeight;
      79             :     sal_uInt16 nCellPadding;
      80             :     sal_uInt16 nCellSpacing;
      81             :     sal_uInt16 nBorder;
      82             :     sal_uInt16 nHSpace;
      83             :     sal_uInt16 nVSpace;
      84             : 
      85             :     SvxAdjust eAdjust;
      86             :     sal_Int16 eVertOri;
      87             :     HTMLTableFrame eFrame;
      88             :     HTMLTableRules eRules;
      89             : 
      90             :     sal_Bool bPrcWidth : 1;
      91             :     sal_Bool bTableAdjust : 1;
      92             :     sal_Bool bBGColor : 1;
      93             : 
      94             :     Color aBorderColor;
      95             :     Color aBGColor;
      96             : 
      97             :     OUString aBGImage, aStyle, aId, aClass, aDir;
      98             : 
      99             :     HTMLTableOptions( const HTMLOptions& rOptions, SvxAdjust eParentAdjust );
     100             : };
     101             : 
     102             : class _HTMLTableContext
     103             : {
     104             :     SwHTMLNumRuleInfo aNumRuleInfo; // Numbering valid before the table
     105             : 
     106             :     SwTableNode *pTblNd;            // table node
     107             :     SwFrmFmt *pFrmFmt;              // der Fly frame::Frame, containing the table
     108             :     SwPosition *pPos;               // position behind the table
     109             : 
     110             :     sal_uInt16 nContextStAttrMin;
     111             :     sal_uInt16 nContextStMin;
     112             : 
     113             :     sal_Bool    bRestartPRE : 1;
     114             :     sal_Bool    bRestartXMP : 1;
     115             :     sal_Bool    bRestartListing : 1;
     116             : 
     117             : public:
     118             : 
     119             :     _HTMLAttrTable aAttrTab;        // attributes
     120             : 
     121           1 :     _HTMLTableContext( SwPosition *pPs, sal_uInt16 nCntxtStMin,
     122             :                        sal_uInt16 nCntxtStAttrMin ) :
     123             :         pTblNd( 0 ),
     124             :         pFrmFmt( 0 ),
     125             :         pPos( pPs ),
     126             :         nContextStAttrMin( nCntxtStAttrMin ),
     127             :         nContextStMin( nCntxtStMin ),
     128             :         bRestartPRE( sal_False ),
     129             :         bRestartXMP( sal_False ),
     130           1 :         bRestartListing( sal_False )
     131             :     {
     132           1 :         memset( &aAttrTab, 0, sizeof( _HTMLAttrTable ));
     133           1 :     }
     134             : 
     135             :     ~_HTMLTableContext();
     136             : 
     137           1 :     void SetNumInfo( const SwHTMLNumRuleInfo& rInf ) { aNumRuleInfo.Set(rInf); }
     138           1 :     const SwHTMLNumRuleInfo& GetNumInfo() const { return aNumRuleInfo; };
     139             : 
     140             :     void SavePREListingXMP( SwHTMLParser& rParser );
     141             :     void RestorePREListingXMP( SwHTMLParser& rParser );
     142             : 
     143           1 :     SwPosition *GetPos() const { return pPos; }
     144             : 
     145           1 :     void SetTableNode( SwTableNode *pNd ) { pTblNd = pNd; }
     146           3 :     SwTableNode *GetTableNode() const { return pTblNd; }
     147             : 
     148           0 :     void SetFrmFmt( SwFrmFmt *pFmt ) { pFrmFmt = pFmt; }
     149           1 :     SwFrmFmt *GetFrmFmt() const { return pFrmFmt; }
     150             : 
     151           1 :     sal_uInt16 GetContextStMin() const { return nContextStMin; }
     152           1 :     sal_uInt16 GetContextStAttrMin() const { return nContextStAttrMin; }
     153             : };
     154             : 
     155             : // Cell content is a linked list with SwStartNodes and
     156             : // HTMLTables.
     157             : 
     158             : class HTMLTableCnts
     159             : {
     160             :     HTMLTableCnts *pNext;               // next content
     161             : 
     162             :     // Only one of the next two pointers must be set!
     163             :     const SwStartNode *pStartNode;      // a paragraph
     164             :     HTMLTable *pTable;                  // a table
     165             : 
     166             :     SwHTMLTableLayoutCnts* pLayoutInfo;
     167             : 
     168             :     sal_Bool bNoBreak;
     169             : 
     170             :     void InitCtor();
     171             : 
     172             : public:
     173             : 
     174             :     HTMLTableCnts( const SwStartNode* pStNd );
     175             :     HTMLTableCnts( HTMLTable* pTab );
     176             : 
     177             :     ~HTMLTableCnts();                   // only allowed in ~HTMLTableCell
     178             : 
     179             :     // Determine SwStartNode and HTMLTable respectively
     180         520 :     const SwStartNode *GetStartNode() const { return pStartNode; }
     181           0 :     const HTMLTable *GetTable() const { return pTable; }
     182         260 :     HTMLTable *GetTable() { return pTable; }
     183             : 
     184             :     // Add a new node at the end of the list
     185             :     void Add( HTMLTableCnts* pNewCnts );
     186             : 
     187             :     // Determine next node
     188           0 :     const HTMLTableCnts *Next() const { return pNext; }
     189         520 :     HTMLTableCnts *Next() { return pNext; }
     190             : 
     191             :     inline void SetTableBox( SwTableBox *pBox );
     192             : 
     193           0 :     void SetNoBreak() { bNoBreak = sal_True; }
     194             : 
     195             :     SwHTMLTableLayoutCnts *CreateLayoutInfo();
     196             : };
     197             : 
     198             : // Cell of a HTML table
     199             : class HTMLTableCell
     200             : {
     201             :     // !!!ATTENTION!!!!! For each new pointer the SetProtected
     202             :     // method (and the dtor) has to be executed.
     203             :     HTMLTableCnts *pContents;       // cell content
     204             :     SvxBrushItem *pBGBrush;         // cell background
     205             :     // !!!ATTENTION!!!!!
     206             :     ::boost::shared_ptr<SvxBoxItem> m_pBoxItem;
     207             : 
     208             :     sal_uInt32 nNumFmt;
     209             :     sal_uInt16 nRowSpan;                // cell ROWSPAN
     210             :     sal_uInt16 nColSpan;                // cell COLSPAN
     211             :     sal_uInt16 nWidth;                  // cell WIDTH
     212             :     double nValue;
     213             :     sal_Int16 eVertOri;         // vertical alignment of the cell
     214             :     sal_Bool bProtected : 1;            // cell must not filled
     215             :     sal_Bool bRelWidth : 1;             // nWidth is given in %
     216             :     sal_Bool bHasNumFmt : 1;
     217             :     sal_Bool bHasValue : 1;
     218             :     sal_Bool bNoWrap : 1;
     219             :     sal_Bool mbCovered : 1;
     220             : 
     221             : public:
     222             : 
     223             :     HTMLTableCell();                // new cells always empty
     224             : 
     225             :     ~HTMLTableCell();               // only allowed in ~HTMLTableRow
     226             : 
     227             :     // Fill a not empty cell
     228             :     void Set( HTMLTableCnts *pCnts, sal_uInt16 nRSpan, sal_uInt16 nCSpan,
     229             :               sal_Int16 eVertOri, SvxBrushItem *pBGBrush,
     230             :               ::boost::shared_ptr<SvxBoxItem> const pBoxItem,
     231             :               sal_Bool bHasNumFmt, sal_uInt32 nNumFmt,
     232             :               sal_Bool bHasValue, double nValue, sal_Bool bNoWrap, sal_Bool bCovered );
     233             : 
     234             :     // Protect an empty 1x1 cell
     235             :     void SetProtected();
     236             : 
     237             :     // Set/Get cell content
     238           0 :     void SetContents( HTMLTableCnts *pCnts ) { pContents = pCnts; }
     239             :     const HTMLTableCnts *GetContents() const { return pContents; }
     240        1347 :     HTMLTableCnts *GetContents() { return pContents; }
     241             : 
     242             :     // Set/Get cell ROWSPAN/COLSPAN
     243           0 :     void SetRowSpan( sal_uInt16 nRSpan ) { nRowSpan = nRSpan; }
     244         260 :     sal_uInt16 GetRowSpan() const { return nRowSpan; }
     245             : 
     246           0 :     void SetColSpan( sal_uInt16 nCSpan ) { nColSpan = nCSpan; }
     247         520 :     sal_uInt16 GetColSpan() const { return nColSpan; }
     248             : 
     249             :     inline void SetWidth( sal_uInt16 nWidth, sal_Bool bRelWidth );
     250             : 
     251         260 :     const SvxBrushItem *GetBGBrush() const { return pBGBrush; }
     252         260 :     ::boost::shared_ptr<SvxBoxItem> GetBoxItem() const { return m_pBoxItem; }
     253             : 
     254             :     inline sal_Bool GetNumFmt( sal_uInt32& rNumFmt ) const;
     255             :     inline sal_Bool GetValue( double& rValue ) const;
     256             : 
     257         260 :     sal_Int16 GetVertOri() const { return eVertOri; }
     258             : 
     259             :     // Is the cell filled or protected ?
     260         260 :     bool IsUsed() const { return pContents!=0 || bProtected; }
     261             : 
     262             :     SwHTMLTableLayoutCell *CreateLayoutInfo();
     263             : 
     264         260 :     sal_Bool IsCovered() const { return mbCovered; }
     265             : };
     266             : 
     267             : // Row of a HTML table
     268             : typedef boost::ptr_vector<HTMLTableCell> HTMLTableCells;
     269             : 
     270             : class HTMLTableRow
     271             : {
     272             :     HTMLTableCells *pCells;             // cells of the row
     273             : 
     274             :     sal_Bool bIsEndOfGroup : 1;
     275             :     sal_Bool bSplitable : 1;
     276             : 
     277             :     sal_uInt16 nHeight;                     // options of <TR>/<TD>
     278             :     sal_uInt16 nEmptyRows;                  // number of empty rows are following
     279             : 
     280             :     SvxAdjust eAdjust;
     281             :     sal_Int16 eVertOri;
     282             :     SvxBrushItem *pBGBrush;             // background of cell from STYLE
     283             : 
     284             : public:
     285             : 
     286             :     bool bBottomBorder;                 // Is there a line after the row?
     287             : 
     288             :     HTMLTableRow( sal_uInt16 nCells=0 );    // cells of the row are empty
     289             : 
     290             :     ~HTMLTableRow();
     291             : 
     292             :     inline void SetHeight( sal_uInt16 nHeight );
     293          52 :     sal_uInt16 GetHeight() const { return nHeight; }
     294             : 
     295             :     inline HTMLTableCell *GetCell( sal_uInt16 nCell ) const;
     296             :     inline const HTMLTableCells *GetCells() const { return pCells; }
     297             : 
     298          52 :     inline void SetAdjust( SvxAdjust eAdj ) { eAdjust = eAdj; }
     299         260 :     inline SvxAdjust GetAdjust() const { return eAdjust; }
     300             : 
     301          52 :     inline void SetVertOri( sal_Int16 eV) { eVertOri = eV; }
     302         260 :     inline sal_Int16 GetVertOri() const { return eVertOri; }
     303             : 
     304           0 :     void SetBGBrush( SvxBrushItem *pBrush ) { pBGBrush = pBrush; }
     305          52 :     const SvxBrushItem *GetBGBrush() const { return pBGBrush; }
     306             : 
     307           1 :     inline void SetEndOfGroup() { bIsEndOfGroup = sal_True; }
     308           0 :     inline sal_Bool IsEndOfGroup() const { return bIsEndOfGroup; }
     309             : 
     310           0 :     void IncEmptyRows() { nEmptyRows++; }
     311           0 :     sal_uInt16 GetEmptyRows() const { return nEmptyRows; }
     312             : 
     313             :     // Expand row by adding empty cells
     314             :     void Expand( sal_uInt16 nCells, sal_Bool bOneCell=sal_False );
     315             : 
     316             :     // Shrink row by deleting empty cells
     317             :     void Shrink( sal_uInt16 nCells );
     318             : 
     319             :     void SetSplitable( sal_Bool bSet ) { bSplitable = bSet; }
     320             :     sal_Bool IsSplitable() const { return bSplitable; }
     321             : };
     322             : 
     323             : // Column of a HTML table
     324             : class HTMLTableColumn
     325             : {
     326             :     sal_Bool bIsEndOfGroup;
     327             : 
     328             :     sal_uInt16 nWidth;                      // options of <COL>
     329             :     sal_Bool bRelWidth;
     330             : 
     331             :     SvxAdjust eAdjust;
     332             :     sal_Int16 eVertOri;
     333             : 
     334             :     SwFrmFmt *aFrmFmts[6];
     335             : 
     336             :     inline sal_uInt16 GetFrmFmtIdx( sal_Bool bBorderLine,
     337             :                                 sal_Int16 eVertOri ) const;
     338             : 
     339             : public:
     340             : 
     341             :     bool bLeftBorder;                   // is there a line before the column
     342             : 
     343             :     HTMLTableColumn();
     344             : 
     345             :     inline void SetWidth( sal_uInt16 nWidth, sal_Bool bRelWidth);
     346             : 
     347           5 :     inline void SetAdjust( SvxAdjust eAdj ) { eAdjust = eAdj; }
     348         260 :     inline SvxAdjust GetAdjust() const { return eAdjust; }
     349             : 
     350           5 :     inline void SetVertOri( sal_Int16 eV) { eVertOri = eV; }
     351           0 :     inline sal_Int16 GetVertOri() const { return eVertOri; }
     352             : 
     353           1 :     inline void SetEndOfGroup() { bIsEndOfGroup = sal_True; }
     354           0 :     inline sal_Bool IsEndOfGroup() const { return bIsEndOfGroup; }
     355             : 
     356             :     inline void SetFrmFmt( SwFrmFmt *pFmt, sal_Bool bBorderLine,
     357             :                            sal_Int16 eVertOri );
     358             :     inline SwFrmFmt *GetFrmFmt( sal_Bool bBorderLine,
     359             :                                 sal_Int16 eVertOri ) const;
     360             : 
     361             :     SwHTMLTableLayoutColumn *CreateLayoutInfo();
     362             : };
     363             : 
     364             : // HTML table
     365             : typedef boost::ptr_vector<HTMLTableRow> HTMLTableRows;
     366             : 
     367             : typedef boost::ptr_vector<HTMLTableColumn> HTMLTableColumns;
     368             : 
     369             : typedef std::vector<SdrObject *> SdrObjects;
     370             : 
     371             : class HTMLTable
     372             : {
     373             :     OUString aId;
     374             :     OUString aStyle;
     375             :     OUString aClass;
     376             :     OUString aDir;
     377             : 
     378             :     SdrObjects *pResizeDrawObjs;// SDR objects
     379             :     std::vector<sal_uInt16> *pDrawObjPrcWidths;   // column of draw object and its rel. width
     380             : 
     381             :     HTMLTableRows *pRows;           // table rows
     382             :     HTMLTableColumns *pColumns;     // table columns
     383             : 
     384             :     sal_uInt16 nRows;                   // number of rows
     385             :     sal_uInt16 nCols;                   // number of columns
     386             :     sal_uInt16 nFilledCols;             // number of filled columns
     387             : 
     388             :     sal_uInt16 nCurRow;                 // aktuelle Zeile
     389             :     sal_uInt16 nCurCol;                 // aktuelle Spalte
     390             : 
     391             :     sal_uInt16 nLeftMargin;             // Abstand zum linken Rand (aus Absatz)
     392             :     sal_uInt16 nRightMargin;            // Abstand zum rechten Rand (aus Absatz)
     393             : 
     394             :     sal_uInt16 nCellPadding;            // Abstand Umrandung zum Text
     395             :     sal_uInt16 nCellSpacing;            // Abstand zwischen zwei Zellen
     396             :     sal_uInt16 nHSpace;
     397             :     sal_uInt16 nVSpace;
     398             : 
     399             :     sal_uInt16 nBoxes;                  // Wievele Boxen enthaelt die Tabelle
     400             : 
     401             :     const SwStartNode *pPrevStNd;   // der Table-Node oder der Start-Node
     402             :                                     // der vorhergehenden Section
     403             :     const SwTable *pSwTable;        // die SW-Tabelle (nur auf dem Top-Level)
     404             :     SwTableBox *pBox1;              // die TableBox, die beim Erstellen
     405             :                                     // der Top-Level-Tabelle angelegt wird
     406             : 
     407             :     SwTableBoxFmt *pBoxFmt;         // das frame::Frame-Format einer SwTableBox
     408             :     SwTableLineFmt *pLineFmt;       // das frame::Frame-Format einer SwTableLine
     409             :     SwTableLineFmt *pLineFrmFmtNoHeight;
     410             :     SvxBrushItem *pBGBrush;         // Hintergrund der Tabelle
     411             :     SvxBrushItem *pInhBGBrush;      // "geerbter" Hintergrund der Tabelle
     412             :     const SwStartNode *pCaptionStartNode;   // Start-Node der Tabellen-Ueberschrift
     413             : 
     414             :     SvxBorderLine aTopBorderLine;   // die Linie fuer die Umrandung
     415             :     SvxBorderLine aBottomBorderLine;// die Linie fuer die Umrandung
     416             :     SvxBorderLine aLeftBorderLine;  // die Linie fuer die Umrandung
     417             :     SvxBorderLine aRightBorderLine; // die Linie fuer die Umrandung
     418             :     SvxBorderLine aBorderLine;      // die Linie fuer die Umrandung
     419             :     SvxBorderLine aInhLeftBorderLine;   // die Linie fuer die Umrandung
     420             :     SvxBorderLine aInhRightBorderLine;  // die Linie fuer die Umrandung
     421             :     bool bTopBorder;                // besitzt die Tabelle oben eine Linie
     422             :     bool bRightBorder;              // besitzt die Tabelle rechts eine Linie
     423             :     bool bTopAlwd;                  // duerfen die Raender gesetzt werden?
     424             :     bool bRightAlwd;
     425             :     bool bFillerTopBorder;          // bekommt eine linke/rechter Filler-
     426             :     bool bFillerBottomBorder;       // Zelle eine obere/untere Umrandung?
     427             :     bool bInhLeftBorder;
     428             :     bool bInhRightBorder;
     429             :     bool bBordersSet;               // die Umrandung wurde bereits gesetzt
     430             :     sal_Bool bForceFrame;
     431             :     sal_Bool bTableAdjustOfTag;         // stammt nTableAdjust aus <TABLE>?
     432             :     sal_uInt32 nHeadlineRepeat;         // repeating rows
     433             :     sal_Bool bIsParentHead;
     434             :     sal_Bool bHasParentSection;
     435             :     sal_Bool bMakeTopSubTable;
     436             :     sal_Bool bHasToFly;
     437             :     sal_Bool bFixedCols;
     438             :     bool bColSpec;                  // Gab es COL(GROUP)-Elemente?
     439             :     sal_Bool bPrcWidth;                 // Breite ist eine %-Angabe
     440             : 
     441             :     SwHTMLParser *pParser;          // der aktuelle Parser
     442             :     HTMLTable *pTopTable;           // die Tabelle auf dem Top-Level
     443             :     HTMLTableCnts *pParentContents;
     444             : 
     445             :     _HTMLTableContext *pContext;    // der Kontext der Tabelle
     446             : 
     447             :     SwHTMLTableLayout *pLayoutInfo;
     448             : 
     449             :     // die folgenden Parameter stammen aus der dem <TABLE>-Tag
     450             :     sal_uInt16 nWidth;                  // die Breite der Tabelle
     451             :     sal_uInt16 nHeight;                 // absolute Hoehe der Tabelle
     452             :     SvxAdjust eTableAdjust;         // drawing::Alignment der Tabelle
     453             :     sal_Int16 eVertOri;         // Default vertikale Ausr. der Zellen
     454             :     sal_uInt16 nBorder;                 // Breite der auesseren Umrandung
     455             :     HTMLTableFrame eFrame;          // Rahmen um die Tabelle
     456             :     HTMLTableRules eRules;          // Ramhen in der Tabelle
     457             :     sal_Bool bTopCaption;               // Ueberschrift ueber der Tabelle
     458             : 
     459             :     void InitCtor( const HTMLTableOptions *pOptions );
     460             : 
     461             :     // Korigieren des Row-Spans fuer alle Zellen oberhalb der
     462             :     // angegeben Zelle und der Zelle selbst, fuer die den anegebenen
     463             :     // Inhalt besitzen. Die angegeben Zelle bekommt den Row-Span 1
     464             :     void FixRowSpan( sal_uInt16 nRow, sal_uInt16 nCol, const HTMLTableCnts *pCnts );
     465             : 
     466             :     // Schuetzen der angegeben Zelle und den darunterliegenden
     467             :     void ProtectRowSpan( sal_uInt16 nRow, sal_uInt16 nCol, sal_uInt16 nRowSpan );
     468             : 
     469             :     // Suchen des SwStartNodes der logisch vorhergehenden Box
     470             :     // bei nRow==nCell==USHRT_MAX wird der allerletzte Start-Node
     471             :     // der Tabelle zurueckgegeben
     472             :     const SwStartNode* GetPrevBoxStartNode( sal_uInt16 nRow, sal_uInt16 nCell ) const;
     473             : 
     474             :     sal_uInt16 GetTopCellSpace( sal_uInt16 nRow, sal_uInt16 nRowSpan,
     475             :                             sal_Bool bSwBorders=sal_True ) const;
     476             :     sal_uInt16 GetBottomCellSpace( sal_uInt16 nRow, sal_uInt16 nRowSpan,
     477             :                                sal_Bool bSwBorders=sal_True ) const;
     478             : 
     479             :     // Anpassen des frame::Frame-Formates einer Box
     480             :     void FixFrameFmt( SwTableBox *pBox, sal_uInt16 nRow, sal_uInt16 nCol,
     481             :                       sal_uInt16 nRowSpan, sal_uInt16 nColSpan,
     482             :                       sal_Bool bFirstPara=sal_True, sal_Bool bLastPara=sal_True ) const;
     483             :     void FixFillerFrameFmt( SwTableBox *pBox, sal_Bool bRight ) const;
     484             : 
     485             :     // den Inhalt (Lines/Boxen) eine Tabelle erstellen
     486             :     void _MakeTable( SwTableBox *pUpper=0 );
     487             : 
     488             :     // Anlegen einer neuen SwTableBox, die einen SwStartNode enthaelt
     489             :     SwTableBox *NewTableBox( const SwStartNode *pStNd,
     490             :                              SwTableLine *pUpper ) const;
     491             : 
     492             :     // Erstellen einer SwTableLine aus den Zellen des Rechtecks
     493             :     // (nTopRow/nLeftCol) inklusive bis (nBottomRow/nRightRow) exklusive
     494             :     SwTableLine *MakeTableLine( SwTableBox *pUpper,
     495             :                                 sal_uInt16 nTopRow, sal_uInt16 nLeftCol,
     496             :                                 sal_uInt16 nBottomRow, sal_uInt16 nRightCol );
     497             : 
     498             :     // Erstellen einer SwTableBox aus dem Inhalt einer Zelle
     499             :     SwTableBox *MakeTableBox( SwTableLine *pUpper,
     500             :                               HTMLTableCnts *pCnts,
     501             :                               sal_uInt16 nTopRow, sal_uInt16 nLeftCol,
     502             :                               sal_uInt16 nBootomRow, sal_uInt16 nRightCol );
     503             : 
     504             :     // der Autolayout-Algorithmus
     505             : 
     506             :     // Setzen der Umrandung anhand der Vorgaben der Parent-Tabelle
     507             :     void InheritBorders( const HTMLTable *pParent,
     508             :                          sal_uInt16 nRow, sal_uInt16 nCol,
     509             :                          sal_uInt16 nRowSpan, sal_uInt16 nColSpan,
     510             :                          sal_Bool bFirstPara, sal_Bool bLastPara );
     511             : 
     512             :     // Linke und rechte Umrandung der umgebenen Tabelle erben
     513             :     void InheritVertBorders( const HTMLTable *pParent,
     514             :                              sal_uInt16 nCol, sal_uInt16 nColSpan );
     515             : 
     516             :     // Setzen der Umrandung anhand der Benutzervorgaben
     517             :     void SetBorders();
     518             : 
     519             :     // wurde die Umrandung der Tabelle schon gesetzt
     520           0 :     bool BordersSet() const { return bBordersSet; }
     521             : 
     522           2 :     const SvxBrushItem *GetBGBrush() const { return pBGBrush; }
     523           0 :     const SvxBrushItem *GetInhBGBrush() const { return pInhBGBrush; }
     524             : 
     525             :     sal_uInt16 GetBorderWidth( const SvxBorderLine& rBLine,
     526             :                            sal_Bool bWithDistance=sal_False ) const;
     527             : 
     528             : public:
     529             : 
     530             :     sal_Bool bFirstCell;                // wurde schon eine Zelle angelegt?
     531             : 
     532             :     HTMLTable( SwHTMLParser* pPars, HTMLTable *pTopTab,
     533             :                sal_Bool bParHead, sal_Bool bHasParentSec,
     534             :                sal_Bool bTopTbl, sal_Bool bHasToFly,
     535             :                const HTMLTableOptions *pOptions );
     536             : 
     537             :     ~HTMLTable();
     538             : 
     539             :     // Ermitteln einer Zelle
     540             :     inline HTMLTableCell *GetCell( sal_uInt16 nRow, sal_uInt16 nCell ) const;
     541             : 
     542             :     // Ueberschrift setzen/ermitteln
     543             :     inline void SetCaption( const SwStartNode *pStNd, sal_Bool bTop );
     544           1 :     const SwStartNode *GetCaptionStartNode() const { return pCaptionStartNode; }
     545           0 :     sal_Bool IsTopCaption() const { return bTopCaption; }
     546             : 
     547           1 :     SvxAdjust GetTableAdjust( sal_Bool bAny ) const
     548             :     {
     549           1 :         return (bTableAdjustOfTag || bAny) ? eTableAdjust : SVX_ADJUST_END;
     550             :     }
     551             :     sal_Int16 GetVertOri() const { return eVertOri; }
     552             : 
     553           0 :     sal_uInt16 GetHSpace() const { return nHSpace; }
     554           0 :     sal_uInt16 GetVSpace() const { return nVSpace; }
     555             : 
     556             :     sal_Bool HasPrcWidth() const { return bPrcWidth; }
     557             :     sal_uInt8 GetPrcWidth() const { return bPrcWidth ? (sal_uInt8)nWidth : 0; }
     558             : 
     559             :     sal_uInt16 GetMinWidth() const
     560             :     {
     561             :         sal_uInt32 nMin = pLayoutInfo->GetMin();
     562             :         return nMin < USHRT_MAX ? (sal_uInt16)nMin : USHRT_MAX;
     563             :     }
     564             : 
     565             :     // von Zeilen oder Spalten geerbtes drawing::Alignment holen
     566             :     SvxAdjust GetInheritedAdjust() const;
     567             :     sal_Int16 GetInheritedVertOri() const;
     568             : 
     569             :     // Einfuegen einer Zelle an der aktuellen Position
     570             :     void InsertCell( HTMLTableCnts *pCnts, sal_uInt16 nRowSpan, sal_uInt16 nColSpan,
     571             :                      sal_uInt16 nWidth, sal_Bool bRelWidth, sal_uInt16 nHeight,
     572             :                      sal_Int16 eVertOri, SvxBrushItem *pBGBrush,
     573             :                      boost::shared_ptr<SvxBoxItem> const pBoxItem,
     574             :                      sal_Bool bHasNumFmt, sal_uInt32 nNumFmt,
     575             :                      sal_Bool bHasValue, double nValue, sal_Bool bNoWrap );
     576             : 
     577             :     // Start/Ende einer neuen Zeile bekanntgeben
     578             :     void OpenRow( SvxAdjust eAdjust, sal_Int16 eVertOri,
     579             :                   SvxBrushItem *pBGBrush );
     580             :     void CloseRow( sal_Bool bEmpty );
     581             : 
     582             :     // Ende einer neuen Section bekanntgeben
     583             :     inline void CloseSection( sal_Bool bHead );
     584             : 
     585             :     // Ende einer Spalten-Gruppe bekanntgeben
     586             :     inline void CloseColGroup( sal_uInt16 nSpan, sal_uInt16 nWidth, bool bRelWidth,
     587             :                                SvxAdjust eAdjust, sal_Int16 eVertOri );
     588             : 
     589             :     // Einfuegen einer Spalte
     590             :     void InsertCol( sal_uInt16 nSpan, sal_uInt16 nWidth, bool bRelWidth,
     591             :                     SvxAdjust eAdjust, sal_Int16 eVertOri );
     592             : 
     593             :     // Beenden einer Tab-Definition (MUSS fuer ALLE Tabs aufgerufen werden)
     594             :     void CloseTable();
     595             : 
     596             :     // SwTable konstruieren (inkl. der Child-Tabellen)
     597             :     void MakeTable( SwTableBox *pUpper, sal_uInt16 nAbsAvail,
     598             :                     sal_uInt16 nRelAvail=0, sal_uInt16 nAbsLeftSpace=0,
     599             :                     sal_uInt16 nAbsRightSpace=0, sal_uInt16 nInhAbsSpace=0 );
     600             : 
     601           0 :     inline sal_Bool IsNewDoc() const { return pParser->IsNewDoc(); }
     602             : 
     603           0 :     void SetHasParentSection( sal_Bool bSet ) { bHasParentSection = bSet; }
     604          14 :     sal_Bool HasParentSection() const { return bHasParentSection; }
     605             : 
     606           0 :     void SetParentContents( HTMLTableCnts *pCnts ) { pParentContents = pCnts; }
     607           0 :     HTMLTableCnts *GetParentContents() const { return pParentContents; }
     608             : 
     609             :     void MakeParentContents();
     610             : 
     611           0 :     sal_Bool GetIsParentHeader() const { return bIsParentHead; }
     612             : 
     613             :     sal_Bool IsMakeTopSubTable() const { return bMakeTopSubTable; }
     614             :     void SetHasToFly() { bHasToFly=sal_True; }
     615           1 :     sal_Bool HasToFly() const { return bHasToFly; }
     616             : 
     617             :     void SetTable( const SwStartNode *pStNd, _HTMLTableContext *pCntxt,
     618             :                    sal_uInt16 nLeft, sal_uInt16 nRight,
     619             :                    const SwTable *pSwTab=0, sal_Bool bFrcFrame=sal_False );
     620             : 
     621         639 :     _HTMLTableContext *GetContext() const { return pContext; }
     622             : 
     623             :     SwHTMLTableLayout *CreateLayoutInfo();
     624             : 
     625           0 :     bool HasColTags() const { return bColSpec; }
     626             : 
     627           0 :     sal_uInt16 IncGrfsThatResize() { return pSwTable ? ((SwTable *)pSwTable)->IncGrfsThatResize() : 0; }
     628             : 
     629             :     void RegisterDrawObject( SdrObject *pObj, sal_uInt8 nPrcWidth );
     630             : 
     631           0 :     const SwTable *GetSwTable() const { return pSwTable; }
     632             : 
     633           0 :     void SetBGBrush( const SvxBrushItem& rBrush ) { delete pBGBrush; pBGBrush = new SvxBrushItem( rBrush ); }
     634             : 
     635           1 :     const OUString& GetId() const { return aId; }
     636           1 :     const OUString& GetClass() const { return aClass; }
     637           1 :     const OUString& GetStyle() const { return aStyle; }
     638           1 :     const OUString& GetDirection() const { return aDir; }
     639             : 
     640         259 :     void IncBoxCount() { nBoxes++; }
     641         573 :     sal_Bool IsOverflowing() const { return nBoxes > 64000; }
     642             : };
     643             : 
     644         260 : void HTMLTableCnts::InitCtor()
     645             : {
     646         260 :     pNext = 0;
     647         260 :     pLayoutInfo = 0;
     648             : 
     649         260 :     bNoBreak = sal_False;
     650         260 : }
     651             : 
     652         260 : HTMLTableCnts::HTMLTableCnts( const SwStartNode* pStNd ):
     653         260 :     pStartNode(pStNd), pTable(0)
     654             : {
     655         260 :     InitCtor();
     656         260 : }
     657             : 
     658           0 : HTMLTableCnts::HTMLTableCnts( HTMLTable* pTab ):
     659           0 :     pStartNode(0), pTable(pTab)
     660             : {
     661           0 :     InitCtor();
     662           0 : }
     663             : 
     664         260 : HTMLTableCnts::~HTMLTableCnts()
     665             : {
     666         260 :     delete pTable;              // die Tabellen brauchen wir nicht mehr
     667         260 :     delete pNext;
     668         260 : }
     669             : 
     670           0 : void HTMLTableCnts::Add( HTMLTableCnts* pNewCnts )
     671             : {
     672           0 :     HTMLTableCnts *pCnts = this;
     673             : 
     674           0 :     while( pCnts->pNext )
     675           0 :         pCnts = pCnts->pNext;
     676             : 
     677           0 :     pCnts->pNext = pNewCnts;
     678           0 : }
     679             : 
     680         260 : inline void HTMLTableCnts::SetTableBox( SwTableBox *pBox )
     681             : {
     682             :     OSL_ENSURE( pLayoutInfo, "Da sit noch keine Layout-Info" );
     683         260 :     if( pLayoutInfo )
     684         260 :         pLayoutInfo->SetTableBox( pBox );
     685         260 : }
     686             : 
     687         260 : SwHTMLTableLayoutCnts *HTMLTableCnts::CreateLayoutInfo()
     688             : {
     689         260 :     if( !pLayoutInfo )
     690             :     {
     691         260 :         SwHTMLTableLayoutCnts *pNextInfo = pNext ? pNext->CreateLayoutInfo() : 0;
     692         260 :         SwHTMLTableLayout *pTableInfo = pTable ? pTable->CreateLayoutInfo() : 0;
     693             : 
     694             :         pLayoutInfo = new SwHTMLTableLayoutCnts( pStartNode, pTableInfo,
     695         260 :                                                  bNoBreak, pNextInfo );
     696             :     }
     697             : 
     698         260 :     return pLayoutInfo;
     699             : }
     700             : 
     701         260 : HTMLTableCell::HTMLTableCell():
     702             :     pContents(0),
     703             :     pBGBrush(0),
     704             :     nNumFmt(0),
     705             :     nRowSpan(1),
     706             :     nColSpan(1),
     707             :     nWidth( 0 ),
     708             :     nValue(0),
     709             :     eVertOri( text::VertOrientation::NONE ),
     710             :     bProtected(sal_False),
     711             :     bRelWidth( sal_False ),
     712             :     bHasNumFmt(sal_False),
     713             :     bHasValue(sal_False),
     714             :     bNoWrap(sal_False),
     715         260 :     mbCovered(sal_False)
     716         260 : {}
     717             : 
     718         520 : HTMLTableCell::~HTMLTableCell()
     719             : {
     720             :     // der Inhalt ist in mehrere Zellen eingetragen, darf aber nur einmal
     721             :     // geloescht werden
     722         260 :     if( 1==nRowSpan && 1==nColSpan )
     723             :     {
     724         260 :         delete pContents;
     725         260 :         delete pBGBrush;
     726             :     }
     727         260 : }
     728             : 
     729         260 : void HTMLTableCell::Set( HTMLTableCnts *pCnts, sal_uInt16 nRSpan, sal_uInt16 nCSpan,
     730             :                          sal_Int16 eVert, SvxBrushItem *pBrush,
     731             :                          ::boost::shared_ptr<SvxBoxItem> const pBoxItem,
     732             :                          sal_Bool bHasNF, sal_uInt32 nNF, sal_Bool bHasV, double nVal,
     733             :                          sal_Bool bNWrap, sal_Bool bCovered )
     734             : {
     735         260 :     pContents = pCnts;
     736         260 :     nRowSpan = nRSpan;
     737         260 :     nColSpan = nCSpan;
     738         260 :     bProtected = sal_False;
     739         260 :     eVertOri = eVert;
     740         260 :     pBGBrush = pBrush;
     741         260 :     m_pBoxItem = pBoxItem;
     742             : 
     743         260 :     bHasNumFmt = bHasNF;
     744         260 :     bHasValue = bHasV;
     745         260 :     nNumFmt = nNF;
     746         260 :     nValue = nVal;
     747             : 
     748         260 :     bNoWrap = bNWrap;
     749         260 :     mbCovered = bCovered;
     750         260 : }
     751             : 
     752         260 : inline void HTMLTableCell::SetWidth( sal_uInt16 nWdth, sal_Bool bRelWdth )
     753             : {
     754         260 :     nWidth = nWdth;
     755         260 :     bRelWidth = bRelWdth;
     756         260 : }
     757             : 
     758           0 : void HTMLTableCell::SetProtected()
     759             : {
     760             :     // Die Inhalte dieser Zelle mussen nich irgenwo anders verankert
     761             :     // sein, weil sie nicht geloescht werden!!!
     762             : 
     763             :     // Inhalt loeschen
     764           0 :     pContents = 0;
     765             : 
     766             :     // Hintergrundfarbe kopieren.
     767           0 :     if( pBGBrush )
     768           0 :         pBGBrush = new SvxBrushItem( *pBGBrush );
     769             : 
     770           0 :     nRowSpan = 1;
     771           0 :     nColSpan = 1;
     772           0 :     bProtected = sal_True;
     773           0 : }
     774             : 
     775         260 : inline sal_Bool HTMLTableCell::GetNumFmt( sal_uInt32& rNumFmt ) const
     776             : {
     777         260 :     rNumFmt = nNumFmt;
     778         260 :     return bHasNumFmt;
     779             : }
     780             : 
     781           0 : inline sal_Bool HTMLTableCell::GetValue( double& rValue ) const
     782             : {
     783           0 :     rValue = nValue;
     784           0 :     return bHasValue;
     785             : }
     786             : 
     787         260 : SwHTMLTableLayoutCell *HTMLTableCell::CreateLayoutInfo()
     788             : {
     789         260 :     SwHTMLTableLayoutCnts *pCntInfo = pContents ? pContents->CreateLayoutInfo() : 0;
     790             : 
     791             :     return new SwHTMLTableLayoutCell( pCntInfo, nRowSpan, nColSpan, nWidth,
     792         260 :                                       bRelWidth, bNoWrap );
     793             : }
     794             : 
     795          52 : HTMLTableRow::HTMLTableRow( sal_uInt16 nCells ):
     796          52 :     pCells(new HTMLTableCells),
     797             :     bIsEndOfGroup(sal_False),
     798             :     bSplitable( sal_False ),
     799             :     nHeight(0),
     800             :     nEmptyRows(0),
     801             :     eAdjust(SVX_ADJUST_END),
     802             :     eVertOri(text::VertOrientation::TOP),
     803             :     pBGBrush(0),
     804         104 :     bBottomBorder(false)
     805             : {
     806         312 :     for( sal_uInt16 i=0; i<nCells; i++ )
     807             :     {
     808         260 :         pCells->push_back( new HTMLTableCell );
     809             :     }
     810             : 
     811             :     OSL_ENSURE(nCells == pCells->size(),
     812             :             "wrong Cell count in new HTML table row");
     813          52 : }
     814             : 
     815          52 : HTMLTableRow::~HTMLTableRow()
     816             : {
     817          52 :     delete pCells;
     818          52 :     delete pBGBrush;
     819          52 : }
     820             : 
     821           0 : inline void HTMLTableRow::SetHeight( sal_uInt16 nHght )
     822             : {
     823           0 :     if( nHght > nHeight  )
     824           0 :         nHeight = nHght;
     825           0 : }
     826             : 
     827        2387 : inline HTMLTableCell *HTMLTableRow::GetCell( sal_uInt16 nCell ) const
     828             : {
     829             :     OSL_ENSURE( nCell<pCells->size(),
     830             :         "ungueltiger Zellen-Index in HTML-Tabellenzeile" );
     831        2387 :     return &(*pCells)[nCell];
     832             : }
     833             : 
     834           0 : void HTMLTableRow::Expand( sal_uInt16 nCells, sal_Bool bOneCell )
     835             : {
     836             :     // die Zeile wird mit einer einzigen Zelle aufgefuellt, wenn
     837             :     // bOneCell gesetzt ist. Das geht, nur fuer Zeilen, in die keine
     838             :     // Zellen mehr eingefuegt werden!
     839             : 
     840           0 :     sal_uInt16 nColSpan = nCells-pCells->size();
     841           0 :     for( sal_uInt16 i=pCells->size(); i<nCells; i++ )
     842             :     {
     843           0 :         HTMLTableCell *pCell = new HTMLTableCell;
     844           0 :         if( bOneCell )
     845           0 :             pCell->SetColSpan( nColSpan );
     846             : 
     847           0 :         pCells->push_back( pCell );
     848           0 :         nColSpan--;
     849             :     }
     850             : 
     851             :     OSL_ENSURE(nCells == pCells->size(),
     852             :             "wrong Cell count in expanded HTML table row");
     853           0 : }
     854             : 
     855           0 : void HTMLTableRow::Shrink( sal_uInt16 nCells )
     856             : {
     857             :     OSL_ENSURE(nCells < pCells->size(), "number of cells too large");
     858             : 
     859             : #if OSL_DEBUG_LEVEL > 0
     860             :      sal_uInt16 nEnd = pCells->size();
     861             : #endif
     862             :     // The colspan of empty cells at the end has to be fixed to the new
     863             :     // number of cells.
     864           0 :     sal_uInt16 i=nCells;
     865           0 :     while( i )
     866             :     {
     867           0 :         HTMLTableCell *pCell = &(*pCells)[--i];
     868           0 :         if( !pCell->GetContents() )
     869             :         {
     870             : #if OSL_DEBUG_LEVEL > 0
     871             :             OSL_ENSURE( pCell->GetColSpan() == nEnd - i,
     872             :                     "invalid col span for empty cell at row end" );
     873             : #endif
     874           0 :             pCell->SetColSpan( nCells-i);
     875             :         }
     876             :         else
     877           0 :             break;
     878             :     }
     879             : #if OSL_DEBUG_LEVEL > 0
     880             :     for( i=nCells; i<nEnd; i++ )
     881             :     {
     882             :         HTMLTableCell *pCell = &(*pCells)[i];
     883             :         OSL_ENSURE( pCell->GetRowSpan() == 1,
     884             :                 "RowSpan von zu loesender Zelle ist falsch" );
     885             :         OSL_ENSURE( pCell->GetColSpan() == nEnd - i,
     886             :                     "ColSpan von zu loesender Zelle ist falsch" );
     887             :         OSL_ENSURE( !pCell->GetContents(), "Zu loeschende Zelle hat Inhalt" );
     888             :     }
     889             : #endif
     890             : 
     891           0 :     pCells->erase( pCells->begin() + nCells, pCells->end() );
     892           0 : }
     893             : 
     894           5 : HTMLTableColumn::HTMLTableColumn():
     895             :     bIsEndOfGroup(sal_False),
     896             :     nWidth(0), bRelWidth(sal_False),
     897             :     eAdjust(SVX_ADJUST_END), eVertOri(text::VertOrientation::TOP),
     898           5 :     bLeftBorder(false)
     899             : {
     900          35 :     for( sal_uInt16 i=0; i<6; i++ )
     901          30 :         aFrmFmts[i] = 0;
     902           5 : }
     903             : 
     904           5 : inline void HTMLTableColumn::SetWidth( sal_uInt16 nWdth, sal_Bool bRelWdth )
     905             : {
     906           5 :     if( bRelWidth==bRelWdth )
     907             :     {
     908           0 :         if( nWdth > nWidth )
     909           0 :             nWidth = nWdth;
     910             :     }
     911             :     else
     912           5 :         nWidth = nWdth;
     913           5 :     bRelWidth = bRelWdth;
     914           5 : }
     915             : 
     916           5 : inline SwHTMLTableLayoutColumn *HTMLTableColumn::CreateLayoutInfo()
     917             : {
     918           5 :     return new SwHTMLTableLayoutColumn( nWidth, bRelWidth, bLeftBorder );
     919             : }
     920             : 
     921           0 : inline sal_uInt16 HTMLTableColumn::GetFrmFmtIdx( sal_Bool bBorderLine,
     922             :                                              sal_Int16 eVertOrient ) const
     923             : {
     924             :     OSL_ENSURE( text::VertOrientation::TOP != eVertOrient, "Top ist nicht erlaubt" );
     925           0 :     sal_uInt16 n = bBorderLine ? 3 : 0;
     926           0 :     switch( eVertOrient )
     927             :     {
     928           0 :     case text::VertOrientation::CENTER:   n+=1;   break;
     929           0 :     case text::VertOrientation::BOTTOM:   n+=2;   break;
     930             :     default:
     931             :         ;
     932             :     }
     933           0 :     return n;
     934             : }
     935             : 
     936           0 : inline void HTMLTableColumn::SetFrmFmt( SwFrmFmt *pFmt, sal_Bool bBorderLine,
     937             :                                         sal_Int16 eVertOrient )
     938             : {
     939           0 :     aFrmFmts[GetFrmFmtIdx(bBorderLine,eVertOrient)] = pFmt;
     940           0 : }
     941             : 
     942           0 : inline SwFrmFmt *HTMLTableColumn::GetFrmFmt( sal_Bool bBorderLine,
     943             :                                              sal_Int16 eVertOrient ) const
     944             : {
     945           0 :     return aFrmFmts[GetFrmFmtIdx(bBorderLine,eVertOrient)];
     946             : }
     947             : 
     948           1 : void HTMLTable::InitCtor( const HTMLTableOptions *pOptions )
     949             : {
     950           1 :     pResizeDrawObjs = 0;
     951           1 :     pDrawObjPrcWidths = 0;
     952             : 
     953           1 :     pRows = new HTMLTableRows;
     954           1 :     pColumns = new HTMLTableColumns;
     955           1 :     nRows = 0;
     956           1 :     nCurRow = 0; nCurCol = 0;
     957             : 
     958           1 :     pBox1 = 0;
     959           1 :     pBoxFmt = 0; pLineFmt = 0;
     960           1 :     pLineFrmFmtNoHeight = 0;
     961           1 :     pInhBGBrush = 0;
     962             : 
     963           1 :     pPrevStNd = 0;
     964           1 :     pSwTable = 0;
     965             : 
     966           1 :     bTopBorder = false; bRightBorder = false;
     967           1 :     bTopAlwd = true; bRightAlwd = true;
     968           1 :     bFillerTopBorder = false; bFillerBottomBorder = false;
     969           1 :     bInhLeftBorder = false; bInhRightBorder = false;
     970           1 :     bBordersSet = false;
     971           1 :     bForceFrame = sal_False;
     972           1 :     nHeadlineRepeat = 0;
     973             : 
     974           1 :     nLeftMargin = 0;
     975           1 :     nRightMargin = 0;
     976             : 
     977           1 :     const Color& rBorderColor = pOptions->aBorderColor;
     978             : 
     979           1 :     long nBorderOpt = (long)pOptions->nBorder;
     980             :     long nPWidth = nBorderOpt==USHRT_MAX ? NETSCAPE_DFLT_BORDER
     981           1 :                                          : nBorderOpt;
     982           1 :     long nPHeight = nBorderOpt==USHRT_MAX ? 0 : nBorderOpt;
     983           1 :     SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
     984             : 
     985             :     // nBorder gibt die Breite der Umrandung an, wie sie in die
     986             :     // Breitenberechnung in Netscape einfliesst. Wenn pOption->nBorder
     987             :     // == USHRT_MAX, wurde keine BORDER-Option angegeben. Trotzdem fliesst
     988             :     // eine 1 Pixel breite Umrandung in die Breitenberechnung mit ein.
     989           1 :     nBorder = (sal_uInt16)nPWidth;
     990           1 :     if( nBorderOpt==USHRT_MAX )
     991           1 :         nPWidth = 0;
     992             : 
     993             :     // HACK: ein Pixel-breite Linien sollen zur Haarlinie werden, wenn
     994             :     // wir mit doppelter Umrandung arbeiten
     995           1 :     if( pOptions->nCellSpacing!=0 && nBorderOpt==1 )
     996             :     {
     997           0 :         nPWidth = 1;
     998           0 :         nPHeight = 1;
     999             :     }
    1000             : 
    1001           1 :     if ( pOptions->nCellSpacing != 0 )
    1002             :     {
    1003           0 :         aTopBorderLine.SetBorderLineStyle(table::BorderLineStyle::DOUBLE);
    1004             :     }
    1005           1 :     aTopBorderLine.SetWidth( nPHeight );
    1006           1 :     aTopBorderLine.SetColor( rBorderColor );
    1007           1 :     aBottomBorderLine = aTopBorderLine;
    1008             : 
    1009           1 :     if( nPWidth == nPHeight )
    1010             :     {
    1011           1 :         aLeftBorderLine = aTopBorderLine;
    1012             :     }
    1013             :     else
    1014             :     {
    1015           0 :         if ( pOptions->nCellSpacing != 0 )
    1016             :         {
    1017           0 :             aLeftBorderLine.SetBorderLineStyle(table::BorderLineStyle::DOUBLE);
    1018             :         }
    1019           0 :         aLeftBorderLine.SetWidth( nPWidth );
    1020           0 :         aLeftBorderLine.SetColor( rBorderColor );
    1021             :     }
    1022           1 :     aRightBorderLine = aLeftBorderLine;
    1023             : 
    1024           1 :     if( pOptions->nCellSpacing != 0 )
    1025             :     {
    1026           0 :         aBorderLine.SetBorderLineStyle(table::BorderLineStyle::DOUBLE);
    1027           0 :         aBorderLine.SetWidth( DEF_LINE_WIDTH_0 );
    1028             :     }
    1029             :     else
    1030             :     {
    1031           1 :         aBorderLine.SetWidth( DEF_LINE_WIDTH_0 );
    1032             :     }
    1033           1 :     aBorderLine.SetColor( rBorderColor );
    1034             : 
    1035           1 :     if( nCellPadding )
    1036             :     {
    1037           1 :         if( nCellPadding==USHRT_MAX )
    1038           0 :             nCellPadding = MIN_BORDER_DIST; // default
    1039             :         else
    1040             :         {
    1041           1 :             nCellPadding = pParser->ToTwips( nCellPadding );
    1042           1 :             if( nCellPadding<MIN_BORDER_DIST  )
    1043           0 :                 nCellPadding = MIN_BORDER_DIST;
    1044             :         }
    1045             :     }
    1046           1 :     if( nCellSpacing )
    1047             :     {
    1048           0 :         if( nCellSpacing==USHRT_MAX )
    1049           0 :             nCellSpacing = NETSCAPE_DFLT_CELLSPACING;
    1050           0 :         nCellSpacing = pParser->ToTwips( nCellSpacing );
    1051             :     }
    1052             : 
    1053           1 :     nPWidth = pOptions->nHSpace;
    1054           1 :     nPHeight = pOptions->nVSpace;
    1055           1 :     SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
    1056           1 :     nHSpace = (sal_uInt16)nPWidth;
    1057           1 :     nVSpace = (sal_uInt16)nPHeight;
    1058             : 
    1059           1 :     bColSpec = false;
    1060             : 
    1061             :     pBGBrush = pParser->CreateBrushItem(
    1062             :                     pOptions->bBGColor ? &(pOptions->aBGColor) : 0,
    1063           1 :                     pOptions->aBGImage, aEmptyOUStr, aEmptyOUStr, aEmptyOUStr );
    1064             : 
    1065           1 :     pContext = 0;
    1066           1 :     pParentContents = 0;
    1067             : 
    1068           1 :     aId = pOptions->aId;
    1069           1 :     aClass = pOptions->aClass;
    1070           1 :     aStyle = pOptions->aStyle;
    1071           1 :     aDir = pOptions->aDir;
    1072           1 : }
    1073             : 
    1074           1 : HTMLTable::HTMLTable( SwHTMLParser* pPars, HTMLTable *pTopTab,
    1075             :                       sal_Bool bParHead,
    1076             :                       sal_Bool bHasParentSec, sal_Bool bTopTbl, sal_Bool bHasToFlw,
    1077             :                       const HTMLTableOptions *pOptions ) :
    1078             :     nCols( pOptions->nCols ),
    1079             :     nFilledCols( 0 ),
    1080             :     nCellPadding( pOptions->nCellPadding ),
    1081             :     nCellSpacing( pOptions->nCellSpacing ),
    1082             :     nBoxes( 1 ),
    1083             :     pCaptionStartNode( 0 ),
    1084             :     bTableAdjustOfTag( pTopTab ? sal_False : pOptions->bTableAdjust ),
    1085             :     bIsParentHead( bParHead ),
    1086             :     bHasParentSection( bHasParentSec ),
    1087             :     bMakeTopSubTable( bTopTbl ),
    1088             :     bHasToFly( bHasToFlw ),
    1089           1 :     bFixedCols( pOptions->nCols>0 ),
    1090             :     bPrcWidth( pOptions->bPrcWidth ),
    1091             :     pParser( pPars ),
    1092             :     pTopTable( pTopTab ? pTopTab : this ),
    1093             :     pLayoutInfo( 0 ),
    1094             :     nWidth( pOptions->nWidth ),
    1095             :     nHeight( pTopTab ? 0 : pOptions->nHeight ),
    1096             :     eTableAdjust( pOptions->eAdjust ),
    1097             :     eVertOri( pOptions->eVertOri ),
    1098             :     eFrame( pOptions->eFrame ),
    1099             :     eRules( pOptions->eRules ),
    1100             :     bTopCaption( sal_False ),
    1101           2 :     bFirstCell( !pTopTab )
    1102             : {
    1103           1 :     InitCtor( pOptions );
    1104             : 
    1105           1 :     for( sal_uInt16 i=0; i<nCols; i++ )
    1106           0 :         pColumns->push_back( new HTMLTableColumn );
    1107           1 : }
    1108             : 
    1109           2 : HTMLTable::~HTMLTable()
    1110             : {
    1111           1 :     delete pResizeDrawObjs;
    1112           1 :     delete pDrawObjPrcWidths;
    1113             : 
    1114           1 :     delete pRows;
    1115           1 :     delete pColumns;
    1116           1 :     delete pBGBrush;
    1117           1 :     delete pInhBGBrush;
    1118             : 
    1119           1 :     delete pContext;
    1120             : 
    1121             :     // pLayoutInfo wurde entweder bereits geloescht oder muss aber es
    1122             :     // in den Besitz der SwTable uebergegangen.
    1123           1 : }
    1124             : 
    1125           1 : SwHTMLTableLayout *HTMLTable::CreateLayoutInfo()
    1126             : {
    1127           1 :     sal_uInt16 nW = bPrcWidth ? nWidth : pParser->ToTwips( nWidth );
    1128             : 
    1129           1 :     sal_uInt16 nBorderWidth = GetBorderWidth( aBorderLine, sal_True );
    1130             :     sal_uInt16 nLeftBorderWidth =
    1131           1 :         ((*pColumns)[0]).bLeftBorder ? GetBorderWidth( aLeftBorderLine, sal_True ) : 0;
    1132             :     sal_uInt16 nRightBorderWidth =
    1133           1 :         bRightBorder ? GetBorderWidth( aRightBorderLine, sal_True ) : 0;
    1134           1 :     sal_uInt16 nInhLeftBorderWidth = 0;
    1135           1 :     sal_uInt16 nInhRightBorderWidth = 0;
    1136             : 
    1137             :     pLayoutInfo = new SwHTMLTableLayout(
    1138             :                         pSwTable,
    1139             :                         nRows, nCols, bFixedCols, bColSpec,
    1140             :                         nW, bPrcWidth, nBorder, nCellPadding,
    1141             :                         nCellSpacing, eTableAdjust,
    1142             :                         nLeftMargin, nRightMargin,
    1143             :                         nBorderWidth, nLeftBorderWidth, nRightBorderWidth,
    1144           1 :                         nInhLeftBorderWidth, nInhRightBorderWidth );
    1145             : 
    1146           1 :     sal_Bool bExportable = sal_True;
    1147             :     sal_uInt16 i;
    1148          53 :     for( i=0; i<nRows; i++ )
    1149             :     {
    1150          52 :         HTMLTableRow *pRow = &(*pRows)[i];
    1151         312 :         for( sal_uInt16 j=0; j<nCols; j++ )
    1152             :         {
    1153             :             SwHTMLTableLayoutCell *pLayoutCell =
    1154         260 :                 pRow->GetCell(j)->CreateLayoutInfo();
    1155             : 
    1156         260 :             pLayoutInfo->SetCell( pLayoutCell, i, j );
    1157             : 
    1158         260 :             if( bExportable )
    1159             :             {
    1160             :                 SwHTMLTableLayoutCnts *pLayoutCnts =
    1161         260 :                     pLayoutCell->GetContents();
    1162         780 :                 bExportable = !pLayoutCnts ||
    1163         520 :                               ( pLayoutCnts->GetStartNode() &&
    1164         520 :                                 !pLayoutCnts->GetNext() );
    1165             :             }
    1166             :         }
    1167             :     }
    1168             : 
    1169           1 :     pLayoutInfo->SetExportable( bExportable );
    1170             : 
    1171           6 :     for( i=0; i<nCols; i++ )
    1172           5 :         pLayoutInfo->SetColumn( ((*pColumns)[i]).CreateLayoutInfo(), i );
    1173             : 
    1174           1 :     return pLayoutInfo;
    1175             : }
    1176             : 
    1177           0 : inline void HTMLTable::SetCaption( const SwStartNode *pStNd, sal_Bool bTop )
    1178             : {
    1179           0 :     pCaptionStartNode = pStNd;
    1180           0 :     bTopCaption = bTop;
    1181           0 : }
    1182             : 
    1183           0 : void HTMLTable::FixRowSpan( sal_uInt16 nRow, sal_uInt16 nCol,
    1184             :                             const HTMLTableCnts *pCnts )
    1185             : {
    1186           0 :     sal_uInt16 nRowSpan=1;
    1187             :     HTMLTableCell *pCell;
    1188           0 :     while( ( pCell=GetCell(nRow,nCol), pCell->GetContents()==pCnts ) )
    1189             :     {
    1190           0 :         pCell->SetRowSpan( nRowSpan );
    1191           0 :         if( pLayoutInfo )
    1192           0 :             pLayoutInfo->GetCell(nRow,nCol)->SetRowSpan( nRowSpan );
    1193             : 
    1194           0 :         if( !nRow ) break;
    1195           0 :         nRowSpan++; nRow--;
    1196             :     }
    1197           0 : }
    1198             : 
    1199           0 : void HTMLTable::ProtectRowSpan( sal_uInt16 nRow, sal_uInt16 nCol, sal_uInt16 nRowSpan )
    1200             : {
    1201           0 :     for( sal_uInt16 i=0; i<nRowSpan; i++ )
    1202             :     {
    1203           0 :         GetCell(nRow+i,nCol)->SetProtected();
    1204           0 :         if( pLayoutInfo )
    1205           0 :             pLayoutInfo->GetCell(nRow+i,nCol)->SetProtected();
    1206             :     }
    1207           0 : }
    1208             : 
    1209             : // Suchen des SwStartNodes der letzten belegten Vorgaengerbox
    1210           0 : const SwStartNode* HTMLTable::GetPrevBoxStartNode( sal_uInt16 nRow, sal_uInt16 nCol ) const
    1211             : {
    1212           0 :     const HTMLTableCnts *pPrevCnts = 0;
    1213             : 
    1214           0 :     if( 0==nRow )
    1215             :     {
    1216             :         // immer die Vorgaenger-Zelle
    1217           0 :         if( nCol>0 )
    1218           0 :             pPrevCnts = GetCell( 0, nCol-1 )->GetContents();
    1219             :         else
    1220           0 :             return pPrevStNd;
    1221             :     }
    1222           0 :     else if( USHRT_MAX==nRow && USHRT_MAX==nCol )
    1223             :         // der Contents der letzten Zelle
    1224           0 :         pPrevCnts = GetCell( nRows-1, nCols-1 )->GetContents();
    1225             :     else
    1226             :     {
    1227             :         sal_uInt16 i;
    1228           0 :         HTMLTableRow *pPrevRow = &(*pRows)[nRow-1];
    1229             : 
    1230             :         // evtl. eine Zelle in der aktuellen Zeile
    1231           0 :         i = nCol;
    1232           0 :         while( i )
    1233             :         {
    1234           0 :             i--;
    1235           0 :             if( 1 == pPrevRow->GetCell(i)->GetRowSpan() )
    1236             :             {
    1237           0 :                 pPrevCnts = GetCell(nRow,i)->GetContents();
    1238           0 :                 break;
    1239             :             }
    1240             :         }
    1241             : 
    1242             :         // sonst die letzte gefuellte Zelle der Zeile davor suchen
    1243           0 :         if( !pPrevCnts )
    1244             :         {
    1245           0 :             i = nCols;
    1246           0 :             while( !pPrevCnts && i )
    1247             :             {
    1248           0 :                 i--;
    1249           0 :                 pPrevCnts = pPrevRow->GetCell(i)->GetContents();
    1250             :             }
    1251             :         }
    1252             :     }
    1253             :     OSL_ENSURE( pPrevCnts, "keine gefuellte Vorgaenger-Zelle gefunden" );
    1254           0 :     if( !pPrevCnts )
    1255             :     {
    1256           0 :         pPrevCnts = GetCell(0,0)->GetContents();
    1257           0 :         if( !pPrevCnts )
    1258           0 :             return pPrevStNd;
    1259             :     }
    1260             : 
    1261           0 :     while( pPrevCnts->Next() )
    1262           0 :         pPrevCnts = pPrevCnts->Next();
    1263             : 
    1264           0 :     return ( pPrevCnts->GetStartNode() ? pPrevCnts->GetStartNode()
    1265           0 :                : pPrevCnts->GetTable()->GetPrevBoxStartNode( USHRT_MAX, USHRT_MAX ) );
    1266             : }
    1267             : 
    1268           0 : static sal_Bool IsBoxEmpty( const SwTableBox *pBox )
    1269             : {
    1270           0 :     const SwStartNode *pSttNd = pBox->GetSttNd();
    1271           0 :     if( pSttNd &&
    1272           0 :         pSttNd->GetIndex() + 2 == pSttNd->EndOfSectionIndex() )
    1273             :     {
    1274             :         const SwCntntNode *pCNd =
    1275           0 :             pSttNd->GetNodes()[pSttNd->GetIndex()+1]->GetCntntNode();
    1276           0 :         if( pCNd && !pCNd->Len() )
    1277           0 :             return sal_True;
    1278             :     }
    1279             : 
    1280           0 :     return sal_False;
    1281             : }
    1282             : 
    1283           0 : sal_uInt16 HTMLTable::GetTopCellSpace( sal_uInt16 nRow, sal_uInt16 nRowSpan,
    1284             :                                    sal_Bool bSwBorders ) const
    1285             : {
    1286           0 :     sal_uInt16 nSpace = nCellPadding;
    1287             : 
    1288           0 :     if( nRow == 0 )
    1289             :     {
    1290           0 :         nSpace += nBorder + nCellSpacing;
    1291           0 :         if( bSwBorders )
    1292             :         {
    1293             :             sal_uInt16 nTopBorderWidth =
    1294           0 :                 GetBorderWidth( aTopBorderLine, sal_True );
    1295           0 :             if( nSpace < nTopBorderWidth )
    1296           0 :                 nSpace = nTopBorderWidth;
    1297             :         }
    1298             :     }
    1299           0 :     else if( bSwBorders && (*pRows)[nRow+nRowSpan-1].bBottomBorder &&
    1300             :              nSpace < MIN_BORDER_DIST )
    1301             :     {
    1302             :         OSL_ENSURE( !nCellPadding, "GetTopCellSpace: CELLPADDING!=0" );
    1303             :         // Wenn die Gegenueberliegende Seite umrandet ist muessen
    1304             :         // wir zumindest den minimalen Abstand zum Inhalt
    1305             :         // beruecksichtigen. (Koennte man zusaetzlich auch an
    1306             :         // nCellPadding festmachen.)
    1307           0 :         nSpace = MIN_BORDER_DIST;
    1308             :     }
    1309             : 
    1310           0 :     return nSpace;
    1311             : }
    1312             : 
    1313           0 : sal_uInt16 HTMLTable::GetBottomCellSpace( sal_uInt16 nRow, sal_uInt16 nRowSpan,
    1314             :                                       sal_Bool bSwBorders ) const
    1315             : {
    1316           0 :     sal_uInt16 nSpace = nCellSpacing + nCellPadding;
    1317             : 
    1318           0 :     if( nRow+nRowSpan == nRows )
    1319             :     {
    1320           0 :         nSpace = nSpace + nBorder;
    1321             : 
    1322           0 :         if( bSwBorders )
    1323             :         {
    1324             :             sal_uInt16 nBottomBorderWidth =
    1325           0 :                 GetBorderWidth( aBottomBorderLine, sal_True );
    1326           0 :             if( nSpace < nBottomBorderWidth )
    1327           0 :                 nSpace = nBottomBorderWidth;
    1328             :         }
    1329             :     }
    1330           0 :     else if( bSwBorders )
    1331             :     {
    1332           0 :         if( (*pRows)[nRow+nRowSpan+1].bBottomBorder )
    1333             :         {
    1334           0 :             sal_uInt16 nBorderWidth = GetBorderWidth( aBorderLine, sal_True );
    1335           0 :             if( nSpace < nBorderWidth )
    1336           0 :                 nSpace = nBorderWidth;
    1337             :         }
    1338           0 :         else if( nRow==0 && bTopBorder && nSpace < MIN_BORDER_DIST )
    1339             :         {
    1340             :             OSL_ENSURE( GetBorderWidth( aTopBorderLine, sal_True ) > 0,
    1341             :                     "GetBottomCellSpace: |aTopLine| == 0" );
    1342             :             OSL_ENSURE( !nCellPadding, "GetBottomCellSpace: CELLPADDING!=0" );
    1343             :             // Wenn die Gegenueberliegende Seite umrandet ist muessen
    1344             :             // wir zumindest den minimalen Abstand zum Inhalt
    1345             :             // beruecksichtigen. (Koennte man zusaetzlich auch an
    1346             :             // nCellPadding festmachen.)
    1347           0 :             nSpace = MIN_BORDER_DIST;
    1348             :         }
    1349             :     }
    1350             : 
    1351           0 :     return nSpace;
    1352             : }
    1353             : 
    1354         260 : void HTMLTable::FixFrameFmt( SwTableBox *pBox,
    1355             :                              sal_uInt16 nRow, sal_uInt16 nCol,
    1356             :                              sal_uInt16 nRowSpan, sal_uInt16 nColSpan,
    1357             :                              sal_Bool bFirstPara, sal_Bool bLastPara ) const
    1358             : {
    1359         260 :     SwFrmFmt *pFrmFmt = 0;      // frame::Frame-Format
    1360         260 :     sal_Int16 eVOri = text::VertOrientation::NONE;
    1361         260 :     const SvxBrushItem *pBGBrushItem = 0;   // Hintergrund
    1362         260 :     boost::shared_ptr<SvxBoxItem> pBoxItem;
    1363         260 :     sal_Bool bTopLine = sal_False, bBottomLine = sal_False, bLastBottomLine = sal_False;
    1364         260 :     sal_Bool bReUsable = sal_False;     // Format nochmals verwendbar?
    1365         260 :     sal_uInt16 nEmptyRows = 0;
    1366         260 :     sal_Bool bHasNumFmt = sal_False;
    1367         260 :     sal_Bool bHasValue = sal_False;
    1368         260 :     sal_uInt32 nNumFmt = 0;
    1369         260 :     double nValue = 0.0;
    1370             : 
    1371         260 :     HTMLTableColumn *pColumn = &(*pColumns)[nCol];
    1372             : 
    1373         260 :     if( pBox->GetSttNd() )
    1374             :     {
    1375             :         // die Hintergrundfarbe/-grafik bestimmen
    1376         260 :         const HTMLTableCell *pCell = GetCell( nRow, nCol );
    1377         260 :         pBoxItem = pCell->GetBoxItem();
    1378         260 :         pBGBrushItem = pCell->GetBGBrush();
    1379         260 :         if( !pBGBrushItem )
    1380             :         {
    1381             :             // Wenn die Zelle ueber mehrere Zeilen geht muss ein evtl.
    1382             :             // an der Zeile gesetzter Hintergrund an die Zelle uebernommen
    1383             :             // werden.
    1384             :             // Wenn es sich um eine Tabelle in der Tabelle handelt und
    1385             :             // die Zelle ueber die gesamte Heoehe der Tabelle geht muss
    1386             :             // ebenfalls der Hintergrund der Zeile uebernommen werden, weil
    1387             :             // die Line von der GC (zu Recht) wegoptimiert wird.
    1388           0 :             if( nRowSpan > 1 || (this != pTopTable && nRowSpan==nRows) )
    1389             :             {
    1390           0 :                 pBGBrushItem = (*pRows)[nRow].GetBGBrush();
    1391           0 :                 if( !pBGBrushItem && this != pTopTable )
    1392             :                 {
    1393           0 :                     pBGBrushItem = GetBGBrush();
    1394           0 :                     if( !pBGBrushItem )
    1395           0 :                         pBGBrushItem = GetInhBGBrush();
    1396             :                 }
    1397             :             }
    1398             :         }
    1399             : 
    1400         260 :         bTopLine = 0==nRow && bTopBorder && bFirstPara;
    1401         260 :         if( (*pRows)[nRow+nRowSpan-1].bBottomBorder && bLastPara )
    1402             :         {
    1403           0 :             nEmptyRows = (*pRows)[nRow+nRowSpan-1].GetEmptyRows();
    1404           0 :             if( nRow+nRowSpan == nRows )
    1405           0 :                 bLastBottomLine = sal_True;
    1406             :             else
    1407           0 :                 bBottomLine = sal_True;
    1408             :         }
    1409             : 
    1410         260 :         eVOri = pCell->GetVertOri();
    1411         260 :         bHasNumFmt = pCell->GetNumFmt( nNumFmt );
    1412         260 :         if( bHasNumFmt )
    1413           0 :             bHasValue = pCell->GetValue( nValue );
    1414             : 
    1415         520 :         if( nColSpan==1 && !bTopLine && !bLastBottomLine && !nEmptyRows &&
    1416         260 :             !pBGBrushItem && !bHasNumFmt && !pBoxItem)
    1417             :         {
    1418           0 :             pFrmFmt = pColumn->GetFrmFmt( bBottomLine, eVOri );
    1419           0 :             bReUsable = !pFrmFmt;
    1420             :         }
    1421             :     }
    1422             : 
    1423         260 :     if( !pFrmFmt )
    1424             :     {
    1425         260 :         pFrmFmt = pBox->ClaimFrmFmt();
    1426             : 
    1427             :         // die Breite der Box berechnen
    1428             :         SwTwips nFrmWidth = (SwTwips)pLayoutInfo->GetColumn(nCol)
    1429         260 :                                                 ->GetRelColWidth();
    1430         260 :         for( sal_uInt16 i=1; i<nColSpan; i++ )
    1431             :             nFrmWidth += (SwTwips)pLayoutInfo->GetColumn(nCol+i)
    1432           0 :                                              ->GetRelColWidth();
    1433             : 
    1434             :         // die Umrandung nur an Edit-Boxen setzen (bei der oberen und unteren
    1435             :         // Umrandung muss beruecks. werden, ob es sich um den ersten oder
    1436             :         // letzen Absatz der Zelle handelt)
    1437         260 :         if( pBox->GetSttNd() )
    1438             :         {
    1439         260 :             sal_Bool bSet = (nCellPadding > 0);
    1440             : 
    1441         260 :             SvxBoxItem aBoxItem( RES_BOX );
    1442         260 :             long nInnerFrmWidth = nFrmWidth;
    1443             : 
    1444         260 :             if( bTopLine )
    1445             :             {
    1446           0 :                 aBoxItem.SetLine( &aTopBorderLine, BOX_LINE_TOP );
    1447           0 :                 bSet = sal_True;
    1448             :             }
    1449         260 :             if( bLastBottomLine )
    1450             :             {
    1451           0 :                 aBoxItem.SetLine( &aBottomBorderLine, BOX_LINE_BOTTOM );
    1452           0 :                 bSet = sal_True;
    1453             :             }
    1454         260 :             else if( bBottomLine )
    1455             :             {
    1456           0 :                 if( nEmptyRows && !aBorderLine.GetInWidth() )
    1457             :                 {
    1458             :                     // Leere Zeilen koennen zur Zeit nur dann ueber
    1459             :                     // dicke Linien simuliert werden, wenn die Linie
    1460             :                     // einfach ist.
    1461           0 :                     SvxBorderLine aThickBorderLine( aBorderLine );
    1462             : 
    1463           0 :                     sal_uInt16 nBorderWidth = aBorderLine.GetOutWidth();
    1464           0 :                     nBorderWidth *= (nEmptyRows + 1);
    1465             :                     aThickBorderLine.SetBorderLineStyle(
    1466           0 :                             table::BorderLineStyle::SOLID);
    1467           0 :                     aThickBorderLine.SetWidth( nBorderWidth );
    1468           0 :                     aBoxItem.SetLine( &aThickBorderLine, BOX_LINE_BOTTOM );
    1469             :                 }
    1470             :                 else
    1471             :                 {
    1472           0 :                     aBoxItem.SetLine( &aBorderLine, BOX_LINE_BOTTOM );
    1473             :                 }
    1474           0 :                 bSet = sal_True;
    1475             :             }
    1476         260 :             if( ((*pColumns)[nCol]).bLeftBorder )
    1477             :             {
    1478             :                 const SvxBorderLine& rBorderLine =
    1479           0 :                     0==nCol ? aLeftBorderLine : aBorderLine;
    1480           0 :                 aBoxItem.SetLine( &rBorderLine, BOX_LINE_LEFT );
    1481           0 :                 nInnerFrmWidth -= GetBorderWidth( rBorderLine );
    1482           0 :                 bSet = sal_True;
    1483             :             }
    1484         260 :             if( nCol+nColSpan == nCols && bRightBorder )
    1485             :             {
    1486           0 :                 aBoxItem.SetLine( &aRightBorderLine, BOX_LINE_RIGHT );
    1487           0 :                 nInnerFrmWidth -= GetBorderWidth( aRightBorderLine );
    1488           0 :                 bSet = sal_True;
    1489             :             }
    1490             : 
    1491         260 :             if (pBoxItem)
    1492             :             {
    1493         260 :                 pFrmFmt->SetFmtAttr( *pBoxItem );
    1494             :             }
    1495           0 :             else if (bSet)
    1496             :             {
    1497             :                 // BorderDist nicht mehr Bestandteil einer Zelle mit fixer Breite
    1498             :                 sal_uInt16 nBDist = static_cast< sal_uInt16 >(
    1499           0 :                     (2*nCellPadding <= nInnerFrmWidth) ? nCellPadding
    1500           0 :                                                       : (nInnerFrmWidth / 2) );
    1501             :                 // wir setzen das Item nur, wenn es eine Umrandung gibt
    1502             :                 // oder eine sheet::Border-Distanz vorgegeben ist. Fehlt letztere,
    1503             :                 // dann gibt es eine Umrandung, und wir muessen die Distanz
    1504             :                 // setzen
    1505           0 :                 aBoxItem.SetDistance( nBDist ? nBDist : MIN_BORDER_DIST );
    1506           0 :                 pFrmFmt->SetFmtAttr( aBoxItem );
    1507             :             }
    1508             :             else
    1509           0 :                 pFrmFmt->ResetFmtAttr( RES_BOX );
    1510             : 
    1511         260 :             if( pBGBrushItem )
    1512             :             {
    1513         260 :                 pFrmFmt->SetFmtAttr( *pBGBrushItem );
    1514             :             }
    1515             :             else
    1516           0 :                 pFrmFmt->ResetFmtAttr( RES_BACKGROUND );
    1517             : 
    1518             :             // Format nur setzten, wenn es auch einen Value gibt oder die Box leer ist.
    1519         260 :             if( bHasNumFmt && (bHasValue || IsBoxEmpty(pBox)) )
    1520             :             {
    1521             :                 sal_Bool bLock = pFrmFmt->GetDoc()->GetNumberFormatter()
    1522           0 :                                      ->IsTextFormat( nNumFmt );
    1523           0 :                 SfxItemSet aItemSet( *pFrmFmt->GetAttrSet().GetPool(),
    1524           0 :                                      RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
    1525           0 :                 SvxAdjust eAdjust = SVX_ADJUST_END;
    1526           0 :                 SwCntntNode *pCNd = 0;
    1527           0 :                 if( !bLock )
    1528             :                 {
    1529           0 :                     const SwStartNode *pSttNd = pBox->GetSttNd();
    1530           0 :                     pCNd = pSttNd->GetNodes()[pSttNd->GetIndex()+1]
    1531           0 :                                  ->GetCntntNode();
    1532             :                     const SfxPoolItem *pItem;
    1533           0 :                     if( pCNd && pCNd->HasSwAttrSet() &&
    1534           0 :                         SFX_ITEM_SET==pCNd->GetpSwAttrSet()->GetItemState(
    1535           0 :                             RES_PARATR_ADJUST, false, &pItem ) )
    1536             :                     {
    1537             :                         eAdjust = ((const SvxAdjustItem *)pItem)
    1538           0 :                             ->GetAdjust();
    1539             :                     }
    1540             :                 }
    1541           0 :                 aItemSet.Put( SwTblBoxNumFormat(nNumFmt) );
    1542           0 :                 if( bHasValue )
    1543           0 :                     aItemSet.Put( SwTblBoxValue(nValue) );
    1544             : 
    1545           0 :                 if( bLock )
    1546           0 :                     pFrmFmt->LockModify();
    1547           0 :                 pFrmFmt->SetFmtAttr( aItemSet );
    1548           0 :                 if( bLock )
    1549           0 :                     pFrmFmt->UnlockModify();
    1550           0 :                 else if( pCNd && SVX_ADJUST_END != eAdjust )
    1551             :                 {
    1552           0 :                     SvxAdjustItem aAdjItem( eAdjust, RES_PARATR_ADJUST );
    1553           0 :                     pCNd->SetAttr( aAdjItem );
    1554           0 :                 }
    1555             :             }
    1556             :             else
    1557         260 :                 pFrmFmt->ResetFmtAttr( RES_BOXATR_FORMAT );
    1558             : 
    1559             :             OSL_ENSURE( eVOri != text::VertOrientation::TOP, "text::VertOrientation::TOP ist nicht erlaubt!" );
    1560         260 :             if( text::VertOrientation::NONE != eVOri )
    1561             :             {
    1562           0 :                 pFrmFmt->SetFmtAttr( SwFmtVertOrient( 0, eVOri ) );
    1563             :             }
    1564             :             else
    1565         260 :                 pFrmFmt->ResetFmtAttr( RES_VERT_ORIENT );
    1566             : 
    1567         260 :             if( bReUsable )
    1568           0 :                 pColumn->SetFrmFmt( pFrmFmt, bBottomLine, eVOri );
    1569             :         }
    1570             :         else
    1571             :         {
    1572           0 :             pFrmFmt->ResetFmtAttr( RES_BOX );
    1573           0 :             pFrmFmt->ResetFmtAttr( RES_BACKGROUND );
    1574           0 :             pFrmFmt->ResetFmtAttr( RES_VERT_ORIENT );
    1575           0 :             pFrmFmt->ResetFmtAttr( RES_BOXATR_FORMAT );
    1576             :         }
    1577             :     }
    1578             :     else
    1579             :     {
    1580             :         OSL_ENSURE( pBox->GetSttNd() ||
    1581             :                 SFX_ITEM_SET!=pFrmFmt->GetAttrSet().GetItemState(
    1582             :                                     RES_VERT_ORIENT, false ),
    1583             :                 "Box ohne Inhalt hat vertikale Ausrichtung" );
    1584           0 :         pBox->ChgFrmFmt( (SwTableBoxFmt*)pFrmFmt );
    1585         260 :     }
    1586             : 
    1587         260 : }
    1588             : 
    1589           0 : void HTMLTable::FixFillerFrameFmt( SwTableBox *pBox, sal_Bool bRight ) const
    1590             : {
    1591           0 :     SwFrmFmt *pFrmFmt = pBox->ClaimFrmFmt();
    1592             : 
    1593           0 :     if( bFillerTopBorder || bFillerBottomBorder ||
    1594           0 :         (!bRight && bInhLeftBorder) || (bRight && bInhRightBorder) )
    1595             :     {
    1596           0 :         SvxBoxItem aBoxItem( RES_BOX );
    1597           0 :         if( bFillerTopBorder )
    1598           0 :             aBoxItem.SetLine( &aTopBorderLine, BOX_LINE_TOP );
    1599           0 :         if( bFillerBottomBorder )
    1600           0 :             aBoxItem.SetLine( &aBottomBorderLine, BOX_LINE_BOTTOM );
    1601           0 :         if( !bRight && bInhLeftBorder )
    1602           0 :             aBoxItem.SetLine( &aInhLeftBorderLine, BOX_LINE_LEFT );
    1603           0 :         if( bRight && bInhRightBorder )
    1604           0 :             aBoxItem.SetLine( &aInhRightBorderLine, BOX_LINE_RIGHT );
    1605           0 :         aBoxItem.SetDistance( MIN_BORDER_DIST );
    1606           0 :         pFrmFmt->SetFmtAttr( aBoxItem );
    1607             :     }
    1608             :     else
    1609             :     {
    1610           0 :         pFrmFmt->ResetFmtAttr( RES_BOX );
    1611             :     }
    1612             : 
    1613           0 :     if( GetInhBGBrush() )
    1614           0 :         pFrmFmt->SetFmtAttr( *GetInhBGBrush() );
    1615             :     else
    1616           0 :         pFrmFmt->ResetFmtAttr( RES_BACKGROUND );
    1617             : 
    1618           0 :     pFrmFmt->ResetFmtAttr( RES_VERT_ORIENT );
    1619           0 :     pFrmFmt->ResetFmtAttr( RES_BOXATR_FORMAT );
    1620           0 : }
    1621             : 
    1622         260 : SwTableBox *HTMLTable::NewTableBox( const SwStartNode *pStNd,
    1623             :                                     SwTableLine *pUpper ) const
    1624             : {
    1625             :     SwTableBox *pBox;
    1626             : 
    1627         261 :     if( pTopTable->pBox1 &&
    1628           1 :         pTopTable->pBox1->GetSttNd() == pStNd )
    1629             :     {
    1630             :         // wenn der StartNode dem StartNode der initial angelegten Box
    1631             :         // entspricht nehmen wir diese Box
    1632           1 :         pBox = pTopTable->pBox1;
    1633           1 :         pBox->SetUpper( pUpper );
    1634           1 :         pTopTable->pBox1 = 0;
    1635             :     }
    1636             :     else
    1637         259 :         pBox = new SwTableBox( pBoxFmt, *pStNd, pUpper );
    1638             : 
    1639         260 :     return pBox;
    1640             : }
    1641             : 
    1642           1 : static void ResetLineFrmFmtAttrs( SwFrmFmt *pFrmFmt )
    1643             : {
    1644           1 :     pFrmFmt->ResetFmtAttr( RES_FRM_SIZE );
    1645           1 :     pFrmFmt->ResetFmtAttr( RES_BACKGROUND );
    1646             :     OSL_ENSURE( SFX_ITEM_SET!=pFrmFmt->GetAttrSet().GetItemState(
    1647             :                                 RES_VERT_ORIENT, false ),
    1648             :             "Zeile hat vertikale Ausrichtung" );
    1649           1 : }
    1650             : 
    1651             : // !!! kann noch vereinfacht werden
    1652          52 : SwTableLine *HTMLTable::MakeTableLine( SwTableBox *pUpper,
    1653             :                                        sal_uInt16 nTopRow, sal_uInt16 nLeftCol,
    1654             :                                        sal_uInt16 nBottomRow, sal_uInt16 nRightCol )
    1655             : {
    1656             :     SwTableLine *pLine;
    1657          52 :     if( this==pTopTable && !pUpper && 0==nTopRow )
    1658           1 :         pLine = (pSwTable->GetTabLines())[0];
    1659             :     else
    1660             :         pLine = new SwTableLine( pLineFrmFmtNoHeight ? pLineFrmFmtNoHeight
    1661             :                                                      : pLineFmt,
    1662          51 :                                  0, pUpper );
    1663             : 
    1664          52 :     HTMLTableRow *pTopRow = &(*pRows)[nTopRow];
    1665          52 :     sal_uInt16 nRowHeight = pTopRow->GetHeight();
    1666          52 :     const SvxBrushItem *pBGBrushItem = 0;
    1667          52 :     if( this == pTopTable || nTopRow>0 || nBottomRow<nRows )
    1668             :     {
    1669             :         // An der Line eine Frabe zu setzen macht keinen Sinn, wenn sie
    1670             :         // die auesserste und gleichzeitig einzige Zeile einer Tabelle in
    1671             :         // der Tabelle ist.
    1672          52 :         pBGBrushItem = pTopRow->GetBGBrush();
    1673             : 
    1674          52 :         if( !pBGBrushItem && this != pTopTable )
    1675             :         {
    1676             :             // Ein an einer Tabellen in der Tabelle gesetzter Hintergrund
    1677             :             // wird an den Rows gesetzt. Das gilt auch fuer den Hintergrund
    1678             :             // der Zelle, in dem die Tabelle vorkommt.
    1679           0 :             pBGBrushItem = GetBGBrush();
    1680           0 :             if( !pBGBrushItem )
    1681           0 :                 pBGBrushItem = GetInhBGBrush();
    1682             :         }
    1683             :     }
    1684          52 :     if( nTopRow==nBottomRow-1 && (nRowHeight || pBGBrushItem) )
    1685             :     {
    1686           0 :         SwTableLineFmt *pFrmFmt = (SwTableLineFmt*)pLine->ClaimFrmFmt();
    1687           0 :         ResetLineFrmFmtAttrs( pFrmFmt );
    1688             : 
    1689           0 :         if( nRowHeight )
    1690             :         {
    1691             :             // Tabellenhoehe einstellen. Da es sich um eine
    1692             :             // Mindesthoehe handelt, kann sie genauso wie in
    1693             :             // Netscape berechnet werden, also ohne Beruecksichtigung
    1694             :             // der tatsaechlichen Umrandungsbreite.
    1695           0 :             nRowHeight += GetTopCellSpace( nTopRow, 1, sal_False ) +
    1696           0 :                        GetBottomCellSpace( nTopRow, 1, sal_False );
    1697             : 
    1698           0 :             pFrmFmt->SetFmtAttr( SwFmtFrmSize( ATT_MIN_SIZE, 0, nRowHeight ) );
    1699             :         }
    1700             : 
    1701           0 :         if( pBGBrushItem )
    1702             :         {
    1703           0 :             pFrmFmt->SetFmtAttr( *pBGBrushItem );
    1704           0 :         }
    1705             : 
    1706             :     }
    1707          52 :     else if( !pLineFrmFmtNoHeight )
    1708             :     {
    1709             :         // sonst muessen wir die Hoehe aus dem Attribut entfernen
    1710             :         // und koennen uns das Format merken
    1711           1 :         pLineFrmFmtNoHeight = (SwTableLineFmt*)pLine->ClaimFrmFmt();
    1712             : 
    1713           1 :         ResetLineFrmFmtAttrs( pLineFrmFmtNoHeight );
    1714             :     }
    1715             : 
    1716          52 :     SwTableBoxes& rBoxes = pLine->GetTabBoxes();
    1717             : 
    1718          52 :     sal_uInt16 nStartCol = nLeftCol;
    1719         364 :     while( nStartCol<nRightCol )
    1720             :     {
    1721         260 :         sal_uInt16 nCol = nStartCol;
    1722         260 :         sal_uInt16 nSplitCol = nRightCol;
    1723         260 :         sal_Bool bSplitted = sal_False;
    1724         780 :         while( !bSplitted )
    1725             :         {
    1726             :             OSL_ENSURE( nCol < nRightCol, "Zu weit gelaufen" );
    1727             : 
    1728         260 :             HTMLTableCell *pCell = GetCell(nTopRow,nCol);
    1729         260 :             const sal_Bool bSplit = 1 == pCell->GetColSpan();
    1730             : 
    1731             :             OSL_ENSURE((nCol != nRightCol-1) || bSplit, "Split-Flag wrong");
    1732         260 :             if( bSplit )
    1733             :             {
    1734         260 :                 SwTableBox* pBox = 0;
    1735         260 :                 HTMLTableCell *pCell2 = GetCell( nTopRow, nStartCol );
    1736         260 :                 if( pCell2->GetColSpan() == (nCol+1-nStartCol) )
    1737             :                 {
    1738             :                     // Die HTML-Tabellen-Zellen bilden genau eine Box.
    1739             :                     // Dann muss hinter der Box gesplittet werden
    1740         260 :                     nSplitCol = nCol + 1;
    1741             : 
    1742         260 :                     long nBoxRowSpan = pCell2->GetRowSpan();
    1743         260 :                     if ( !pCell2->GetContents() || pCell2->IsCovered() )
    1744             :                     {
    1745           0 :                         if ( pCell2->IsCovered() )
    1746           0 :                             nBoxRowSpan = -1 * nBoxRowSpan;
    1747             : 
    1748             :                         const SwStartNode* pPrevStartNd =
    1749           0 :                             GetPrevBoxStartNode( nTopRow, nStartCol );
    1750             :                         HTMLTableCnts *pCnts = new HTMLTableCnts(
    1751           0 :                             pParser->InsertTableSection(pPrevStartNd) );
    1752             :                         SwHTMLTableLayoutCnts *pCntsLayoutInfo =
    1753           0 :                             pCnts->CreateLayoutInfo();
    1754             : 
    1755           0 :                         pCell2->SetContents( pCnts );
    1756           0 :                         SwHTMLTableLayoutCell *pCurrCell = pLayoutInfo->GetCell( nTopRow, nStartCol );
    1757           0 :                         pCurrCell->SetContents( pCntsLayoutInfo );
    1758           0 :                         if( nBoxRowSpan < 0 )
    1759           0 :                             pCurrCell->SetRowSpan( 0 );
    1760             : 
    1761             :                         // ggf. COLSPAN beachten
    1762           0 :                         for( sal_uInt16 j=nStartCol+1; j<nSplitCol; j++ )
    1763             :                         {
    1764           0 :                             GetCell(nTopRow,j)->SetContents( pCnts );
    1765             :                             pLayoutInfo->GetCell( nTopRow, j )
    1766           0 :                                        ->SetContents( pCntsLayoutInfo );
    1767             :                         }
    1768             :                     }
    1769             : 
    1770             :                     pBox = MakeTableBox( pLine, pCell2->GetContents(),
    1771             :                                          nTopRow, nStartCol,
    1772         260 :                                          nBottomRow, nSplitCol );
    1773             : 
    1774         260 :                     if ( 1 != nBoxRowSpan )
    1775           0 :                         pBox->setRowSpan( nBoxRowSpan );
    1776             : 
    1777         260 :                     bSplitted = sal_True;
    1778             :                 }
    1779             : 
    1780             :                 OSL_ENSURE( pBox, "Colspan trouble" );
    1781             : 
    1782         260 :                 if( pBox )
    1783         260 :                     rBoxes.push_back( pBox );
    1784             :             }
    1785         260 :             nCol++;
    1786             :         }
    1787         260 :         nStartCol = nSplitCol;
    1788             :     }
    1789             : 
    1790          52 :     return pLine;
    1791             : }
    1792             : 
    1793         260 : SwTableBox *HTMLTable::MakeTableBox( SwTableLine *pUpper,
    1794             :                                      HTMLTableCnts *pCnts,
    1795             :                                      sal_uInt16 nTopRow, sal_uInt16 nLeftCol,
    1796             :                                      sal_uInt16 nBottomRow, sal_uInt16 nRightCol )
    1797             : {
    1798             :     SwTableBox *pBox;
    1799         260 :     sal_uInt16 nColSpan = nRightCol - nLeftCol;
    1800         260 :     sal_uInt16 nRowSpan = nBottomRow - nTopRow;
    1801             : 
    1802         260 :     if( !pCnts->Next() )
    1803             :     {
    1804             :         // nur eine Inhalts-Section
    1805         260 :         if( pCnts->GetStartNode() )
    1806             :         {
    1807             :             // und die ist keine Tabelle
    1808         260 :             pBox = NewTableBox( pCnts->GetStartNode(), pUpper );
    1809         260 :             pCnts->SetTableBox( pBox );
    1810             :         }
    1811             :         else
    1812             :         {
    1813             :             pCnts->GetTable()->InheritVertBorders( this, nLeftCol,
    1814           0 :                                                    nRightCol-nLeftCol );
    1815             :             // und die ist eine Tabelle: dann bauen wir eine neue
    1816             :             // Box und fuegen die Zeilen der Tabelle in die Zeilen
    1817             :             // der Box ein
    1818           0 :             pBox = new SwTableBox( pBoxFmt, 0, pUpper );
    1819             :             sal_uInt16 nAbs, nRel;
    1820           0 :             pLayoutInfo->GetAvail( nLeftCol, nColSpan, nAbs, nRel );
    1821           0 :             sal_uInt16 nLSpace = pLayoutInfo->GetLeftCellSpace( nLeftCol, nColSpan );
    1822           0 :             sal_uInt16 nRSpace = pLayoutInfo->GetRightCellSpace( nLeftCol, nColSpan );
    1823           0 :             sal_uInt16 nInhSpace = pLayoutInfo->GetInhCellSpace( nLeftCol, nColSpan );
    1824             :             pCnts->GetTable()->MakeTable( pBox, nAbs, nRel, nLSpace, nRSpace,
    1825           0 :                                           nInhSpace );
    1826             :         }
    1827             :     }
    1828             :     else
    1829             :     {
    1830             :         // mehrere Inhalts Sections: dann brauchen wir eine Box mit Zeilen
    1831           0 :         pBox = new SwTableBox( pBoxFmt, 0, pUpper );
    1832           0 :         SwTableLines& rLines = pBox->GetTabLines();
    1833           0 :         sal_Bool bFirstPara = sal_True;
    1834             : 
    1835           0 :         while( pCnts )
    1836             :         {
    1837           0 :             if( pCnts->GetStartNode() )
    1838             :             {
    1839             :                 // normale Absaetze werden zu einer Box in einer Zeile
    1840             :                 SwTableLine *pLine =
    1841             :                     new SwTableLine( pLineFrmFmtNoHeight ? pLineFrmFmtNoHeight
    1842           0 :                                                          : pLineFmt, 0, pBox );
    1843           0 :                 if( !pLineFrmFmtNoHeight )
    1844             :                 {
    1845             :                     // Wenn es noch kein Line-Format ohne Hoehe gibt, koennen
    1846             :                     // wir uns dieses her als soleches merken
    1847           0 :                     pLineFrmFmtNoHeight = (SwTableLineFmt*)pLine->ClaimFrmFmt();
    1848             : 
    1849           0 :                     ResetLineFrmFmtAttrs( pLineFrmFmtNoHeight );
    1850             :                 }
    1851             : 
    1852             :                 SwTableBox* pCntBox = NewTableBox( pCnts->GetStartNode(),
    1853           0 :                                                    pLine );
    1854           0 :                 pCnts->SetTableBox( pCntBox );
    1855             :                 FixFrameFmt( pCntBox, nTopRow, nLeftCol, nRowSpan, nColSpan,
    1856           0 :                              bFirstPara, 0==pCnts->Next() );
    1857           0 :                 pLine->GetTabBoxes().push_back( pCntBox );
    1858             : 
    1859           0 :                 rLines.push_back( pLine );
    1860             :             }
    1861             :             else
    1862             :             {
    1863             :                 pCnts->GetTable()->InheritVertBorders( this, nLeftCol,
    1864           0 :                                                        nRightCol-nLeftCol );
    1865             :                 // Tabellen werden direkt eingetragen
    1866             :                 sal_uInt16 nAbs, nRel;
    1867           0 :                 pLayoutInfo->GetAvail( nLeftCol, nColSpan, nAbs, nRel );
    1868             :                 sal_uInt16 nLSpace = pLayoutInfo->GetLeftCellSpace( nLeftCol,
    1869           0 :                                                                 nColSpan );
    1870             :                 sal_uInt16 nRSpace = pLayoutInfo->GetRightCellSpace( nLeftCol,
    1871           0 :                                                                  nColSpan );
    1872           0 :                 sal_uInt16 nInhSpace = pLayoutInfo->GetInhCellSpace( nLeftCol, nColSpan );
    1873             :                 pCnts->GetTable()->MakeTable( pBox, nAbs, nRel, nLSpace,
    1874           0 :                                               nRSpace, nInhSpace );
    1875             :             }
    1876             : 
    1877           0 :             pCnts = pCnts->Next();
    1878           0 :             bFirstPara = sal_False;
    1879             :         }
    1880             :     }
    1881             : 
    1882         260 :     FixFrameFmt( pBox, nTopRow, nLeftCol, nRowSpan, nColSpan );
    1883             : 
    1884         260 :     return pBox;
    1885             : }
    1886             : 
    1887           0 : void HTMLTable::InheritBorders( const HTMLTable *pParent,
    1888             :                                 sal_uInt16 nRow, sal_uInt16 nCol,
    1889             :                                 sal_uInt16 nRowSpan, sal_uInt16 /*nColSpan*/,
    1890             :                                 sal_Bool bFirstPara, sal_Bool bLastPara )
    1891             : {
    1892             :     OSL_ENSURE( nRows>0 && nCols>0 && nCurRow==nRows,
    1893             :             "Wurde CloseTable nicht aufgerufen?" );
    1894             : 
    1895             :     // Die Child-Tabelle muss einen Rahmen bekommen, wenn die umgebende
    1896             :     // Zelle einen Rand an der betreffenden Seite besitzt.
    1897             :     // Der obere bzw. untere Rand wird nur gesetzt, wenn die Tabelle
    1898             :     // ale erster bzw. letzter Absatz in der Zelle vorkommt. Ansonsten
    1899             :     // Fuer den linken/rechten Rand kann noch nicht entschieden werden,
    1900             :     // ob eine Umrandung der Tabelle noetig/moeglich ist, weil das davon
    1901             :     // abhaengt, ob "Filler"-Zellen eingefuegt werden. Hier werden deshalb
    1902             :     // erstmal nur Informationen gesammelt
    1903             : 
    1904           0 :     if( 0==nRow && pParent->bTopBorder && bFirstPara )
    1905             :     {
    1906           0 :         bTopBorder = true;
    1907           0 :         bFillerTopBorder = true; // auch Filler bekommt eine Umrandung
    1908           0 :         aTopBorderLine = pParent->aTopBorderLine;
    1909             :     }
    1910           0 :     if( (*pParent->pRows)[nRow+nRowSpan-1].bBottomBorder && bLastPara )
    1911             :     {
    1912           0 :         (*pRows)[nRows-1].bBottomBorder = true;
    1913           0 :         bFillerBottomBorder = true; // auch Filler bekommt eine Umrandung
    1914           0 :         aBottomBorderLine =
    1915           0 :             nRow+nRowSpan==pParent->nRows ? pParent->aBottomBorderLine
    1916           0 :                                           : pParent->aBorderLine;
    1917             :     }
    1918             : 
    1919             :     // Die Child Tabelle darf keinen oberen oder linken Rahmen bekommen,
    1920             :     // wenn der bereits durch die umgebende Tabelle gesetzt ist.
    1921             :     // Sie darf jedoch immer einen oberen Rand bekommen, wenn die Tabelle
    1922             :     // nicht der erste Absatz in der Zelle ist.
    1923           0 :     bTopAlwd = ( !bFirstPara || (pParent->bTopAlwd &&
    1924           0 :                  (0==nRow || !((*pParent->pRows)[nRow-1]).bBottomBorder)) );
    1925             : 
    1926             :     // die Child-Tabelle muss die Farbe der Zelle erben, in der sie
    1927             :     // vorkommt, wenn sie keine eigene besitzt
    1928           0 :     const SvxBrushItem *pInhBG = pParent->GetCell(nRow,nCol)->GetBGBrush();
    1929           0 :     if( !pInhBG && pParent != pTopTable &&
    1930           0 :         pParent->GetCell(nRow,nCol)->GetRowSpan() == pParent->nRows )
    1931             :     {
    1932             :         // die ganze umgebende Tabelle ist eine Tabelle in der Tabelle
    1933             :         // und besteht nur aus einer Line, die bei der GC (zu Recht)
    1934             :         // wegoptimiert wird. Deshalb muss der Hintergrund der Line in
    1935             :         // diese Tabelle uebernommen werden.
    1936           0 :         pInhBG = (*pParent->pRows)[nRow].GetBGBrush();
    1937           0 :         if( !pInhBG )
    1938           0 :             pInhBG = pParent->GetBGBrush();
    1939           0 :         if( !pInhBG )
    1940           0 :             pInhBG = pParent->GetInhBGBrush();
    1941             :     }
    1942           0 :     if( pInhBG )
    1943           0 :         pInhBGBrush = new SvxBrushItem( *pInhBG );
    1944           0 : }
    1945             : 
    1946           0 : void HTMLTable::InheritVertBorders( const HTMLTable *pParent,
    1947             :                                  sal_uInt16 nCol, sal_uInt16 nColSpan )
    1948             : {
    1949           0 :     sal_uInt16 nInhLeftBorderWidth = 0;
    1950           0 :     sal_uInt16 nInhRightBorderWidth = 0;
    1951             : 
    1952           0 :     if( nCol+nColSpan==pParent->nCols && pParent->bRightBorder )
    1953             :     {
    1954           0 :         bInhRightBorder = true; // erstmal nur merken
    1955           0 :         aInhRightBorderLine = pParent->aRightBorderLine;
    1956             :         nInhRightBorderWidth =
    1957           0 :             GetBorderWidth( aInhRightBorderLine, sal_True ) + MIN_BORDER_DIST;
    1958             :     }
    1959             : 
    1960           0 :     if( ((*pParent->pColumns)[nCol]).bLeftBorder )
    1961             :     {
    1962           0 :         bInhLeftBorder = true;  // erstmal nur merken
    1963           0 :         aInhLeftBorderLine = 0==nCol ? pParent->aLeftBorderLine
    1964           0 :                                      : pParent->aBorderLine;
    1965             :         nInhLeftBorderWidth =
    1966           0 :             GetBorderWidth( aInhLeftBorderLine, sal_True ) + MIN_BORDER_DIST;
    1967             :     }
    1968             : 
    1969           0 :     if( !bInhLeftBorder && (bFillerTopBorder || bFillerBottomBorder) )
    1970           0 :         nInhLeftBorderWidth = 2 * MIN_BORDER_DIST;
    1971           0 :     if( !bInhRightBorder && (bFillerTopBorder || bFillerBottomBorder) )
    1972           0 :         nInhRightBorderWidth = 2 * MIN_BORDER_DIST;
    1973             :     pLayoutInfo->SetInhBorderWidths( nInhLeftBorderWidth,
    1974           0 :                                      nInhRightBorderWidth );
    1975             : 
    1976           0 :     bRightAlwd = ( pParent->bRightAlwd &&
    1977           0 :                   (nCol+nColSpan==pParent->nCols ||
    1978           0 :                    !((*pParent->pColumns)[nCol+nColSpan]).bLeftBorder) );
    1979           0 : }
    1980             : 
    1981           1 : void HTMLTable::SetBorders()
    1982             : {
    1983             :     sal_uInt16 i;
    1984           5 :     for( i=1; i<nCols; i++ )
    1985           8 :         if( HTML_TR_ALL==eRules || HTML_TR_COLS==eRules ||
    1986           8 :             ((HTML_TR_ROWS==eRules || HTML_TR_GROUPS==eRules) &&
    1987           0 :              ((*pColumns)[i-1]).IsEndOfGroup()) )
    1988           0 :             ((*pColumns)[i]).bLeftBorder = true;
    1989             : 
    1990          52 :     for( i=0; i<nRows-1; i++ )
    1991         102 :         if( HTML_TR_ALL==eRules || HTML_TR_ROWS==eRules ||
    1992         102 :             ((HTML_TR_COLS==eRules || HTML_TR_GROUPS==eRules) &&
    1993           0 :              (*pRows)[i].IsEndOfGroup()) )
    1994           0 :             (*pRows)[i].bBottomBorder = true;
    1995             : 
    1996           2 :     if( bTopAlwd && (HTML_TF_ABOVE==eFrame || HTML_TF_HSIDES==eFrame ||
    1997           1 :                      HTML_TF_BOX==eFrame) )
    1998           0 :         bTopBorder = true;
    1999           2 :     if( HTML_TF_BELOW==eFrame || HTML_TF_HSIDES==eFrame ||
    2000           1 :         HTML_TF_BOX==eFrame )
    2001           0 :         (*pRows)[nRows-1].bBottomBorder = true;
    2002           2 :     if( (HTML_TF_RHS==eFrame || HTML_TF_VSIDES==eFrame ||
    2003           1 :                       HTML_TF_BOX==eFrame) )
    2004           0 :         bRightBorder = true;
    2005           1 :     if( HTML_TF_LHS==eFrame || HTML_TF_VSIDES==eFrame || HTML_TF_BOX==eFrame )
    2006           0 :         ((*pColumns)[0]).bLeftBorder = true;
    2007             : 
    2008          53 :     for( i=0; i<nRows; i++ )
    2009             :     {
    2010          52 :         HTMLTableRow *pRow = &(*pRows)[i];
    2011         312 :         for( sal_uInt16 j=0; j<nCols; j++ )
    2012             :         {
    2013         260 :             HTMLTableCell *pCell = pRow->GetCell(j);
    2014         260 :             if( pCell->GetContents()  )
    2015             :             {
    2016         260 :                 HTMLTableCnts *pCnts = pCell->GetContents();
    2017         260 :                 sal_Bool bFirstPara = sal_True;
    2018         780 :                 while( pCnts )
    2019             :                 {
    2020         260 :                     HTMLTable *pTable = pCnts->GetTable();
    2021         260 :                     if( pTable && !pTable->BordersSet() )
    2022             :                     {
    2023             :                         pTable->InheritBorders( this, i, j,
    2024           0 :                                                 pCell->GetRowSpan(),
    2025           0 :                                                 pCell->GetColSpan(),
    2026             :                                                 bFirstPara,
    2027           0 :                                                 0==pCnts->Next() );
    2028           0 :                         pTable->SetBorders();
    2029             :                     }
    2030         260 :                     bFirstPara = sal_False;
    2031         260 :                     pCnts = pCnts->Next();
    2032             :                 }
    2033             :             }
    2034             :         }
    2035             :     }
    2036             : 
    2037           1 :     bBordersSet = true;
    2038           1 : }
    2039             : 
    2040           1 : sal_uInt16 HTMLTable::GetBorderWidth( const SvxBorderLine& rBLine,
    2041             :                                   sal_Bool bWithDistance ) const
    2042             : {
    2043           1 :     sal_uInt16 nBorderWidth = rBLine.GetWidth();
    2044           1 :     if( bWithDistance )
    2045             :     {
    2046           1 :         if( nCellPadding )
    2047           1 :             nBorderWidth = nBorderWidth + nCellPadding;
    2048           0 :         else if( nBorderWidth )
    2049           0 :             nBorderWidth = nBorderWidth + MIN_BORDER_DIST;
    2050             :     }
    2051             : 
    2052           1 :     return nBorderWidth;
    2053             : }
    2054             : 
    2055        1560 : inline HTMLTableCell *HTMLTable::GetCell( sal_uInt16 nRow,
    2056             :                                           sal_uInt16 nCell ) const
    2057             : {
    2058             :     OSL_ENSURE(nRow < pRows->size(), "invalid row index in HTML table");
    2059        1560 :     return (*pRows)[nRow].GetCell( nCell );
    2060             : }
    2061             : 
    2062         260 : SvxAdjust HTMLTable::GetInheritedAdjust() const
    2063             : {
    2064         520 :     SvxAdjust eAdjust = (nCurCol<nCols ? ((*pColumns)[nCurCol]).GetAdjust()
    2065         520 :                                        : SVX_ADJUST_END );
    2066         260 :     if( SVX_ADJUST_END==eAdjust )
    2067         260 :         eAdjust = (*pRows)[nCurRow].GetAdjust();
    2068             : 
    2069         260 :     return eAdjust;
    2070             : }
    2071             : 
    2072         260 : sal_Int16 HTMLTable::GetInheritedVertOri() const
    2073             : {
    2074             :     // text::VertOrientation::TOP ist der default!
    2075         260 :     sal_Int16 eVOri = (*pRows)[nCurRow].GetVertOri();
    2076         260 :     if( text::VertOrientation::TOP==eVOri && nCurCol<nCols )
    2077           0 :         eVOri = ((*pColumns)[nCurCol]).GetVertOri();
    2078         260 :     if( text::VertOrientation::TOP==eVOri )
    2079           0 :         eVOri = eVertOri;
    2080             : 
    2081             :     OSL_ENSURE( eVertOri != text::VertOrientation::TOP, "text::VertOrientation::TOP ist nicht erlaubt!" );
    2082         260 :     return eVOri;
    2083             : }
    2084             : 
    2085         260 : void HTMLTable::InsertCell( HTMLTableCnts *pCnts,
    2086             :                             sal_uInt16 nRowSpan, sal_uInt16 nColSpan,
    2087             :                             sal_uInt16 nCellWidth, sal_Bool bRelWidth, sal_uInt16 nCellHeight,
    2088             :                             sal_Int16 eVertOrient, SvxBrushItem *pBGBrushItem,
    2089             :                             boost::shared_ptr<SvxBoxItem> const pBoxItem,
    2090             :                             sal_Bool bHasNumFmt, sal_uInt32 nNumFmt,
    2091             :                             sal_Bool bHasValue, double nValue, sal_Bool bNoWrap )
    2092             : {
    2093         260 :     if( !nRowSpan || (sal_uInt32)nCurRow + nRowSpan > USHRT_MAX )
    2094           0 :         nRowSpan = 1;
    2095             : 
    2096         260 :     if( !nColSpan || (sal_uInt32)nCurCol + nColSpan > USHRT_MAX )
    2097           0 :         nColSpan = 1;
    2098             : 
    2099         260 :     sal_uInt16 nColsReq = nCurCol + nColSpan;       // benoetigte Spalten
    2100         260 :     sal_uInt16 nRowsReq = nCurRow + nRowSpan;       // benoetigte Zeilen
    2101             :     sal_uInt16 i, j;
    2102             : 
    2103             :     // falls wir mehr Spalten benoetigen als wir zur Zeit haben,
    2104             :     // muessen wir in allen Zeilen noch Zellen hinzufuegen
    2105         260 :     if( nCols < nColsReq )
    2106             :     {
    2107           0 :         for( i=nCols; i<nColsReq; i++ )
    2108           0 :             pColumns->push_back( new HTMLTableColumn );
    2109           0 :         for( i=0; i<nRows; i++ )
    2110           0 :             (*pRows)[i].Expand( nColsReq, i<nCurRow );
    2111           0 :         nCols = nColsReq;
    2112             :         OSL_ENSURE(pColumns->size() == nCols,
    2113             :                 "wrong number of columns after expanding");
    2114             :     }
    2115         260 :     if( nColsReq > nFilledCols )
    2116           5 :         nFilledCols = nColsReq;
    2117             : 
    2118             :     // falls wir mehr Zeilen benoetigen als wir zur Zeit haben,
    2119             :     // muessen wir noch neue Zeilen hinzufuegen
    2120         260 :     if( nRows < nRowsReq )
    2121             :     {
    2122           0 :         for( i=nRows; i<nRowsReq; i++ )
    2123           0 :             pRows->push_back( new HTMLTableRow(nCols) );
    2124           0 :         nRows = nRowsReq;
    2125             :         OSL_ENSURE(nRows == pRows->size(), "wrong number of rows in Insert");
    2126             :     }
    2127             : 
    2128             :     // Testen, ob eine Ueberschneidung vorliegt und diese
    2129             :     // gegebenfalls beseitigen
    2130         260 :     sal_uInt16 nSpanedCols = 0;
    2131         260 :     if( nCurRow>0 )
    2132             :     {
    2133         255 :         HTMLTableRow *pCurRow = &(*pRows)[nCurRow];
    2134         510 :         for( i=nCurCol; i<nColsReq; i++ )
    2135             :         {
    2136         255 :             HTMLTableCell *pCell = pCurRow->GetCell(i);
    2137         255 :             if( pCell->GetContents() )
    2138             :             {
    2139             :                 // Der Inhalt reicht von einer weiter oben stehenden Zelle
    2140             :                 // hier herein. Inhalt und Farbe der Zelle sind deshalb in
    2141             :                 // jedem Fall noch dort verankert und koennen deshalb
    2142             :                 // ueberschrieben werden bzw. von ProtectRowSpan geloescht
    2143             :                 // (Inhalt) oder kopiert (Farbe) werden.
    2144           0 :                 nSpanedCols = i + pCell->GetColSpan();
    2145           0 :                 FixRowSpan( nCurRow-1, i, pCell->GetContents() );
    2146           0 :                 if( pCell->GetRowSpan() > nRowSpan )
    2147             :                     ProtectRowSpan( nRowsReq, i,
    2148           0 :                                     pCell->GetRowSpan()-nRowSpan );
    2149             :             }
    2150             :         }
    2151         255 :         for( i=nColsReq; i<nSpanedCols; i++ )
    2152             :         {
    2153             :             // Auch diese Inhalte sind in jedem Fall nich in der Zeile
    2154             :             // darueber verankert.
    2155           0 :             HTMLTableCell *pCell = pCurRow->GetCell(i);
    2156           0 :             FixRowSpan( nCurRow-1, i, pCell->GetContents() );
    2157           0 :             ProtectRowSpan( nCurRow, i, pCell->GetRowSpan() );
    2158             :         }
    2159             :     }
    2160             : 
    2161             :     // Fill the cells
    2162         520 :     for( i=nColSpan; i>0; i-- )
    2163             :     {
    2164         520 :         for( j=nRowSpan; j>0; j-- )
    2165             :         {
    2166         260 :             const bool bCovered = i != nColSpan || j != nRowSpan;
    2167             :             GetCell( nRowsReq-j, nColsReq-i )
    2168             :                 ->Set( pCnts, j, i, eVertOrient, pBGBrushItem, pBoxItem,
    2169         260 :                        bHasNumFmt, nNumFmt, bHasValue, nValue, bNoWrap, bCovered );
    2170             :         }
    2171             :     }
    2172             : 
    2173         260 :     Size aTwipSz( bRelWidth ? 0 : nCellWidth, nCellHeight );
    2174         260 :     if( (aTwipSz.Width() || aTwipSz.Height()) && Application::GetDefaultDevice() )
    2175             :     {
    2176             :         aTwipSz = Application::GetDefaultDevice()
    2177           0 :                     ->PixelToLogic( aTwipSz, MapMode( MAP_TWIP ) );
    2178             :     }
    2179             : 
    2180             :     // die Breite nur in die erste Zelle setzen!
    2181         260 :     if( nCellWidth )
    2182             :     {
    2183         260 :         sal_uInt16 nTmp = bRelWidth ? nCellWidth : (sal_uInt16)aTwipSz.Width();
    2184         260 :         GetCell( nCurRow, nCurCol )->SetWidth( nTmp, bRelWidth );
    2185             :     }
    2186             : 
    2187             :     // Ausserdem noch die Hoehe merken
    2188         260 :     if( nCellHeight && 1==nRowSpan )
    2189             :     {
    2190           0 :         if( nCellHeight < MINLAY )
    2191           0 :             nCellHeight = MINLAY;
    2192           0 :         (*pRows)[nCurRow].SetHeight( (sal_uInt16)aTwipSz.Height() );
    2193             :     }
    2194             : 
    2195             :     // den Spaltenzaehler hinter die neuen Zellen setzen
    2196         260 :     nCurCol = nColsReq;
    2197         260 :     if( nSpanedCols > nCurCol )
    2198           0 :         nCurCol = nSpanedCols;
    2199             : 
    2200             :     // und die naechste freie Zelle suchen
    2201         520 :     while( nCurCol<nCols && GetCell(nCurRow,nCurCol)->IsUsed() )
    2202           0 :         nCurCol++;
    2203         260 : }
    2204             : 
    2205           1 : inline void HTMLTable::CloseSection( sal_Bool bHead )
    2206             : {
    2207             :     // die vorhergende Section beenden, falls es schon eine Zeile gibt
    2208             :     OSL_ENSURE( nCurRow<=nRows, "ungeultige aktuelle Zeile" );
    2209           1 :     if( nCurRow>0 && nCurRow<=nRows )
    2210           1 :         (*pRows)[nCurRow-1].SetEndOfGroup();
    2211           1 :     if( bHead )
    2212           0 :         nHeadlineRepeat = nCurRow;
    2213           1 : }
    2214             : 
    2215          52 : void HTMLTable::OpenRow( SvxAdjust eAdjust, sal_Int16 eVertOrient,
    2216             :                          SvxBrushItem *pBGBrushItem )
    2217             : {
    2218          52 :     sal_uInt16 nRowsReq = nCurRow+1;    // Anzahl benoetigter Zeilen;
    2219             : 
    2220             :     // die naechste Zeile anlegen, falls sie nicht schon da ist
    2221          52 :     if( nRows<nRowsReq )
    2222             :     {
    2223         104 :         for( sal_uInt16 i=nRows; i<nRowsReq; i++ )
    2224          52 :             pRows->push_back( new HTMLTableRow(nCols) );
    2225          52 :         nRows = nRowsReq;
    2226             :         OSL_ENSURE( nRows==pRows->size(),
    2227             :                 "Zeilenzahl in OpenRow stimmt nicht" );
    2228             :     }
    2229             : 
    2230          52 :     HTMLTableRow *pCurRow = &((*pRows)[nCurRow]);
    2231          52 :     pCurRow->SetAdjust( eAdjust );
    2232          52 :     pCurRow->SetVertOri( eVertOrient );
    2233          52 :     if( pBGBrushItem )
    2234           0 :         (*pRows)[nCurRow].SetBGBrush( pBGBrushItem );
    2235             : 
    2236             :     // den Spaltenzaehler wieder an den Anfang setzen
    2237          52 :     nCurCol=0;
    2238             : 
    2239             :     // und die naechste freie Zelle suchen
    2240         104 :     while( nCurCol<nCols && GetCell(nCurRow,nCurCol)->IsUsed() )
    2241           0 :         nCurCol++;
    2242          52 : }
    2243             : 
    2244          52 : void HTMLTable::CloseRow( sal_Bool bEmpty )
    2245             : {
    2246             :     OSL_ENSURE( nCurRow<nRows, "aktulle Zeile hinter dem Tabellenende" );
    2247             : 
    2248             :     // leere Zellen bekommen einfach einen etwas dickeren unteren Rand!
    2249          52 :     if( bEmpty )
    2250             :     {
    2251           0 :         if( nCurRow > 0 )
    2252           0 :             (*pRows)[nCurRow-1].IncEmptyRows();
    2253          52 :         return;
    2254             :     }
    2255             : 
    2256          52 :     HTMLTableRow *pRow = &(*pRows)[nCurRow];
    2257             : 
    2258             :     // den COLSPAN aller leeren Zellen am Zeilenende so anpassen, dass
    2259             :     // eine Zelle daraus wird. Das kann man hier machen (und auf keinen
    2260             :     // Fall frueher), weill jetzt keine Zellen mehr in die Zeile eingefuegt
    2261             :     // werden.
    2262          52 :     sal_uInt16 i=nCols;
    2263         104 :     while( i )
    2264             :     {
    2265          52 :         HTMLTableCell *pCell = pRow->GetCell(--i);
    2266          52 :         if( !pCell->GetContents() )
    2267             :         {
    2268           0 :             sal_uInt16 nColSpan = nCols-i;
    2269           0 :             if( nColSpan > 1 )
    2270           0 :                 pCell->SetColSpan( nColSpan );
    2271             :         }
    2272             :         else
    2273          52 :             break;
    2274             :     }
    2275             : 
    2276          52 :     nCurRow++;
    2277             : }
    2278             : 
    2279           1 : inline void HTMLTable::CloseColGroup( sal_uInt16 nSpan, sal_uInt16 _nWidth,
    2280             :                                       bool bRelWidth, SvxAdjust eAdjust,
    2281             :                                       sal_Int16 eVertOrient )
    2282             : {
    2283           1 :     if( nSpan )
    2284           0 :         InsertCol( nSpan, _nWidth, bRelWidth, eAdjust, eVertOrient );
    2285             : 
    2286             :     OSL_ENSURE( nCurCol<=nCols, "ungueltige Spalte" );
    2287           1 :     if( nCurCol>0 && nCurCol<=nCols )
    2288           1 :         ((*pColumns)[nCurCol-1]).SetEndOfGroup();
    2289           1 : }
    2290             : 
    2291           5 : void HTMLTable::InsertCol( sal_uInt16 nSpan, sal_uInt16 nColWidth, bool bRelWidth,
    2292             :                            SvxAdjust eAdjust, sal_Int16 eVertOrient )
    2293             : {
    2294             :     // #i35143# - no columns, if rows already exist.
    2295           5 :     if ( nRows > 0 )
    2296           5 :         return;
    2297             : 
    2298             :     sal_uInt16 i;
    2299             : 
    2300           5 :     if( !nSpan )
    2301           0 :         nSpan = 1;
    2302             : 
    2303           5 :     sal_uInt16 nColsReq = nCurCol + nSpan;      // benoetigte Spalten
    2304             : 
    2305           5 :     if( nCols < nColsReq )
    2306             :     {
    2307          10 :         for( i=nCols; i<nColsReq; i++ )
    2308           5 :             pColumns->push_back( new HTMLTableColumn );
    2309           5 :         nCols = nColsReq;
    2310             :     }
    2311             : 
    2312           5 :     Size aTwipSz( bRelWidth ? 0 : nColWidth, 0 );
    2313           5 :     if( aTwipSz.Width() && Application::GetDefaultDevice() )
    2314             :     {
    2315             :         aTwipSz = Application::GetDefaultDevice()
    2316           0 :                     ->PixelToLogic( aTwipSz, MapMode( MAP_TWIP ) );
    2317             :     }
    2318             : 
    2319          10 :     for( i=nCurCol; i<nColsReq; i++ )
    2320             :     {
    2321           5 :         HTMLTableColumn *pCol = &(*pColumns)[i];
    2322           5 :         sal_uInt16 nTmp = bRelWidth ? nColWidth : (sal_uInt16)aTwipSz.Width();
    2323           5 :         pCol->SetWidth( nTmp, bRelWidth );
    2324           5 :         pCol->SetAdjust( eAdjust );
    2325           5 :         pCol->SetVertOri( eVertOrient );
    2326             :     }
    2327             : 
    2328           5 :     bColSpec = true;
    2329             : 
    2330           5 :     nCurCol = nColsReq;
    2331             : }
    2332             : 
    2333           1 : void HTMLTable::CloseTable()
    2334             : {
    2335             :     sal_uInt16 i;
    2336             : 
    2337             :     // Die Anzahl der Tabellenzeilen richtet sich nur nach den
    2338             :     // <TR>-Elementen (d.h. nach nCurRow). Durch ROWSPAN aufgespannte
    2339             :     // Zeilen hinter Zeile nCurRow muessen wir deshalb loeschen
    2340             :     // und vor allem aber den ROWSPAN in den darueberliegenden Zeilen
    2341             :     // anpassen.
    2342           1 :     if( nRows>nCurRow )
    2343             :     {
    2344           0 :         HTMLTableRow *pPrevRow = &(*pRows)[nCurRow-1];
    2345             :         HTMLTableCell *pCell;
    2346           0 :         for( i=0; i<nCols; i++ )
    2347           0 :             if( ( (pCell=(pPrevRow->GetCell(i))), (pCell->GetRowSpan()) > 1 ) )
    2348             :             {
    2349           0 :                 FixRowSpan( nCurRow-1, i, pCell->GetContents() );
    2350           0 :                 ProtectRowSpan( nCurRow, i, (*pRows)[nCurRow].GetCell(i)->GetRowSpan() );
    2351             :             }
    2352           0 :         for( i=nRows-1; i>=nCurRow; i-- )
    2353           0 :             pRows->erase(pRows->begin() + i);
    2354           0 :         nRows = nCurRow;
    2355             :     }
    2356             : 
    2357             :     // falls die Tabelle keine Spalte hat, muessen wir eine hinzufuegen
    2358           1 :     if( 0==nCols )
    2359             :     {
    2360           0 :         pColumns->push_back( new HTMLTableColumn );
    2361           0 :         for( i=0; i<nRows; i++ )
    2362           0 :             (*pRows)[i].Expand(1);
    2363           0 :         nCols = 1;
    2364           0 :         nFilledCols = 1;
    2365             :     }
    2366             : 
    2367             :     // falls die Tabelle keine Zeile hat, muessen wir eine hinzufuegen
    2368           1 :     if( 0==nRows )
    2369             :     {
    2370           0 :         pRows->push_back( new HTMLTableRow(nCols) );
    2371           0 :         nRows = 1;
    2372           0 :         nCurRow = 1;
    2373             :     }
    2374             : 
    2375           1 :     if( nFilledCols < nCols )
    2376             :     {
    2377           0 :         pColumns->erase( pColumns->begin() + nFilledCols, pColumns->begin() + nCols );
    2378           0 :         for( i=0; i<nRows; i++ )
    2379           0 :             (*pRows)[i].Shrink( nFilledCols );
    2380           0 :         nCols = nFilledCols;
    2381             :     }
    2382           1 : }
    2383             : 
    2384           1 : void HTMLTable::_MakeTable( SwTableBox *pBox )
    2385             : {
    2386             :     SwTableLines& rLines = (pBox ? pBox->GetTabLines()
    2387           1 :                                  : ((SwTable *)pSwTable)->GetTabLines() );
    2388             : 
    2389             :     // jetzt geht's richtig los ...
    2390             : 
    2391          53 :     for( sal_uInt16 i=0; i<nRows; i++ )
    2392             :     {
    2393          52 :         SwTableLine *pLine = MakeTableLine( pBox, i, 0, i+1, nCols );
    2394          52 :         if( pBox || i > 0 )
    2395          51 :             rLines.push_back( pLine );
    2396             :     }
    2397           1 : }
    2398             : 
    2399             : /* Wie werden Tabellen ausgerichtet?
    2400             : 
    2401             : erste Zeile: ohne Absatz-Einzuege
    2402             : zweite Zeile: mit Absatz-Einzuegen
    2403             : 
    2404             : ALIGN=          LEFT            RIGHT           CENTER          -
    2405             : -------------------------------------------------------------------------
    2406             : xxx bei Tabellen mit WIDTH=nn% ist die Prozent-Angabe von Bedeutung:
    2407             : xxx nn = 100        text::HoriOrientation::FULL       text::HoriOrientation::FULL       text::HoriOrientation::FULL       text::HoriOrientation::FULL %
    2408             : xxx             text::HoriOrientation::NONE       text::HoriOrientation::NONE       text::HoriOrientation::NONE %     text::HoriOrientation::NONE %
    2409             : xxx nn < 100        Rahmen F        Rahmen F        text::HoriOrientation::CENTER %   text::HoriOrientation::LEFT %
    2410             : xxx             Rahmen F        Rahmen F        text::HoriOrientation::CENTER %   text::HoriOrientation::NONE %
    2411             : 
    2412             : bei Tabellen mit WIDTH=nn% ist die Prozent-Angabe von Bedeutung:
    2413             : nn = 100        text::HoriOrientation::LEFT       text::HoriOrientation::RIGHT      text::HoriOrientation::CENTER %   text::HoriOrientation::LEFT %
    2414             :                 text::HoriOrientation::LEFT_AND   text::HoriOrientation::RIGHT      text::HoriOrientation::CENTER %   text::HoriOrientation::LEFT_AND %
    2415             : nn < 100        Rahmen F        Rahmen F        text::HoriOrientation::CENTER %   text::HoriOrientation::LEFT %
    2416             :                 Rahmen F        Rahmen F        text::HoriOrientation::CENTER %   text::HoriOrientation::NONE %
    2417             : 
    2418             : sonst die berechnete Breite w
    2419             : w = avail*      text::HoriOrientation::LEFT       text::HoriOrientation::RIGHT      text::HoriOrientation::CENTER     text::HoriOrientation::LEFT
    2420             :                 HORI_LEDT_AND   text::HoriOrientation::RIGHT      text::HoriOrientation::CENTER     text::HoriOrientation::LEFT_AND
    2421             : w < avail       Rahmen L        Rahmen L        text::HoriOrientation::CENTER     text::HoriOrientation::LEFT
    2422             :                 Rahmen L        Rahmen L        text::HoriOrientation::CENTER     text::HoriOrientation::NONE
    2423             : 
    2424             : xxx *) wenn fuer die Tabelle keine Groesse angegeben wurde, wird immer
    2425             : xxx   text::HoriOrientation::FULL genommen
    2426             : 
    2427             : */
    2428             : 
    2429           1 : void HTMLTable::MakeTable( SwTableBox *pBox, sal_uInt16 nAbsAvail,
    2430             :                            sal_uInt16 nRelAvail, sal_uInt16 nAbsLeftSpace,
    2431             :                            sal_uInt16 nAbsRightSpace, sal_uInt16 nInhAbsSpace )
    2432             : {
    2433             :     OSL_ENSURE( nRows>0 && nCols>0 && nCurRow==nRows,
    2434             :             "Wurde CloseTable nicht aufgerufen?" );
    2435             : 
    2436             :     OSL_ENSURE( (pLayoutInfo==0) == (this==pTopTable),
    2437             :             "Top-Tabelle hat keine Layout-Info oder umgekehrt" );
    2438             : 
    2439           1 :     if( this==pTopTable )
    2440             :     {
    2441             :         // Umrandung der Tabelle und aller in ihr enthaltenen berechnen
    2442           1 :         SetBorders();
    2443             : 
    2444             :         // Schritt 1: Die benoetigten Layout-Strukturen werden angelegt
    2445             :         // (inklusive Tabellen in Tabellen).
    2446           1 :         CreateLayoutInfo();
    2447             : 
    2448             :         // Schritt 2: Die minimalen und maximalen Spaltenbreiten werden
    2449             :         // berechnet (inklusive Tabellen in Tabellen). Da wir noch keine
    2450             :         // Boxen haben, arabeiten wir noch auf den Start-Nodes.
    2451           1 :         pLayoutInfo->AutoLayoutPass1();
    2452             :     }
    2453             : 
    2454             :     // Schritt 3: Die tatsaechlichen Spaltenbreiten dieser Tabelle werden
    2455             :     // berechnet (nicht von Tabellen in Tabellen). Dies muss jetzt schon
    2456             :     // sein, damit wir entscheiden koennen ob Filler-Zellen benoetigt werden
    2457             :     // oder nicht (deshalb war auch Pass1 schon noetig).
    2458             :     pLayoutInfo->AutoLayoutPass2( nAbsAvail, nRelAvail, nAbsLeftSpace,
    2459           1 :                                   nAbsRightSpace, nInhAbsSpace );
    2460             : 
    2461           1 :     if( this!=pTopTable )
    2462             :     {
    2463             :         // die linke und rechte Umrandung der Tabelle kann jetzt entgueltig
    2464             :         // festgelegt werden
    2465           0 :         if( pLayoutInfo->GetRelRightFill() == 0 )
    2466             :         {
    2467           0 :             if( !bRightBorder )
    2468             :             {
    2469             :                 // linke Umrandung von auesserer Tabelle uebernehmen
    2470           0 :                 if( bInhRightBorder )
    2471             :                 {
    2472           0 :                     bRightBorder = true;
    2473           0 :                     aRightBorderLine = aInhRightBorderLine;
    2474             :                 }
    2475             :             }
    2476             :             else
    2477             :             {
    2478             :                 // Umrandung nur setzen, wenn es erlaubt ist
    2479           0 :                 bRightBorder = bRightAlwd;
    2480             :             }
    2481             :         }
    2482             : 
    2483           0 :         if( pLayoutInfo->GetRelLeftFill() == 0 &&
    2484           0 :             !((*pColumns)[0]).bLeftBorder &&
    2485             :             bInhLeftBorder )
    2486             :         {
    2487             :             // ggf. rechte Umrandung von auesserer Tabelle uebernehmen
    2488           0 :             ((*pColumns)[0]).bLeftBorder = true;
    2489           0 :             aLeftBorderLine = aInhLeftBorderLine;
    2490             :         }
    2491             :     }
    2492             : 
    2493             :     // Fuer die Top-Table muss die Ausrichtung gesetzt werden
    2494           1 :     if( this==pTopTable )
    2495             :     {
    2496             :         sal_Int16 eHoriOri;
    2497           1 :         if( bForceFrame )
    2498             :         {
    2499             :             // Die Tabelle soll in einen Rahmen und ist auch schmaler
    2500             :             // als der verfuegbare Platz und nicht 100% breit.
    2501             :             // Dann kommt sie in einen Rahmen
    2502           0 :             eHoriOri = bPrcWidth ? text::HoriOrientation::FULL : text::HoriOrientation::LEFT;
    2503             :         }
    2504           1 :         else switch( eTableAdjust )
    2505             :         {
    2506             :             // Die Tabelle passt entweder auf die Seite, soll aber in keinen
    2507             :             // Rahmen oder sie ist Breiter als die Seite und soll deshalb
    2508             :             // in keinen Rahmen
    2509             : 
    2510             :         case SVX_ADJUST_RIGHT:
    2511             :             // in rechtsbuendigen Tabellen kann nicht auf den rechten
    2512             :             // Rand Ruecksicht genommen werden
    2513           0 :             eHoriOri = text::HoriOrientation::RIGHT;
    2514           0 :             break;
    2515             :         case SVX_ADJUST_CENTER:
    2516             :             // zentrierte Tabellen nehmen keine Ruecksicht auf Raender!
    2517           0 :             eHoriOri = text::HoriOrientation::CENTER;
    2518           0 :             break;
    2519             :         case SVX_ADJUST_LEFT:
    2520             :         default:
    2521             :             // linksbuendige Tabellen nehmen nur auf den linken Rand
    2522             :             // Ruecksicht
    2523           1 :             eHoriOri = nLeftMargin ? text::HoriOrientation::LEFT_AND_WIDTH : text::HoriOrientation::LEFT;
    2524           1 :             break;
    2525             :         }
    2526             : 
    2527             :         // das Tabellenform holen und anpassen
    2528           1 :         SwFrmFmt *pFrmFmt = pSwTable->GetFrmFmt();
    2529           1 :         pFrmFmt->SetFmtAttr( SwFmtHoriOrient(0,eHoriOri) );
    2530           1 :         if( text::HoriOrientation::LEFT_AND_WIDTH==eHoriOri )
    2531             :         {
    2532             :             OSL_ENSURE( nLeftMargin || nRightMargin,
    2533             :                     "Da gibt's wohl noch Reste von relativen Breiten" );
    2534             : 
    2535             :             // The right margin will be ignored anyway.
    2536           0 :             SvxLRSpaceItem aLRItem( pSwTable->GetFrmFmt()->GetLRSpace() );
    2537           0 :             aLRItem.SetLeft( nLeftMargin );
    2538           0 :             aLRItem.SetRight( nRightMargin );
    2539           0 :             pFrmFmt->SetFmtAttr( aLRItem );
    2540             :         }
    2541             : 
    2542           1 :         if( bPrcWidth && text::HoriOrientation::FULL!=eHoriOri )
    2543             :         {
    2544           1 :             pFrmFmt->LockModify();
    2545           1 :             SwFmtFrmSize aFrmSize( pFrmFmt->GetFrmSize() );
    2546           1 :             aFrmSize.SetWidthPercent( (sal_uInt8)nWidth );
    2547           1 :             pFrmFmt->SetFmtAttr( aFrmSize );
    2548           1 :             pFrmFmt->UnlockModify();
    2549             :         }
    2550             :     }
    2551             : 
    2552             :     // die Default Line- und Box-Formate holen
    2553           1 :     if( this==pTopTable )
    2554             :     {
    2555             :         // die erste Box merken und aus der ersten Zeile ausketten
    2556           1 :         SwTableLine *pLine1 = (pSwTable->GetTabLines())[0];
    2557           1 :         pBox1 = (pLine1->GetTabBoxes())[0];
    2558           1 :         pLine1->GetTabBoxes().erase(pLine1->GetTabBoxes().begin());
    2559             : 
    2560           1 :         pLineFmt = (SwTableLineFmt*)pLine1->GetFrmFmt();
    2561           1 :         pBoxFmt = (SwTableBoxFmt*)pBox1->GetFrmFmt();
    2562             :     }
    2563             :     else
    2564             :     {
    2565           0 :         pLineFmt = (SwTableLineFmt*)pTopTable->pLineFmt;
    2566           0 :         pBoxFmt = (SwTableBoxFmt*)pTopTable->pBoxFmt;
    2567             :     }
    2568             : 
    2569             :     // ggf. muessen fuer Tabellen in Tabellen "Filler"-Zellen eingefuegt
    2570             :     // werden
    2571           1 :     if( this != pTopTable &&
    2572           0 :         ( pLayoutInfo->GetRelLeftFill() > 0  ||
    2573           0 :           pLayoutInfo->GetRelRightFill() > 0 ) )
    2574             :     {
    2575             :         OSL_ENSURE( pBox, "kein TableBox fuer Tabelle in Tabelle" );
    2576             : 
    2577           0 :         SwTableLines& rLines = pBox->GetTabLines();
    2578             : 
    2579             :         // dazu brauchen wir erstmal ein eine neue Table-Line in der Box
    2580             :         SwTableLine *pLine =
    2581             :             new SwTableLine( pLineFrmFmtNoHeight ? pLineFrmFmtNoHeight
    2582           0 :                                                  : pLineFmt, 0, pBox );
    2583           0 :         rLines.push_back( pLine );
    2584             : 
    2585             :         // Sicherstellen, dass wie ein Format ohne Hoehe erwischt haben
    2586           0 :         if( !pLineFrmFmtNoHeight )
    2587             :         {
    2588             :             // sonst muessen wir die Hoehe aus dem Attribut entfernen
    2589             :             // und koennen uns das Format merken
    2590           0 :             pLineFrmFmtNoHeight = (SwTableLineFmt*)pLine->ClaimFrmFmt();
    2591             : 
    2592           0 :             ResetLineFrmFmtAttrs( pLineFrmFmtNoHeight );
    2593             :         }
    2594             : 
    2595           0 :         SwTableBoxes& rBoxes = pLine->GetTabBoxes();
    2596             :         SwTableBox *pNewBox;
    2597             : 
    2598             :         // ggf. links eine Zelle einfuegen
    2599           0 :         if( pLayoutInfo->GetRelLeftFill() > 0 )
    2600             :         {
    2601             :             // pPrevStNd ist der Vorgaenger-Start-Node der Tabelle. Den
    2602             :             // "Filler"-Node fuegen wir einfach dahinter ein ...
    2603           0 :             pPrevStNd = pParser->InsertTableSection( pPrevStNd );
    2604             : 
    2605           0 :             pNewBox = NewTableBox( pPrevStNd, pLine );
    2606           0 :             rBoxes.push_back( pNewBox );
    2607           0 :             FixFillerFrameFmt( pNewBox, sal_False );
    2608           0 :             pLayoutInfo->SetLeftFillerBox( pNewBox );
    2609             :         }
    2610             : 
    2611             :         // jetzt die Tabelle bearbeiten
    2612           0 :         pNewBox = new SwTableBox( pBoxFmt, 0, pLine );
    2613           0 :         rBoxes.push_back( pNewBox );
    2614             : 
    2615           0 :         SwFrmFmt *pFrmFmt = pNewBox->ClaimFrmFmt();
    2616           0 :         pFrmFmt->ResetFmtAttr( RES_BOX );
    2617           0 :         pFrmFmt->ResetFmtAttr( RES_BACKGROUND );
    2618           0 :         pFrmFmt->ResetFmtAttr( RES_VERT_ORIENT );
    2619           0 :         pFrmFmt->ResetFmtAttr( RES_BOXATR_FORMAT );
    2620             : 
    2621           0 :         _MakeTable( pNewBox );
    2622             : 
    2623             :         // und noch ggf. rechts eine Zelle einfuegen
    2624           0 :         if( pLayoutInfo->GetRelRightFill() > 0 )
    2625             :         {
    2626             :             const SwStartNode *pStNd =
    2627           0 :                 GetPrevBoxStartNode( USHRT_MAX, USHRT_MAX );
    2628           0 :             pStNd = pParser->InsertTableSection( pStNd );
    2629             : 
    2630           0 :             pNewBox = NewTableBox( pStNd, pLine );
    2631           0 :             rBoxes.push_back( pNewBox );
    2632             : 
    2633           0 :             FixFillerFrameFmt( pNewBox, sal_True );
    2634           0 :             pLayoutInfo->SetRightFillerBox( pNewBox );
    2635             :         }
    2636             :     }
    2637             :     else
    2638             :     {
    2639           1 :         _MakeTable( pBox );
    2640             :     }
    2641             : 
    2642             :     // zum Schluss fuehren wir noch eine Garbage-Collection fuer die
    2643             :     // Top-Level-Tabelle durch
    2644           1 :     if( this==pTopTable )
    2645             :     {
    2646           1 :         if( 1==nRows && nHeight && 1==pSwTable->GetTabLines().size() )
    2647             :         {
    2648             :             // Hoehe einer einzeiligen Tabelle als Mindesthoehe der
    2649             :             // Zeile setzen. (War mal fixe Hoehe, aber das gibt manchmal
    2650             :             // Probleme (fix #34972#) und ist auch nicht Netscape 4.0
    2651             :             // konform
    2652           0 :             nHeight = pParser->ToTwips( nHeight );
    2653           0 :             if( nHeight < MINLAY )
    2654           0 :                 nHeight = MINLAY;
    2655             : 
    2656           0 :             (pSwTable->GetTabLines())[0]->ClaimFrmFmt();
    2657           0 :             (pSwTable->GetTabLines())[0]->GetFrmFmt()
    2658           0 :                 ->SetFmtAttr( SwFmtFrmSize( ATT_MIN_SIZE, 0, nHeight ) );
    2659             :         }
    2660             : 
    2661           1 :         if( GetBGBrush() )
    2662           1 :             pSwTable->GetFrmFmt()->SetFmtAttr( *GetBGBrush() );
    2663             : 
    2664           1 :         ((SwTable *)pSwTable)->SetRowsToRepeat( static_cast< sal_uInt16 >(nHeadlineRepeat) );
    2665           1 :         ((SwTable *)pSwTable)->GCLines();
    2666             : 
    2667           1 :         sal_Bool bIsInFlyFrame = pContext && pContext->GetFrmFmt();
    2668           1 :         if( bIsInFlyFrame && !nWidth )
    2669             :         {
    2670           0 :             SvxAdjust eTblAdjust = GetTableAdjust(sal_False);
    2671           0 :             if( eTblAdjust != SVX_ADJUST_LEFT &&
    2672             :                 eTblAdjust != SVX_ADJUST_RIGHT )
    2673             :             {
    2674             :                 // Wenn eine Tabelle ohne Breitenangabe nicht links oder
    2675             :                 // rechts umflossen werden soll, dann stacken wir sie
    2676             :                 // in einem Rahmen mit 100%-Breite, damit ihre Groesse
    2677             :                 // angepasst wird. Der Rahmen darf nicht angepasst werden.
    2678             :                 OSL_ENSURE( HasToFly(), "Warum ist die Tabelle in einem Rahmen?" );
    2679           0 :                 sal_uInt32 nMin = pLayoutInfo->GetMin();
    2680           0 :                 if( nMin > USHRT_MAX )
    2681           0 :                     nMin = USHRT_MAX;
    2682           0 :                 SwFmtFrmSize aFlyFrmSize( ATT_VAR_SIZE, (SwTwips)nMin, MINLAY );
    2683           0 :                 aFlyFrmSize.SetWidthPercent( 100 );
    2684           0 :                 pContext->GetFrmFmt()->SetFmtAttr( aFlyFrmSize );
    2685           0 :                 bIsInFlyFrame = sal_False;
    2686             :             }
    2687             :             else
    2688             :             {
    2689             :                 // Links und rechts ausgerichtete Tabellen ohne Breite
    2690             :                 // duerfen leider nicht in der Breite angepasst werden, denn
    2691             :                 // sie wuerden nur schrumpfen aber nie wachsen.
    2692           0 :                 pLayoutInfo->SetMustNotRecalc( sal_True );
    2693           0 :                 if( pContext->GetFrmFmt()->GetAnchor().GetCntntAnchor()
    2694           0 :                     ->nNode.GetNode().FindTableNode() )
    2695             :                 {
    2696           0 :                     sal_uInt32 nMax = pLayoutInfo->GetMax();
    2697           0 :                     if( nMax > USHRT_MAX )
    2698           0 :                         nMax = USHRT_MAX;
    2699           0 :                     SwFmtFrmSize aFlyFrmSize( ATT_VAR_SIZE, (SwTwips)nMax, MINLAY );
    2700           0 :                     pContext->GetFrmFmt()->SetFmtAttr( aFlyFrmSize );
    2701           0 :                     bIsInFlyFrame = sal_False;
    2702             :                 }
    2703             :                 else
    2704             :                 {
    2705           0 :                     pLayoutInfo->SetMustNotResize( sal_True );
    2706             :                 }
    2707             :             }
    2708             :         }
    2709           1 :         pLayoutInfo->SetMayBeInFlyFrame( bIsInFlyFrame );
    2710             : 
    2711             :         // Nur Tabellen mit relativer Breite oder ohne Breite muessen
    2712             :         // angepasst werden.
    2713           1 :         pLayoutInfo->SetMustResize( bPrcWidth || !nWidth );
    2714             : 
    2715           1 :         pLayoutInfo->SetWidths();
    2716             : 
    2717           1 :         ((SwTable *)pSwTable)->SetHTMLTableLayout( pLayoutInfo );
    2718             : 
    2719           1 :         if( pResizeDrawObjs )
    2720             :         {
    2721           0 :             sal_uInt16 nCount = pResizeDrawObjs->size();
    2722           0 :             for( sal_uInt16 i=0; i<nCount; i++ )
    2723             :             {
    2724           0 :                 SdrObject *pObj = (*pResizeDrawObjs)[i];
    2725           0 :                 sal_uInt16 nRow = (*pDrawObjPrcWidths)[3*i];
    2726           0 :                 sal_uInt16 nCol = (*pDrawObjPrcWidths)[3*i+1];
    2727           0 :                 sal_uInt8 nPrcWidth = (sal_uInt8)(*pDrawObjPrcWidths)[3*i+2];
    2728             : 
    2729             :                 SwHTMLTableLayoutCell *pLayoutCell =
    2730           0 :                     pLayoutInfo->GetCell( nRow, nCol );
    2731           0 :                 sal_uInt16 nColSpan = pLayoutCell->GetColSpan();
    2732             : 
    2733             :                 sal_uInt16 nWidth2, nDummy;
    2734           0 :                 pLayoutInfo->GetAvail( nCol, nColSpan, nWidth2, nDummy );
    2735           0 :                 nWidth2 = nWidth2 - pLayoutInfo->GetLeftCellSpace( nCol, nColSpan );
    2736           0 :                 nWidth2 = nWidth2 - pLayoutInfo->GetRightCellSpace( nCol, nColSpan );
    2737           0 :                 nWidth2 = static_cast< sal_uInt16 >(((long)nWidth * nPrcWidth) / 100);
    2738             : 
    2739           0 :                 pParser->ResizeDrawObject( pObj, nWidth2 );
    2740             :             }
    2741             :         }
    2742             :     }
    2743           1 : }
    2744             : 
    2745           1 : void HTMLTable::SetTable( const SwStartNode *pStNd, _HTMLTableContext *pCntxt,
    2746             :                           sal_uInt16 nLeft, sal_uInt16 nRight,
    2747             :                           const SwTable *pSwTab, sal_Bool bFrcFrame )
    2748             : {
    2749           1 :     pPrevStNd = pStNd;
    2750           1 :     pSwTable = pSwTab;
    2751           1 :     pContext = pCntxt;
    2752             : 
    2753           1 :     nLeftMargin = nLeft;
    2754           1 :     nRightMargin = nRight;
    2755             : 
    2756           1 :     bForceFrame = bFrcFrame;
    2757           1 : }
    2758             : 
    2759           0 : void HTMLTable::RegisterDrawObject( SdrObject *pObj, sal_uInt8 nPrcWidth )
    2760             : {
    2761           0 :     if( !pResizeDrawObjs )
    2762           0 :         pResizeDrawObjs = new SdrObjects;
    2763           0 :     pResizeDrawObjs->push_back( pObj );
    2764             : 
    2765           0 :     if( !pDrawObjPrcWidths )
    2766           0 :         pDrawObjPrcWidths = new std::vector<sal_uInt16>;
    2767           0 :     pDrawObjPrcWidths->push_back( nCurRow );
    2768           0 :     pDrawObjPrcWidths->push_back( nCurCol );
    2769           0 :     pDrawObjPrcWidths->push_back( (sal_uInt16)nPrcWidth );
    2770           0 : }
    2771             : 
    2772           7 : void HTMLTable::MakeParentContents()
    2773             : {
    2774           7 :     if( !GetContext() && !HasParentSection() )
    2775             :     {
    2776             :         SetParentContents(
    2777           0 :             pParser->InsertTableContents( GetIsParentHeader() ) );
    2778             : 
    2779           0 :         SetHasParentSection( sal_True );
    2780             :     }
    2781           7 : }
    2782             : 
    2783           1 : _HTMLTableContext::~_HTMLTableContext()
    2784             : {
    2785           1 :     delete pPos;
    2786           1 : }
    2787             : 
    2788           1 : void _HTMLTableContext::SavePREListingXMP( SwHTMLParser& rParser )
    2789             : {
    2790           1 :     bRestartPRE = rParser.IsReadPRE();
    2791           1 :     bRestartXMP = rParser.IsReadXMP();
    2792           1 :     bRestartListing = rParser.IsReadListing();
    2793           1 :     rParser.FinishPREListingXMP();
    2794           1 : }
    2795             : 
    2796           1 : void _HTMLTableContext::RestorePREListingXMP( SwHTMLParser& rParser )
    2797             : {
    2798           1 :     rParser.FinishPREListingXMP();
    2799             : 
    2800           1 :     if( bRestartPRE )
    2801           0 :         rParser.StartPRE();
    2802             : 
    2803           1 :     if( bRestartXMP )
    2804           0 :         rParser.StartXMP();
    2805             : 
    2806           1 :     if( bRestartListing )
    2807           0 :         rParser.StartListing();
    2808           1 : }
    2809             : 
    2810           0 : const SwStartNode *SwHTMLParser::InsertTableSection
    2811             :     ( const SwStartNode *pPrevStNd )
    2812             : {
    2813             :     OSL_ENSURE( pPrevStNd, "Start-Node ist NULL" );
    2814             : 
    2815           0 :     pCSS1Parser->SetTDTagStyles();
    2816           0 :     SwTxtFmtColl *pColl = pCSS1Parser->GetTxtCollFromPool( RES_POOLCOLL_TABLE );
    2817             : 
    2818             :     const SwStartNode *pStNd;
    2819           0 :     if( pTable && pTable->bFirstCell )
    2820             :     {
    2821           0 :         SwNode *const pNd = & pPam->GetPoint()->nNode.GetNode();
    2822           0 :         pNd->GetTxtNode()->ChgFmtColl( pColl );
    2823           0 :         pStNd = pNd->FindTableBoxStartNode();
    2824           0 :         pTable->bFirstCell = sal_False;
    2825             :     }
    2826             :     else
    2827             :     {
    2828             :         const SwNode* pNd;
    2829           0 :         if( pPrevStNd->IsTableNode() )
    2830           0 :             pNd = pPrevStNd;
    2831             :         else
    2832           0 :             pNd = pPrevStNd->EndOfSectionNode();
    2833           0 :         SwNodeIndex nIdx( *pNd, 1 );
    2834           0 :         pStNd = pDoc->GetNodes().MakeTextSection( nIdx, SwTableBoxStartNode,
    2835           0 :                                                   pColl );
    2836           0 :         pTable->IncBoxCount();
    2837             :     }
    2838             : 
    2839             :     //Added defaults to CJK and CTL
    2840           0 :     SwCntntNode *pCNd = pDoc->GetNodes()[pStNd->GetIndex()+1] ->GetCntntNode();
    2841           0 :     SvxFontHeightItem aFontHeight( 40, 100, RES_CHRATR_FONTSIZE );
    2842           0 :     pCNd->SetAttr( aFontHeight );
    2843           0 :     SvxFontHeightItem aFontHeightCJK( 40, 100, RES_CHRATR_CJK_FONTSIZE );
    2844           0 :     pCNd->SetAttr( aFontHeightCJK );
    2845           0 :     SvxFontHeightItem aFontHeightCTL( 40, 100, RES_CHRATR_CTL_FONTSIZE );
    2846           0 :     pCNd->SetAttr( aFontHeightCTL );
    2847             : 
    2848           0 :     return pStNd;
    2849             : }
    2850             : 
    2851         260 : const SwStartNode *SwHTMLParser::InsertTableSection( sal_uInt16 nPoolId )
    2852             : {
    2853         260 :     switch( nPoolId )
    2854             :     {
    2855             :     case RES_POOLCOLL_TABLE_HDLN:
    2856           0 :         pCSS1Parser->SetTHTagStyles();
    2857           0 :         break;
    2858             :     case RES_POOLCOLL_TABLE:
    2859         260 :         pCSS1Parser->SetTDTagStyles();
    2860         260 :         break;
    2861             :     }
    2862             : 
    2863         260 :     SwTxtFmtColl *pColl = pCSS1Parser->GetTxtCollFromPool( nPoolId );
    2864             : 
    2865         260 :     SwNode *const pNd = & pPam->GetPoint()->nNode.GetNode();
    2866             :     const SwStartNode *pStNd;
    2867         260 :     if( pTable && pTable->bFirstCell )
    2868             :     {
    2869           1 :         pNd->GetTxtNode()->ChgFmtColl( pColl );
    2870           1 :         pTable->bFirstCell = sal_False;
    2871           1 :         pStNd = pNd->FindTableBoxStartNode();
    2872             :     }
    2873             :     else
    2874             :     {
    2875         259 :         SwTableNode *pTblNd = pNd->FindTableNode();
    2876         259 :         if( pTblNd->GetTable().GetHTMLTableLayout() )
    2877             :         { // if there is already a HTMTableLayout, this table is already finished
    2878             :           // and we have to look for the right table in the environment
    2879           0 :             SwTableNode *pOutTbl = pTblNd;
    2880           0 :             do {
    2881           0 :                 pTblNd = pOutTbl;
    2882           0 :                 pOutTbl = pOutTbl->StartOfSectionNode()->FindTableNode();
    2883           0 :             } while( pOutTbl && pTblNd->GetTable().GetHTMLTableLayout() );
    2884             :         }
    2885         259 :         SwNodeIndex aIdx( *pTblNd->EndOfSectionNode() );
    2886         259 :         pStNd = pDoc->GetNodes().MakeTextSection( aIdx, SwTableBoxStartNode,
    2887         259 :                                                   pColl );
    2888             : 
    2889         259 :         pPam->GetPoint()->nNode = pStNd->GetIndex() + 1;
    2890         259 :         SwTxtNode *pTxtNd = pPam->GetPoint()->nNode.GetNode().GetTxtNode();
    2891         259 :         pPam->GetPoint()->nContent.Assign( pTxtNd, 0 );
    2892         259 :         pTable->IncBoxCount();
    2893             :     }
    2894             : 
    2895         260 :     return pStNd;
    2896             : }
    2897             : 
    2898           0 : SwStartNode *SwHTMLParser::InsertTempTableCaptionSection()
    2899             : {
    2900           0 :     SwTxtFmtColl *pColl = pCSS1Parser->GetTxtCollFromPool( RES_POOLCOLL_TEXT );
    2901           0 :     SwNodeIndex& rIdx = pPam->GetPoint()->nNode;
    2902           0 :     rIdx = pDoc->GetNodes().GetEndOfExtras();
    2903           0 :     SwStartNode *pStNd = pDoc->GetNodes().MakeTextSection( rIdx,
    2904           0 :                                           SwNormalStartNode, pColl );
    2905             : 
    2906           0 :     rIdx = pStNd->GetIndex() + 1;
    2907           0 :     pPam->GetPoint()->nContent.Assign( rIdx.GetNode().GetTxtNode(), 0 );
    2908             : 
    2909           0 :     return pStNd;
    2910             : }
    2911             : 
    2912         539 : sal_Int32 SwHTMLParser::StripTrailingLF()
    2913             : {
    2914         539 :     sal_Int32 nStripped = 0;
    2915             : 
    2916         539 :     const sal_Int32 nLen = pPam->GetPoint()->nContent.GetIndex();
    2917         539 :     if( nLen )
    2918             :     {
    2919         271 :         SwTxtNode* pTxtNd = pPam->GetPoint()->nNode.GetNode().GetTxtNode();
    2920             :         // vorsicht, wenn Kommentare nicht uebrlesen werden!!!
    2921         271 :         if( pTxtNd )
    2922             :         {
    2923         271 :             sal_Int32 nPos = nLen;
    2924         271 :             sal_Int32 nLFCount = 0;
    2925         801 :             while (nPos && ('\x0a' == pTxtNd->GetTxt()[--nPos]))
    2926         259 :                 nLFCount++;
    2927             : 
    2928         271 :             if( nLFCount )
    2929             :             {
    2930         258 :                 if( nLFCount > 2 )
    2931             :                 {
    2932             :                     // Bei Netscape entspricht ein Absatz-Ende zwei LFs
    2933             :                     // (mit einem kommt man in die naechste Zeile, das
    2934             :                     // zweite erzeugt eine Leerzeile) Diesen Abstand
    2935             :                     // erreichen wie aber schon mit dem unteren
    2936             :                     // Absatz-Abstand. Wenn nach den <BR> ein neuer
    2937             :                     // Absatz aufgemacht wird, wird das Maximum des Abstands,
    2938             :                     // der sich aus den BR und dem P ergibt genommen.
    2939             :                     // Deshalb muessen wir 2 bzw. alle bei weniger
    2940             :                     // als zweien loeschen
    2941           0 :                     nLFCount = 2;
    2942             :                 }
    2943             : 
    2944         258 :                 nPos = nLen - nLFCount;
    2945         258 :                 SwIndex nIdx( pTxtNd, nPos );
    2946         258 :                 pTxtNd->EraseText( nIdx, nLFCount );
    2947         258 :                 nStripped = nLFCount;
    2948             :             }
    2949             :         }
    2950             :     }
    2951             : 
    2952         539 :     return nStripped;
    2953             : }
    2954             : 
    2955         313 : SvxBrushItem* SwHTMLParser::CreateBrushItem( const Color *pColor,
    2956             :                                              const OUString& rImageURL,
    2957             :                                              const OUString& rStyle,
    2958             :                                              const OUString& rId,
    2959             :                                              const OUString& rClass )
    2960             : {
    2961         313 :     SvxBrushItem *pBrushItem = 0;
    2962             : 
    2963         313 :     if( !rStyle.isEmpty() || !rId.isEmpty() || !rClass.isEmpty() )
    2964             :     {
    2965         260 :         SfxItemSet aItemSet( pDoc->GetAttrPool(), RES_BACKGROUND,
    2966         260 :                                                   RES_BACKGROUND );
    2967         520 :         SvxCSS1PropertyInfo aPropInfo;
    2968             : 
    2969         260 :         if( !rClass.isEmpty() )
    2970             :         {
    2971           0 :             OUString aClass( rClass );
    2972           0 :             SwCSS1Parser::GetScriptFromClass( aClass );
    2973           0 :             const SvxCSS1MapEntry *pClass = pCSS1Parser->GetClass( aClass );
    2974           0 :             if( pClass )
    2975           0 :                 aItemSet.Put( pClass->GetItemSet() );
    2976             :         }
    2977             : 
    2978         260 :         if( !rId.isEmpty() )
    2979             :         {
    2980           0 :             const SvxCSS1MapEntry *pId = pCSS1Parser->GetId( rId );
    2981           0 :             if( pId )
    2982           0 :                 aItemSet.Put( pId->GetItemSet() );
    2983             :         }
    2984             : 
    2985         260 :         pCSS1Parser->ParseStyleOption( rStyle, aItemSet, aPropInfo );
    2986         260 :         const SfxPoolItem *pItem = 0;
    2987         260 :         if( SFX_ITEM_SET == aItemSet.GetItemState( RES_BACKGROUND, false,
    2988         260 :                                                    &pItem ) )
    2989             :         {
    2990           0 :             pBrushItem = new SvxBrushItem( *((const SvxBrushItem *)pItem) );
    2991         260 :         }
    2992             :     }
    2993             : 
    2994         313 :     if( !pBrushItem && (pColor || !rImageURL.isEmpty()) )
    2995             :     {
    2996         261 :         pBrushItem = new SvxBrushItem(RES_BACKGROUND);
    2997             : 
    2998         261 :         if( pColor )
    2999         261 :             pBrushItem->SetColor(*pColor);
    3000             : 
    3001         261 :         if( !rImageURL.isEmpty() )
    3002             :         {
    3003           0 :             pBrushItem->SetGraphicLink( URIHelper::SmartRel2Abs( INetURLObject(sBaseURL), rImageURL, Link(), false) );
    3004           0 :             pBrushItem->SetGraphicPos( GPOS_TILED );
    3005             :         }
    3006             :     }
    3007             : 
    3008         313 :     return pBrushItem;
    3009             : }
    3010             : 
    3011             : class _SectionSaveStruct : public SwPendingStackData
    3012             : {
    3013             :     sal_uInt16 nBaseFontStMinSave, nFontStMinSave, nFontStHeadStartSave;
    3014             :     sal_uInt16 nDefListDeepSave, nContextStMinSave, nContextStAttrMinSave;
    3015             : 
    3016             : public:
    3017             : 
    3018             :     HTMLTable *pTable;
    3019             : 
    3020             :     _SectionSaveStruct( SwHTMLParser& rParser );
    3021             :     virtual ~_SectionSaveStruct();
    3022             : 
    3023             :     sal_uInt16 GetContextStAttrMin() const { return nContextStAttrMinSave; }
    3024             : 
    3025             :     void Restore( SwHTMLParser& rParser );
    3026             : };
    3027             : 
    3028         260 : _SectionSaveStruct::_SectionSaveStruct( SwHTMLParser& rParser ) :
    3029             :     nBaseFontStMinSave(0), nFontStMinSave(0), nFontStHeadStartSave(0),
    3030             :     nDefListDeepSave(0), nContextStMinSave(0), nContextStAttrMinSave(0),
    3031         260 :     pTable( 0 )
    3032             : {
    3033             :     // Font-Stacks einfrieren
    3034         260 :     nBaseFontStMinSave = rParser.nBaseFontStMin;
    3035         260 :     rParser.nBaseFontStMin = rParser.aBaseFontStack.size();
    3036             : 
    3037         260 :     nFontStMinSave = rParser.nFontStMin;
    3038         260 :     nFontStHeadStartSave = rParser.nFontStHeadStart;
    3039         260 :     rParser.nFontStMin = rParser.aFontStack.size();
    3040             : 
    3041             :     // Kontext-Stack einfrieren
    3042         260 :     nContextStMinSave = rParser.nContextStMin;
    3043         260 :     nContextStAttrMinSave = rParser.nContextStAttrMin;
    3044         260 :     rParser.nContextStMin = rParser.aContexts.size();
    3045         260 :     rParser.nContextStAttrMin = rParser.nContextStMin;
    3046             : 
    3047             :     // und noch ein par Zaehler retten
    3048         260 :     nDefListDeepSave = rParser.nDefListDeep;
    3049         260 :     rParser.nDefListDeep = 0;
    3050         260 : }
    3051             : 
    3052         260 : _SectionSaveStruct::~_SectionSaveStruct()
    3053         260 : {}
    3054             : 
    3055         260 : void _SectionSaveStruct::Restore( SwHTMLParser& rParser )
    3056             : {
    3057             :     // Font-Stacks wieder auftauen
    3058         260 :     sal_uInt16 nMin = rParser.nBaseFontStMin;
    3059         260 :     if( rParser.aBaseFontStack.size() > nMin )
    3060           0 :         rParser.aBaseFontStack.erase( rParser.aBaseFontStack.begin() + nMin,
    3061           0 :                 rParser.aBaseFontStack.end() );
    3062         260 :     rParser.nBaseFontStMin = nBaseFontStMinSave;
    3063             : 
    3064         260 :     nMin = rParser.nFontStMin;
    3065         260 :     if( rParser.aFontStack.size() > nMin )
    3066           0 :         rParser.aFontStack.erase( rParser.aFontStack.begin() + nMin,
    3067           0 :                 rParser.aFontStack.end() );
    3068         260 :     rParser.nFontStMin = nFontStMinSave;
    3069         260 :     rParser.nFontStHeadStart = nFontStHeadStartSave;
    3070             : 
    3071             :     OSL_ENSURE( rParser.aContexts.size() == rParser.nContextStMin &&
    3072             :             rParser.aContexts.size() == rParser.nContextStAttrMin,
    3073             :             "The Context Stack was not cleaned up" );
    3074         260 :     rParser.nContextStMin = nContextStMinSave;
    3075         260 :     rParser.nContextStAttrMin = nContextStAttrMinSave;
    3076             : 
    3077             :     // und noch ein par Zaehler rekonstruieren
    3078         260 :     rParser.nDefListDeep = nDefListDeepSave;
    3079             : 
    3080             :     // und ein par Flags zuruecksetzen
    3081         260 :     rParser.bNoParSpace = false;
    3082         260 :     rParser.nOpenParaToken = 0;
    3083             : 
    3084         260 :     if( !rParser.aParaAttrs.empty() )
    3085           0 :         rParser.aParaAttrs.clear();
    3086         260 : }
    3087             : 
    3088             : class _CellSaveStruct : public _SectionSaveStruct
    3089             : {
    3090             :     OUString aStyle, aId, aClass, aLang, aDir;
    3091             :     OUString aBGImage;
    3092             :     Color aBGColor;
    3093             :     boost::shared_ptr<SvxBoxItem> m_pBoxItem;
    3094             : 
    3095             :     HTMLTableCnts* pCnts;           // Liste aller Inhalte
    3096             :     HTMLTableCnts* pCurrCnts;   // der aktuelle Inhalt oder 0
    3097             :     SwNodeIndex *pNoBreakEndParaIdx;// Absatz-Index eines </NOBR>
    3098             : 
    3099             :     double nValue;
    3100             : 
    3101             :     sal_uInt32 nNumFmt;
    3102             : 
    3103             :     sal_uInt16 nRowSpan, nColSpan, nWidth, nHeight;
    3104             :     sal_Int32 nNoBreakEndCntntPos;     // Zeichen-Index eines </NOBR>
    3105             : 
    3106             :     SvxAdjust eAdjust;
    3107             :     sal_Int16 eVertOri;
    3108             : 
    3109             :     sal_Bool bHead : 1;
    3110             :     sal_Bool bPrcWidth : 1;
    3111             :     sal_Bool bHasNumFmt : 1;
    3112             :     sal_Bool bHasValue : 1;
    3113             :     sal_Bool bBGColor : 1;
    3114             :     sal_Bool bNoWrap : 1;       // NOWRAP-Option
    3115             :     sal_Bool bNoBreak : 1;      // NOBREAK-Tag
    3116             : 
    3117             : public:
    3118             : 
    3119             :     _CellSaveStruct( SwHTMLParser& rParser, HTMLTable *pCurTable, sal_Bool bHd,
    3120             :                      sal_Bool bReadOpt );
    3121             : 
    3122             :     virtual ~_CellSaveStruct();
    3123             : 
    3124             :     void AddContents( HTMLTableCnts *pNewCnts );
    3125         260 :     HTMLTableCnts *GetFirstContents() { return pCnts; }
    3126             : 
    3127           0 :     void ClearIsInSection() { pCurrCnts = 0; }
    3128        2646 :     sal_Bool IsInSection() const { return pCurrCnts!=0; }
    3129             :     HTMLTableCnts *GetCurrContents() const { return pCurrCnts; }
    3130             : 
    3131             :     void InsertCell( SwHTMLParser& rParser, HTMLTable *pCurTable );
    3132             : 
    3133           0 :     sal_Bool IsHeaderCell() const { return bHead; }
    3134             : 
    3135             :     void StartNoBreak( const SwPosition& rPos );
    3136             :     void EndNoBreak( const SwPosition& rPos );
    3137             :     void CheckNoBreak( const SwPosition& rPos, SwDoc *pDoc );
    3138             : };
    3139             : 
    3140         260 : _CellSaveStruct::_CellSaveStruct( SwHTMLParser& rParser, HTMLTable *pCurTable,
    3141             :                                   sal_Bool bHd, sal_Bool bReadOpt ) :
    3142             :     _SectionSaveStruct( rParser ),
    3143             :     pCnts( 0 ),
    3144             :     pCurrCnts( 0 ),
    3145             :     pNoBreakEndParaIdx( 0 ),
    3146             :     nValue( 0.0 ),
    3147             :     nNumFmt( 0 ),
    3148             :     nRowSpan( 1 ),
    3149             :     nColSpan( 1 ),
    3150             :     nWidth( 0 ),
    3151             :     nHeight( 0 ),
    3152             :     nNoBreakEndCntntPos( 0 ),
    3153         260 :     eAdjust( pCurTable->GetInheritedAdjust() ),
    3154         260 :     eVertOri( pCurTable->GetInheritedVertOri() ),
    3155             :     bHead( bHd ),
    3156             :     bPrcWidth( sal_False ),
    3157             :     bHasNumFmt( sal_False ),
    3158             :     bHasValue( sal_False ),
    3159             :     bBGColor( sal_False ),
    3160             :     bNoWrap( sal_False ),
    3161         780 :     bNoBreak( sal_False )
    3162             : {
    3163         520 :     OUString aNumFmt, aValue;
    3164             : 
    3165         260 :     if( bReadOpt )
    3166             :     {
    3167         260 :         const HTMLOptions& rOptions = rParser.GetOptions();
    3168        1300 :         for (size_t i = rOptions.size(); i; )
    3169             :         {
    3170         780 :             const HTMLOption& rOption = rOptions[--i];
    3171         780 :             switch( rOption.GetToken() )
    3172             :             {
    3173             :             case HTML_O_ID:
    3174           0 :                 aId = rOption.GetString();
    3175           0 :                 break;
    3176             :             case HTML_O_COLSPAN:
    3177           0 :                 nColSpan = (sal_uInt16)rOption.GetNumber();
    3178           0 :                 break;
    3179             :             case HTML_O_ROWSPAN:
    3180           0 :                 nRowSpan = (sal_uInt16)rOption.GetNumber();
    3181           0 :                 break;
    3182             :             case HTML_O_ALIGN:
    3183             :                 eAdjust = (SvxAdjust)rOption.GetEnum(
    3184           0 :                                         aHTMLPAlignTable, static_cast< sal_uInt16 >(eAdjust) );
    3185           0 :                 break;
    3186             :             case HTML_O_VALIGN:
    3187             :                 eVertOri = rOption.GetEnum(
    3188           0 :                                         aHTMLTblVAlignTable, eVertOri );
    3189           0 :                 break;
    3190             :             case HTML_O_WIDTH:
    3191         260 :                 nWidth = (sal_uInt16)rOption.GetNumber();   // nur fuer Netscape
    3192         260 :                 bPrcWidth = (rOption.GetString().indexOf('%') != -1);
    3193         260 :                 if( bPrcWidth && nWidth>100 )
    3194           0 :                     nWidth = 100;
    3195         260 :                 break;
    3196             :             case HTML_O_HEIGHT:
    3197           0 :                 nHeight = (sal_uInt16)rOption.GetNumber();  // nur fuer Netscape
    3198           0 :                 if( rOption.GetString().indexOf('%') != -1)
    3199           0 :                     nHeight = 0;    // keine %-Angaben beruecksichtigen
    3200           0 :                 break;
    3201             :             case HTML_O_BGCOLOR:
    3202             :                 // Leere BGCOLOR bei <TABLE>, <TR> und <TD>/<TH> wie Netscape
    3203             :                 // ignorieren, bei allen anderen Tags *wirklich* nicht.
    3204         260 :                 if( !rOption.GetString().isEmpty() )
    3205             :                 {
    3206         260 :                     rOption.GetColor( aBGColor );
    3207         260 :                     bBGColor = sal_True;
    3208             :                 }
    3209         260 :                 break;
    3210             :             case HTML_O_BACKGROUND:
    3211           0 :                 aBGImage = rOption.GetString();
    3212           0 :                 break;
    3213             :             case HTML_O_STYLE:
    3214         260 :                 aStyle = rOption.GetString();
    3215         260 :                 break;
    3216             :             case HTML_O_CLASS:
    3217           0 :                 aClass = rOption.GetString();
    3218           0 :                 break;
    3219             :             case HTML_O_LANG:
    3220           0 :                 aLang = rOption.GetString();
    3221           0 :                 break;
    3222             :             case HTML_O_DIR:
    3223           0 :                 aDir = rOption.GetString();
    3224           0 :                 break;
    3225             :             case HTML_O_SDNUM:
    3226           0 :                 aNumFmt = rOption.GetString();
    3227           0 :                 bHasNumFmt = sal_True;
    3228           0 :                 break;
    3229             :             case HTML_O_SDVAL:
    3230           0 :                 bHasValue = sal_True;
    3231           0 :                 aValue = rOption.GetString();
    3232           0 :                 break;
    3233             :             case HTML_O_NOWRAP:
    3234           0 :                 bNoWrap = sal_True;
    3235           0 :                 break;
    3236             :             }
    3237             :         }
    3238             : 
    3239         260 :         if( !aId.isEmpty() )
    3240           0 :             rParser.InsertBookmark( aId );
    3241             :     }
    3242             : 
    3243         260 :     if( bHasNumFmt )
    3244             :     {
    3245             :         LanguageType eLang;
    3246             :         nValue = rParser.GetTableDataOptionsValNum(
    3247             :                             nNumFmt, eLang, aValue, aNumFmt,
    3248           0 :                             *rParser.pDoc->GetNumberFormatter() );
    3249             :     }
    3250             : 
    3251             :     // einen neuen Kontext anlegen, aber das drawing::Alignment-Attribut
    3252             :     // nicht dort verankern, weil es noch ger keine Section gibt, in der
    3253             :     // es gibt.
    3254             :     sal_uInt16 nToken, nColl;
    3255         260 :     if( bHead )
    3256             :     {
    3257           0 :         nToken = HTML_TABLEHEADER_ON;
    3258           0 :         nColl = RES_POOLCOLL_TABLE_HDLN;
    3259             :     }
    3260             :     else
    3261             :     {
    3262         260 :         nToken = HTML_TABLEDATA_ON;
    3263         260 :         nColl = RES_POOLCOLL_TABLE;
    3264             :     }
    3265         260 :     _HTMLAttrContext *pCntxt = new _HTMLAttrContext( nToken, nColl, aEmptyOUStr, sal_True );
    3266         260 :     if( SVX_ADJUST_END != eAdjust )
    3267             :         rParser.InsertAttr( &rParser.aAttrTab.pAdjust, SvxAdjustItem(eAdjust, RES_PARATR_ADJUST),
    3268           0 :                             pCntxt );
    3269             : 
    3270         260 :     if( rParser.HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
    3271             :     {
    3272         260 :         SfxItemSet aItemSet( rParser.pDoc->GetAttrPool(),
    3273         520 :                              rParser.pCSS1Parser->GetWhichMap() );
    3274         520 :         SvxCSS1PropertyInfo aPropInfo;
    3275             : 
    3276         260 :         if( rParser.ParseStyleOptions( aStyle, aId, aClass, aItemSet,
    3277         260 :                                        aPropInfo, &aLang, &aDir ) )
    3278             :         {
    3279             :             SfxPoolItem const* pItem;
    3280         260 :             if (SFX_ITEM_SET == aItemSet.GetItemState(RES_BOX, false, &pItem))
    3281             :             {   // fdo#41796: steal box item to set it in FixFrameFmt later!
    3282         260 :                 m_pBoxItem.reset(dynamic_cast<SvxBoxItem *>(pItem->Clone()));
    3283         260 :                 aItemSet.ClearItem(RES_BOX);
    3284             :             }
    3285         260 :             rParser.InsertAttrs( aItemSet, aPropInfo, pCntxt );
    3286         260 :         }
    3287             :     }
    3288             : 
    3289         260 :     rParser.SplitPREListingXMP( pCntxt );
    3290             : 
    3291         520 :     rParser.PushContext( pCntxt );
    3292         260 : }
    3293             : 
    3294         780 : _CellSaveStruct::~_CellSaveStruct()
    3295             : {
    3296         260 :     delete pNoBreakEndParaIdx;
    3297         520 : }
    3298             : 
    3299         260 : void _CellSaveStruct::AddContents( HTMLTableCnts *pNewCnts )
    3300             : {
    3301         260 :     if( pCnts )
    3302           0 :         pCnts->Add( pNewCnts );
    3303             :     else
    3304         260 :         pCnts = pNewCnts;
    3305             : 
    3306         260 :     pCurrCnts = pNewCnts;
    3307         260 : }
    3308             : 
    3309         260 : void _CellSaveStruct::InsertCell( SwHTMLParser& rParser,
    3310             :                                   HTMLTable *pCurTable )
    3311             : {
    3312             : #if OSL_DEBUG_LEVEL > 0
    3313             :     // Die Attribute muessen schon beim Auefrauemen des Kontext-Stacks
    3314             :     // entfernt worden sein, sonst ist etwas schiefgelaufen. Das
    3315             :     // Checken wir mal eben ...
    3316             :     // MIB 8.1.98: Wenn ausserhalb einer Zelle Attribute geoeffnet
    3317             :     // wurden stehen diese noch in der Attribut-Tabelle und werden erst
    3318             :     // ganz zum Schluss durch die CleanContext-Aufrufe in BuildTable
    3319             :     // geloescht. Damit es in diesem Fall keine Asserts gibt findet dann
    3320             :     // keine Ueberpruefung statt. Erkennen tut man diesen Fall an
    3321             :     // nContextStAttrMin: Der gemerkte Wert nContextStAttrMinSave ist der
    3322             :     // Wert, den nContextStAttrMin beim Start der Tabelle hatte. Und
    3323             :     // der aktuelle Wert von nContextStAttrMin entspricht der Anzahl der
    3324             :     // Kontexte, die beim Start der Zelle vorgefunden wurden. Sind beide
    3325             :     // Werte unterschiedlich, wurden ausserhalb der Zelle Kontexte
    3326             :     // angelegt und wir ueberpruefen nichts.
    3327             : 
    3328             :     if( rParser.nContextStAttrMin == GetContextStAttrMin() )
    3329             :     {
    3330             :         _HTMLAttr** pTbl = (_HTMLAttr**)&rParser.aAttrTab;
    3331             : 
    3332             :         for( sal_uInt16 nCnt = sizeof( _HTMLAttrTable ) / sizeof( _HTMLAttr* );
    3333             :             nCnt--; ++pTbl )
    3334             :         {
    3335             :             OSL_ENSURE( !*pTbl, "Die Attribut-Tabelle ist nicht leer" );
    3336             :         }
    3337             :     }
    3338             : #endif
    3339             : 
    3340             :     // jetzt muessen wir noch die Zelle an der aktuellen Position einfuegen
    3341             :     SvxBrushItem *pBrushItem =
    3342             :         rParser.CreateBrushItem( bBGColor ? &aBGColor : 0, aBGImage,
    3343         260 :                                  aStyle, aId, aClass );
    3344             :     pCurTable->InsertCell( pCnts, nRowSpan, nColSpan, nWidth,
    3345             :                            bPrcWidth, nHeight, eVertOri, pBrushItem, m_pBoxItem,
    3346             :                            bHasNumFmt, nNumFmt, bHasValue, nValue,
    3347         260 :                            bNoWrap );
    3348         260 :     Restore( rParser );
    3349         260 : }
    3350             : 
    3351           0 : void _CellSaveStruct::StartNoBreak( const SwPosition& rPos )
    3352             : {
    3353           0 :     if( !pCnts ||
    3354           0 :         (!rPos.nContent.GetIndex() && pCurrCnts==pCnts &&
    3355           0 :          pCnts->GetStartNode() &&
    3356           0 :          pCnts->GetStartNode()->GetIndex() + 1 ==
    3357           0 :             rPos.nNode.GetIndex()) )
    3358             :     {
    3359           0 :         bNoBreak = sal_True;
    3360             :     }
    3361           0 : }
    3362             : 
    3363           0 : void _CellSaveStruct::EndNoBreak( const SwPosition& rPos )
    3364             : {
    3365           0 :     if( bNoBreak )
    3366             :     {
    3367           0 :         delete pNoBreakEndParaIdx;
    3368           0 :         pNoBreakEndParaIdx = new SwNodeIndex( rPos.nNode );
    3369           0 :         nNoBreakEndCntntPos = rPos.nContent.GetIndex();
    3370           0 :         bNoBreak = sal_False;
    3371             :     }
    3372           0 : }
    3373             : 
    3374         260 : void _CellSaveStruct::CheckNoBreak( const SwPosition& rPos, SwDoc * /*pDoc*/ )
    3375             : {
    3376         260 :     if( pCnts && pCurrCnts==pCnts )
    3377             :     {
    3378         260 :         if( bNoBreak )
    3379             :         {
    3380             :             // <NOBR> wurde nicht beendet
    3381           0 :             pCnts->SetNoBreak();
    3382             :         }
    3383         260 :         else if( pNoBreakEndParaIdx &&
    3384           0 :                  pNoBreakEndParaIdx->GetIndex() == rPos.nNode.GetIndex() )
    3385             :         {
    3386           0 :             if( nNoBreakEndCntntPos == rPos.nContent.GetIndex() )
    3387             :             {
    3388             :                 // <NOBR> wurde unmittelbar vor dem Zellen-Ende beendet
    3389           0 :                 pCnts->SetNoBreak();
    3390             :             }
    3391           0 :             else if( nNoBreakEndCntntPos + 1 == rPos.nContent.GetIndex() )
    3392             :             {
    3393           0 :                 SwTxtNode const*const pTxtNd(rPos.nNode.GetNode().GetTxtNode());
    3394           0 :                 if( pTxtNd )
    3395             :                 {
    3396             :                     sal_Unicode const cLast =
    3397           0 :                             pTxtNd->GetTxt()[nNoBreakEndCntntPos];
    3398           0 :                     if( ' '==cLast || '\x0a'==cLast )
    3399             :                     {
    3400             :                         // Zwischem dem </NOBR> und dem Zellen-Ende gibt es nur
    3401             :                         // ein Blank oder einen Zeilenumbruch.
    3402           0 :                         pCnts->SetNoBreak();
    3403             :                     }
    3404             :                 }
    3405             :             }
    3406             :         }
    3407             :     }
    3408         260 : }
    3409             : 
    3410         260 : HTMLTableCnts *SwHTMLParser::InsertTableContents(
    3411             :                                         sal_Bool bHead )
    3412             : {
    3413             :     // eine neue Section anlegen, der PaM steht dann darin
    3414             :     const SwStartNode *pStNd =
    3415             :         InsertTableSection( static_cast< sal_uInt16 >(bHead ? RES_POOLCOLL_TABLE_HDLN
    3416         260 :                                            : RES_POOLCOLL_TABLE) );
    3417             : 
    3418         260 :     if( GetNumInfo().GetNumRule() )
    3419             :     {
    3420             :         // 1. Absatz auf nicht numeriert setzen
    3421           0 :         sal_uInt8 nLvl = GetNumInfo().GetLevel();
    3422             : 
    3423           0 :         SetNodeNum( nLvl, false );
    3424             :     }
    3425             : 
    3426             :     // Attributierungs-Anfang neu setzen
    3427         260 :     const SwNodeIndex& rSttPara = pPam->GetPoint()->nNode;
    3428         260 :     sal_Int32 nSttCnt = pPam->GetPoint()->nContent.GetIndex();
    3429             : 
    3430         260 :     _HTMLAttr** pTbl = (_HTMLAttr**)&aAttrTab;
    3431       10660 :     for( sal_uInt16 nCnt = sizeof( _HTMLAttrTable ) / sizeof( _HTMLAttr* );
    3432             :         nCnt--; ++pTbl )
    3433             :     {
    3434             : 
    3435       10400 :         _HTMLAttr *pAttr = *pTbl;
    3436       20800 :         while( pAttr )
    3437             :         {
    3438             :             OSL_ENSURE( !pAttr->GetPrev(), "Attribut hat Previous-Liste" );
    3439           0 :             pAttr->nSttPara = rSttPara;
    3440           0 :             pAttr->nEndPara = rSttPara;
    3441           0 :             pAttr->nSttCntnt = nSttCnt;
    3442           0 :             pAttr->nEndCntnt = nSttCnt;
    3443             : 
    3444           0 :             pAttr = pAttr->GetNext();
    3445             :         }
    3446             :     }
    3447             : 
    3448         260 :     return new HTMLTableCnts( pStNd );
    3449             : }
    3450             : 
    3451           0 : sal_uInt16 SwHTMLParser::IncGrfsThatResizeTable()
    3452             : {
    3453           0 :     return pTable ? pTable->IncGrfsThatResize() : 0;
    3454             : }
    3455             : 
    3456           0 : void SwHTMLParser::RegisterDrawObjectToTable( HTMLTable *pCurTable,
    3457             :                                         SdrObject *pObj, sal_uInt8 nPrcWidth )
    3458             : {
    3459           0 :     pCurTable->RegisterDrawObject( pObj, nPrcWidth );
    3460           0 : }
    3461             : 
    3462         260 : void SwHTMLParser::BuildTableCell( HTMLTable *pCurTable, sal_Bool bReadOptions,
    3463             :                                    sal_Bool bHead )
    3464             : {
    3465         260 :     if( !IsParserWorking() && !pPendStack )
    3466           0 :         return;
    3467             : 
    3468             :     _CellSaveStruct* pSaveStruct;
    3469             : 
    3470         260 :     int nToken = 0;
    3471         260 :     sal_Bool bPending = sal_False;
    3472         260 :     if( pPendStack )
    3473             :     {
    3474           0 :         pSaveStruct = (_CellSaveStruct*)pPendStack->pData;
    3475             : 
    3476           0 :         SwPendingStack* pTmp = pPendStack->pNext;
    3477           0 :         delete pPendStack;
    3478           0 :         pPendStack = pTmp;
    3479           0 :         nToken = pPendStack ? pPendStack->nToken : GetSaveToken();
    3480           0 :         bPending = SVPAR_ERROR == eState && pPendStack != 0;
    3481             : 
    3482           0 :         SaveState( nToken );
    3483             :     }
    3484             :     else
    3485             :     {
    3486             :         // <TH> bzw. <TD> wurde bereits gelesen
    3487         260 :         if( pTable->IsOverflowing() )
    3488             :         {
    3489           0 :             SaveState( 0 );
    3490           0 :             return;
    3491             :         }
    3492             : 
    3493         260 :         if( !pCurTable->GetContext() )
    3494             :         {
    3495           1 :             sal_Bool bTopTable = pTable==pCurTable;
    3496             : 
    3497             :             // die Tabelle besitzt noch keinen Inhalt, d.h. die eigentliche
    3498             :             // Tabelle muss erst noch angelegt werden
    3499             : 
    3500             :             static sal_uInt16 aWhichIds[] =
    3501             :             {
    3502             :                 RES_PARATR_SPLIT,   RES_PARATR_SPLIT,
    3503             :                 RES_PAGEDESC,       RES_PAGEDESC,
    3504             :                 RES_BREAK,          RES_BREAK,
    3505             :                 RES_BACKGROUND,     RES_BACKGROUND,
    3506             :                 RES_KEEP,           RES_KEEP,
    3507             :                 RES_LAYOUT_SPLIT,   RES_LAYOUT_SPLIT,
    3508             :                 RES_FRAMEDIR,       RES_FRAMEDIR,
    3509             :                 0
    3510             :             };
    3511             : 
    3512           1 :             SfxItemSet aItemSet( pDoc->GetAttrPool(), aWhichIds );
    3513           2 :             SvxCSS1PropertyInfo aPropInfo;
    3514             : 
    3515           1 :             sal_Bool bStyleParsed = ParseStyleOptions( pCurTable->GetStyle(),
    3516           1 :                                                    pCurTable->GetId(),
    3517           1 :                                                    pCurTable->GetClass(),
    3518             :                                                    aItemSet, aPropInfo,
    3519           2 :                                                       0, &pCurTable->GetDirection() );
    3520           1 :             const SfxPoolItem *pItem = 0;
    3521           1 :             if( bStyleParsed )
    3522             :             {
    3523           1 :                 if( SFX_ITEM_SET == aItemSet.GetItemState(
    3524           1 :                                         RES_BACKGROUND, false, &pItem ) )
    3525             :                 {
    3526           0 :                     pCurTable->SetBGBrush( *(const SvxBrushItem *)pItem );
    3527           0 :                     aItemSet.ClearItem( RES_BACKGROUND );
    3528             :                 }
    3529           1 :                 if( SFX_ITEM_SET == aItemSet.GetItemState(
    3530           1 :                                         RES_PARATR_SPLIT, false, &pItem ) )
    3531             :                 {
    3532             :                     aItemSet.Put(
    3533             :                         SwFmtLayoutSplit( ((const SvxFmtSplitItem *)pItem)
    3534           0 :                                                 ->GetValue() ) );
    3535           0 :                     aItemSet.ClearItem( RES_PARATR_SPLIT );
    3536             :                 }
    3537             :             }
    3538             : 
    3539             :             // Den linken/rechten Absatzeinzug ermitteln
    3540           1 :             sal_uInt16 nLeftSpace = 0;
    3541           1 :             sal_uInt16 nRightSpace = 0;
    3542             :             short nIndent;
    3543           1 :             GetMarginsFromContextWithNumBul( nLeftSpace, nRightSpace, nIndent );
    3544             : 
    3545             :             // die aktuelle Position an die wir irgendwann zurueckkehren
    3546           1 :             SwPosition *pSavePos = 0;
    3547           1 :             sal_Bool bForceFrame = sal_False;
    3548           1 :             sal_Bool bAppended = sal_False;
    3549           1 :             sal_Bool bParentLFStripped = sal_False;
    3550           1 :             if( bTopTable )
    3551             :             {
    3552           1 :                 SvxAdjust eTblAdjust = pTable->GetTableAdjust(sal_False);
    3553             : 
    3554             :                 // Wenn die Tabelle links oder rechts ausgerivchtet ist,
    3555             :                 // oder in einen Rahmen soll, dann kommt sie auch in einen
    3556             :                 // solchen.
    3557           1 :                 bForceFrame = eTblAdjust == SVX_ADJUST_LEFT ||
    3558           2 :                               eTblAdjust == SVX_ADJUST_RIGHT ||
    3559           2 :                               pCurTable->HasToFly();
    3560             : 
    3561             :                 // Entweder kommt die Tabelle in keinen Rahmen und befindet
    3562             :                 // sich in keinem Rahmen (wird also durch Zellen simuliert),
    3563             :                 // oder es gibt bereits Inhalt an der entsprechenden Stelle.
    3564             :                 OSL_ENSURE( !bForceFrame || pCurTable->HasParentSection(),
    3565             :                         "Tabelle im Rahmen hat keine Umgebung!" );
    3566             : 
    3567           1 :                 sal_Bool bAppend = sal_False;
    3568           1 :                 if( bForceFrame )
    3569             :                 {
    3570             :                     // Wenn die Tabelle in einen Rahmen kommt, muss
    3571             :                     // nur ein neuer Absatz aufgemacht werden, wenn
    3572             :                     // der Absatz Rahmen ohne Umlauf enthaelt.
    3573           0 :                     bAppend = HasCurrentParaFlys(sal_True);
    3574             :                 }
    3575             :                 else
    3576             :                 {
    3577             :                     // Sonst muss ein neuer Absatz aufgemacht werden,
    3578             :                     // wenn der Absatz nicht leer ist, oder Rahmen
    3579             :                     // oder text::Bookmarks enthaelt.
    3580             :                     bAppend =
    3581           2 :                         pPam->GetPoint()->nContent.GetIndex() ||
    3582           2 :                         HasCurrentParaFlys() ||
    3583           2 :                         HasCurrentParaBookmarks();
    3584             :                 }
    3585           1 :                 if( bAppend )
    3586             :                 {
    3587           0 :                     if( !pPam->GetPoint()->nContent.GetIndex() )
    3588             :                     {
    3589             :                         //Set default to CJK and CTL
    3590             :                         pDoc->SetTxtFmtColl( *pPam,
    3591           0 :                             pCSS1Parser->GetTxtCollFromPool(RES_POOLCOLL_STANDARD) );
    3592           0 :                         SvxFontHeightItem aFontHeight( 40, 100, RES_CHRATR_FONTSIZE );
    3593             : 
    3594             :                         _HTMLAttr* pTmp =
    3595           0 :                             new _HTMLAttr( *pPam->GetPoint(), aFontHeight );
    3596           0 :                         aSetAttrTab.push_back( pTmp );
    3597             : 
    3598           0 :                         SvxFontHeightItem aFontHeightCJK( 40, 100, RES_CHRATR_CJK_FONTSIZE );
    3599             :                         pTmp =
    3600           0 :                             new _HTMLAttr( *pPam->GetPoint(), aFontHeightCJK );
    3601           0 :                         aSetAttrTab.push_back( pTmp );
    3602             : 
    3603           0 :                         SvxFontHeightItem aFontHeightCTL( 40, 100, RES_CHRATR_CTL_FONTSIZE );
    3604             :                         pTmp =
    3605           0 :                             new _HTMLAttr( *pPam->GetPoint(), aFontHeightCTL );
    3606           0 :                         aSetAttrTab.push_back( pTmp );
    3607             : 
    3608           0 :                         pTmp = new _HTMLAttr( *pPam->GetPoint(),
    3609           0 :                                             SvxULSpaceItem( 0, 0, RES_UL_SPACE ) );
    3610           0 :                         aSetAttrTab.push_front( pTmp ); // ja, 0, weil schon
    3611             :                                                         // vom Tabellenende vorher
    3612             :                                                         // was gesetzt sein kann.
    3613             :                     }
    3614           0 :                     AppendTxtNode( AM_NOSPACE );
    3615           0 :                     bAppended = sal_True;
    3616             :                 }
    3617           1 :                 else if( !aParaAttrs.empty() )
    3618             :                 {
    3619           0 :                     if( !bForceFrame )
    3620             :                     {
    3621             :                         // Der Absatz wird gleich hinter die Tabelle
    3622             :                         // verschoben. Deshalb entfernen wir alle harten
    3623             :                         // Attribute des Absatzes
    3624             : 
    3625           0 :                         for( sal_uInt16 i=0; i<aParaAttrs.size(); i++ )
    3626           0 :                             aParaAttrs[i]->Invalidate();
    3627             :                     }
    3628             : 
    3629           0 :                     aParaAttrs.clear();
    3630             :                 }
    3631             : 
    3632           1 :                 pSavePos = new SwPosition( *pPam->GetPoint() );
    3633             :             }
    3634           0 :             else if( pCurTable->HasParentSection() )
    3635             :             {
    3636           0 :                 bParentLFStripped = StripTrailingLF() > 0;
    3637             : 
    3638             :                 // Absaetze bzw. ueberschriften beeenden
    3639           0 :                 nOpenParaToken = 0;
    3640           0 :                 nFontStHeadStart = nFontStMin;
    3641             : 
    3642             :                 // die harten Attribute an diesem Absatz werden nie mehr ungueltig
    3643           0 :                 if( !aParaAttrs.empty() )
    3644           0 :                     aParaAttrs.clear();
    3645             :             }
    3646             : 
    3647             :             // einen Tabellen Kontext anlegen
    3648             :             _HTMLTableContext *pTCntxt =
    3649             :                         new _HTMLTableContext( pSavePos, nContextStMin,
    3650           1 :                                                nContextStAttrMin );
    3651             : 
    3652             :             // alle noch offenen Attribute beenden und hinter der Tabelle
    3653             :             // neu aufspannen
    3654           1 :             _HTMLAttrs *pPostIts = 0;
    3655           1 :             if( !bForceFrame && (bTopTable || pCurTable->HasParentSection()) )
    3656             :             {
    3657           1 :                 SplitAttrTab( pTCntxt->aAttrTab, bTopTable );
    3658             :                 // Wenn wir einen schon vorhandenen Absatz verwenden, duerfen
    3659             :                 // in den keine PostIts eingefuegt werden, weil der Absatz
    3660             :                 // ja hinter die Tabelle wandert. Sie werden deshalb in den
    3661             :                 // ersten Absatz der Tabelle verschoben.
    3662             :                 // Bei Tabellen in Tabellen duerfen ebenfalls keine PostIts
    3663             :                 // in einen noch leeren Absatz eingefuegt werden, weil
    3664             :                 // der sonat nicht geloescht wird.
    3665           2 :                 if( (bTopTable && !bAppended) ||
    3666           0 :                     (!bTopTable && !bParentLFStripped &&
    3667           0 :                      !pPam->GetPoint()->nContent.GetIndex()) )
    3668           1 :                     pPostIts = new _HTMLAttrs;
    3669           1 :                 SetAttr( bTopTable, bTopTable, pPostIts );
    3670             :             }
    3671             :             else
    3672             :             {
    3673           0 :                 SaveAttrTab( pTCntxt->aAttrTab );
    3674           0 :                 if( bTopTable && !bAppended )
    3675             :                 {
    3676           0 :                     pPostIts = new _HTMLAttrs;
    3677           0 :                     SetAttr( sal_True, sal_True, pPostIts );
    3678             :                 }
    3679             :             }
    3680           1 :             bNoParSpace = false;
    3681             : 
    3682             :             // Aktuelle Numerierung retten und auschalten.
    3683           1 :             pTCntxt->SetNumInfo( GetNumInfo() );
    3684           1 :             GetNumInfo().Clear();
    3685           1 :             pTCntxt->SavePREListingXMP( *this );
    3686             : 
    3687           1 :             if( bTopTable )
    3688             :             {
    3689           1 :                 if( bForceFrame )
    3690             :                 {
    3691             :                     // Die Tabelle soll in einen Rahmen geschaufelt werden.
    3692             : 
    3693           0 :                     SfxItemSet aFrmSet( pDoc->GetAttrPool(),
    3694           0 :                                         RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
    3695           0 :                     if( !pCurTable->IsNewDoc() )
    3696           0 :                         Reader::ResetFrmFmtAttrs( aFrmSet );
    3697             : 
    3698           0 :                     SwSurround eSurround = SURROUND_NONE;
    3699             :                     sal_Int16 eHori;
    3700             : 
    3701           0 :                     switch( pCurTable->GetTableAdjust(sal_True) )
    3702             :                     {
    3703             :                     case SVX_ADJUST_RIGHT:
    3704           0 :                         eHori = text::HoriOrientation::RIGHT;
    3705           0 :                         eSurround = SURROUND_LEFT;
    3706           0 :                         break;
    3707             :                     case SVX_ADJUST_CENTER:
    3708           0 :                         eHori = text::HoriOrientation::CENTER;
    3709           0 :                         break;
    3710             :                     case SVX_ADJUST_LEFT:
    3711           0 :                         eSurround = SURROUND_RIGHT;
    3712             :                     default:
    3713           0 :                         eHori = text::HoriOrientation::LEFT;
    3714           0 :                         break;
    3715             :                     }
    3716             :                     SetAnchorAndAdjustment( text::VertOrientation::NONE, eHori, aFrmSet,
    3717           0 :                                             sal_True );
    3718           0 :                     aFrmSet.Put( SwFmtSurround(eSurround) );
    3719             : 
    3720           0 :                     SwFmtFrmSize aFrmSize( ATT_VAR_SIZE, 20*MM50, MINLAY );
    3721           0 :                     aFrmSize.SetWidthPercent( 100 );
    3722           0 :                     aFrmSet.Put( aFrmSize );
    3723             : 
    3724           0 :                     sal_uInt16 nSpace = pCurTable->GetHSpace();
    3725           0 :                     if( nSpace )
    3726           0 :                         aFrmSet.Put( SvxLRSpaceItem(nSpace,nSpace, 0, 0, RES_LR_SPACE) );
    3727           0 :                     nSpace = pCurTable->GetVSpace();
    3728           0 :                     if( nSpace )
    3729           0 :                         aFrmSet.Put( SvxULSpaceItem(nSpace,nSpace, RES_UL_SPACE) );
    3730             : 
    3731             :                     RndStdIds eAnchorId = ((const SwFmtAnchor&)aFrmSet.
    3732           0 :                                                 Get( RES_ANCHOR )).
    3733           0 :                                                 GetAnchorId();
    3734             :                     SwFrmFmt *pFrmFmt =  pDoc->MakeFlySection(
    3735           0 :                                 eAnchorId, pPam->GetPoint(), &aFrmSet );
    3736             : 
    3737           0 :                     pTCntxt->SetFrmFmt( pFrmFmt );
    3738           0 :                     const SwFmtCntnt& rFlyCntnt = pFrmFmt->GetCntnt();
    3739           0 :                     pPam->GetPoint()->nNode = *rFlyCntnt.GetCntntIdx();
    3740             :                     SwCntntNode *pCNd =
    3741           0 :                         pDoc->GetNodes().GoNext( &(pPam->GetPoint()->nNode) );
    3742           0 :                     pPam->GetPoint()->nContent.Assign( pCNd, 0 );
    3743             : 
    3744             :                 }
    3745             : 
    3746             :                 // eine SwTable mit einer Box anlegen und den PaM in den
    3747             :                 // Inhalt der Box-Section bewegen (der Ausrichtungs-Parameter
    3748             :                 // ist erstmal nur ein Dummy und wird spaeter noch richtig
    3749             :                 // gesetzt)
    3750             :                 OSL_ENSURE( !pPam->GetPoint()->nContent.GetIndex(),
    3751             :                         "Der Absatz hinter der Tabelle ist nicht leer!" );
    3752             :                 const SwTable* pSwTable = pDoc->InsertTable(
    3753             :                         SwInsertTableOptions( tabopts::HEADLINE_NO_BORDER, 1 ),
    3754           1 :                         *pPam->GetPoint(), 1, 1, text::HoriOrientation::LEFT );
    3755             : 
    3756           1 :                 if( bForceFrame )
    3757             :                 {
    3758           0 :                     SwNodeIndex aDstIdx( pPam->GetPoint()->nNode );
    3759           0 :                     pPam->Move( fnMoveBackward );
    3760           0 :                     pDoc->GetNodes().Delete( aDstIdx );
    3761             :                 }
    3762             :                 else
    3763             :                 {
    3764           1 :                     if( bStyleParsed )
    3765             :                     {
    3766           1 :                         pCSS1Parser->SetFmtBreak( aItemSet, aPropInfo );
    3767           1 :                         pSwTable->GetFrmFmt()->SetFmtAttr( aItemSet );
    3768             :                     }
    3769           1 :                     pPam->Move( fnMoveBackward );
    3770             :                 }
    3771             : 
    3772           1 :                 SwNode const*const pNd = & pPam->GetPoint()->nNode.GetNode();
    3773           1 :                 if( !bAppended && !bForceFrame )
    3774             :                 {
    3775             :                     SwTxtNode *const pOldTxtNd =
    3776           1 :                         pSavePos->nNode.GetNode().GetTxtNode();
    3777             :                     OSL_ENSURE( pOldTxtNd, "Wieso stehen wir in keinem Txt-Node?" );
    3778           1 :                     SwFrmFmt *pFrmFmt = pSwTable->GetFrmFmt();
    3779             : 
    3780             :                     const SfxPoolItem* pItem2;
    3781           2 :                     if( SFX_ITEM_SET == pOldTxtNd->GetSwAttrSet()
    3782           1 :                             .GetItemState( RES_PAGEDESC, false, &pItem2 ) &&
    3783           0 :                         ((SwFmtPageDesc *)pItem2)->GetPageDesc() )
    3784             :                     {
    3785           0 :                         pFrmFmt->SetFmtAttr( *pItem2 );
    3786           0 :                         pOldTxtNd->ResetAttr( RES_PAGEDESC );
    3787             :                     }
    3788           2 :                     if( SFX_ITEM_SET == pOldTxtNd->GetSwAttrSet()
    3789           1 :                             .GetItemState( RES_BREAK, true, &pItem2 ) )
    3790             :                     {
    3791           0 :                         switch( ((SvxFmtBreakItem *)pItem2)->GetBreak() )
    3792             :                         {
    3793             :                         case SVX_BREAK_PAGE_BEFORE:
    3794             :                         case SVX_BREAK_PAGE_AFTER:
    3795             :                         case SVX_BREAK_PAGE_BOTH:
    3796           0 :                             pFrmFmt->SetFmtAttr( *pItem2 );
    3797           0 :                             pOldTxtNd->ResetAttr( RES_BREAK );
    3798             :                         default:
    3799             :                             ;
    3800             :                         }
    3801             :                     }
    3802             :                 }
    3803             : 
    3804           1 :                 if( !bAppended && pPostIts )
    3805             :                 {
    3806             :                     // noch vorhandene PostIts in den ersten Absatz
    3807             :                     // der Tabelle setzen
    3808           1 :                     InsertAttrs( *pPostIts );
    3809           1 :                     delete pPostIts;
    3810           1 :                     pPostIts = 0;
    3811             :                 }
    3812             : 
    3813           1 :                 pTCntxt->SetTableNode( (SwTableNode *)pNd->FindTableNode() );
    3814             : 
    3815           1 :                 pCurTable->SetTable( pTCntxt->GetTableNode(), pTCntxt,
    3816             :                                      nLeftSpace, nRightSpace,
    3817           2 :                                      pSwTable, bForceFrame );
    3818             : 
    3819             :                 OSL_ENSURE( !pPostIts, "ubenutzte PostIts" );
    3820             :             }
    3821             :             else
    3822             :             {
    3823             :                 // noch offene Bereiche muessen noch entfernt werden
    3824           0 :                 if( EndSections( bParentLFStripped ) )
    3825           0 :                     bParentLFStripped = sal_False;
    3826             : 
    3827           0 :                 if( pCurTable->HasParentSection() )
    3828             :                 {
    3829             :                     // dannach entfernen wir ein ggf. zu viel vorhandenen
    3830             :                     // leeren Absatz, aber nur, wenn er schon vor dem
    3831             :                     // entfernen von LFs leer war
    3832           0 :                     if( !bParentLFStripped )
    3833           0 :                         StripTrailingPara();
    3834             : 
    3835           0 :                     if( pPostIts )
    3836             :                     {
    3837             :                         // noch vorhandene PostIts an das Ende des jetzt
    3838             :                         // aktuellen Absatzes schieben
    3839           0 :                         InsertAttrs( *pPostIts );
    3840           0 :                         delete pPostIts;
    3841           0 :                         pPostIts = 0;
    3842             :                     }
    3843             :                 }
    3844             : 
    3845           0 :                 SwNode const*const pNd = & pPam->GetPoint()->nNode.GetNode();
    3846             :                 const SwStartNode *pStNd = (pTable->bFirstCell ? pNd->FindTableNode()
    3847           0 :                                                             : pNd->FindTableBoxStartNode() );
    3848             : 
    3849           0 :                 pCurTable->SetTable( pStNd, pTCntxt, nLeftSpace, nRightSpace );
    3850             :             }
    3851             : 
    3852             :             // Den Kontext-Stack einfrieren, denn es koennen auch mal
    3853             :             // irgendwo ausserhalb von Zellen Attribute gesetzt werden.
    3854             :             // Darf nicht frueher passieren, weil eventuell noch im
    3855             :             // Stack gesucht wird!!!
    3856           1 :             nContextStMin = aContexts.size();
    3857           2 :             nContextStAttrMin = nContextStMin;
    3858             :         }
    3859             : 
    3860             :         pSaveStruct = new _CellSaveStruct( *this, pCurTable, bHead,
    3861         260 :                                             bReadOptions );
    3862             : 
    3863             :         // ist beim ersten GetNextToken schon pending, muss bei
    3864             :         // wiederaufsetzen auf jedenfall neu gelesen werden!
    3865         260 :         SaveState( 0 );
    3866             :     }
    3867             : 
    3868         260 :     if( !nToken )
    3869         260 :         nToken = GetNextToken();    // Token nach <TABLE>
    3870             : 
    3871         260 :     sal_Bool bDone = sal_False;
    3872        2383 :     while( (IsParserWorking() && !bDone) || bPending )
    3873             :     {
    3874        1863 :         SaveState( nToken );
    3875             : 
    3876        1863 :         nToken = FilterToken( nToken );
    3877             : 
    3878             :         OSL_ENSURE( pPendStack || !bCallNextToken || pSaveStruct->IsInSection(),
    3879             :                 "Wo ist die Section gebieben?" );
    3880        1863 :         if( !pPendStack && bCallNextToken && pSaveStruct->IsInSection() )
    3881             :         {
    3882             :             // NextToken direkt aufrufen (z.B. um den Inhalt von
    3883             :             // Floating-Frames oder Applets zu ignorieren)
    3884           0 :             NextToken( nToken );
    3885             :         }
    3886        1863 :         else switch( nToken )
    3887             :         {
    3888             :         case HTML_TABLEHEADER_ON:
    3889             :         case HTML_TABLEDATA_ON:
    3890             :         case HTML_TABLEROW_ON:
    3891             :         case HTML_TABLEROW_OFF:
    3892             :         case HTML_THEAD_ON:
    3893             :         case HTML_THEAD_OFF:
    3894             :         case HTML_TFOOT_ON:
    3895             :         case HTML_TFOOT_OFF:
    3896             :         case HTML_TBODY_ON:
    3897             :         case HTML_TBODY_OFF:
    3898             :         case HTML_TABLE_OFF:
    3899           0 :             SkipToken(-1);
    3900             :         case HTML_TABLEHEADER_OFF:
    3901             :         case HTML_TABLEDATA_OFF:
    3902         260 :             bDone = sal_True;
    3903         260 :             break;
    3904             :         case HTML_TABLE_ON:
    3905             :             {
    3906           0 :                 sal_Bool bTopTable = sal_False;
    3907           0 :                 sal_Bool bHasToFly = sal_False;
    3908           0 :                 SvxAdjust eTabAdjust = SVX_ADJUST_END;
    3909           0 :                 if( !pPendStack )
    3910             :                 {
    3911             :                     // nur wenn eine neue Tabelle aufgemacht wird, aber
    3912             :                     // nicht wenn nach einem Pending in der Tabelle
    3913             :                     // weitergelesen wird!
    3914           0 :                     pSaveStruct->pTable = pTable;
    3915             : 
    3916             :                     // HACK: Eine Section fuer eine Tabelle anlegen, die
    3917             :                     // in einen Rahmen kommt.
    3918           0 :                     if( !pSaveStruct->IsInSection() )
    3919             :                     {
    3920             :                         // Diese Schleife muss vorwartes sein, weil die
    3921             :                         // erste Option immer gewinnt.
    3922           0 :                         sal_Bool bNeedsSection = sal_False;
    3923           0 :                         const HTMLOptions& rHTMLOptions = GetOptions();
    3924           0 :                         for (size_t i = 0; i < rHTMLOptions.size(); ++i)
    3925             :                         {
    3926           0 :                             const HTMLOption& rOption = rHTMLOptions[i];
    3927           0 :                             if( HTML_O_ALIGN==rOption.GetToken() )
    3928             :                             {
    3929             :                                 SvxAdjust eAdjust =
    3930             :                                     (SvxAdjust)rOption.GetEnum(
    3931           0 :                                             aHTMLPAlignTable, SVX_ADJUST_END );
    3932           0 :                                 bNeedsSection = SVX_ADJUST_LEFT == eAdjust ||
    3933           0 :                                                 SVX_ADJUST_RIGHT == eAdjust;
    3934           0 :                                 break;
    3935             :                             }
    3936             :                         }
    3937           0 :                         if( bNeedsSection )
    3938             :                         {
    3939             :                             pSaveStruct->AddContents(
    3940           0 :                                 InsertTableContents(bHead  ) );
    3941             :                         }
    3942             :                     }
    3943             :                     else
    3944             :                     {
    3945             :                         // Wenn wir mitlerweile in einem Rahmen stehen
    3946             :                         // koennen wir erneut eine echte Tabelle aufmachen.
    3947             :                         // Wir erkennen das daran, dass wir keinen
    3948             :                         // Tabellen-Node mehr finden.
    3949           0 :                         bTopTable = (0 ==
    3950           0 :                             pPam->GetPoint()->nNode.GetNode().FindTableNode());
    3951             : 
    3952             :                         // Wenn im aktuellen Absatz Flys verankert sind,
    3953             :                         // muss die neue Tabelle in einen Rahmen.
    3954           0 :                         bHasToFly = HasCurrentParaFlys(sal_False,sal_True);
    3955             :                     }
    3956             : 
    3957             :                     // in der Zelle kann sich ein Bereich befinden!
    3958             :                     eTabAdjust = aAttrTab.pAdjust
    3959           0 :                         ? ((const SvxAdjustItem&)aAttrTab.pAdjust->GetItem()).
    3960             :                                                  GetAdjust()
    3961           0 :                         : SVX_ADJUST_END;
    3962             :                 }
    3963             : 
    3964             :                 HTMLTable *pSubTable = BuildTable( eTabAdjust,
    3965             :                                                    bHead,
    3966           0 :                                                    pSaveStruct->IsInSection(),
    3967           0 :                                                    bTopTable, bHasToFly );
    3968           0 :                 if( SVPAR_PENDING != GetStatus() )
    3969             :                 {
    3970             :                     // nur wenn die Tabelle wirklich zu Ende ist!
    3971           0 :                     if( pSubTable )
    3972             :                     {
    3973             :                         OSL_ENSURE( pSubTable->GetTableAdjust(sal_False)!= SVX_ADJUST_LEFT &&
    3974             :                                 pSubTable->GetTableAdjust(sal_False)!= SVX_ADJUST_RIGHT,
    3975             :                                 "links oder rechts ausgerichtete Tabellen gehoehren in Rahmen" );
    3976             : 
    3977             :                         HTMLTableCnts *pParentContents =
    3978           0 :                             pSubTable->GetParentContents();
    3979           0 :                         if( pParentContents )
    3980             :                         {
    3981             :                             OSL_ENSURE( !pSaveStruct->IsInSection(),
    3982             :                                     "Wo ist die Section geblieben" );
    3983             : 
    3984             :                             // Wenn jetzt keine Tabelle kommt haben wir eine
    3985             :                             // Section
    3986           0 :                             pSaveStruct->AddContents( pParentContents );
    3987             :                         }
    3988             : 
    3989             :                         const SwStartNode *pCapStNd =
    3990           0 :                                 pSubTable->GetCaptionStartNode();
    3991             : 
    3992           0 :                         if( pSubTable->GetContext() )
    3993             :                         {
    3994             :                             OSL_ENSURE( !pSubTable->GetContext()->GetFrmFmt(),
    3995             :                                     "Tabelle steht im Rahmen" );
    3996             : 
    3997           0 :                             if( pCapStNd && pSubTable->IsTopCaption() )
    3998             :                             {
    3999             :                                 pSaveStruct->AddContents(
    4000           0 :                                     new HTMLTableCnts(pCapStNd) );
    4001             :                             }
    4002             : 
    4003             :                             pSaveStruct->AddContents(
    4004           0 :                                 new HTMLTableCnts(pSubTable) );
    4005             : 
    4006           0 :                             if( pCapStNd && !pSubTable->IsTopCaption() )
    4007             :                             {
    4008             :                                 pSaveStruct->AddContents(
    4009           0 :                                     new HTMLTableCnts(pCapStNd) );
    4010             :                             }
    4011             : 
    4012             :                             // Jetzt haben wir keine Section mehr
    4013           0 :                             pSaveStruct->ClearIsInSection();
    4014             :                         }
    4015           0 :                         else if( pCapStNd )
    4016             :                         {
    4017             :                             // Da wir diese Sction nicht mehr loeschen
    4018             :                             // koennen (sie koeente zur erster Box
    4019             :                             // gehoeren), fuegen wir sie ein.
    4020             :                             pSaveStruct->AddContents(
    4021           0 :                                 new HTMLTableCnts(pCapStNd) );
    4022             : 
    4023             :                             // Jetzt haben wir keine Section mehr
    4024           0 :                             pSaveStruct->ClearIsInSection();
    4025             :                         }
    4026             :                     }
    4027             : 
    4028           0 :                     pTable = pSaveStruct->pTable;
    4029             :                 }
    4030             :             }
    4031           0 :             break;
    4032             : 
    4033             :         case HTML_NOBR_ON:
    4034             :             // HACK fuer MS: Steht das <NOBR> zu beginn der Zelle?
    4035           0 :             pSaveStruct->StartNoBreak( *pPam->GetPoint() );
    4036           0 :             break;
    4037             : 
    4038             :         case HTML_NOBR_OFF:
    4039           0 :                 pSaveStruct->EndNoBreak( *pPam->GetPoint() );
    4040           0 :             break;
    4041             : 
    4042             :         case HTML_COMMENT:
    4043             :             // Mit Kommentar-Feldern werden Spaces nicht mehr geloescht
    4044             :             // ausserdem wollen wir fuer einen Kommentar keine neue Zelle
    4045             :             // anlegen !!!
    4046           0 :             NextToken( nToken );
    4047           0 :             break;
    4048             : 
    4049             :         case HTML_MARQUEE_ON:
    4050           0 :             if( !pSaveStruct->IsInSection() )
    4051             :             {
    4052             :                 // eine neue Section anlegen, der PaM steht dann darin
    4053             :                 pSaveStruct->AddContents(
    4054           0 :                     InsertTableContents( bHead ) );
    4055             :             }
    4056           0 :             bCallNextToken = true;
    4057           0 :             NewMarquee( pCurTable );
    4058           0 :             break;
    4059             : 
    4060             :         case HTML_TEXTTOKEN:
    4061             :             // keine Section fuer einen leeren String anlegen
    4062        1043 :             if( !pSaveStruct->IsInSection() && 1==aToken.getLength() &&
    4063         260 :                 ' '==aToken[0] )
    4064         260 :                 break;
    4065             :         default:
    4066        1343 :             if( !pSaveStruct->IsInSection() )
    4067             :             {
    4068             :                 // eine neue Section anlegen, der PaM steht dann darin
    4069             :                 pSaveStruct->AddContents(
    4070         260 :                     InsertTableContents( bHead ) );
    4071             :             }
    4072             : 
    4073        1343 :             if( IsParserWorking() || bPending )
    4074        1343 :                 NextToken( nToken );
    4075        1343 :             break;
    4076             :         }
    4077             : 
    4078             :         OSL_ENSURE( !bPending || !pPendStack,
    4079             :                 "SwHTMLParser::BuildTableCell: Es gibt wieder einen Pend-Stack" );
    4080        1863 :         bPending = sal_False;
    4081        1863 :         if( IsParserWorking() )
    4082        1863 :             SaveState( 0 );
    4083             : 
    4084        1863 :         if( !bDone )
    4085        1603 :             nToken = GetNextToken();
    4086             :     }
    4087             : 
    4088         260 :     if( SVPAR_PENDING == GetStatus() )
    4089             :     {
    4090             :         pPendStack = new SwPendingStack( bHead ? HTML_TABLEHEADER_ON
    4091           0 :                                                : HTML_TABLEDATA_ON, pPendStack );
    4092           0 :         pPendStack->pData = pSaveStruct;
    4093             : 
    4094           0 :         return;
    4095             :     }
    4096             : 
    4097             :     // Falls der Inhalt der Zelle leer war, muessen wir noch einen
    4098             :     // leeren Inhalt anlegen. Ausserdem legen wir einen leeren Inhalt
    4099             :     // an, wenn die Zelle mit einer Tabelle aufgehoert hat und keine
    4100             :     // COL-Tags hatte (sonst wurde sie wahrscheinlich von uns exportiert,
    4101             :     // und dann wollen wir natuerlich keinen zusaetzlichen Absatz haben).
    4102         520 :     if( !pSaveStruct->GetFirstContents() ||
    4103         260 :         (!pSaveStruct->IsInSection() && !pCurTable->HasColTags()) )
    4104             :     {
    4105             :         OSL_ENSURE( pSaveStruct->GetFirstContents() ||
    4106             :                 !pSaveStruct->IsInSection(),
    4107             :                 "Section oder nicht, das ist hier die Frage" );
    4108             :         const SwStartNode *pStNd =
    4109           0 :             InsertTableSection( static_cast< sal_uInt16 >(pSaveStruct->IsHeaderCell()
    4110             :                                         ? RES_POOLCOLL_TABLE_HDLN
    4111           0 :                                         : RES_POOLCOLL_TABLE ));
    4112           0 :         const SwEndNode *pEndNd = pStNd->EndOfSectionNode();
    4113           0 :         SwCntntNode *pCNd = pDoc->GetNodes()[pEndNd->GetIndex()-1] ->GetCntntNode();
    4114             :         //Added defaults to CJK and CTL
    4115           0 :         SvxFontHeightItem aFontHeight( 40, 100, RES_CHRATR_FONTSIZE );
    4116           0 :         pCNd->SetAttr( aFontHeight );
    4117           0 :         SvxFontHeightItem aFontHeightCJK( 40, 100, RES_CHRATR_CJK_FONTSIZE );
    4118           0 :         pCNd->SetAttr( aFontHeightCJK );
    4119           0 :         SvxFontHeightItem aFontHeightCTL( 40, 100, RES_CHRATR_CTL_FONTSIZE );
    4120           0 :         pCNd->SetAttr( aFontHeightCTL );
    4121             : 
    4122           0 :         pSaveStruct->AddContents( new HTMLTableCnts(pStNd) );
    4123           0 :         pSaveStruct->ClearIsInSection();
    4124             :     }
    4125             : 
    4126         260 :     if( pSaveStruct->IsInSection() )
    4127             :     {
    4128         260 :         pSaveStruct->CheckNoBreak( *pPam->GetPoint(), pDoc );
    4129             : 
    4130             :         // Alle noch offenen Kontexte beenden. Wir nehmen hier
    4131             :         // AttrMin, weil nContxtStMin evtl. veraendert wurde.
    4132             :         // Da es durch EndContext wieder restauriert wird, geht das.
    4133         520 :         while( (sal_uInt16)aContexts.size() > nContextStAttrMin+1 )
    4134             :         {
    4135           0 :             _HTMLAttrContext *pCntxt = PopContext();
    4136           0 :             EndContext( pCntxt );
    4137           0 :             delete pCntxt;
    4138             :         }
    4139             : 
    4140             :         // LFs am Absatz-Ende entfernen
    4141         260 :         if( StripTrailingLF()==0 && !pPam->GetPoint()->nContent.GetIndex() )
    4142         260 :             StripTrailingPara();
    4143             : 
    4144             :         // falls fuer die Zelle eine Ausrichtung gesetzt wurde, muessen
    4145             :         // wir die beenden
    4146         260 :         _HTMLAttrContext *pCntxt = PopContext();
    4147         260 :         EndContext( pCntxt );
    4148         260 :         delete pCntxt;
    4149             :     }
    4150             :     else
    4151             :     {
    4152             :         // Alle noch offenen Kontexte beenden
    4153           0 :         while( aContexts.size() > nContextStAttrMin )
    4154             :         {
    4155           0 :             _HTMLAttrContext *pCntxt = PopContext();
    4156           0 :             ClearContext( pCntxt );
    4157           0 :             delete pCntxt;
    4158             :         }
    4159             :     }
    4160             : 
    4161             :     // auch eine Numerierung muss beendet werden
    4162         260 :     GetNumInfo().Clear();
    4163             : 
    4164         260 :     SetAttr( sal_False );
    4165             : 
    4166         260 :     pSaveStruct->InsertCell( *this, pCurTable );
    4167             : 
    4168             :     // wir stehen jetzt (wahrschenlich) vor <TH>, <TD>, <TR> oder </TABLE>
    4169         260 :     delete pSaveStruct;
    4170             : }
    4171             : 
    4172         106 : class _RowSaveStruct : public SwPendingStackData
    4173             : {
    4174             : public:
    4175             :     SvxAdjust eAdjust;
    4176             :     sal_Int16 eVertOri;
    4177             :     sal_Bool bHasCells;
    4178             : 
    4179          53 :     _RowSaveStruct() :
    4180          53 :         eAdjust( SVX_ADJUST_END ), eVertOri( text::VertOrientation::TOP ), bHasCells( sal_False )
    4181          53 :     {}
    4182             : };
    4183             : 
    4184          52 : void SwHTMLParser::BuildTableRow( HTMLTable *pCurTable, sal_Bool bReadOptions,
    4185             :                                   SvxAdjust eGrpAdjust,
    4186             :                                   sal_Int16 eGrpVertOri )
    4187             : {
    4188             :     // <TR> wurde bereist gelesen
    4189             : 
    4190          52 :     if( !IsParserWorking() && !pPendStack )
    4191          52 :         return;
    4192             : 
    4193          52 :     int nToken = 0;
    4194             :     _RowSaveStruct* pSaveStruct;
    4195             : 
    4196          52 :     sal_Bool bPending = sal_False;
    4197          52 :     if( pPendStack )
    4198             :     {
    4199           0 :         pSaveStruct = (_RowSaveStruct*)pPendStack->pData;
    4200             : 
    4201           0 :         SwPendingStack* pTmp = pPendStack->pNext;
    4202           0 :         delete pPendStack;
    4203           0 :         pPendStack = pTmp;
    4204           0 :         nToken = pPendStack ? pPendStack->nToken : GetSaveToken();
    4205           0 :         bPending = SVPAR_ERROR == eState && pPendStack != 0;
    4206             : 
    4207           0 :         SaveState( nToken );
    4208             :     }
    4209             :     else
    4210             :     {
    4211          52 :         SvxAdjust eAdjust = eGrpAdjust;
    4212          52 :         sal_Int16 eVertOri = eGrpVertOri;
    4213          52 :         Color aBGColor;
    4214         104 :         OUString aBGImage, aStyle, aId, aClass;
    4215          52 :         sal_Bool bBGColor = sal_False;
    4216          52 :         pSaveStruct = new _RowSaveStruct;
    4217             : 
    4218          52 :         if( bReadOptions )
    4219             :         {
    4220          52 :             const HTMLOptions& rHTMLOptions = GetOptions();
    4221         156 :             for (size_t i = rHTMLOptions.size(); i; )
    4222             :             {
    4223          52 :                 const HTMLOption& rOption = rHTMLOptions[--i];
    4224          52 :                 switch( rOption.GetToken() )
    4225             :                 {
    4226             :                 case HTML_O_ID:
    4227           0 :                     aId = rOption.GetString();
    4228           0 :                     break;
    4229             :                 case HTML_O_ALIGN:
    4230             :                     eAdjust = (SvxAdjust)rOption.GetEnum(
    4231           0 :                                     aHTMLPAlignTable, static_cast< sal_uInt16 >(eAdjust) );
    4232           0 :                     break;
    4233             :                 case HTML_O_VALIGN:
    4234             :                     eVertOri = rOption.GetEnum(
    4235          52 :                                     aHTMLTblVAlignTable, eVertOri );
    4236          52 :                     break;
    4237             :                 case HTML_O_BGCOLOR:
    4238             :                     // Leere BGCOLOR bei <TABLE>, <TR> und <TD>/<TH> wie Netsc.
    4239             :                     // ignorieren, bei allen anderen Tags *wirklich* nicht.
    4240           0 :                     if( !rOption.GetString().isEmpty() )
    4241             :                     {
    4242           0 :                         rOption.GetColor( aBGColor );
    4243           0 :                         bBGColor = sal_True;
    4244             :                     }
    4245           0 :                     break;
    4246             :                 case HTML_O_BACKGROUND:
    4247           0 :                     aBGImage = rOption.GetString();
    4248           0 :                     break;
    4249             :                 case HTML_O_STYLE:
    4250           0 :                     aStyle = rOption.GetString();
    4251           0 :                     break;
    4252             :                 case HTML_O_CLASS:
    4253           0 :                     aClass= rOption.GetString();
    4254           0 :                     break;
    4255             :                 }
    4256             :             }
    4257             :         }
    4258             : 
    4259          52 :         if( !aId.isEmpty() )
    4260           0 :             InsertBookmark( aId );
    4261             : 
    4262             :         SvxBrushItem *pBrushItem =
    4263             :             CreateBrushItem( bBGColor ? &aBGColor : 0, aBGImage, aStyle,
    4264          52 :                              aId, aClass );
    4265          52 :         pCurTable->OpenRow( eAdjust, eVertOri, pBrushItem );
    4266             :         // ist beim ersten GetNextToken schon pending, muss bei
    4267             :         // wiederaufsetzen auf jedenfall neu gelesen werden!
    4268         104 :         SaveState( 0 );
    4269             :     }
    4270             : 
    4271          52 :     if( !nToken )
    4272          52 :         nToken = GetNextToken();    // naechstes Token
    4273             : 
    4274          52 :     sal_Bool bDone = sal_False;
    4275         728 :     while( (IsParserWorking() && !bDone) || bPending )
    4276             :     {
    4277         624 :         SaveState( nToken );
    4278             : 
    4279         624 :         nToken = FilterToken( nToken );
    4280             : 
    4281             :         OSL_ENSURE( pPendStack || !bCallNextToken ||
    4282             :                 pCurTable->GetContext() || pCurTable->HasParentSection(),
    4283             :                 "Wo ist die Section gebieben?" );
    4284         624 :         if( !pPendStack && bCallNextToken &&
    4285           0 :             (pCurTable->GetContext() || pCurTable->HasParentSection()) )
    4286             :         {
    4287             :             // NextToken direkt aufrufen (z.B. um den Inhalt von
    4288             :             // Floating-Frames oder Applets zu ignorieren)
    4289           0 :             NextToken( nToken );
    4290             :         }
    4291         624 :         else switch( nToken )
    4292             :         {
    4293             :         case HTML_TABLE_ON:
    4294           0 :             if( !pCurTable->GetContext()  )
    4295             :             {
    4296           0 :                 SkipToken( -1 );
    4297           0 :                 bDone = sal_True;
    4298             :             }
    4299             : 
    4300           0 :             break;
    4301             :         case HTML_TABLEROW_ON:
    4302             :         case HTML_THEAD_ON:
    4303             :         case HTML_THEAD_OFF:
    4304             :         case HTML_TBODY_ON:
    4305             :         case HTML_TBODY_OFF:
    4306             :         case HTML_TFOOT_ON:
    4307             :         case HTML_TFOOT_OFF:
    4308             :         case HTML_TABLE_OFF:
    4309           0 :             SkipToken( -1 );
    4310             :         case HTML_TABLEROW_OFF:
    4311          52 :             bDone = sal_True;
    4312          52 :             break;
    4313             :         case HTML_TABLEHEADER_ON:
    4314             :         case HTML_TABLEDATA_ON:
    4315         260 :             BuildTableCell( pCurTable, sal_True, HTML_TABLEHEADER_ON==nToken );
    4316         260 :             if( SVPAR_PENDING != GetStatus() )
    4317             :             {
    4318         260 :                 pSaveStruct->bHasCells = sal_True;
    4319         260 :                 bDone = pTable->IsOverflowing();
    4320             :             }
    4321         260 :             break;
    4322             :         case HTML_CAPTION_ON:
    4323           0 :             BuildTableCaption( pCurTable );
    4324           0 :             bDone = pTable->IsOverflowing();
    4325           0 :             break;
    4326             :         case HTML_CAPTION_OFF:
    4327             :         case HTML_TABLEHEADER_OFF:
    4328             :         case HTML_TABLEDATA_OFF:
    4329             :         case HTML_COLGROUP_ON:
    4330             :         case HTML_COLGROUP_OFF:
    4331             :         case HTML_COL_ON:
    4332             :         case HTML_COL_OFF:
    4333             :             // wo keine Zelle anfing kann auch keine aufhoehren, oder?
    4334             :             // und die ganzen anderen Tokens haben hier auch nicht zu
    4335             :             // suchen und machen nur die Tabelle kaputt
    4336           0 :             break;
    4337             :         case HTML_MULTICOL_ON:
    4338             :             // spaltige Rahmen koennen wir hier leider nicht einguegen
    4339           0 :             break;
    4340             :         case HTML_FORM_ON:
    4341           0 :             NewForm( sal_False );   // keinen neuen Absatz aufmachen!
    4342           0 :             break;
    4343             :         case HTML_FORM_OFF:
    4344           0 :             EndForm( sal_False );   // keinen neuen Absatz aufmachen!
    4345           0 :             break;
    4346             :         case HTML_COMMENT:
    4347           0 :             NextToken( nToken );
    4348           0 :             break;
    4349             :         case HTML_MAP_ON:
    4350             :             // eine Image-Map fuegt nichts ein, deshalb koennen wir sie
    4351             :             // problemlos auch ohne Zelle parsen
    4352           0 :             NextToken( nToken );
    4353           0 :             break;
    4354             :         case HTML_TEXTTOKEN:
    4355         625 :             if( (pCurTable->GetContext() ||
    4356         312 :                  !pCurTable->HasParentSection()) &&
    4357         934 :                 1==aToken.getLength() && ' '==aToken[0] )
    4358         311 :                 break;
    4359             :         default:
    4360           1 :             pCurTable->MakeParentContents();
    4361           1 :             NextToken( nToken );
    4362           1 :             break;
    4363             :         }
    4364             : 
    4365             :         OSL_ENSURE( !bPending || !pPendStack,
    4366             :                 "SwHTMLParser::BuildTableRow: Es gibt wieder einen Pend-Stack" );
    4367         624 :         bPending = sal_False;
    4368         624 :         if( IsParserWorking() )
    4369         624 :             SaveState( 0 );
    4370             : 
    4371         624 :         if( !bDone )
    4372         572 :             nToken = GetNextToken();
    4373             :     }
    4374             : 
    4375          52 :     if( SVPAR_PENDING == GetStatus() )
    4376             :     {
    4377           0 :         pPendStack = new SwPendingStack( HTML_TABLEROW_ON, pPendStack );
    4378           0 :         pPendStack->pData = pSaveStruct;
    4379             :     }
    4380             :     else
    4381             :     {
    4382          52 :         pCurTable->CloseRow( !pSaveStruct->bHasCells );
    4383          52 :         delete pSaveStruct;
    4384             :     }
    4385             : 
    4386             :     // wir stehen jetzt (wahrscheinlich) vor <TR> oder </TABLE>
    4387             : }
    4388             : 
    4389           1 : void SwHTMLParser::BuildTableSection( HTMLTable *pCurTable,
    4390             :                                       sal_Bool bReadOptions,
    4391             :                                       sal_Bool bHead )
    4392             : {
    4393             :     // <THEAD>, <TBODY> bzw. <TFOOT> wurde bereits gelesen
    4394           1 :     if( !IsParserWorking() && !pPendStack )
    4395           1 :         return;
    4396             : 
    4397           1 :     int nToken = 0;
    4398           1 :     sal_Bool bPending = sal_False;
    4399             :     _RowSaveStruct* pSaveStruct;
    4400             : 
    4401           1 :     if( pPendStack )
    4402             :     {
    4403           0 :         pSaveStruct = (_RowSaveStruct*)pPendStack->pData;
    4404             : 
    4405           0 :         SwPendingStack* pTmp = pPendStack->pNext;
    4406           0 :         delete pPendStack;
    4407           0 :         pPendStack = pTmp;
    4408           0 :         nToken = pPendStack ? pPendStack->nToken : GetSaveToken();
    4409           0 :         bPending = SVPAR_ERROR == eState && pPendStack != 0;
    4410             : 
    4411           0 :         SaveState( nToken );
    4412             :     }
    4413             :     else
    4414             :     {
    4415           1 :         pSaveStruct = new _RowSaveStruct;
    4416             : 
    4417           1 :         if( bReadOptions )
    4418             :         {
    4419           0 :             const HTMLOptions& rHTMLOptions = GetOptions();
    4420           0 :             for (size_t i = rHTMLOptions.size(); i; )
    4421             :             {
    4422           0 :                 const HTMLOption& rOption = rHTMLOptions[--i];
    4423           0 :                 switch( rOption.GetToken() )
    4424             :                 {
    4425             :                 case HTML_O_ID:
    4426           0 :                     InsertBookmark( rOption.GetString() );
    4427           0 :                     break;
    4428             :                 case HTML_O_ALIGN:
    4429             :                     pSaveStruct->eAdjust =
    4430             :                         (SvxAdjust)rOption.GetEnum( aHTMLPAlignTable,
    4431           0 :                                                      static_cast< sal_uInt16 >(pSaveStruct->eAdjust) );
    4432           0 :                     break;
    4433             :                 case HTML_O_VALIGN:
    4434             :                     pSaveStruct->eVertOri =
    4435             :                         rOption.GetEnum( aHTMLTblVAlignTable,
    4436           0 :                                           pSaveStruct->eVertOri );
    4437           0 :                     break;
    4438             :                 }
    4439             :             }
    4440             :         }
    4441             : 
    4442             :         // ist beim ersten GetNextToken schon pending, muss bei
    4443             :         // wiederaufsetzen auf jedenfall neu gelesen werden!
    4444           1 :         SaveState( 0 );
    4445             :     }
    4446             : 
    4447           1 :     if( !nToken )
    4448           1 :         nToken = GetNextToken();    // naechstes Token
    4449             : 
    4450           1 :     sal_Bool bDone = sal_False;
    4451         107 :     while( (IsParserWorking() && !bDone) || bPending )
    4452             :     {
    4453         105 :         SaveState( nToken );
    4454             : 
    4455         105 :         nToken = FilterToken( nToken );
    4456             : 
    4457             :         OSL_ENSURE( pPendStack || !bCallNextToken ||
    4458             :                 pCurTable->GetContext() || pCurTable->HasParentSection(),
    4459             :                 "Wo ist die Section gebieben?" );
    4460         105 :         if( !pPendStack && bCallNextToken &&
    4461           0 :             (pCurTable->GetContext() || pCurTable->HasParentSection()) )
    4462             :         {
    4463             :             // NextToken direkt aufrufen (z.B. um den Inhalt von
    4464             :             // Floating-Frames oder Applets zu ignorieren)
    4465           0 :             NextToken( nToken );
    4466             :         }
    4467         105 :         else switch( nToken )
    4468             :         {
    4469             :         case HTML_TABLE_ON:
    4470           0 :             if( !pCurTable->GetContext()  )
    4471             :             {
    4472           0 :                 SkipToken( -1 );
    4473           0 :                 bDone = sal_True;
    4474             :             }
    4475             : 
    4476           0 :             break;
    4477             :         case HTML_THEAD_ON:
    4478             :         case HTML_TFOOT_ON:
    4479             :         case HTML_TBODY_ON:
    4480             :         case HTML_TABLE_OFF:
    4481           1 :             SkipToken( -1 );
    4482             :         case HTML_THEAD_OFF:
    4483             :         case HTML_TBODY_OFF:
    4484             :         case HTML_TFOOT_OFF:
    4485           1 :             bDone = sal_True;
    4486           1 :             break;
    4487             :         case HTML_CAPTION_ON:
    4488           0 :             BuildTableCaption( pCurTable );
    4489           0 :             bDone = pTable->IsOverflowing();
    4490           0 :             break;
    4491             :         case HTML_CAPTION_OFF:
    4492           0 :             break;
    4493             :         case HTML_TABLEHEADER_ON:
    4494             :         case HTML_TABLEDATA_ON:
    4495           0 :             SkipToken( -1 );
    4496             :             BuildTableRow( pCurTable, sal_False, pSaveStruct->eAdjust,
    4497           0 :                            pSaveStruct->eVertOri );
    4498           0 :             bDone = pTable->IsOverflowing();
    4499           0 :             break;
    4500             :         case HTML_TABLEROW_ON:
    4501             :             BuildTableRow( pCurTable, sal_True, pSaveStruct->eAdjust,
    4502          52 :                            pSaveStruct->eVertOri );
    4503          52 :             bDone = pTable->IsOverflowing();
    4504          52 :             break;
    4505             :         case HTML_MULTICOL_ON:
    4506             :             // spaltige Rahmen koennen wir hier leider nicht einguegen
    4507           0 :             break;
    4508             :         case HTML_FORM_ON:
    4509           0 :             NewForm( sal_False );   // keinen neuen Absatz aufmachen!
    4510           0 :             break;
    4511             :         case HTML_FORM_OFF:
    4512           0 :             EndForm( sal_False );   // keinen neuen Absatz aufmachen!
    4513           0 :             break;
    4514             :         case HTML_TEXTTOKEN:
    4515             :             // Blank-Strings sind Folge von CR+LF und kein Text
    4516         104 :             if( (pCurTable->GetContext() ||
    4517          52 :                  !pCurTable->HasParentSection()) &&
    4518         156 :                 1==aToken.getLength() && ' ' == aToken[0] )
    4519          52 :                 break;
    4520             :         default:
    4521           0 :             pCurTable->MakeParentContents();
    4522           0 :             NextToken( nToken );
    4523             :         }
    4524             : 
    4525             :         OSL_ENSURE( !bPending || !pPendStack,
    4526             :                 "SwHTMLParser::BuildTableSection: Es gibt wieder einen Pend-Stack" );
    4527         105 :         bPending = sal_False;
    4528         105 :         if( IsParserWorking() )
    4529         105 :             SaveState( 0 );
    4530             : 
    4531         105 :         if( !bDone )
    4532         104 :             nToken = GetNextToken();
    4533             :     }
    4534             : 
    4535           1 :     if( SVPAR_PENDING == GetStatus() )
    4536             :     {
    4537             :         pPendStack = new SwPendingStack( bHead ? HTML_THEAD_ON
    4538           0 :                                                : HTML_TBODY_ON, pPendStack );
    4539           0 :         pPendStack->pData = pSaveStruct;
    4540             :     }
    4541             :     else
    4542             :     {
    4543           1 :         pCurTable->CloseSection( bHead );
    4544           1 :         delete pSaveStruct;
    4545             :     }
    4546             : 
    4547             :     // now we stand (perhaps) in front of <TBODY>,... or </TABLE>
    4548             : }
    4549             : 
    4550           2 : struct _TblColGrpSaveStruct : public SwPendingStackData
    4551             : {
    4552             :     sal_uInt16 nColGrpSpan;
    4553             :     sal_uInt16 nColGrpWidth;
    4554             :     sal_Bool bRelColGrpWidth;
    4555             :     SvxAdjust eColGrpAdjust;
    4556             :     sal_Int16 eColGrpVertOri;
    4557             : 
    4558             :     inline _TblColGrpSaveStruct();
    4559             : 
    4560             :     inline void CloseColGroup( HTMLTable *pTable );
    4561             : };
    4562             : 
    4563           1 : inline _TblColGrpSaveStruct::_TblColGrpSaveStruct() :
    4564             :     nColGrpSpan( 1 ), nColGrpWidth( 0 ),
    4565             :     bRelColGrpWidth( sal_False ), eColGrpAdjust( SVX_ADJUST_END ),
    4566           1 :     eColGrpVertOri( text::VertOrientation::TOP )
    4567           1 : {}
    4568             : 
    4569           1 : inline void _TblColGrpSaveStruct::CloseColGroup( HTMLTable *pTable )
    4570             : {
    4571             :     pTable->CloseColGroup( nColGrpSpan, nColGrpWidth,
    4572           1 :                             bRelColGrpWidth, eColGrpAdjust, eColGrpVertOri );
    4573           1 : }
    4574             : 
    4575           1 : void SwHTMLParser::BuildTableColGroup( HTMLTable *pCurTable,
    4576             :                                        sal_Bool bReadOptions )
    4577             : {
    4578             :     // <COLGROUP> wurde bereits gelesen, wenn bReadOptions
    4579             : 
    4580           1 :     if( !IsParserWorking() && !pPendStack )
    4581           1 :         return;
    4582             : 
    4583           1 :     int nToken = 0;
    4584           1 :     sal_Bool bPending = sal_False;
    4585             :     _TblColGrpSaveStruct* pSaveStruct;
    4586             : 
    4587           1 :     if( pPendStack )
    4588             :     {
    4589           0 :         pSaveStruct = (_TblColGrpSaveStruct*)pPendStack->pData;
    4590             : 
    4591           0 :         SwPendingStack* pTmp = pPendStack->pNext;
    4592           0 :         delete pPendStack;
    4593           0 :         pPendStack = pTmp;
    4594           0 :         nToken = pPendStack ? pPendStack->nToken : GetSaveToken();
    4595           0 :         bPending = SVPAR_ERROR == eState && pPendStack != 0;
    4596             : 
    4597           0 :         SaveState( nToken );
    4598             :     }
    4599             :     else
    4600             :     {
    4601             : 
    4602           1 :         pSaveStruct = new _TblColGrpSaveStruct;
    4603           1 :         if( bReadOptions )
    4604             :         {
    4605           0 :             const HTMLOptions& rColGrpOptions = GetOptions();
    4606           0 :             for (size_t i = rColGrpOptions.size(); i; )
    4607             :             {
    4608           0 :                 const HTMLOption& rOption = rColGrpOptions[--i];
    4609           0 :                 switch( rOption.GetToken() )
    4610             :                 {
    4611             :                 case HTML_O_ID:
    4612           0 :                     InsertBookmark( rOption.GetString() );
    4613           0 :                     break;
    4614             :                 case HTML_O_SPAN:
    4615           0 :                     pSaveStruct->nColGrpSpan = (sal_uInt16)rOption.GetNumber();
    4616           0 :                     break;
    4617             :                 case HTML_O_WIDTH:
    4618           0 :                     pSaveStruct->nColGrpWidth = (sal_uInt16)rOption.GetNumber();
    4619             :                     pSaveStruct->bRelColGrpWidth =
    4620           0 :                         (rOption.GetString().indexOf('*') != -1);
    4621           0 :                     break;
    4622             :                 case HTML_O_ALIGN:
    4623             :                     pSaveStruct->eColGrpAdjust =
    4624             :                         (SvxAdjust)rOption.GetEnum( aHTMLPAlignTable,
    4625           0 :                                                 static_cast< sal_uInt16 >(pSaveStruct->eColGrpAdjust) );
    4626           0 :                     break;
    4627             :                 case HTML_O_VALIGN:
    4628             :                     pSaveStruct->eColGrpVertOri =
    4629             :                         rOption.GetEnum( aHTMLTblVAlignTable,
    4630           0 :                                                 pSaveStruct->eColGrpVertOri );
    4631           0 :                     break;
    4632             :                 }
    4633             :             }
    4634             :         }
    4635             :         // ist beim ersten GetNextToken schon pending, muss bei
    4636             :         // wiederaufsetzen auf jedenfall neu gelesen werden!
    4637           1 :         SaveState( 0 );
    4638             :     }
    4639             : 
    4640           1 :     if( !nToken )
    4641           1 :         nToken = GetNextToken();    // naechstes Token
    4642             : 
    4643           1 :     sal_Bool bDone = sal_False;
    4644          13 :     while( (IsParserWorking() && !bDone) || bPending )
    4645             :     {
    4646          11 :         SaveState( nToken );
    4647             : 
    4648          11 :         nToken = FilterToken( nToken );
    4649             : 
    4650             :         OSL_ENSURE( pPendStack || !bCallNextToken ||
    4651             :                 pCurTable->GetContext() || pCurTable->HasParentSection(),
    4652             :                 "Wo ist die Section gebieben?" );
    4653          11 :         if( !pPendStack && bCallNextToken &&
    4654           0 :             (pCurTable->GetContext() || pCurTable->HasParentSection()) )
    4655             :         {
    4656             :             // NextToken direkt aufrufen (z.B. um den Inhalt von
    4657             :             // Floating-Frames oder Applets zu ignorieren)
    4658           0 :             NextToken( nToken );
    4659             :         }
    4660          11 :         else switch( nToken )
    4661             :         {
    4662             :         case HTML_TABLE_ON:
    4663           0 :             if( !pCurTable->GetContext()  )
    4664             :             {
    4665           0 :                 SkipToken( -1 );
    4666           0 :                 bDone = sal_True;
    4667             :             }
    4668             : 
    4669           0 :             break;
    4670             :         case HTML_COLGROUP_ON:
    4671             :         case HTML_THEAD_ON:
    4672             :         case HTML_TFOOT_ON:
    4673             :         case HTML_TBODY_ON:
    4674             :         case HTML_TABLEROW_ON:
    4675             :         case HTML_TABLE_OFF:
    4676           1 :             SkipToken( -1 );
    4677             :         case HTML_COLGROUP_OFF:
    4678           1 :             bDone = sal_True;
    4679           1 :             break;
    4680             :         case HTML_COL_ON:
    4681             :             {
    4682           5 :                 sal_uInt16 nColSpan = 1;
    4683           5 :                 sal_uInt16 nColWidth = pSaveStruct->nColGrpWidth;
    4684           5 :                 sal_Bool bRelColWidth = pSaveStruct->bRelColGrpWidth;
    4685           5 :                 SvxAdjust eColAdjust = pSaveStruct->eColGrpAdjust;
    4686           5 :                 sal_Int16 eColVertOri = pSaveStruct->eColGrpVertOri;
    4687             : 
    4688           5 :                 const HTMLOptions& rColOptions = GetOptions();
    4689          15 :                 for (size_t i = rColOptions.size(); i; )
    4690             :                 {
    4691           5 :                     const HTMLOption& rOption = rColOptions[--i];
    4692           5 :                     switch( rOption.GetToken() )
    4693             :                     {
    4694             :                     case HTML_O_ID:
    4695           0 :                         InsertBookmark( rOption.GetString() );
    4696           0 :                         break;
    4697             :                     case HTML_O_SPAN:
    4698           0 :                         nColSpan = (sal_uInt16)rOption.GetNumber();
    4699           0 :                         break;
    4700             :                     case HTML_O_WIDTH:
    4701           5 :                         nColWidth = (sal_uInt16)rOption.GetNumber();
    4702             :                         bRelColWidth =
    4703           5 :                             (rOption.GetString().indexOf('*') != -1);
    4704           5 :                         break;
    4705             :                     case HTML_O_ALIGN:
    4706             :                         eColAdjust =
    4707             :                             (SvxAdjust)rOption.GetEnum( aHTMLPAlignTable,
    4708           0 :                                                             static_cast< sal_uInt16 >(eColAdjust) );
    4709           0 :                         break;
    4710             :                     case HTML_O_VALIGN:
    4711             :                         eColVertOri =
    4712             :                             rOption.GetEnum( aHTMLTblVAlignTable,
    4713           0 :                                                         eColVertOri );
    4714           0 :                         break;
    4715             :                     }
    4716             :                 }
    4717             :                 pCurTable->InsertCol( nColSpan, nColWidth, bRelColWidth,
    4718           5 :                                       eColAdjust, eColVertOri );
    4719             : 
    4720             :                 // die Angaben in <COLGRP> sollen ignoriert werden, wenn
    4721             :                 // <COL>-Elemente existieren
    4722           5 :                 pSaveStruct->nColGrpSpan = 0;
    4723             :             }
    4724           5 :             break;
    4725             :         case HTML_COL_OFF:
    4726           0 :             break;      // Ignorieren
    4727             :         case HTML_MULTICOL_ON:
    4728             :             // spaltige Rahmen koennen wir hier leider nicht einguegen
    4729           0 :             break;
    4730             :         case HTML_TEXTTOKEN:
    4731          15 :             if( (pCurTable->GetContext() ||
    4732           5 :                  !pCurTable->HasParentSection()) &&
    4733           5 :                 1==aToken.getLength() && ' '==aToken[0] )
    4734           0 :                 break;
    4735             :         default:
    4736           5 :             pCurTable->MakeParentContents();
    4737           5 :             NextToken( nToken );
    4738             :         }
    4739             : 
    4740             :         OSL_ENSURE( !bPending || !pPendStack,
    4741             :                 "SwHTMLParser::BuildTableColGrp: Es gibt wieder einen Pend-Stack" );
    4742          11 :         bPending = sal_False;
    4743          11 :         if( IsParserWorking() )
    4744          11 :             SaveState( 0 );
    4745             : 
    4746          11 :         if( !bDone )
    4747          10 :             nToken = GetNextToken();
    4748             :     }
    4749             : 
    4750           1 :     if( SVPAR_PENDING == GetStatus() )
    4751             :     {
    4752           0 :         pPendStack = new SwPendingStack( HTML_COL_ON, pPendStack );
    4753           0 :         pPendStack->pData = pSaveStruct;
    4754             :     }
    4755             :     else
    4756             :     {
    4757           1 :         pSaveStruct->CloseColGroup( pCurTable );
    4758           1 :         delete pSaveStruct;
    4759             :     }
    4760             : }
    4761             : 
    4762             : class _CaptionSaveStruct : public _SectionSaveStruct
    4763             : {
    4764             :     SwPosition aSavePos;
    4765             :     SwHTMLNumRuleInfo aNumRuleInfo; // gueltige Numerierung
    4766             : 
    4767             : public:
    4768             : 
    4769             :     _HTMLAttrTable aAttrTab;        // und die Attribute
    4770             : 
    4771           0 :     _CaptionSaveStruct( SwHTMLParser& rParser, const SwPosition& rPos ) :
    4772           0 :         _SectionSaveStruct( rParser ), aSavePos( rPos )
    4773             :     {
    4774           0 :         rParser.SaveAttrTab( aAttrTab );
    4775             : 
    4776             :         // Die aktuelle Numerierung wurde gerettet und muss nur
    4777             :         // noch beendet werden.
    4778           0 :         aNumRuleInfo.Set( rParser.GetNumInfo() );
    4779           0 :         rParser.GetNumInfo().Clear();
    4780           0 :     }
    4781             : 
    4782           0 :     const SwPosition& GetPos() const { return aSavePos; }
    4783             : 
    4784           0 :     void RestoreAll( SwHTMLParser& rParser )
    4785             :     {
    4786             :         // Die alten Stack wiederherstellen
    4787           0 :         Restore( rParser );
    4788             : 
    4789             :         // Die alte Attribut-Tabelle wiederherstellen
    4790           0 :         rParser.RestoreAttrTab( aAttrTab );
    4791             : 
    4792             :         // Die alte Numerierung wieder aufspannen
    4793           0 :         rParser.GetNumInfo().Set( aNumRuleInfo );
    4794           0 :     }
    4795             : 
    4796             :     virtual ~_CaptionSaveStruct();
    4797             : };
    4798             : 
    4799           0 : _CaptionSaveStruct::~_CaptionSaveStruct()
    4800           0 : {}
    4801             : 
    4802           0 : void SwHTMLParser::BuildTableCaption( HTMLTable *pCurTable )
    4803             : {
    4804             :     // <CAPTION> wurde bereits gelesen
    4805             : 
    4806           0 :     if( !IsParserWorking() && !pPendStack )
    4807           0 :         return;
    4808             : 
    4809           0 :     int nToken = 0;
    4810             :     _CaptionSaveStruct* pSaveStruct;
    4811             : 
    4812           0 :     if( pPendStack )
    4813             :     {
    4814           0 :         pSaveStruct = (_CaptionSaveStruct*)pPendStack->pData;
    4815             : 
    4816           0 :         SwPendingStack* pTmp = pPendStack->pNext;
    4817           0 :         delete pPendStack;
    4818           0 :         pPendStack = pTmp;
    4819           0 :         nToken = pPendStack ? pPendStack->nToken : GetSaveToken();
    4820             :         OSL_ENSURE( !pPendStack, "Wo kommt hier ein Pending-Stack her?" );
    4821             : 
    4822           0 :         SaveState( nToken );
    4823             :     }
    4824             :     else
    4825             :     {
    4826           0 :         if( pTable->IsOverflowing() )
    4827             :         {
    4828           0 :             SaveState( 0 );
    4829           0 :             return;
    4830             :         }
    4831             : 
    4832           0 :         sal_Bool bTop = sal_True;
    4833           0 :         const HTMLOptions& rHTMLOptions = GetOptions();
    4834           0 :         for ( size_t i = rHTMLOptions.size(); i; )
    4835             :         {
    4836           0 :             const HTMLOption& rOption = rHTMLOptions[--i];
    4837           0 :             if( HTML_O_ALIGN == rOption.GetToken() )
    4838             :             {
    4839           0 :                 if (rOption.GetString().equalsIgnoreAsciiCase(
    4840             :                         OOO_STRING_SVTOOLS_HTML_VA_bottom))
    4841             :                 {
    4842           0 :                     bTop = sal_False;
    4843             :                 }
    4844             :             }
    4845             :         }
    4846             : 
    4847             :         // Alte PaM-Position retten.
    4848           0 :         pSaveStruct = new _CaptionSaveStruct( *this, *pPam->GetPoint() );
    4849             : 
    4850             :         // Eine Text-Section im Icons-Bereich als Container fuer die
    4851             :         // Ueberschrift anlegen und PaM dort reinstellen.
    4852             :         const SwStartNode *pStNd;
    4853           0 :         if( pTable == pCurTable )
    4854           0 :             pStNd = InsertTempTableCaptionSection();
    4855             :         else
    4856           0 :             pStNd = InsertTableSection( RES_POOLCOLL_TEXT );
    4857             : 
    4858           0 :         _HTMLAttrContext *pCntxt = new _HTMLAttrContext( HTML_CAPTION_ON );
    4859             : 
    4860             :         // Tabellen-Ueberschriften sind immer zentriert.
    4861           0 :         NewAttr( &aAttrTab.pAdjust, SvxAdjustItem(SVX_ADJUST_CENTER, RES_PARATR_ADJUST) );
    4862             : 
    4863           0 :         _HTMLAttrs &rAttrs = pCntxt->GetAttrs();
    4864           0 :         rAttrs.push_back( aAttrTab.pAdjust );
    4865             : 
    4866           0 :         PushContext( pCntxt );
    4867             : 
    4868             :         // StartNode der Section an der Tabelle merken.
    4869           0 :         pCurTable->SetCaption( pStNd, bTop );
    4870             : 
    4871             :         // ist beim ersten GetNextToken schon pending, muss bei
    4872             :         // wiederaufsetzen auf jedenfall neu gelesen werden!
    4873           0 :         SaveState( 0 );
    4874             :     }
    4875             : 
    4876           0 :     if( !nToken )
    4877           0 :         nToken = GetNextToken();    // naechstes Token
    4878             : 
    4879             :     // </CAPTION> wird laut DTD benoetigt
    4880           0 :     sal_Bool bDone = sal_False;
    4881           0 :     while( IsParserWorking() && !bDone )
    4882             :     {
    4883           0 :         SaveState( nToken );
    4884             : 
    4885           0 :         nToken = FilterToken( nToken );
    4886             : 
    4887           0 :         switch( nToken )
    4888             :         {
    4889             :         case HTML_TABLE_ON:
    4890           0 :             if( !pPendStack )
    4891             :             {
    4892           0 :                 pSaveStruct->pTable = pTable;
    4893           0 :                 sal_Bool bHasToFly = pSaveStruct->pTable!=pCurTable;
    4894             :                 BuildTable( pCurTable->GetTableAdjust( sal_True ),
    4895           0 :                             sal_False, sal_True, sal_True, bHasToFly );
    4896             :             }
    4897             :             else
    4898             :             {
    4899           0 :                 BuildTable( SVX_ADJUST_END );
    4900             :             }
    4901           0 :             if( SVPAR_PENDING != GetStatus() )
    4902             :             {
    4903           0 :                 pTable = pSaveStruct->pTable;
    4904             :             }
    4905           0 :             break;
    4906             :         case HTML_TABLE_OFF:
    4907             :         case HTML_COLGROUP_ON:
    4908             :         case HTML_THEAD_ON:
    4909             :         case HTML_TFOOT_ON:
    4910             :         case HTML_TBODY_ON:
    4911             :         case HTML_TABLEROW_ON:
    4912           0 :             SkipToken( -1 );
    4913           0 :             bDone = sal_True;
    4914           0 :             break;
    4915             : 
    4916             :         case HTML_CAPTION_OFF:
    4917           0 :             bDone = sal_True;
    4918           0 :             break;
    4919             :         default:
    4920           0 :             if( pPendStack )
    4921             :             {
    4922           0 :                 SwPendingStack* pTmp = pPendStack->pNext;
    4923           0 :                 delete pPendStack;
    4924           0 :                 pPendStack = pTmp;
    4925             : 
    4926             :                 OSL_ENSURE( !pTmp, "weiter kann es nicht gehen!" );
    4927             :             }
    4928             : 
    4929           0 :             if( IsParserWorking() )
    4930           0 :                 NextToken( nToken );
    4931           0 :             break;
    4932             :         }
    4933             : 
    4934           0 :         if( IsParserWorking() )
    4935           0 :             SaveState( 0 );
    4936             : 
    4937           0 :         if( !bDone )
    4938           0 :             nToken = GetNextToken();
    4939             :     }
    4940             : 
    4941           0 :     if( SVPAR_PENDING==GetStatus() )
    4942             :     {
    4943           0 :         pPendStack = new SwPendingStack( HTML_CAPTION_ON, pPendStack );
    4944           0 :         pPendStack->pData = pSaveStruct;
    4945           0 :         return;
    4946             :     }
    4947             : 
    4948             :     // Alle noch offenen Kontexte beenden
    4949           0 :     while( (sal_uInt16)aContexts.size() > nContextStAttrMin+1 )
    4950             :     {
    4951           0 :         _HTMLAttrContext *pCntxt = PopContext();
    4952           0 :         EndContext( pCntxt );
    4953           0 :         delete pCntxt;
    4954             :     }
    4955             : 
    4956             :     // LF am Absatz-Ende entfernen
    4957           0 :     sal_Bool bLFStripped = StripTrailingLF() > 0;
    4958             : 
    4959           0 :     if( pTable==pCurTable )
    4960             :     {
    4961             :         // Beim spaeteren verschieben der Beschriftung vor oder hinter
    4962             :         // die Tabelle wird der letzte Absatz nicht mitverschoben.
    4963             :         // Deshalb muss sich am Ende der Section immer ein leerer
    4964             :         // Absatz befinden.
    4965           0 :         if( pPam->GetPoint()->nContent.GetIndex() || bLFStripped )
    4966           0 :             AppendTxtNode( AM_NOSPACE );
    4967             :     }
    4968             :     else
    4969             :     {
    4970             :         // LFs am Absatz-Ende entfernen
    4971           0 :         if( !pPam->GetPoint()->nContent.GetIndex() && !bLFStripped )
    4972           0 :             StripTrailingPara();
    4973             :     }
    4974             : 
    4975             :     // falls fuer die Zelle eine Ausrichtung gesetzt wurde, muessen
    4976             :     // wir die beenden
    4977           0 :     _HTMLAttrContext *pCntxt = PopContext();
    4978           0 :     EndContext( pCntxt );
    4979           0 :     delete pCntxt;
    4980             : 
    4981           0 :     SetAttr( sal_False );
    4982             : 
    4983             :     // Stacks und Attribut-Tabelle wiederherstellen
    4984           0 :     pSaveStruct->RestoreAll( *this );
    4985             : 
    4986             :     // PaM wiederherstellen.
    4987           0 :     *pPam->GetPoint() = pSaveStruct->GetPos();
    4988             : 
    4989           0 :     delete pSaveStruct;
    4990             : }
    4991             : 
    4992             : class _TblSaveStruct : public SwPendingStackData
    4993             : {
    4994             : public:
    4995             :     HTMLTable *pCurTable;
    4996             : 
    4997           1 :     _TblSaveStruct( HTMLTable *pCurTbl ) :
    4998           1 :         pCurTable( pCurTbl )
    4999           1 :     {}
    5000             : 
    5001             :     virtual ~_TblSaveStruct();
    5002             : 
    5003             :     // Aufbau der Tabelle anstossen und die Tabelle ggf. in einen
    5004             :     // Rahmen packen. Wenn sal_True zurueckgegeben wird muss noch ein
    5005             :     // Absatz eingefuegt werden!
    5006             :     void MakeTable( sal_uInt16 nWidth, SwPosition& rPos, SwDoc *pDoc );
    5007             : };
    5008             : 
    5009           2 : _TblSaveStruct::~_TblSaveStruct()
    5010           2 : {}
    5011             : 
    5012           1 : void _TblSaveStruct::MakeTable( sal_uInt16 nWidth, SwPosition& rPos, SwDoc *pDoc )
    5013             : {
    5014           1 :     pCurTable->MakeTable( 0, nWidth );
    5015             : 
    5016           1 :     _HTMLTableContext *pTCntxt = pCurTable->GetContext();
    5017             :     OSL_ENSURE( pTCntxt, "Wo ist der Tabellen-Kontext" );
    5018             : 
    5019           1 :     SwTableNode *pTblNd = pTCntxt->GetTableNode();
    5020             :     OSL_ENSURE( pTblNd, "Wo ist der Tabellen-Node" );
    5021             : 
    5022           1 :     if( pDoc->GetCurrentViewShell() && pTblNd )
    5023             :     {
    5024             :         // Existiert schon ein Layout, dann muss an dieser Tabelle die
    5025             :         // BoxFrames neu erzeugt werden.
    5026             : 
    5027           0 :         if( pTCntxt->GetFrmFmt() )
    5028             :         {
    5029           0 :             pTCntxt->GetFrmFmt()->DelFrms();
    5030           0 :             pTblNd->DelFrms();
    5031           0 :             pTCntxt->GetFrmFmt()->MakeFrms();
    5032             :         }
    5033             :         else
    5034             :         {
    5035           0 :             pTblNd->DelFrms();
    5036           0 :             SwNodeIndex aIdx( *pTblNd->EndOfSectionNode(), 1 );
    5037             :             OSL_ENSURE( aIdx.GetIndex() <= pTCntxt->GetPos()->nNode.GetIndex(),
    5038             :                     "unerwarteter Node fuer das Tabellen-Layout" );
    5039           0 :             pTblNd->MakeFrms( &aIdx );
    5040             :         }
    5041             :     }
    5042             : 
    5043           1 :     rPos = *pTCntxt->GetPos();
    5044           1 : }
    5045             : 
    5046           1 : HTMLTableOptions::HTMLTableOptions( const HTMLOptions& rOptions,
    5047             :                                     SvxAdjust eParentAdjust ) :
    5048             :     nCols( 0 ),
    5049             :     nWidth( 0 ), nHeight( 0 ),
    5050             :     nCellPadding( USHRT_MAX ), nCellSpacing( USHRT_MAX ),
    5051             :     nBorder( USHRT_MAX ),
    5052             :     nHSpace( 0 ), nVSpace( 0 ),
    5053             :     eAdjust( eParentAdjust ), eVertOri( text::VertOrientation::CENTER ),
    5054             :     eFrame( HTML_TF_VOID ), eRules( HTML_TR_NONE ),
    5055             :     bPrcWidth( sal_False ),
    5056             :     bTableAdjust( sal_False ),
    5057             :     bBGColor( sal_False ),
    5058           1 :     aBorderColor( COL_GRAY )
    5059             : {
    5060           1 :     sal_Bool bBorderColor = sal_False;
    5061           1 :     sal_Bool bHasFrame = sal_False, bHasRules = sal_False;
    5062             : 
    5063           7 :     for (size_t i = rOptions.size(); i; )
    5064             :     {
    5065           5 :         const HTMLOption& rOption = rOptions[--i];
    5066           5 :         switch( rOption.GetToken() )
    5067             :         {
    5068             :         case HTML_O_ID:
    5069           0 :             aId = rOption.GetString();
    5070           0 :             break;
    5071             :         case HTML_O_COLS:
    5072           0 :             nCols = (sal_uInt16)rOption.GetNumber();
    5073           0 :             break;
    5074             :         case HTML_O_WIDTH:
    5075           1 :             nWidth = (sal_uInt16)rOption.GetNumber();
    5076           1 :             bPrcWidth = (rOption.GetString().indexOf('%') != -1);
    5077           1 :             if( bPrcWidth && nWidth>100 )
    5078           0 :                 nWidth = 100;
    5079           1 :             break;
    5080             :         case HTML_O_HEIGHT:
    5081           0 :             nHeight = (sal_uInt16)rOption.GetNumber();
    5082           0 :             if( rOption.GetString().indexOf('%') != -1 )
    5083           0 :                 nHeight = 0;    // keine %-Anagben benutzen!!!
    5084           0 :             break;
    5085             :         case HTML_O_CELLPADDING:
    5086           1 :             nCellPadding = (sal_uInt16)rOption.GetNumber();
    5087           1 :             break;
    5088             :         case HTML_O_CELLSPACING:
    5089           1 :             nCellSpacing = (sal_uInt16)rOption.GetNumber();
    5090           1 :             break;
    5091             :         case HTML_O_ALIGN:
    5092             :             {
    5093           0 :                 sal_uInt16 nAdjust = static_cast< sal_uInt16 >(eAdjust);
    5094           0 :                 if( rOption.GetEnum( nAdjust, aHTMLPAlignTable ) )
    5095             :                 {
    5096           0 :                     eAdjust = (SvxAdjust)nAdjust;
    5097           0 :                     bTableAdjust = sal_True;
    5098             :                 }
    5099             :             }
    5100           0 :             break;
    5101             :         case HTML_O_VALIGN:
    5102           0 :             eVertOri = rOption.GetEnum( aHTMLTblVAlignTable, eVertOri );
    5103           0 :             break;
    5104             :         case HTML_O_BORDER:
    5105             :             // BORDER und BORDER=BORDER wie BORDER=1 behandeln
    5106           0 :             if (!rOption.GetString().isEmpty() &&
    5107           0 :                 !rOption.GetString().equalsIgnoreAsciiCase(
    5108           0 :                         OOO_STRING_SVTOOLS_HTML_O_border))
    5109             :             {
    5110           0 :                 nBorder = (sal_uInt16)rOption.GetNumber();
    5111             :             }
    5112             :             else
    5113           0 :                 nBorder = 1;
    5114             : 
    5115           0 :             if( !bHasFrame )
    5116           0 :                 eFrame = ( nBorder ? HTML_TF_BOX : HTML_TF_VOID );
    5117           0 :             if( !bHasRules )
    5118           0 :                 eRules = ( nBorder ? HTML_TR_ALL : HTML_TR_NONE );
    5119           0 :             break;
    5120             :         case HTML_O_FRAME:
    5121           0 :             eFrame = rOption.GetTableFrame();
    5122           0 :             bHasFrame = sal_True;
    5123           0 :             break;
    5124             :         case HTML_O_RULES:
    5125           0 :             eRules = rOption.GetTableRules();
    5126           0 :             bHasRules = sal_True;
    5127           0 :             break;
    5128             :         case HTML_O_BGCOLOR:
    5129             :             // Leere BGCOLOR bei <TABLE>, <TR> und <TD>/<TH> wie Netscape
    5130             :             // ignorieren, bei allen anderen Tags *wirklich* nicht.
    5131           1 :             if( !rOption.GetString().isEmpty() )
    5132             :             {
    5133           1 :                 rOption.GetColor( aBGColor );
    5134           1 :                 bBGColor = sal_True;
    5135             :             }
    5136           1 :             break;
    5137             :         case HTML_O_BACKGROUND:
    5138           0 :             aBGImage = rOption.GetString();
    5139           0 :             break;
    5140             :         case HTML_O_BORDERCOLOR:
    5141           0 :             rOption.GetColor( aBorderColor );
    5142           0 :             bBorderColor = sal_True;
    5143           0 :             break;
    5144             :         case HTML_O_BORDERCOLORDARK:
    5145           0 :             if( !bBorderColor )
    5146           0 :                 rOption.GetColor( aBorderColor );
    5147           0 :             break;
    5148             :         case HTML_O_STYLE:
    5149           1 :             aStyle = rOption.GetString();
    5150           1 :             break;
    5151             :         case HTML_O_CLASS:
    5152           0 :             aClass = rOption.GetString();
    5153           0 :             break;
    5154             :         case HTML_O_DIR:
    5155           0 :             aDir = rOption.GetString();
    5156           0 :             break;
    5157             :         case HTML_O_HSPACE:
    5158           0 :             nHSpace = (sal_uInt16)rOption.GetNumber();
    5159           0 :             break;
    5160             :         case HTML_O_VSPACE:
    5161           0 :             nVSpace = (sal_uInt16)rOption.GetNumber();
    5162           0 :             break;
    5163             :         }
    5164             :     }
    5165             : 
    5166           1 :     if( nCols && !nWidth )
    5167             :     {
    5168           0 :         nWidth = 100;
    5169           0 :         bPrcWidth = sal_True;
    5170             :     }
    5171             : 
    5172             :     // Wenn BORDER=0 oder kein BORDER gegeben ist, daan darf es auch
    5173             :     // keine Umrandung geben
    5174           1 :     if( 0==nBorder || USHRT_MAX==nBorder )
    5175             :     {
    5176           1 :         eFrame = HTML_TF_VOID;
    5177           1 :         eRules = HTML_TR_NONE;
    5178             :     }
    5179           1 : }
    5180             : 
    5181           1 : HTMLTable *SwHTMLParser::BuildTable( SvxAdjust eParentAdjust,
    5182             :                                      sal_Bool bIsParentHead,
    5183             :                                      sal_Bool bHasParentSection,
    5184             :                                      sal_Bool bMakeTopSubTable,
    5185             :                                      sal_Bool bHasToFly )
    5186             : {
    5187           1 :     if( !IsParserWorking() && !pPendStack )
    5188           0 :         return 0;
    5189             : 
    5190           1 :     int nToken = 0;
    5191           1 :     sal_Bool bPending = sal_False;
    5192             :     _TblSaveStruct* pSaveStruct;
    5193             : 
    5194           1 :     if( pPendStack )
    5195             :     {
    5196           0 :         pSaveStruct = (_TblSaveStruct*)pPendStack->pData;
    5197             : 
    5198           0 :         SwPendingStack* pTmp = pPendStack->pNext;
    5199           0 :         delete pPendStack;
    5200           0 :         pPendStack = pTmp;
    5201           0 :         nToken = pPendStack ? pPendStack->nToken : GetSaveToken();
    5202           0 :         bPending = SVPAR_ERROR == eState && pPendStack != 0;
    5203             : 
    5204           0 :         SaveState( nToken );
    5205             :     }
    5206             :     else
    5207             :     {
    5208           1 :         pTable = 0;
    5209             :         HTMLTableOptions *pTblOptions =
    5210           1 :             new HTMLTableOptions( GetOptions(), eParentAdjust );
    5211             : 
    5212           1 :         if( !pTblOptions->aId.isEmpty() )
    5213           0 :             InsertBookmark( pTblOptions->aId );
    5214             : 
    5215             :         HTMLTable *pCurTable = new HTMLTable( this, pTable,
    5216             :                                               bIsParentHead,
    5217             :                                               bHasParentSection,
    5218             :                                               bMakeTopSubTable,
    5219             :                                               bHasToFly,
    5220           1 :                                               pTblOptions );
    5221           1 :         if( !pTable )
    5222           1 :             pTable = pCurTable;
    5223             : 
    5224           1 :         pSaveStruct = new _TblSaveStruct( pCurTable );
    5225             : 
    5226           1 :         delete pTblOptions;
    5227             : 
    5228             :         // ist beim ersten GetNextToken schon pending, muss bei
    5229             :         // wiederaufsetzen auf jedenfall neu gelesen werden!
    5230           1 :         SaveState( 0 );
    5231             :     }
    5232             : 
    5233           1 :     HTMLTable *pCurTable = pSaveStruct->pCurTable;
    5234             : 
    5235             :     // </TABLE> wird laut DTD benoetigt
    5236           1 :     if( !nToken )
    5237           1 :         nToken = GetNextToken();    // naechstes Token
    5238             : 
    5239           1 :     sal_Bool bDone = sal_False;
    5240           6 :     while( (IsParserWorking() && !bDone) || bPending )
    5241             :     {
    5242           4 :         SaveState( nToken );
    5243             : 
    5244           4 :         nToken = FilterToken( nToken );
    5245             : 
    5246             :         OSL_ENSURE( pPendStack || !bCallNextToken ||
    5247             :                 pCurTable->GetContext() || pCurTable->HasParentSection(),
    5248             :                 "Wo ist die Section gebieben?" );
    5249           4 :         if( !pPendStack && bCallNextToken &&
    5250           0 :             (pCurTable->GetContext() || pCurTable->HasParentSection()) )
    5251             :         {
    5252             :             // NextToken direkt aufrufen (z.B. um den Inhalt von
    5253             :             // Floating-Frames oder Applets zu ignorieren)
    5254           0 :             NextToken( nToken );
    5255             :         }
    5256           4 :         else switch( nToken )
    5257             :         {
    5258             :         case HTML_TABLE_ON:
    5259           0 :             if( !pCurTable->GetContext() )
    5260             :             {
    5261             :                 // Wenn noch keine Tabelle eingefuegt wurde,
    5262             :                 // die naechste Tabelle lesen
    5263           0 :                 SkipToken( -1 );
    5264           0 :                 bDone = sal_True;
    5265             :             }
    5266             : 
    5267           0 :             break;
    5268             :         case HTML_TABLE_OFF:
    5269           1 :             bDone = sal_True;
    5270           1 :             break;
    5271             :         case HTML_CAPTION_ON:
    5272           0 :             BuildTableCaption( pCurTable );
    5273           0 :             bDone = pTable->IsOverflowing();
    5274           0 :             break;
    5275             :         case HTML_COL_ON:
    5276           1 :             SkipToken( -1 );
    5277           1 :             BuildTableColGroup( pCurTable, sal_False );
    5278           1 :             break;
    5279             :         case HTML_COLGROUP_ON:
    5280           0 :             BuildTableColGroup( pCurTable, sal_True );
    5281           0 :             break;
    5282             :         case HTML_TABLEROW_ON:
    5283             :         case HTML_TABLEHEADER_ON:
    5284             :         case HTML_TABLEDATA_ON:
    5285           1 :             SkipToken( -1 );
    5286           1 :             BuildTableSection( pCurTable, sal_False, sal_False );
    5287           1 :             bDone = pTable->IsOverflowing();
    5288           1 :             break;
    5289             :         case HTML_THEAD_ON:
    5290             :         case HTML_TFOOT_ON:
    5291             :         case HTML_TBODY_ON:
    5292           0 :             BuildTableSection( pCurTable, sal_True, HTML_THEAD_ON==nToken );
    5293           0 :             bDone = pTable->IsOverflowing();
    5294           0 :             break;
    5295             :         case HTML_MULTICOL_ON:
    5296             :             // spaltige Rahmen koennen wir hier leider nicht einguegen
    5297           0 :             break;
    5298             :         case HTML_FORM_ON:
    5299           0 :             NewForm( sal_False );   // keinen neuen Absatz aufmachen!
    5300           0 :             break;
    5301             :         case HTML_FORM_OFF:
    5302           0 :             EndForm( sal_False );   // keinen neuen Absatz aufmachen!
    5303           0 :             break;
    5304             :         case HTML_TEXTTOKEN:
    5305             :             // Blank-Strings sind u. U. eine Folge von CR+LF und kein Text
    5306           3 :             if( (pCurTable->GetContext() ||
    5307           1 :                  !pCurTable->HasParentSection()) &&
    5308           1 :                 1==aToken.getLength() && ' '==aToken[0] )
    5309           0 :                 break;
    5310             :         default:
    5311           1 :             pCurTable->MakeParentContents();
    5312           1 :             NextToken( nToken );
    5313           1 :             break;
    5314             :         }
    5315             : 
    5316             :         OSL_ENSURE( !bPending || !pPendStack,
    5317             :                 "SwHTMLParser::BuildTable: Es gibt wieder einen Pend-Stack" );
    5318           4 :         bPending = sal_False;
    5319           4 :         if( IsParserWorking() )
    5320           4 :             SaveState( 0 );
    5321             : 
    5322           4 :         if( !bDone )
    5323           3 :             nToken = GetNextToken();
    5324             :     }
    5325             : 
    5326           1 :     if( SVPAR_PENDING == GetStatus() )
    5327             :     {
    5328           0 :         pPendStack = new SwPendingStack( HTML_TABLE_ON, pPendStack );
    5329           0 :         pPendStack->pData = pSaveStruct;
    5330           0 :         return 0;
    5331             :     }
    5332             : 
    5333           1 :     _HTMLTableContext *pTCntxt = pCurTable->GetContext();
    5334           1 :     if( pTCntxt )
    5335             :     {
    5336             :         // Die Tabelle wurde auch angelegt
    5337             : 
    5338             :         // Tabellen-Struktur anpassen
    5339           1 :         pCurTable->CloseTable();
    5340             : 
    5341             :         // ausserhalb von Zellen begonnene Kontexte beenden
    5342             :         // muss vor(!) dem Umsetzten der Attribut Tabelle existieren,
    5343             :         // weil die aktuelle danach nicht mehr existiert
    5344           2 :         while( aContexts.size() > nContextStAttrMin )
    5345             :         {
    5346           0 :             _HTMLAttrContext *pCntxt = PopContext();
    5347           0 :             ClearContext( pCntxt );
    5348           0 :             delete pCntxt;
    5349             :         }
    5350             : 
    5351           1 :         nContextStMin = pTCntxt->GetContextStMin();
    5352           1 :         nContextStAttrMin = pTCntxt->GetContextStAttrMin();
    5353             : 
    5354           1 :         if( pTable==pCurTable )
    5355             :         {
    5356             :             // Tabellen-Beschriftung setzen
    5357           1 :             const SwStartNode *pCapStNd = pTable->GetCaptionStartNode();
    5358           1 :             if( pCapStNd )
    5359             :             {
    5360             :                 // Der letzte Absatz der Section wird nie mitkopiert. Deshalb
    5361             :                 // muss die Section mindestens zwei Absaetze enthalten.
    5362             : 
    5363           0 :                 if( pCapStNd->EndOfSectionIndex() - pCapStNd->GetIndex() > 2 )
    5364             :                 {
    5365             :                     // Start-Node und letzten Absatz nicht mitkopieren.
    5366             :                     SwNodeRange aSrcRg( *pCapStNd, 1,
    5367           0 :                                     *pCapStNd->EndOfSectionNode(), -1 );
    5368             : 
    5369           0 :                     sal_Bool bTop = pTable->IsTopCaption();
    5370           0 :                     SwStartNode *pTblStNd = pTCntxt->GetTableNode();
    5371             : 
    5372             :                     OSL_ENSURE( pTblStNd, "Wo ist der Tabellen-Node" );
    5373             :                     OSL_ENSURE( pTblStNd==pPam->GetNode()->FindTableNode(),
    5374             :                             "Stehen wir in der falschen Tabelle?" );
    5375             : 
    5376             :                     SwNode* pNd;
    5377           0 :                     if( bTop )
    5378           0 :                         pNd = pTblStNd;
    5379             :                     else
    5380           0 :                         pNd = pTblStNd->EndOfSectionNode();
    5381           0 :                     SwNodeIndex aDstIdx( *pNd, bTop ? 0 : 1 );
    5382             : 
    5383             :                     pDoc->MoveNodeRange( aSrcRg, aDstIdx,
    5384           0 :                         IDocumentContentOperations::DOC_MOVEDEFAULT );
    5385             : 
    5386             :                     // Wenn die Caption vor der Tabelle eingefuegt wurde muss
    5387             :                     // eine an der Tabelle gestzte Seitenvorlage noch in den
    5388             :                     // ersten Absatz der Ueberschrift verschoben werden.
    5389             :                     // Ausserdem muessen alle gemerkten Indizes, die auf den
    5390             :                     // Tabellen-Node zeigen noch verschoben werden.
    5391           0 :                     if( bTop )
    5392             :                     {
    5393             :                         MovePageDescAttrs( pTblStNd, aSrcRg.aStart.GetIndex(),
    5394           0 :                                            sal_False );
    5395           0 :                     }
    5396             :                 }
    5397             : 
    5398             :                 // Die Section wird jetzt nicht mehr gebraucht.
    5399           0 :                 pPam->SetMark();
    5400           0 :                 pPam->DeleteMark();
    5401           0 :                 pDoc->DeleteSection( (SwStartNode *)pCapStNd );
    5402           0 :                 pTable->SetCaption( 0, sal_False );
    5403             :             }
    5404             : 
    5405             :             // SwTable aufbereiten
    5406           1 :             sal_uInt16 nBrowseWidth = (sal_uInt16)GetCurrentBrowseWidth();
    5407           1 :             pSaveStruct->MakeTable( nBrowseWidth, *pPam->GetPoint(), pDoc );
    5408             :         }
    5409             : 
    5410           1 :         GetNumInfo().Set( pTCntxt->GetNumInfo() );
    5411           1 :         pTCntxt->RestorePREListingXMP( *this );
    5412           1 :         RestoreAttrTab( pTCntxt->aAttrTab );
    5413             : 
    5414           1 :         if( pTable==pCurTable )
    5415             :         {
    5416             :             // oberen Absatz-Abstand einstellen
    5417           1 :             bUpperSpace = true;
    5418           1 :             SetTxtCollAttrs();
    5419             : 
    5420           2 :             nParaCnt = nParaCnt - std::min(nParaCnt,
    5421           2 :                 pTCntxt->GetTableNode()->GetTable().GetTabSortBoxes().size());
    5422             : 
    5423             :             // ggfs. eine Tabelle anspringen
    5424           3 :             if( JUMPTO_TABLE == eJumpTo && pTable->GetSwTable() &&
    5425           1 :                 pTable->GetSwTable()->GetFrmFmt()->GetName() == sJmpMark )
    5426             :             {
    5427           0 :                 bChkJumpMark = true;
    5428           0 :                 eJumpTo = JUMPTO_NONE;
    5429             :             }
    5430             : 
    5431             :             // Wenn Import abgebrochen wurde kein erneutes Show
    5432             :             // aufrufen, weil die SwViewShell schon geloescht wurde!
    5433             :             // Genuegt nicht. Auch im ACCEPTING_STATE darf
    5434             :             // kein Show aufgerufen werden, weil sonst waehrend des
    5435             :             // Reschedules der Parser zerstoert wird, wenn noch ein
    5436             :             // DataAvailable-Link kommt. Deshalb: Nur im WORKING-State.
    5437           1 :             if( !nParaCnt && SVPAR_WORKING == GetStatus() )
    5438           1 :                 Show();
    5439             :         }
    5440             :     }
    5441           0 :     else if( pTable==pCurTable )
    5442             :     {
    5443             :         // Es wurde gar keine Tabelle gelesen.
    5444             : 
    5445             :         // Dann muss eine evtl gelesene Beschriftung noch geloescht werden.
    5446           0 :         const SwStartNode *pCapStNd = pCurTable->GetCaptionStartNode();
    5447           0 :         if( pCapStNd )
    5448             :         {
    5449           0 :             pPam->SetMark();
    5450           0 :             pPam->DeleteMark();
    5451           0 :             pDoc->DeleteSection( (SwStartNode *)pCapStNd );
    5452           0 :             pCurTable->SetCaption( 0, sal_False );
    5453             :         }
    5454             :     }
    5455             : 
    5456           1 :     if( pTable == pCurTable  )
    5457             :     {
    5458           1 :         delete pSaveStruct->pCurTable;
    5459           1 :         pSaveStruct->pCurTable = 0;
    5460           1 :         pTable = 0;
    5461             :     }
    5462             : 
    5463           1 :     HTMLTable* pRetTbl = pSaveStruct->pCurTable;
    5464           1 :     delete pSaveStruct;
    5465             : 
    5466           1 :     return pRetTbl;
    5467             : }
    5468             : 
    5469             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10