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

Generated by: LCOV version 1.11