LCOV - code coverage report
Current view: top level - libreoffice/sw/source/filter/html - htmltab.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 2255 0.0 %
Date: 2012-12-27 Functions: 0 184 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10