LCOV - code coverage report
Current view: top level - libreoffice/sw/source/filter/xml - xmltbli.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 539 1162 46.4 %
Date: 2012-12-27 Functions: 69 121 57.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "hintids.hxx"
      21             : 
      22             : #include <limits.h>
      23             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      24             : #include <com/sun/star/text/XTextTable.hpp>
      25             : #include <com/sun/star/table/XCellRange.hpp>
      26             : #include <svl/itemset.hxx>
      27             : #include <svl/zformat.hxx>
      28             : #include <sax/tools/converter.hxx>
      29             : #include <xmloff/xmlnmspe.hxx>
      30             : #include <xmloff/xmltkmap.hxx>
      31             : #include <xmloff/nmspmap.hxx>
      32             : 
      33             : #include <xmloff/families.hxx>
      34             : #include <xmloff/xmluconv.hxx>
      35             : #include <xmloff/i18nmap.hxx>
      36             : #include <editeng/protitem.hxx>
      37             : #include "poolfmt.hxx"
      38             : #include "fmtfsize.hxx"
      39             : #include "fmtornt.hxx"
      40             : #include "fmtfordr.hxx"
      41             : #include "doc.hxx"
      42             : #include "swtable.hxx"
      43             : #include "swtblfmt.hxx"
      44             : #include "pam.hxx"
      45             : #include "unotbl.hxx"
      46             : #include "unotextrange.hxx"
      47             : #include "unocrsr.hxx"
      48             : #include "cellatr.hxx"
      49             : #include "swddetbl.hxx"
      50             : #include "ddefld.hxx"
      51             : #include <sfx2/linkmgr.hxx>  // for cTokenSeparator
      52             : #include "xmlimp.hxx"
      53             : #include "xmltbli.hxx"
      54             : 
      55             : // for locking SolarMutex: svapp + mutex
      56             : #include <vcl/svapp.hxx>
      57             : #include <osl/mutex.hxx>
      58             : #include "ndtxt.hxx"
      59             : 
      60             : using ::rtl::OUString;
      61             : using namespace ::com::sun::star;
      62             : using namespace ::com::sun::star::uno;
      63             : using namespace ::com::sun::star::lang;
      64             : using namespace ::com::sun::star::text;
      65             : using namespace ::com::sun::star::frame;
      66             : using namespace ::com::sun::star::table;
      67             : using namespace ::com::sun::star::xml::sax;
      68             : using namespace ::xmloff::token;
      69             : using ::boost::unordered_map;
      70             : using rtl::OUString;
      71             : 
      72             : enum SwXMLTableElemTokens
      73             : {
      74             :     XML_TOK_TABLE_HEADER_COLS,
      75             :     XML_TOK_TABLE_COLS,
      76             :     XML_TOK_TABLE_COL,
      77             :     XML_TOK_TABLE_HEADER_ROWS,
      78             :     XML_TOK_TABLE_ROWS,
      79             :     XML_TOK_TABLE_ROW,
      80             :     XML_TOK_OFFICE_DDE_SOURCE,
      81             :     XML_TOK_TABLE_ELEM_END=XML_TOK_UNKNOWN
      82             : };
      83             : 
      84             : enum SwXMLTableCellAttrTokens
      85             : {
      86             :     XML_TOK_TABLE_XMLID,
      87             :     XML_TOK_TABLE_STYLE_NAME,
      88             :     XML_TOK_TABLE_NUM_COLS_SPANNED,
      89             :     XML_TOK_TABLE_NUM_ROWS_SPANNED,
      90             :     XML_TOK_TABLE_NUM_COLS_REPEATED,
      91             :     XML_TOK_TABLE_FORMULA,
      92             :     XML_TOK_TABLE_VALUE,
      93             :     XML_TOK_TABLE_TIME_VALUE,
      94             :     XML_TOK_TABLE_DATE_VALUE,
      95             :     XML_TOK_TABLE_BOOLEAN_VALUE,
      96             :     XML_TOK_TABLE_PROTECTED,
      97             :     XML_TOK_TABLE_STRING_VALUE,
      98             :     XML_TOK_TABLE_CELL_ATTR_END=XML_TOK_UNKNOWN
      99             : };
     100             : 
     101             : static SvXMLTokenMapEntry aTableElemTokenMap[] =
     102             : {
     103             :     { XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS,
     104             :             XML_TOK_TABLE_HEADER_COLS },
     105             :     { XML_NAMESPACE_TABLE, XML_TABLE_COLUMNS,           XML_TOK_TABLE_COLS },
     106             :     { XML_NAMESPACE_TABLE, XML_TABLE_COLUMN,            XML_TOK_TABLE_COL },
     107             :     { XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS,
     108             :             XML_TOK_TABLE_HEADER_ROWS },
     109             :     { XML_NAMESPACE_TABLE, XML_TABLE_ROWS,              XML_TOK_TABLE_ROWS },
     110             :     { XML_NAMESPACE_TABLE, XML_TABLE_ROW,               XML_TOK_TABLE_ROW },
     111             :     { XML_NAMESPACE_OFFICE, XML_DDE_SOURCE,
     112             :             XML_TOK_OFFICE_DDE_SOURCE },
     113             : 
     114             :     // There are slight differences between <table:table-columns> and
     115             :     // <table:table-columns-groups>. However, none of these are
     116             :     // supported in Writer (they are Calc-only features), so we
     117             :     // support column groups by simply using the <table:table-columns>
     118             :     // token for column groups, too.
     119             :     { XML_NAMESPACE_TABLE, XML_TABLE_COLUMN_GROUP,      XML_TOK_TABLE_COLS },
     120             : 
     121             :     XML_TOKEN_MAP_END
     122             : };
     123             : 
     124             : static SvXMLTokenMapEntry aTableCellAttrTokenMap[] =
     125             : {
     126             :     { XML_NAMESPACE_XML, XML_ID, XML_TOK_TABLE_XMLID },
     127             :     { XML_NAMESPACE_TABLE, XML_STYLE_NAME, XML_TOK_TABLE_STYLE_NAME },
     128             :     { XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_SPANNED, XML_TOK_TABLE_NUM_COLS_SPANNED },
     129             :     { XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_SPANNED, XML_TOK_TABLE_NUM_ROWS_SPANNED },
     130             :     { XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, XML_TOK_TABLE_NUM_COLS_REPEATED },
     131             :     { XML_NAMESPACE_TABLE, XML_FORMULA, XML_TOK_TABLE_FORMULA },
     132             :     { XML_NAMESPACE_OFFICE, XML_VALUE, XML_TOK_TABLE_VALUE },
     133             :     { XML_NAMESPACE_OFFICE, XML_TIME_VALUE, XML_TOK_TABLE_TIME_VALUE },
     134             :     { XML_NAMESPACE_OFFICE, XML_DATE_VALUE, XML_TOK_TABLE_DATE_VALUE },
     135             :     { XML_NAMESPACE_OFFICE, XML_BOOLEAN_VALUE, XML_TOK_TABLE_BOOLEAN_VALUE },
     136             :     { XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TOK_TABLE_PROTECTED },
     137             :     { XML_NAMESPACE_TABLE, XML_PROTECT, XML_TOK_TABLE_PROTECTED }, // for backwards compatibility with SRC629 (and before)
     138             :     { XML_NAMESPACE_OFFICE, XML_STRING_VALUE, XML_TOK_TABLE_STRING_VALUE },
     139             :     XML_TOKEN_MAP_END
     140             : };
     141             : 
     142          24 : const SvXMLTokenMap& SwXMLImport::GetTableElemTokenMap()
     143             : {
     144          24 :     if( !pTableElemTokenMap )
     145           1 :         pTableElemTokenMap = new SvXMLTokenMap( aTableElemTokenMap );
     146             : 
     147          24 :     return *pTableElemTokenMap;
     148             : }
     149             : 
     150         132 : const SvXMLTokenMap& SwXMLImport::GetTableCellAttrTokenMap()
     151             : {
     152         132 :     if( !pTableCellAttrTokenMap )
     153           1 :         pTableCellAttrTokenMap = new SvXMLTokenMap( aTableCellAttrTokenMap );
     154             : 
     155         132 :     return *pTableCellAttrTokenMap;
     156             : }
     157             : 
     158             : // ---------------------------------------------------------------------
     159             : 
     160         115 : class SwXMLTableCell_Impl
     161             : {
     162             :     OUString aStyleName;
     163             : 
     164             :     OUString mXmlId;
     165             : 
     166             :     OUString sFormula;  // cell formula; valid if length > 0
     167             :     double dValue;      // formula value
     168             : 
     169             :     SvXMLImportContextRef   xSubTable;
     170             : 
     171             :     const SwStartNode *pStartNode;
     172             :     sal_uInt32 nRowSpan;
     173             :     sal_uInt32 nColSpan;
     174             : 
     175             :     sal_Bool bProtected : 1;
     176             :     sal_Bool bHasValue; // determines whether dValue attribute is valid
     177             :     sal_Bool mbCovered;
     178             :     sal_Bool mbTextValue;
     179             : 
     180             : public:
     181             : 
     182         115 :     SwXMLTableCell_Impl( sal_uInt32 nRSpan=1UL, sal_uInt32 nCSpan=1UL ) :
     183             :         pStartNode( 0 ),
     184             :         nRowSpan( nRSpan ),
     185             :         nColSpan( nCSpan ),
     186             :         bProtected( sal_False ),
     187         115 :         mbCovered( sal_False )
     188         115 :         {}
     189             : 
     190             :     inline void Set( const OUString& rStyleName,
     191             :                       sal_uInt32 nRSpan, sal_uInt32 nCSpan,
     192             :                      const SwStartNode *pStNd, SwXMLTableContext *pTable,
     193             :                      sal_Bool bProtect = sal_False,
     194             :                      const OUString* pFormula = NULL,
     195             :                      sal_Bool bHasValue = sal_False,
     196             :                      sal_Bool mbCovered = sal_False,
     197             :                      double dVal = 0.0,
     198             :                      sal_Bool mbTextValue = sal_False,
     199             :                      OUString const& i_rXmlId = OUString());
     200             : 
     201         115 :     bool IsUsed() const { return pStartNode!=0 ||
     202         115 :                                      xSubTable.Is() || bProtected;}
     203             : 
     204         115 :     sal_uInt32 GetRowSpan() const { return nRowSpan; }
     205           0 :     void SetRowSpan( sal_uInt32 nSet ) { nRowSpan = nSet; }
     206         230 :     sal_uInt32 GetColSpan() const { return nColSpan; }
     207         115 :     const OUString& GetStyleName() const { return aStyleName; }
     208         230 :     const OUString& GetFormula() const { return sFormula; }
     209           0 :     double GetValue() const { return dValue; }
     210         460 :     sal_Bool HasValue() const { return bHasValue; }
     211         230 :     sal_Bool IsProtected() const { return bProtected; }
     212         115 :     sal_Bool IsCovered() const { return mbCovered; }
     213         115 :     sal_Bool HasTextValue() const { return mbTextValue; }
     214             :     const OUString& GetXmlId() const { return mXmlId; }
     215             : 
     216         593 :     const SwStartNode *GetStartNode() const { return pStartNode; }
     217             :     inline void SetStartNode( const SwStartNode *pSttNd );
     218             : 
     219             :     inline SwXMLTableContext *GetSubTable() const;
     220             : 
     221             :     inline void Dispose();
     222             : };
     223             : 
     224         115 : inline void SwXMLTableCell_Impl::Set( const OUString& rStyleName,
     225             :                                       sal_uInt32 nRSpan, sal_uInt32 nCSpan,
     226             :                                       const SwStartNode *pStNd,
     227             :                                       SwXMLTableContext *pTable,
     228             :                                       sal_Bool bProtect,
     229             :                                       const OUString* pFormula,
     230             :                                       sal_Bool bHasVal,
     231             :                                       sal_Bool bCov,
     232             :                                       double dVal,
     233             :                                       sal_Bool bTextVal,
     234             :                                       OUString const& i_rXmlId )
     235             : {
     236         115 :     aStyleName = rStyleName;
     237         115 :     nRowSpan = nRSpan;
     238         115 :     nColSpan = nCSpan;
     239         115 :     pStartNode = pStNd;
     240         115 :     xSubTable = pTable;
     241         115 :     dValue = dVal;
     242         115 :     bHasValue = bHasVal;
     243         115 :     mbCovered = bCov;
     244         115 :     mbTextValue = bTextVal;
     245         115 :     bProtected = bProtect;
     246             : 
     247         115 :     if (!mbCovered) // ensure uniqueness
     248             :     {
     249         115 :         mXmlId = i_rXmlId;
     250             :     }
     251             : 
     252             :     // set formula, if valid
     253         115 :     if (pFormula != NULL)
     254             :     {
     255         115 :         sFormula = *pFormula;
     256             :     }
     257         115 : }
     258             : 
     259           0 : inline void SwXMLTableCell_Impl::SetStartNode( const SwStartNode *pSttNd )
     260             : {
     261           0 :     pStartNode = pSttNd;
     262           0 :     xSubTable = 0;
     263           0 : }
     264             : 
     265           0 : inline SwXMLTableContext *SwXMLTableCell_Impl::GetSubTable() const
     266             : {
     267           0 :     return (SwXMLTableContext *)&xSubTable;
     268             : }
     269             : 
     270         115 : inline void SwXMLTableCell_Impl::Dispose()
     271             : {
     272         115 :     if( xSubTable.Is() )
     273           0 :         xSubTable = 0;
     274         115 : }
     275             : 
     276             : // ---------------------------------------------------------------------
     277             : 
     278             : typedef boost::ptr_vector<SwXMLTableCell_Impl> SwXMLTableCells_Impl;
     279             : 
     280             : class SwXMLTableRow_Impl
     281             : {
     282             :     OUString aStyleName;
     283             :     OUString aDfltCellStyleName;
     284             :     OUString mXmlId;
     285             : 
     286             :     SwXMLTableCells_Impl aCells;
     287             : 
     288             :     sal_Bool bSplitable;
     289             : 
     290             : public:
     291             : 
     292             :     SwXMLTableRow_Impl( const OUString& rStyleName, sal_uInt32 nCells,
     293             :                          const OUString *pDfltCellStyleName = 0,
     294             :                         const OUString& i_rXmlId = OUString() );
     295          23 :     ~SwXMLTableRow_Impl() {}
     296             : 
     297             :     inline const SwXMLTableCell_Impl *GetCell( sal_uInt32 nCol ) const;
     298             :     inline SwXMLTableCell_Impl *GetCell( sal_uInt32 nCol );
     299             : 
     300             :     inline void Set( const OUString& rStyleName,
     301             :                      const OUString& rDfltCellStyleName,
     302             :                      const OUString& i_rXmlId );
     303             : 
     304             :     void Expand( sal_uInt32 nCells, sal_Bool bOneCell );
     305             : 
     306         115 :     void SetSplitable( sal_Bool bSet ) { bSplitable = bSet; }
     307           0 :     sal_Bool IsSplitable() const { return bSplitable; }
     308             : 
     309          23 :     const OUString& GetStyleName() const { return aStyleName; }
     310          98 :     const OUString& GetDefaultCellStyleName() const { return aDfltCellStyleName; }
     311             :     const OUString& GetXmlId() const { return mXmlId; }
     312             : 
     313             :     void Dispose();
     314             : };
     315             : 
     316          23 : SwXMLTableRow_Impl::SwXMLTableRow_Impl( const OUString& rStyleName,
     317             :                                         sal_uInt32 nCells,
     318             :                                         const OUString *pDfltCellStyleName,
     319             :                                         const OUString& i_rXmlId ) :
     320             :     aStyleName( rStyleName ),
     321             :     mXmlId( i_rXmlId ),
     322          23 :     bSplitable( sal_False )
     323             : {
     324          23 :     if( pDfltCellStyleName  )
     325          23 :         aDfltCellStyleName = *pDfltCellStyleName;
     326             :     OSL_ENSURE( nCells <= USHRT_MAX,
     327             :             "SwXMLTableRow_Impl::SwXMLTableRow_Impl: too many cells" );
     328          23 :     if( nCells > USHRT_MAX )
     329           0 :         nCells = USHRT_MAX;
     330             : 
     331         138 :     for( sal_uInt16 i=0U; i<nCells; i++ )
     332             :     {
     333         115 :         aCells.push_back( new SwXMLTableCell_Impl );
     334             :     }
     335          23 : }
     336             : 
     337           0 : inline const SwXMLTableCell_Impl *SwXMLTableRow_Impl::GetCell( sal_uInt32 nCol ) const
     338             : {
     339             :     OSL_ENSURE( nCol < USHRT_MAX,
     340             :             "SwXMLTableRow_Impl::GetCell: column number is to big" );
     341             :     // #i95726# - some fault tolerance
     342             :     OSL_ENSURE( nCol < aCells.size(),
     343             :             "SwXMLTableRow_Impl::GetCell: column number is out of bound" );
     344           0 :     return nCol < aCells.size() ? &aCells[(sal_uInt16)nCol] : 0;
     345             : }
     346             : 
     347         460 : inline SwXMLTableCell_Impl *SwXMLTableRow_Impl::GetCell( sal_uInt32 nCol )
     348             : {
     349             :     OSL_ENSURE( nCol < USHRT_MAX,
     350             :             "SwXMLTableRow_Impl::GetCell: column number is to big" );
     351             :     // #i95726# - some fault tolerance
     352             :     OSL_ENSURE( nCol < aCells.size(),
     353             :             "SwXMLTableRow_Impl::GetCell: column number is out of bound" );
     354         460 :     return nCol < aCells.size() ? &aCells[(sal_uInt16)nCol] : 0;
     355             : }
     356             : 
     357           0 : void SwXMLTableRow_Impl::Expand( sal_uInt32 nCells, sal_Bool bOneCell )
     358             : {
     359             :     OSL_ENSURE( nCells <= USHRT_MAX,
     360             :             "SwXMLTableRow_Impl::Expand: too many cells" );
     361           0 :     if( nCells > USHRT_MAX )
     362           0 :         nCells = USHRT_MAX;
     363             : 
     364           0 :     sal_uInt32 nColSpan = nCells - aCells.size();
     365           0 :     for( sal_uInt16 i=aCells.size(); i<nCells; i++ )
     366             :     {
     367             :         aCells.push_back( new SwXMLTableCell_Impl( 1UL,
     368           0 :                                                 bOneCell ? nColSpan : 1UL ) );
     369           0 :         nColSpan--;
     370             :     }
     371             : 
     372             :     OSL_ENSURE( nCells<=aCells.size(),
     373             :             "SwXMLTableRow_Impl::Expand: wrong number of cells" );
     374           0 : }
     375             : 
     376           0 : inline void SwXMLTableRow_Impl::Set( const OUString& rStyleName,
     377             :                                      const OUString& rDfltCellStyleName,
     378             :                                      const OUString& i_rXmlId )
     379             : {
     380           0 :     aStyleName = rStyleName;
     381           0 :     aDfltCellStyleName = rDfltCellStyleName;
     382           0 :     mXmlId = i_rXmlId;
     383           0 : }
     384             : 
     385          23 : void SwXMLTableRow_Impl::Dispose()
     386             : {
     387         138 :     for( sal_uInt16 i=0; i < aCells.size(); i++ )
     388         115 :         aCells[i].Dispose();
     389          23 : }
     390             : 
     391             : // ---------------------------------------------------------------------
     392             : 
     393             : class SwXMLTableCellContext_Impl : public SvXMLImportContext
     394             : {
     395             :     OUString aStyleName;
     396             :     OUString sFormula;
     397             :     OUString sSaveParaDefault;
     398             :     OUString mXmlId;
     399             : 
     400             :     SvXMLImportContextRef   xMyTable;
     401             : 
     402             :     double fValue;
     403             :     sal_Bool bHasValue;
     404             :     sal_Bool bHasTextValue;
     405             :     sal_Bool bProtect;
     406             : 
     407             :     sal_uInt32                  nRowSpan;
     408             :     sal_uInt32                  nColSpan;
     409             :     sal_uInt32                  nColRepeat;
     410             : 
     411             :     sal_Bool                    bHasTextContent : 1;
     412             :     sal_Bool                    bHasTableContent : 1;
     413             : 
     414         460 :     SwXMLTableContext *GetTable() { return (SwXMLTableContext *)&xMyTable; }
     415             : 
     416         115 :     sal_Bool HasContent() const { return bHasTextContent || bHasTableContent; }
     417             :     inline void _InsertContent();
     418             :     inline void InsertContent();
     419             :     inline void InsertContentIfNotThere();
     420             :     inline void InsertContent( SwXMLTableContext *pTable );
     421             : 
     422             : public:
     423             : 
     424             :     SwXMLTableCellContext_Impl(
     425             :             SwXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName,
     426             :             const Reference< xml::sax::XAttributeList > & xAttrList,
     427             :             SwXMLTableContext *pTable );
     428             : 
     429             :     virtual ~SwXMLTableCellContext_Impl();
     430             : 
     431             :     virtual SvXMLImportContext *CreateChildContext(
     432             :             sal_uInt16 nPrefix, const OUString& rLocalName,
     433             :             const Reference< xml::sax::XAttributeList > & xAttrList );
     434             :     virtual void EndElement();
     435             : 
     436         132 :     SwXMLImport& GetSwImport() { return (SwXMLImport&)GetImport(); }
     437             : };
     438             : 
     439         115 : SwXMLTableCellContext_Impl::SwXMLTableCellContext_Impl(
     440             :         SwXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName,
     441             :         const Reference< xml::sax::XAttributeList > & xAttrList,
     442             :         SwXMLTableContext *pTable ) :
     443             :     SvXMLImportContext( rImport, nPrfx, rLName ),
     444             :     sFormula(),
     445             :     xMyTable( pTable ),
     446             :     fValue( 0.0 ),
     447             :     bHasValue( sal_False ),
     448             :     bHasTextValue( sal_False ),
     449             :     bProtect( sal_False ),
     450             :     nRowSpan( 1UL ),
     451             :     nColSpan( 1UL ),
     452             :     nColRepeat( 1UL ),
     453             :     bHasTextContent( sal_False ),
     454         115 :     bHasTableContent( sal_False )
     455             : {
     456         115 :     sSaveParaDefault = GetImport().GetTextImport()->GetCellParaStyleDefault();
     457         115 :     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
     458         247 :     for( sal_Int16 i=0; i < nAttrCount; i++ )
     459             :     {
     460         132 :         const OUString& rAttrName = xAttrList->getNameByIndex( i );
     461             : 
     462         132 :         OUString aLocalName;
     463             :         sal_uInt16 nPrefix =
     464         132 :             GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
     465         132 :                                                             &aLocalName );
     466         132 :         const OUString& rValue = xAttrList->getValueByIndex( i );
     467             :         const SvXMLTokenMap& rTokenMap =
     468         132 :             GetSwImport().GetTableCellAttrTokenMap();
     469         132 :         switch( rTokenMap.Get( nPrefix, aLocalName ) )
     470             :         {
     471             :         case XML_TOK_TABLE_XMLID:
     472           0 :             mXmlId = rValue;
     473           0 :             break;
     474             :         case XML_TOK_TABLE_STYLE_NAME:
     475          17 :             aStyleName = rValue;
     476          17 :             GetImport().GetTextImport()->SetCellParaStyleDefault(rValue);
     477          17 :             break;
     478             :         case XML_TOK_TABLE_NUM_COLS_SPANNED:
     479           0 :             nColSpan = (sal_uInt32)rValue.toInt32();
     480           0 :             if( nColSpan < 1UL )
     481           0 :                 nColSpan = 1UL;
     482           0 :             break;
     483             :         case XML_TOK_TABLE_NUM_ROWS_SPANNED:
     484           0 :             nRowSpan = (sal_uInt32)rValue.toInt32();
     485           0 :             if( nRowSpan < 1UL )
     486           0 :                 nRowSpan = 1UL;
     487           0 :             break;
     488             :         case XML_TOK_TABLE_NUM_COLS_REPEATED:
     489           0 :             nColRepeat = (sal_uInt32)rValue.toInt32();
     490           0 :             if( nColRepeat < 1UL )
     491           0 :                 nColRepeat = 1UL;
     492           0 :             break;
     493             :         case XML_TOK_TABLE_FORMULA:
     494             :             {
     495           0 :                 OUString sTmp;
     496           0 :                 sal_uInt16 nPrefix2 = GetImport().GetNamespaceMap().
     497           0 :                         _GetKeyByAttrName( rValue, &sTmp, sal_False );
     498           0 :                 sFormula = XML_NAMESPACE_OOOW == nPrefix2 ? sTmp : rValue;
     499             :             }
     500           0 :             break;
     501             :         case XML_TOK_TABLE_VALUE:
     502             :             {
     503             :                 double fTmp;
     504           0 :                 if (::sax::Converter::convertDouble(fTmp, rValue))
     505             :                 {
     506           0 :                     fValue = fTmp;
     507           0 :                     bHasValue = sal_True;
     508             :                 }
     509             :             }
     510           0 :             break;
     511             :         case XML_TOK_TABLE_TIME_VALUE:
     512             :             {
     513             :                 double fTmp;
     514           0 :                 if (::sax::Converter::convertDuration(fTmp, rValue))
     515             :                 {
     516           0 :                     fValue = fTmp;
     517           0 :                     bHasValue = sal_True;
     518             :                 }
     519             :             }
     520           0 :             break;
     521             :         case XML_TOK_TABLE_DATE_VALUE:
     522             :             {
     523             :                 double fTmp;
     524           0 :                 if (GetImport().GetMM100UnitConverter().convertDateTime(fTmp,
     525             :                                                                       rValue))
     526             :                 {
     527           0 :                     fValue = fTmp;
     528           0 :                     bHasValue = sal_True;
     529             :                 }
     530             :             }
     531           0 :             break;
     532             :         case XML_TOK_TABLE_BOOLEAN_VALUE:
     533             :             {
     534           0 :                 bool bTmp(false);
     535           0 :                 if (::sax::Converter::convertBool(bTmp, rValue))
     536             :                 {
     537           0 :                     fValue = (bTmp ? 1.0 : 0.0);
     538           0 :                     bHasValue = sal_True;
     539             :                 }
     540             :             }
     541           0 :             break;
     542             :         case XML_TOK_TABLE_PROTECTED:
     543             :             {
     544           0 :                 bool bTmp(false);
     545           0 :                 if (::sax::Converter::convertBool(bTmp, rValue))
     546             :                 {
     547           0 :                     bProtect = bTmp;
     548             :                 }
     549             :             }
     550           0 :             break;
     551             :         case XML_TOK_TABLE_STRING_VALUE:
     552             :             {
     553           0 :                 bHasTextValue = sal_True;
     554             :             }
     555           0 :             break;
     556             :         }
     557         132 :     }
     558         115 : }
     559             : 
     560         230 : SwXMLTableCellContext_Impl::~SwXMLTableCellContext_Impl()
     561             : {
     562         230 : }
     563             : 
     564         115 : inline void SwXMLTableCellContext_Impl::_InsertContent()
     565             : {
     566             :     GetTable()->InsertCell( aStyleName, nRowSpan, nColSpan,
     567             :                             GetTable()->InsertTableSection(),
     568             :                             mXmlId,
     569         115 :                             NULL, bProtect, &sFormula, bHasValue, fValue, bHasTextValue );
     570         115 : }
     571             : 
     572         115 : inline void SwXMLTableCellContext_Impl::InsertContent()
     573             : {
     574             :     OSL_ENSURE( !HasContent(), "content already there" );
     575         115 :     bHasTextContent = sal_True;
     576         115 :     _InsertContent();
     577         115 : }
     578             : 
     579         115 : inline void SwXMLTableCellContext_Impl::InsertContentIfNotThere()
     580             : {
     581         115 :     if( !HasContent() )
     582         115 :         InsertContent();
     583         115 : }
     584             : 
     585           0 : inline void SwXMLTableCellContext_Impl::InsertContent(
     586             :                                                 SwXMLTableContext *pTable )
     587             : {
     588           0 :     GetTable()->InsertCell( aStyleName, nRowSpan, nColSpan, 0, mXmlId, pTable, bProtect );
     589           0 :     bHasTableContent = sal_True;
     590           0 : }
     591             : 
     592         115 : SvXMLImportContext *SwXMLTableCellContext_Impl::CreateChildContext(
     593             :         sal_uInt16 nPrefix,
     594             :         const OUString& rLocalName,
     595             :         const Reference< xml::sax::XAttributeList > & xAttrList )
     596             : {
     597         115 :     SvXMLImportContext *pContext = 0;
     598             : 
     599         115 :     OUString sXmlId;
     600         115 :     sal_Bool bSubTable = sal_False;
     601         115 :     if( XML_NAMESPACE_TABLE == nPrefix &&
     602           0 :         IsXMLToken( rLocalName, XML_TABLE ) )
     603             :     {
     604           0 :         sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
     605           0 :         for( sal_Int16 i=0; i < nAttrCount; i++ )
     606             :         {
     607           0 :             const OUString& rAttrName = xAttrList->getNameByIndex( i );
     608             : 
     609           0 :             OUString aLocalName;
     610             :             sal_uInt16 nPrefix2 =
     611           0 :                 GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
     612           0 :                                                                 &aLocalName );
     613           0 :             if( XML_NAMESPACE_TABLE == nPrefix2 &&
     614           0 :                  IsXMLToken( aLocalName, XML_IS_SUB_TABLE ) &&
     615           0 :                  IsXMLToken( xAttrList->getValueByIndex( i ), XML_TRUE ) )
     616             :             {
     617           0 :                 bSubTable = sal_True;
     618             :             }
     619           0 :             else if ( (XML_NAMESPACE_XML == nPrefix2) &&
     620           0 :                      IsXMLToken( aLocalName, XML_ID ) )
     621             :             {
     622           0 :                 sXmlId = xAttrList->getValueByIndex( i );
     623             :             }
     624             : //FIXME: RDFa
     625           0 :         }
     626             :     }
     627             : 
     628         115 :     if( bSubTable )
     629             :     {
     630           0 :         if( !HasContent() )
     631             :         {
     632             :             SwXMLTableContext *pTblContext =
     633             :                 new SwXMLTableContext( GetSwImport(), nPrefix, rLocalName,
     634           0 :                                        xAttrList, GetTable(), sXmlId );
     635           0 :             pContext = pTblContext;
     636           0 :             if( GetTable()->IsValid() )
     637           0 :                 InsertContent( pTblContext );
     638             : 
     639           0 :             GetTable()->SetHasSubTables( sal_True );
     640             :         }
     641             :     }
     642             :     else
     643             :     {
     644         115 :         if( GetTable()->IsValid() )
     645         115 :             InsertContentIfNotThere();
     646         115 :         pContext = GetImport().GetTextImport()->CreateTextChildContext(
     647         115 :                         GetImport(), nPrefix, rLocalName, xAttrList,
     648         230 :                         XML_TEXT_TYPE_CELL  );
     649             :     }
     650             : 
     651         115 :     if( !pContext )
     652           0 :         pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
     653             : 
     654         115 :     return pContext;
     655             : }
     656             : 
     657         115 : void SwXMLTableCellContext_Impl::EndElement()
     658             : {
     659         115 :     if( GetTable()->IsValid() )
     660             :     {
     661         115 :         if( bHasTextContent )
     662             :         {
     663         115 :             GetImport().GetTextImport()->DeleteParagraph();
     664         115 :             if( nColRepeat > 1 && nColSpan == 1 )
     665             :             {
     666             :                 // The original text is invalid after deleting the last
     667             :                 // paragraph
     668             :                 Reference < XTextCursor > xSrcTxtCursor =
     669           0 :                     GetImport().GetTextImport()->GetText()->createTextCursor();
     670           0 :                 xSrcTxtCursor->gotoEnd( sal_True );
     671             : 
     672             :                 // Until we have an API for copying we have to use the core.
     673           0 :                 Reference<XUnoTunnel> xSrcCrsrTunnel( xSrcTxtCursor, UNO_QUERY);
     674             :                 OSL_ENSURE( xSrcCrsrTunnel.is(), "missing XUnoTunnel for Cursor" );
     675             :                 OTextCursorHelper *pSrcTxtCrsr = reinterpret_cast< OTextCursorHelper * >(
     676           0 :                         sal::static_int_cast< sal_IntPtr >( xSrcCrsrTunnel->getSomething( OTextCursorHelper::getUnoTunnelId() )));
     677             :                 OSL_ENSURE( pSrcTxtCrsr, "SwXTextCursor missing" );
     678           0 :                 SwDoc *pDoc = pSrcTxtCrsr->GetDoc();
     679           0 :                 const SwPaM *pSrcPaM = pSrcTxtCrsr->GetPaM();
     680             : 
     681           0 :                 while( nColRepeat > 1 && GetTable()->IsInsertCellPossible() )
     682             :                 {
     683           0 :                     _InsertContent();
     684             : 
     685             :                     Reference<XUnoTunnel> xDstCrsrTunnel(
     686           0 :                         GetImport().GetTextImport()->GetCursor(), UNO_QUERY);
     687             :                     OSL_ENSURE( xDstCrsrTunnel.is(),
     688             :                             "missing XUnoTunnel for Cursor" );
     689             :                     OTextCursorHelper *pDstTxtCrsr = reinterpret_cast< OTextCursorHelper * >(
     690           0 :                             sal::static_int_cast< sal_IntPtr >( xDstCrsrTunnel->getSomething( OTextCursorHelper::getUnoTunnelId() )) );
     691             :                     OSL_ENSURE( pDstTxtCrsr, "SwXTextCursor missing" );
     692           0 :                     SwPaM aSrcPaM( *pSrcPaM->GetPoint(),
     693           0 :                                    *pSrcPaM->GetMark() );
     694           0 :                     SwPosition aDstPos( *pDstTxtCrsr->GetPaM()->GetPoint() );
     695           0 :                     pDoc->CopyRange( aSrcPaM, aDstPos, false );
     696             : 
     697           0 :                     nColRepeat--;
     698           0 :                 }
     699             :             }
     700             :         }
     701           0 :         else if( !bHasTableContent )
     702             :         {
     703           0 :             InsertContent();
     704           0 :             if( nColRepeat > 1 && nColSpan == 1 )
     705             :             {
     706           0 :                 while( nColRepeat > 1 && GetTable()->IsInsertCellPossible() )
     707             :                 {
     708           0 :                     _InsertContent();
     709           0 :                     nColRepeat--;
     710             :                 }
     711             :             }
     712             :         }
     713             :     }
     714         115 :     GetImport().GetTextImport()->SetCellParaStyleDefault(sSaveParaDefault);
     715         115 : }
     716             : 
     717             : // ---------------------------------------------------------------------
     718             : 
     719             : class SwXMLTableColContext_Impl : public SvXMLImportContext
     720             : {
     721             :     SvXMLImportContextRef   xMyTable;
     722             : 
     723          10 :     SwXMLTableContext *GetTable() { return (SwXMLTableContext *)&xMyTable; }
     724             : 
     725             : public:
     726             : 
     727             :     SwXMLTableColContext_Impl(
     728             :             SwXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName,
     729             :             const Reference< xml::sax::XAttributeList > & xAttrList,
     730             :             SwXMLTableContext *pTable );
     731             : 
     732             :     virtual ~SwXMLTableColContext_Impl();
     733             : 
     734           1 :     SwXMLImport& GetSwImport() { return (SwXMLImport&)GetImport(); }
     735             : };
     736             : 
     737           1 : SwXMLTableColContext_Impl::SwXMLTableColContext_Impl(
     738             :         SwXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName,
     739             :         const Reference< xml::sax::XAttributeList > & xAttrList,
     740             :         SwXMLTableContext *pTable ) :
     741             :     SvXMLImportContext( rImport, nPrfx, rLName ),
     742           1 :     xMyTable( pTable )
     743             : {
     744           1 :     sal_uInt32 nColRep = 1UL;
     745           1 :     OUString aStyleName, aDfltCellStyleName;
     746             : 
     747           1 :     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
     748           3 :     for( sal_Int16 i=0; i < nAttrCount; i++ )
     749             :     {
     750           2 :         const OUString& rAttrName = xAttrList->getNameByIndex( i );
     751             : 
     752           2 :         OUString aLocalName;
     753             :         sal_uInt16 nPrefix =
     754           2 :             GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
     755           2 :                                                             &aLocalName );
     756           2 :         const OUString& rValue = xAttrList->getValueByIndex( i );
     757           2 :         if( XML_NAMESPACE_TABLE == nPrefix )
     758             :         {
     759           2 :             if( IsXMLToken( aLocalName, XML_STYLE_NAME ) )
     760           1 :                 aStyleName = rValue;
     761           1 :             else if( IsXMLToken( aLocalName, XML_NUMBER_COLUMNS_REPEATED ) )
     762           1 :                 nColRep = (sal_uInt32)rValue.toInt32();
     763           0 :             else if( IsXMLToken( aLocalName, XML_DEFAULT_CELL_STYLE_NAME ) )
     764           0 :                 aDfltCellStyleName = rValue;
     765             :         }
     766           0 :         else if ( (XML_NAMESPACE_XML == nPrefix) &&
     767           0 :                  IsXMLToken( aLocalName, XML_ID ) )
     768             :         {
     769             :             (void) rValue;
     770             : //FIXME where to put this??? columns do not actually exist in writer...
     771             :         }
     772           2 :     }
     773             : 
     774           1 :     sal_Int32 nWidth = MINLAY;
     775           1 :     sal_Bool bRelWidth = sal_True;
     776           1 :     if( !aStyleName.isEmpty() )
     777             :     {
     778             :         const SfxPoolItem *pItem;
     779           1 :         const SfxItemSet *pAutoItemSet = 0;
     780           3 :         if( GetSwImport().FindAutomaticStyle(
     781             :                     XML_STYLE_FAMILY_TABLE_COLUMN,
     782           1 :                                               aStyleName, &pAutoItemSet ) &&
     783             :             pAutoItemSet &&
     784             :             SFX_ITEM_SET == pAutoItemSet->GetItemState( RES_FRM_SIZE, sal_False,
     785           1 :                                                         &pItem ) )
     786             :         {
     787           1 :             const SwFmtFrmSize *pSize = ((const SwFmtFrmSize *)pItem);
     788           1 :             nWidth = pSize->GetWidth();
     789           1 :             bRelWidth = ATT_VAR_SIZE == pSize->GetHeightSizeType();
     790             :         }
     791             :     }
     792             : 
     793           1 :     if( nWidth )
     794             :     {
     795           7 :         while( nColRep-- && GetTable()->IsInsertColPossible() )
     796           5 :             GetTable()->InsertColumn( nWidth, bRelWidth, &aDfltCellStyleName );
     797           1 :     }
     798           1 : }
     799             : 
     800           2 : SwXMLTableColContext_Impl::~SwXMLTableColContext_Impl()
     801             : {
     802           2 : }
     803             : 
     804             : // ---------------------------------------------------------------------
     805             : 
     806             : class SwXMLTableColsContext_Impl : public SvXMLImportContext
     807             : {
     808             :     SvXMLImportContextRef   xMyTable;
     809             : 
     810           0 :     SwXMLTableContext *GetTable() { return (SwXMLTableContext *)&xMyTable; }
     811             : 
     812             : public:
     813             : 
     814             :     SwXMLTableColsContext_Impl(
     815             :             SwXMLImport& rImport, sal_uInt16 nPrfx,
     816             :             const OUString& rLName,
     817             :             const Reference< xml::sax::XAttributeList > & xAttrList,
     818             :             SwXMLTableContext *pTable );
     819             : 
     820             :     virtual ~SwXMLTableColsContext_Impl();
     821             : 
     822             :     virtual SvXMLImportContext *CreateChildContext(
     823             :             sal_uInt16 nPrefix, const OUString& rLocalName,
     824             :             const Reference< xml::sax::XAttributeList > & xAttrList );
     825             : 
     826           0 :     SwXMLImport& GetSwImport() { return (SwXMLImport&)GetImport(); }
     827             : };
     828             : 
     829           0 : SwXMLTableColsContext_Impl::SwXMLTableColsContext_Impl(
     830             :         SwXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName,
     831             :         const Reference< xml::sax::XAttributeList > &,
     832             :         SwXMLTableContext *pTable ) :
     833             :     SvXMLImportContext( rImport, nPrfx, rLName ),
     834           0 :     xMyTable( pTable )
     835             : {
     836           0 : }
     837             : 
     838           0 : SwXMLTableColsContext_Impl::~SwXMLTableColsContext_Impl()
     839             : {
     840           0 : }
     841             : 
     842           0 : SvXMLImportContext *SwXMLTableColsContext_Impl::CreateChildContext(
     843             :         sal_uInt16 nPrefix,
     844             :         const OUString& rLocalName,
     845             :         const Reference< xml::sax::XAttributeList > & xAttrList )
     846             : {
     847           0 :     SvXMLImportContext *pContext = 0;
     848             : 
     849           0 :     if( XML_NAMESPACE_TABLE == nPrefix &&
     850           0 :         IsXMLToken( rLocalName, XML_TABLE_COLUMN ) &&
     851           0 :         GetTable()->IsInsertColPossible() )
     852             :         pContext = new SwXMLTableColContext_Impl( GetSwImport(), nPrefix,
     853             :                                                   rLocalName, xAttrList,
     854           0 :                                                   GetTable() );
     855             : 
     856           0 :     if( !pContext )
     857           0 :         pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
     858             : 
     859           0 :     return pContext;
     860             : }
     861             : 
     862             : // ---------------------------------------------------------------------
     863             : 
     864             : class SwXMLTableRowContext_Impl : public SvXMLImportContext
     865             : {
     866             :     SvXMLImportContextRef   xMyTable;
     867             : 
     868             :     sal_uInt32                  nRowRepeat;
     869             : 
     870         437 :     SwXMLTableContext *GetTable() { return (SwXMLTableContext *)&xMyTable; }
     871             : 
     872             : public:
     873             : 
     874             :     SwXMLTableRowContext_Impl(
     875             :             SwXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName,
     876             :             const Reference< xml::sax::XAttributeList > & xAttrList,
     877             :             SwXMLTableContext *pTable, sal_Bool bInHead=sal_False );
     878             : 
     879             :     virtual ~SwXMLTableRowContext_Impl();
     880             : 
     881             :     virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
     882             :             const OUString& rLocalName,
     883             :             const Reference< xml::sax::XAttributeList > & xAttrList );
     884             : 
     885             :     virtual void EndElement();
     886             : 
     887         115 :     SwXMLImport& GetSwImport() { return (SwXMLImport&)GetImport(); }
     888             : };
     889             : 
     890          23 : SwXMLTableRowContext_Impl::SwXMLTableRowContext_Impl( SwXMLImport& rImport,
     891             :         sal_uInt16 nPrfx,
     892             :         const OUString& rLName,
     893             :         const Reference< xml::sax::XAttributeList > & xAttrList,
     894             :         SwXMLTableContext *pTable,
     895             :         sal_Bool bInHead ) :
     896             :     SvXMLImportContext( rImport, nPrfx, rLName ),
     897             :     xMyTable( pTable ),
     898          23 :     nRowRepeat( 1 )
     899             : {
     900          23 :     OUString aStyleName, aDfltCellStyleName;
     901          23 :     OUString sXmlId;
     902             : 
     903          23 :     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
     904          23 :     for( sal_Int16 i=0; i < nAttrCount; i++ )
     905             :     {
     906           0 :         const OUString& rAttrName = xAttrList->getNameByIndex( i );
     907             : 
     908           0 :         OUString aLocalName;
     909             :         sal_uInt16 nPrefix =
     910           0 :             GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
     911           0 :                                                             &aLocalName );
     912           0 :         const OUString& rValue = xAttrList->getValueByIndex( i );
     913           0 :         if( XML_NAMESPACE_TABLE == nPrefix )
     914             :         {
     915           0 :             if( IsXMLToken( aLocalName, XML_STYLE_NAME ) )
     916             :             {
     917           0 :                 aStyleName = rValue;
     918             :             }
     919           0 :             else if( IsXMLToken( aLocalName, XML_NUMBER_ROWS_REPEATED ) )
     920             :             {
     921           0 :                 nRowRepeat = (sal_uInt32)rValue.toInt32();
     922           0 :                 if( nRowRepeat < 1UL )
     923           0 :                     nRowRepeat = 1UL;
     924             :             }
     925           0 :             else if( IsXMLToken( aLocalName, XML_DEFAULT_CELL_STYLE_NAME ) )
     926             :             {
     927           0 :                 aDfltCellStyleName = rValue;
     928             :             }
     929             :         }
     930           0 :         else if ( (XML_NAMESPACE_XML == nPrefix) &&
     931           0 :                  IsXMLToken( aLocalName, XML_ID ) )
     932             :         {
     933           0 :             sXmlId = rValue;
     934             :         }
     935           0 :     }
     936          23 :     if( GetTable()->IsValid() )
     937             :         GetTable()->InsertRow( aStyleName, aDfltCellStyleName, bInHead,
     938          23 :                                sXmlId );
     939          23 : }
     940             : 
     941          23 : void SwXMLTableRowContext_Impl::EndElement()
     942             : {
     943          23 :     if( GetTable()->IsValid() )
     944             :     {
     945          23 :         GetTable()->FinishRow();
     946             : 
     947          23 :         if( nRowRepeat > 1UL )
     948           0 :             GetTable()->InsertRepRows( nRowRepeat );
     949             :     }
     950          23 : }
     951             : 
     952          46 : SwXMLTableRowContext_Impl::~SwXMLTableRowContext_Impl()
     953             : {
     954          46 : }
     955             : 
     956         115 : SvXMLImportContext *SwXMLTableRowContext_Impl::CreateChildContext(
     957             :         sal_uInt16 nPrefix, const OUString& rLocalName,
     958             :         const Reference< xml::sax::XAttributeList > & xAttrList )
     959             : {
     960         115 :     SvXMLImportContext *pContext = 0;
     961             : 
     962         115 :     if( XML_NAMESPACE_TABLE == nPrefix )
     963             :     {
     964         115 :         if( IsXMLToken( rLocalName, XML_TABLE_CELL ) )
     965             :         {
     966         115 :             if( !GetTable()->IsValid() || GetTable()->IsInsertCellPossible() )
     967             :                 pContext = new SwXMLTableCellContext_Impl( GetSwImport(),
     968             :                                                            nPrefix,
     969             :                                                            rLocalName,
     970             :                                                            xAttrList,
     971         115 :                                                            GetTable() );
     972             :         }
     973           0 :         else if( IsXMLToken( rLocalName, XML_COVERED_TABLE_CELL ) )
     974           0 :             pContext = new SvXMLImportContext( GetImport(), nPrefix,
     975           0 :                                                rLocalName );
     976             :     }
     977             : 
     978         115 :     if( !pContext )
     979           0 :         pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
     980             : 
     981         115 :     return pContext;
     982             : }
     983             : 
     984             : // ---------------------------------------------------------------------
     985             : 
     986             : class SwXMLTableRowsContext_Impl : public SvXMLImportContext
     987             : {
     988             :     SvXMLImportContextRef   xMyTable;
     989             : 
     990             :     sal_Bool bHeader;
     991             : 
     992           0 :     SwXMLTableContext *GetTable() { return (SwXMLTableContext *)&xMyTable; }
     993             : 
     994             : public:
     995             : 
     996             :     SwXMLTableRowsContext_Impl( SwXMLImport& rImport, sal_uInt16 nPrfx,
     997             :             const OUString& rLName,
     998             :             const Reference< xml::sax::XAttributeList > & xAttrList,
     999             :             SwXMLTableContext *pTable,
    1000             :             sal_Bool bHead );
    1001             : 
    1002             :     virtual ~SwXMLTableRowsContext_Impl();
    1003             : 
    1004             :     virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
    1005             :             const OUString& rLocalName,
    1006             :             const Reference< xml::sax::XAttributeList > & xAttrList );
    1007             : 
    1008           0 :     SwXMLImport& GetSwImport() { return (SwXMLImport&)GetImport(); }
    1009             : };
    1010             : 
    1011           0 : SwXMLTableRowsContext_Impl::SwXMLTableRowsContext_Impl( SwXMLImport& rImport,
    1012             :         sal_uInt16 nPrfx,
    1013             :         const OUString& rLName,
    1014             :         const Reference< xml::sax::XAttributeList > &,
    1015             :         SwXMLTableContext *pTable,
    1016             :         sal_Bool bHead ) :
    1017             :     SvXMLImportContext( rImport, nPrfx, rLName ),
    1018             :     xMyTable( pTable ),
    1019           0 :     bHeader( bHead )
    1020             : {
    1021           0 : }
    1022             : 
    1023           0 : SwXMLTableRowsContext_Impl::~SwXMLTableRowsContext_Impl()
    1024             : {
    1025           0 : }
    1026             : 
    1027           0 : SvXMLImportContext *SwXMLTableRowsContext_Impl::CreateChildContext(
    1028             :         sal_uInt16 nPrefix,
    1029             :         const OUString& rLocalName,
    1030             :         const Reference< xml::sax::XAttributeList > & xAttrList )
    1031             : {
    1032           0 :     SvXMLImportContext *pContext = 0;
    1033             : 
    1034           0 :     if( XML_NAMESPACE_TABLE == nPrefix &&
    1035           0 :         IsXMLToken( rLocalName, XML_TABLE_ROW ) &&
    1036           0 :         GetTable()->IsInsertRowPossible() )
    1037             :         pContext = new SwXMLTableRowContext_Impl( GetSwImport(), nPrefix,
    1038             :                                                   rLocalName, xAttrList,
    1039             :                                                   GetTable(),
    1040           0 :                                                   bHeader );
    1041             : 
    1042           0 :     if( !pContext )
    1043           0 :         pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
    1044             : 
    1045           0 :     return pContext;
    1046             : }
    1047             : 
    1048             : // ---------------------------------------------------------------------
    1049             : 
    1050             : class SwXMLDDETableContext_Impl : public SvXMLImportContext
    1051             : {
    1052             :     OUString sConnectionName;
    1053             :     OUString sDDEApplication;
    1054             :     OUString sDDEItem;
    1055             :     OUString sDDETopic;
    1056             :     sal_Bool bIsAutomaticUpdate;
    1057             : 
    1058             : public:
    1059             : 
    1060             :     TYPEINFO();
    1061             : 
    1062             :     SwXMLDDETableContext_Impl(
    1063             :         SwXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName);
    1064             : 
    1065             :     ~SwXMLDDETableContext_Impl();
    1066             : 
    1067             :     virtual void StartElement(
    1068             :         const Reference<xml::sax::XAttributeList> & xAttrList);
    1069             : 
    1070           0 :     OUString& GetConnectionName()   { return sConnectionName; }
    1071           0 :     OUString& GetDDEApplication()   { return sDDEApplication; }
    1072           0 :     OUString& GetDDEItem()          { return sDDEItem; }
    1073           0 :     OUString& GetDDETopic()         { return sDDETopic; }
    1074           0 :     sal_Bool GetIsAutomaticUpdate() { return bIsAutomaticUpdate; }
    1075             : };
    1076             : 
    1077           0 : TYPEINIT1( SwXMLDDETableContext_Impl, SvXMLImportContext );
    1078             : 
    1079           0 : SwXMLDDETableContext_Impl::SwXMLDDETableContext_Impl(
    1080             :     SwXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName) :
    1081             :         SvXMLImportContext(rImport, nPrfx, rLName),
    1082             :         sConnectionName(),
    1083             :         sDDEApplication(),
    1084             :         sDDEItem(),
    1085             :         sDDETopic(),
    1086           0 :         bIsAutomaticUpdate(sal_False)
    1087             : {
    1088           0 : }
    1089             : 
    1090           0 : SwXMLDDETableContext_Impl::~SwXMLDDETableContext_Impl()
    1091             : {
    1092           0 : }
    1093             : 
    1094           0 : void SwXMLDDETableContext_Impl::StartElement(
    1095             :     const Reference<xml::sax::XAttributeList> & xAttrList)
    1096             : {
    1097           0 :     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
    1098           0 :     for( sal_Int16 i = 0; i < nAttrCount; i++ )
    1099             :     {
    1100           0 :         const OUString& rAttrName = xAttrList->getNameByIndex( i );
    1101             : 
    1102           0 :         OUString aLocalName;
    1103             :         sal_uInt16 nPrefix =
    1104           0 :             GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
    1105           0 :                                                             &aLocalName );
    1106           0 :         const OUString& rValue = xAttrList->getValueByIndex( i );
    1107             : 
    1108           0 :         if (XML_NAMESPACE_OFFICE == nPrefix)
    1109             :         {
    1110           0 :             if ( IsXMLToken( aLocalName, XML_DDE_APPLICATION ) )
    1111             :             {
    1112           0 :                 sDDEApplication = rValue;
    1113             :             }
    1114           0 :             else if ( IsXMLToken( aLocalName, XML_DDE_TOPIC ) )
    1115             :             {
    1116           0 :                 sDDETopic = rValue;
    1117             :             }
    1118           0 :             else if ( IsXMLToken( aLocalName, XML_DDE_ITEM ) )
    1119             :             {
    1120           0 :                 sDDEItem = rValue;
    1121             :             }
    1122           0 :             else if ( IsXMLToken( aLocalName, XML_NAME ) )
    1123             :             {
    1124           0 :                 sConnectionName = rValue;
    1125             :             }
    1126           0 :             else if ( IsXMLToken( aLocalName, XML_AUTOMATIC_UPDATE ) )
    1127             :             {
    1128           0 :                 bool bTmp(false);
    1129           0 :                 if (::sax::Converter::convertBool(bTmp, rValue))
    1130             :                 {
    1131           0 :                     bIsAutomaticUpdate = bTmp;
    1132             :                 }
    1133             :             }
    1134             :             // else: unknown attribute
    1135             :         }
    1136             :         // else: unknown attribute namespace
    1137           0 :     }
    1138           0 : }
    1139             : 
    1140             : // generate a new name for DDE field type (called by lcl_GetDDEFieldType below)
    1141           0 : static String lcl_GenerateFldTypeName(OUString sPrefix, SwTableNode* pTableNode)
    1142             : {
    1143           0 :     String sPrefixStr(sPrefix);
    1144             : 
    1145           0 :     if (sPrefixStr.Len() == 0)
    1146             :     {
    1147           0 :         sPrefixStr = rtl::OUString('_');
    1148             :     }
    1149             : 
    1150             :     // increase count until we find a name that is not yet taken
    1151           0 :     String sName;
    1152           0 :     sal_Int32 nCount = 0;
    1153           0 :     do
    1154             :     {
    1155             :         // this is crazy, but just in case all names are taken: exit gracefully
    1156           0 :         if (nCount < 0)
    1157             :             return sName;
    1158             : 
    1159           0 :         nCount++;
    1160           0 :         sName = sPrefixStr;
    1161           0 :         sName += String::CreateFromInt32(nCount);
    1162             : 
    1163             :     }
    1164           0 :     while (NULL != pTableNode->GetDoc()->GetFldType(RES_DDEFLD, sName, false));
    1165             : 
    1166           0 :     return sName;
    1167             : }
    1168             : 
    1169             : // set table properties
    1170           0 : static SwDDEFieldType* lcl_GetDDEFieldType(SwXMLDDETableContext_Impl* pContext,
    1171             :                                     SwTableNode* pTableNode)
    1172             : {
    1173             :     // make command string
    1174           0 :     String sCommand(pContext->GetDDEApplication());
    1175           0 :     sCommand += sfx2::cTokenSeperator;
    1176           0 :     sCommand += String(pContext->GetDDEItem());
    1177           0 :     sCommand += sfx2::cTokenSeperator;
    1178           0 :     sCommand += String(pContext->GetDDETopic());
    1179             : 
    1180           0 :     sal_uInt16 nType = static_cast< sal_uInt16 >(pContext->GetIsAutomaticUpdate() ? sfx2::LINKUPDATE_ALWAYS
    1181           0 :                                                         : sfx2::LINKUPDATE_ONCALL);
    1182             : 
    1183           0 :     String sName(pContext->GetConnectionName());
    1184             : 
    1185             :     // field type to be returned
    1186           0 :     SwDDEFieldType* pType = NULL;
    1187             : 
    1188             :     // valid name?
    1189           0 :     if (sName.Len() == 0)
    1190             :     {
    1191           0 :         sName = lcl_GenerateFldTypeName(pContext->GetDDEApplication(),
    1192           0 :                                         pTableNode);
    1193             :     }
    1194             :     else
    1195             :     {
    1196             :         // check for existing DDE field type with the same name
    1197           0 :         SwDDEFieldType* pOldType = (SwDDEFieldType*)pTableNode->GetDoc()->GetFldType(RES_DDEFLD, sName, false);
    1198           0 :         if (NULL != pOldType)
    1199             :         {
    1200             :             // same values -> return old type
    1201           0 :             if ( (pOldType->GetCmd() == sCommand) &&
    1202           0 :                  (pOldType->GetType() == nType) )
    1203             :             {
    1204             :                 // same name, same values -> return old type!
    1205           0 :                 pType = pOldType;
    1206             :             }
    1207             :             else
    1208             :             {
    1209             :                 // same name, different values -> think of new name
    1210           0 :                 sName = lcl_GenerateFldTypeName(pContext->GetDDEApplication(),
    1211           0 :                                                 pTableNode);
    1212             :             }
    1213             :         }
    1214             :         // no old type -> create new one
    1215             :     }
    1216             : 
    1217             :     // create new field type (unless we already have one)
    1218           0 :     if (NULL == pType)
    1219             :     {
    1220             :         // create new field type and return
    1221           0 :         SwDDEFieldType aDDEFieldType(sName, sCommand, nType);
    1222             :         pType = (SwDDEFieldType*)pTableNode->
    1223           0 :             GetDoc()->InsertFldType(aDDEFieldType);
    1224             :     }
    1225             : 
    1226             :     OSL_ENSURE(NULL != pType, "We really want a SwDDEFieldType here!");
    1227           0 :     return pType;
    1228             : }
    1229             : 
    1230             : 
    1231             : // ---------------------------------------------------------------------
    1232             : 
    1233         187 : class TableBoxIndex
    1234             : {
    1235             : public:
    1236             :     OUString msName;
    1237             :     sal_Int32 mnWidth;
    1238             :     sal_Bool mbProtected;
    1239             : 
    1240         115 :     TableBoxIndex( const OUString& rName, sal_Int32 nWidth,
    1241             :                    sal_Bool bProtected ) :
    1242             :         msName( rName ),
    1243             :         mnWidth( nWidth ),
    1244         115 :         mbProtected( bProtected )
    1245         115 :     { }
    1246             : 
    1247          97 :     bool operator== ( const TableBoxIndex& rArg ) const
    1248             :     {
    1249             :         return (rArg.mnWidth == mnWidth) &&
    1250             :             (rArg.mbProtected == mbProtected) &&
    1251          97 :             (rArg.msName == msName);
    1252             :     }
    1253             : };
    1254             : 
    1255             : class TableBoxIndexHasher
    1256             : {
    1257             : public:
    1258         132 :     size_t operator() (const TableBoxIndex& rArg) const
    1259             :     {
    1260         132 :         return rArg.msName.hashCode() + rArg.mnWidth + rArg.mbProtected;
    1261             :     }
    1262             : };
    1263             : 
    1264             : 
    1265             : 
    1266             : 
    1267             : typedef boost::ptr_vector<SwXMLTableRow_Impl> SwXMLTableRows_Impl;
    1268             : 
    1269           0 : const SwXMLTableCell_Impl *SwXMLTableContext::GetCell( sal_uInt32 nRow,
    1270             :                                                  sal_uInt32 nCol ) const
    1271             : {
    1272           0 :     return (*pRows)[(sal_uInt16)nRow].GetCell( (sal_uInt16)nCol );
    1273             : }
    1274             : 
    1275         460 : SwXMLTableCell_Impl *SwXMLTableContext::GetCell( sal_uInt32 nRow,
    1276             :                                                  sal_uInt32 nCol )
    1277             : {
    1278         460 :     return (*pRows)[(sal_uInt16)nRow].GetCell( (sal_uInt16)nCol );
    1279             : }
    1280             : 
    1281           0 : TYPEINIT1( SwXMLTableContext, XMLTextTableContext );
    1282             : 
    1283           1 : SwXMLTableContext::SwXMLTableContext( SwXMLImport& rImport,
    1284             :         sal_uInt16 nPrfx,
    1285             :         const OUString& rLName,
    1286             :         const Reference< xml::sax::XAttributeList > & xAttrList ) :
    1287             :     XMLTextTableContext( rImport, nPrfx, rLName ),
    1288             :     pColumnDefaultCellStyleNames( 0 ),
    1289           1 :     pRows( new SwXMLTableRows_Impl ),
    1290             :     pTableNode( 0 ),
    1291             :     pBox1( 0 ),
    1292             :     pSttNd1( 0 ),
    1293             :     pBoxFmt( 0 ),
    1294             :     pLineFmt( 0 ),
    1295             :     pSharedBoxFormats(NULL),
    1296             :     pDDESource(NULL),
    1297             :     bFirstSection( sal_True ),
    1298             :     bRelWidth( sal_True ),
    1299             :     bHasSubTables( sal_False ),
    1300             :     nHeaderRows( 0 ),
    1301             :     nCurRow( 0UL ),
    1302             :     nCurCol( 0UL ),
    1303           2 :     nWidth( 0UL )
    1304             : {
    1305           1 :     OUString aName;
    1306           1 :     OUString sXmlId;
    1307             : 
    1308             :     // this method will modify the document directly -> lock SolarMutex
    1309           1 :     SolarMutexGuard aGuard;
    1310             : 
    1311           1 :     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
    1312           3 :     for( sal_Int16 i=0; i < nAttrCount; i++ )
    1313             :     {
    1314           2 :         const OUString& rAttrName = xAttrList->getNameByIndex( i );
    1315             : 
    1316           2 :         OUString aLocalName;
    1317             :         sal_uInt16 nPrefix =
    1318           2 :             GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
    1319           2 :                                                             &aLocalName );
    1320           2 :         const OUString& rValue = xAttrList->getValueByIndex( i );
    1321           2 :         if( XML_NAMESPACE_TABLE == nPrefix )
    1322             :         {
    1323           2 :             if( IsXMLToken( aLocalName, XML_STYLE_NAME ) )
    1324           1 :                 aStyleName = rValue;
    1325           1 :             else if( IsXMLToken( aLocalName, XML_NAME ) )
    1326           1 :                 aName = rValue;
    1327           0 :             else if( IsXMLToken( aLocalName, XML_DEFAULT_CELL_STYLE_NAME ) )
    1328           0 :                 aDfltCellStyleName = rValue;
    1329             :         }
    1330           0 :         else if ( (XML_NAMESPACE_XML == nPrefix) &&
    1331           0 :                  IsXMLToken( aLocalName, XML_ID ) )
    1332             :         {
    1333           0 :             sXmlId = rValue;
    1334             :         }
    1335           2 :     }
    1336             : 
    1337           1 :     SwDoc *pDoc = SwImport::GetDocFromXMLImport( GetSwImport() );
    1338             : 
    1339           1 :     String sTblName;
    1340           1 :     if( !aName.isEmpty() )
    1341             :     {
    1342           1 :         const SwTableFmt *pTblFmt = pDoc->FindTblFmtByName( aName );
    1343           1 :         if( !pTblFmt )
    1344           1 :             sTblName = aName;
    1345             :     }
    1346           1 :     if( !sTblName.Len() )
    1347             :     {
    1348           0 :         sTblName = pDoc->GetUniqueTblName();
    1349           0 :         GetImport().GetTextImport()
    1350           0 :             ->GetRenameMap().Add( XML_TEXT_RENAME_TYPE_TABLE, aName, sTblName );
    1351             :     }
    1352             : 
    1353           1 :     Reference< XTextTable > xTable;
    1354           1 :     const SwXTextTable *pXTable = 0;
    1355           1 :     Reference<XMultiServiceFactory> xFactory( GetImport().GetModel(),
    1356           1 :                                               UNO_QUERY );
    1357             :     OSL_ENSURE( xFactory.is(), "factory missing" );
    1358           1 :     if( xFactory.is() )
    1359             :     {
    1360             :         OUString sService(
    1361           1 :                 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.TextTable" ) );
    1362           1 :         Reference<XInterface> xIfc = xFactory->createInstance( sService );
    1363             :         OSL_ENSURE( xIfc.is(), "Couldn't create a table" );
    1364             : 
    1365           1 :         if( xIfc.is() )
    1366           1 :             xTable = Reference< XTextTable > ( xIfc, UNO_QUERY );
    1367             :     }
    1368             : 
    1369           1 :     if( xTable.is() )
    1370             :     {
    1371           1 :         xTable->initialize( 1, 1 );
    1372             : 
    1373             :         try
    1374             :         {
    1375           1 :             xTextContent = Reference< XTextContent >( xTable, UNO_QUERY );
    1376           1 :             GetImport().GetTextImport()->InsertTextContent( xTextContent );
    1377             :         }
    1378           0 :         catch( IllegalArgumentException& )
    1379             :         {
    1380           0 :             xTable = 0;
    1381             :         }
    1382             :     }
    1383             : 
    1384           1 :     if( xTable.is() )
    1385             :     {
    1386             : //FIXME
    1387             :         // xml:id for RDF metadata
    1388           1 :         GetImport().SetXmlId(xTable, sXmlId);
    1389             : 
    1390           1 :         Reference<XUnoTunnel> xTableTunnel( xTable, UNO_QUERY);
    1391           1 :         if( xTableTunnel.is() )
    1392             :         {
    1393             :             pXTable = reinterpret_cast< SwXTextTable * >(
    1394           1 :                     sal::static_int_cast< sal_IntPtr >( xTableTunnel->getSomething( SwXTextTable::getUnoTunnelId() )));
    1395             :             OSL_ENSURE( pXTable, "SwXTextTable missing" );
    1396             :         }
    1397             : 
    1398           1 :         Reference < XCellRange > xCellRange( xTable, UNO_QUERY );
    1399           1 :         Reference < XCell > xCell = xCellRange->getCellByPosition( 0, 0 );
    1400           1 :         Reference < XText> xText( xCell, UNO_QUERY );
    1401           1 :         xOldCursor = GetImport().GetTextImport()->GetCursor();
    1402           1 :         GetImport().GetTextImport()->SetCursor( xText->createTextCursor() );
    1403             : 
    1404             :         // take care of open redlines for tables
    1405           1 :         GetImport().GetTextImport()->RedlineAdjustStartNodeCursor(sal_True);
    1406             :     }
    1407           1 :     if( pXTable )
    1408             :     {
    1409           1 :         SwFrmFmt *pTblFrmFmt = pXTable->GetFrmFmt();
    1410             :         OSL_ENSURE( pTblFrmFmt, "table format missing" );
    1411           1 :         SwTable *pTbl = SwTable::FindTable( pTblFrmFmt );
    1412             :         OSL_ENSURE( pTbl, "table missing" );
    1413           1 :         pTableNode = pTbl->GetTableNode();
    1414             :         OSL_ENSURE( pTableNode, "table node missing" );
    1415             : 
    1416           1 :         pTblFrmFmt->SetName( sTblName );
    1417             : 
    1418           1 :         SwTableLine *pLine1 = pTableNode->GetTable().GetTabLines()[0U];
    1419           1 :         pBox1 = pLine1->GetTabBoxes()[0U];
    1420           1 :         pSttNd1 = pBox1->GetSttNd();
    1421           1 :     }
    1422           1 : }
    1423             : 
    1424           0 : SwXMLTableContext::SwXMLTableContext( SwXMLImport& rImport,
    1425             :         sal_uInt16 nPrfx,
    1426             :         const OUString& rLName,
    1427             :         const Reference< xml::sax::XAttributeList > &,
    1428             :         SwXMLTableContext *pTable,
    1429             :         OUString const & i_rXmlId ) :
    1430             :     XMLTextTableContext( rImport, nPrfx, rLName ),
    1431             :     mXmlId( i_rXmlId ),
    1432             :     pColumnDefaultCellStyleNames( 0 ),
    1433           0 :     pRows( new SwXMLTableRows_Impl ),
    1434             :     pTableNode( pTable->pTableNode ),
    1435             :     pBox1( 0 ),
    1436             :     pSttNd1( 0 ),
    1437             :     pBoxFmt( 0 ),
    1438             :     pLineFmt( 0 ),
    1439             :     pSharedBoxFormats(NULL),
    1440             :     xParentTable( pTable ),
    1441             :     pDDESource(NULL),
    1442             :     bFirstSection( sal_False ),
    1443             :     bRelWidth( sal_True ),
    1444             :     bHasSubTables( sal_False ),
    1445             :     nHeaderRows( 0 ),
    1446             :     nCurRow( 0UL ),
    1447             :     nCurCol( 0UL ),
    1448           0 :     nWidth( 0UL )
    1449             : {
    1450           0 : }
    1451             : 
    1452           3 : SwXMLTableContext::~SwXMLTableContext()
    1453             : {
    1454           1 :     delete pColumnDefaultCellStyleNames;
    1455           1 :     delete pSharedBoxFormats;
    1456           1 :     delete pRows;
    1457             : 
    1458             :     // close redlines on table end nodes
    1459           1 :     GetImport().GetTextImport()->RedlineAdjustStartNodeCursor(sal_False);
    1460           2 : }
    1461             : 
    1462          24 : SvXMLImportContext *SwXMLTableContext::CreateChildContext( sal_uInt16 nPrefix,
    1463             :         const OUString& rLocalName,
    1464             :         const Reference< xml::sax::XAttributeList > & xAttrList )
    1465             : {
    1466          24 :     SvXMLImportContext *pContext = 0;
    1467             : 
    1468          24 :     const SvXMLTokenMap& rTokenMap = GetSwImport().GetTableElemTokenMap();
    1469          24 :     sal_Bool bHeader = sal_False;
    1470          24 :     switch( rTokenMap.Get( nPrefix, rLocalName ) )
    1471             :     {
    1472             :     case XML_TOK_TABLE_HEADER_COLS:
    1473             :     case XML_TOK_TABLE_COLS:
    1474           0 :         if( IsValid() )
    1475             :             pContext = new SwXMLTableColsContext_Impl( GetSwImport(), nPrefix,
    1476             :                                                        rLocalName, xAttrList,
    1477           0 :                                                        this );
    1478           0 :         break;
    1479             :     case XML_TOK_TABLE_COL:
    1480           1 :         if( IsValid() && IsInsertColPossible() )
    1481             :             pContext = new SwXMLTableColContext_Impl( GetSwImport(), nPrefix,
    1482             :                                                       rLocalName, xAttrList,
    1483           1 :                                                       this );
    1484           1 :         break;
    1485             :     case XML_TOK_TABLE_HEADER_ROWS:
    1486           0 :         bHeader = sal_True;
    1487             :     case XML_TOK_TABLE_ROWS:
    1488             :         pContext = new SwXMLTableRowsContext_Impl( GetSwImport(), nPrefix,
    1489             :                                                    rLocalName, xAttrList,
    1490           0 :                                                    this, bHeader );
    1491           0 :         break;
    1492             :     case XML_TOK_TABLE_ROW:
    1493          23 :         if( IsInsertRowPossible() )
    1494             :             pContext = new SwXMLTableRowContext_Impl( GetSwImport(), nPrefix,
    1495             :                                                       rLocalName, xAttrList,
    1496          23 :                                                       this );
    1497          23 :         break;
    1498             :     case XML_TOK_OFFICE_DDE_SOURCE:
    1499             :         // save context for later processing (discard old context, if approp.)
    1500           0 :         if( IsValid() )
    1501             :         {
    1502           0 :             if (pDDESource != NULL)
    1503             :             {
    1504           0 :                 pDDESource->ReleaseRef();
    1505             :             }
    1506             :             pDDESource = new SwXMLDDETableContext_Impl( GetSwImport(), nPrefix,
    1507           0 :                                                         rLocalName );
    1508           0 :             pDDESource->AddRef();
    1509           0 :             pContext = pDDESource;
    1510             :         }
    1511           0 :         break;
    1512             :     }
    1513             : 
    1514          24 :     if( !pContext )
    1515           0 :         pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
    1516             : 
    1517          24 :     return pContext;
    1518             : }
    1519             : 
    1520           5 : void SwXMLTableContext::InsertColumn( sal_Int32 nWidth2, sal_Bool bRelWidth2,
    1521             :                                          const OUString *pDfltCellStyleName )
    1522             : {
    1523             :     OSL_ENSURE( nCurCol < USHRT_MAX,
    1524             :             "SwXMLTableContext::InsertColumn: no space left" );
    1525           5 :     if( nCurCol >= USHRT_MAX )
    1526           5 :         return;
    1527             : 
    1528           5 :     if( nWidth2 < MINLAY )
    1529           0 :         nWidth2 = MINLAY;
    1530           5 :     else if( nWidth2 > USHRT_MAX )
    1531           0 :         nWidth2 = USHRT_MAX;
    1532           5 :     aColumnWidths.push_back( ColumnWidthInfo(nWidth2, bRelWidth2) );
    1533           5 :     if( (pDfltCellStyleName && !pDfltCellStyleName->isEmpty()) ||
    1534             :         pColumnDefaultCellStyleNames )
    1535             :     {
    1536           0 :         if( !pColumnDefaultCellStyleNames )
    1537             :         {
    1538           0 :             pColumnDefaultCellStyleNames = new std::vector<String>;
    1539           0 :             sal_uLong nCount = aColumnWidths.size() - 1;
    1540           0 :             while( nCount-- )
    1541           0 :                 pColumnDefaultCellStyleNames->push_back(String());
    1542             :         }
    1543             : 
    1544           0 :         if(pDfltCellStyleName)
    1545           0 :             pColumnDefaultCellStyleNames->push_back(*pDfltCellStyleName);
    1546             :         else
    1547           0 :             pColumnDefaultCellStyleNames->push_back(String());
    1548             :     }
    1549             : }
    1550             : 
    1551         115 : sal_Int32 SwXMLTableContext::GetColumnWidth( sal_uInt32 nCol,
    1552             :                                              sal_uInt32 nColSpan ) const
    1553             : {
    1554         115 :     sal_uInt32 nLast = nCol+nColSpan;
    1555         115 :     if( nLast > aColumnWidths.size() )
    1556           0 :         nLast = aColumnWidths.size();
    1557             : 
    1558         115 :     sal_Int32 nWidth2 = 0L;
    1559         230 :     for( sal_uInt32 i=nCol; i < nLast; ++i )
    1560         115 :         nWidth2 += aColumnWidths[i].width;
    1561             : 
    1562         115 :     return nWidth2;
    1563             : }
    1564             : 
    1565           0 : OUString SwXMLTableContext::GetColumnDefaultCellStyleName( sal_uInt32 nCol ) const
    1566             : {
    1567           0 :     if( pColumnDefaultCellStyleNames && nCol < pColumnDefaultCellStyleNames->size())
    1568           0 :         return (*pColumnDefaultCellStyleNames)[static_cast<size_t>(nCol)];
    1569             : 
    1570           0 :     return OUString();
    1571             : }
    1572             : 
    1573         115 : void SwXMLTableContext::InsertCell( const OUString& rStyleName,
    1574             :                                     sal_uInt32 nRowSpan, sal_uInt32 nColSpan,
    1575             :                                     const SwStartNode *pStartNode,
    1576             :                                     const OUString & i_rXmlId,
    1577             :                                     SwXMLTableContext *pTable,
    1578             :                                     sal_Bool bProtect,
    1579             :                                     const OUString* pFormula,
    1580             :                                     sal_Bool bHasValue,
    1581             :                                     double fValue,
    1582             :                                     sal_Bool bTextValue )
    1583             : {
    1584             :     OSL_ENSURE( nCurCol < GetColumnCount(),
    1585             :             "SwXMLTableContext::InsertCell: row is full" );
    1586             :     OSL_ENSURE( nCurRow < USHRT_MAX,
    1587             :             "SwXMLTableContext::InsertCell: table is full" );
    1588         115 :     if( nCurCol >= USHRT_MAX || nCurRow > USHRT_MAX )
    1589         115 :         return;
    1590             : 
    1591             :     OSL_ENSURE( nRowSpan >=1UL, "SwXMLTableContext::InsertCell: row span is 0" );
    1592         115 :     if( 0UL == nRowSpan )
    1593           0 :         nRowSpan = 1UL;
    1594             :     OSL_ENSURE( nColSpan >=1UL, "SwXMLTableContext::InsertCell: col span is 0" );
    1595         115 :     if( 0UL == nColSpan )
    1596           0 :         nColSpan = 1UL;
    1597             : 
    1598             :     sal_uInt32 i, j;
    1599             : 
    1600             :     // Until it is possible to add columns here, fix the column span.
    1601         115 :     sal_uInt32 nColsReq = nCurCol + nColSpan;
    1602         115 :     if( nColsReq > GetColumnCount() )
    1603             :     {
    1604           0 :         nColSpan = GetColumnCount() - nCurCol;
    1605           0 :         nColsReq = GetColumnCount();
    1606             :     }
    1607             : 
    1608             :     // Check whether there are cells from a previous line already that reach
    1609             :     // into the current row.
    1610         115 :     if( nCurRow > 0UL && nColSpan > 1UL )
    1611             :     {
    1612           0 :         SwXMLTableRow_Impl *pCurRow = &(*pRows)[(sal_uInt16)nCurRow];
    1613           0 :         sal_uInt32 nLastCol = GetColumnCount() < nColsReq ? GetColumnCount()
    1614           0 :                                                      : nColsReq;
    1615           0 :         for( i=nCurCol+1UL; i<nLastCol; i++ )
    1616             :         {
    1617           0 :             if( pCurRow->GetCell(i)->IsUsed() )
    1618             :             {
    1619             :                 // If this cell is used, the column span is truncated
    1620           0 :                 nColSpan = i - nCurCol;
    1621           0 :                 nColsReq = i;
    1622           0 :                 break;
    1623             :             }
    1624             :         }
    1625             :     }
    1626             : 
    1627         115 :     sal_uInt32 nRowsReq = nCurRow + nRowSpan;
    1628         115 :     if( nRowsReq > USHRT_MAX )
    1629             :     {
    1630           0 :         nRowSpan = USHRT_MAX - nCurRow;
    1631           0 :         nRowsReq = USHRT_MAX;
    1632             :     }
    1633             : 
    1634             :     // Add columns (if # required columns greater than # columns):
    1635             :     // This should never happen, since we require column definitions!
    1636         115 :     if ( nColsReq > GetColumnCount() )
    1637             :     {
    1638           0 :         for( i=GetColumnCount(); i<nColsReq; i++ )
    1639             :         {
    1640           0 :             aColumnWidths.push_back( ColumnWidthInfo(MINLAY, sal_True) );
    1641             :         }
    1642             :         // adjust columns in *all* rows, if columns must be inserted
    1643           0 :         for( i=0; i<pRows->size(); i++ )
    1644           0 :             (*pRows)[(sal_uInt16)i].Expand( nColsReq, i<nCurRow );
    1645             :     }
    1646             : 
    1647             :     // Add rows
    1648         115 :     if( pRows->size() < nRowsReq )
    1649             :     {
    1650           0 :         OUString aStyleName2;
    1651           0 :         for( i = pRows->size(); i < nRowsReq; ++i )
    1652           0 :             pRows->push_back( new SwXMLTableRow_Impl(aStyleName2, GetColumnCount()) );
    1653             :     }
    1654             : 
    1655         115 :     OUString sStyleName( rStyleName );
    1656         115 :     if( sStyleName.isEmpty() )
    1657             :     {
    1658          98 :         sStyleName = (*pRows)[(sal_uInt16)nCurRow].GetDefaultCellStyleName();
    1659          98 :         if( sStyleName.isEmpty() && HasColumnDefaultCellStyleNames() )
    1660             :         {
    1661           0 :             sStyleName = GetColumnDefaultCellStyleName( nCurCol );
    1662           0 :             if( sStyleName.isEmpty() )
    1663           0 :                 sStyleName = aDfltCellStyleName;
    1664             :         }
    1665             :     }
    1666             : 
    1667             :     // Fill the cells
    1668         230 :     for( i=nColSpan; i>0UL; i-- )
    1669             :     {
    1670         230 :         for( j=nRowSpan; j>0UL; j-- )
    1671             :         {
    1672         115 :             const bool bCovered = i != nColSpan || j != nRowSpan;
    1673             :             GetCell( nRowsReq-j, nColsReq-i )
    1674             :                 ->Set( sStyleName, j, i, pStartNode,
    1675             :                        pTable, bProtect, pFormula, bHasValue, bCovered, fValue,
    1676         115 :                        bTextValue, i_rXmlId );
    1677             :         }
    1678             :     }
    1679             : 
    1680             :     // Set current col to the next (free) column
    1681         115 :     nCurCol = nColsReq;
    1682         230 :     while( nCurCol<GetColumnCount() && GetCell(nCurRow,nCurCol)->IsUsed() )
    1683         115 :         nCurCol++;
    1684             : }
    1685             : 
    1686          23 : void SwXMLTableContext::InsertRow( const OUString& rStyleName,
    1687             :                                    const OUString& rDfltCellStyleName,
    1688             :                                    bool bInHead,
    1689             :                                    const OUString & i_rXmlId )
    1690             : {
    1691             :     OSL_ENSURE( nCurRow < USHRT_MAX,
    1692             :             "SwXMLTableContext::InsertRow: no space left" );
    1693          23 :     if( nCurRow >= USHRT_MAX )
    1694          23 :         return;
    1695             : 
    1696             :     // Make sure there is at least one column.
    1697          23 :     if( 0==nCurRow && 0UL == GetColumnCount()  )
    1698           0 :         InsertColumn( USHRT_MAX, sal_True );
    1699             : 
    1700          23 :     if( nCurRow < pRows->size() )
    1701             :     {
    1702             :         // The current row has already been inserted because of a row span
    1703             :         // of a previous row.
    1704           0 :         (*pRows)[(sal_uInt16)nCurRow].Set(
    1705           0 :             rStyleName, rDfltCellStyleName, i_rXmlId );
    1706             :     }
    1707             :     else
    1708             :     {
    1709             :         // add a new row
    1710             :         pRows->push_back( new SwXMLTableRow_Impl( rStyleName, GetColumnCount(),
    1711          23 :                                                &rDfltCellStyleName, i_rXmlId ) );
    1712             :     }
    1713             : 
    1714             :     // We start at the first column ...
    1715          23 :     nCurCol=0UL;
    1716             : 
    1717             :     // ... but this cell may be occupied already.
    1718          46 :     while( nCurCol<GetColumnCount() && GetCell(nCurRow,nCurCol)->IsUsed() )
    1719           0 :         nCurCol++;
    1720             : 
    1721          23 :     if( bInHead  &&  nHeaderRows == nCurRow )
    1722           0 :         nHeaderRows++;
    1723             : }
    1724             : 
    1725           0 : void SwXMLTableContext::InsertRepRows( sal_uInt32 nCount )
    1726             : {
    1727           0 :     const SwXMLTableRow_Impl *pSrcRow = &(*pRows)[(sal_uInt16)nCurRow-1];
    1728           0 :     while( nCount > 1 && IsInsertRowPossible() )
    1729             :     {
    1730           0 :         InsertRow( pSrcRow->GetStyleName(), pSrcRow->GetDefaultCellStyleName(),
    1731           0 :                    false );
    1732           0 :         while( nCurCol < GetColumnCount() )
    1733             :         {
    1734           0 :             if( !GetCell(nCurRow,nCurCol)->IsUsed() )
    1735             :             {
    1736             :                 const SwXMLTableCell_Impl *pSrcCell =
    1737           0 :                     GetCell( nCurRow-1, nCurCol );
    1738           0 :                 InsertCell( pSrcCell->GetStyleName(), 1U,
    1739             :                             pSrcCell->GetColSpan(),
    1740             :                             InsertTableSection(),
    1741             :                             OUString(),
    1742           0 :                             0, pSrcCell->IsProtected(),
    1743           0 :                             &pSrcCell->GetFormula(),
    1744           0 :                             pSrcCell->HasValue(), pSrcCell->GetValue(),
    1745           0 :                             pSrcCell->HasTextValue() );
    1746             :             }
    1747             :         }
    1748           0 :         FinishRow();
    1749           0 :         nCount--;
    1750             :     }
    1751           0 : }
    1752             : 
    1753          23 : void SwXMLTableContext::FinishRow()
    1754             : {
    1755             :     // Insert an empty cell at the end of the line if the row is not complete
    1756          23 :     if( nCurCol < GetColumnCount() )
    1757             :     {
    1758           0 :         OUString aStyleName2;
    1759           0 :         InsertCell( aStyleName2, 1U, GetColumnCount() - nCurCol,
    1760           0 :                     InsertTableSection() );
    1761             :     }
    1762             : 
    1763             :     // Move to the next row.
    1764          23 :     nCurRow++;
    1765          23 : }
    1766             : 
    1767           0 : const SwStartNode *SwXMLTableContext::GetPrevStartNode( sal_uInt32 nRow,
    1768             :                                                         sal_uInt32 nCol ) const
    1769             : {
    1770           0 :     const SwXMLTableCell_Impl *pPrevCell = 0;
    1771           0 :     if( GetColumnCount() == nCol )
    1772             :     {
    1773             :         // The last cell is the right one here.
    1774           0 :         pPrevCell = GetCell( pRows->size()-1U, GetColumnCount()-1UL );
    1775             :     }
    1776           0 :     else if( 0UL == nRow )
    1777             :     {
    1778             :         // There are no vertically merged cells within the first row, so the
    1779             :         // previous cell is the right one always.
    1780           0 :         if( nCol > 0UL )
    1781           0 :             pPrevCell = GetCell( nRow, nCol-1UL );
    1782             :     }
    1783             :     else
    1784             :     {
    1785             :         // If there is a previous cell in the current row that is not spanned
    1786             :         // from the previous row, its the right one.
    1787           0 :         const SwXMLTableRow_Impl *pPrevRow = &(*pRows)[(sal_uInt16)nRow-1U];
    1788           0 :         sal_uInt32 i = nCol;
    1789           0 :         while( !pPrevCell &&  i > 0UL )
    1790             :         {
    1791           0 :             i--;
    1792           0 :             if( 1UL == pPrevRow->GetCell( i )->GetRowSpan() )
    1793           0 :                 pPrevCell = GetCell( nRow, i );
    1794             :         }
    1795             : 
    1796             :         // Otherwise, the last cell from the previous row is the right one.
    1797           0 :         if( !pPrevCell )
    1798           0 :             pPrevCell = pPrevRow->GetCell( GetColumnCount()-1UL );
    1799             :     }
    1800             : 
    1801           0 :     const SwStartNode *pSttNd = 0;
    1802           0 :     if( pPrevCell )
    1803             :     {
    1804           0 :         if( pPrevCell->GetStartNode() )
    1805           0 :             pSttNd = pPrevCell->GetStartNode();
    1806             :         // #i95726# - Some fault tolerance
    1807             : //        else
    1808           0 :         else if ( pPrevCell->GetSubTable() )
    1809           0 :             pSttNd = pPrevCell->GetSubTable()->GetLastStartNode();
    1810             : 
    1811             :         OSL_ENSURE( pSttNd != 0,
    1812             :                 "table corrupt" );
    1813             :     }
    1814             : 
    1815           0 :     return pSttNd;
    1816             : }
    1817             : 
    1818           0 : void SwXMLTableContext::FixRowSpan( sal_uInt32 nRow, sal_uInt32 nCol,
    1819             :                                     sal_uInt32 nColSpan )
    1820             : {
    1821           0 :     sal_uInt32 nLastCol = nCol + nColSpan;
    1822           0 :     for( sal_uInt16 i = (sal_uInt16)nCol; i < nLastCol; i++ )
    1823             :     {
    1824           0 :         sal_uInt32 j = nRow;
    1825           0 :         sal_uInt32 nRowSpan = 1UL;
    1826           0 :         SwXMLTableCell_Impl *pCell = GetCell( j, i );
    1827           0 :         while( pCell && pCell->GetRowSpan() > 1UL )
    1828             :         {
    1829           0 :             pCell->SetRowSpan( nRowSpan++ );
    1830           0 :             pCell = j > 0UL ? GetCell( --j, i ) : 0;
    1831             :         }
    1832             :     }
    1833           0 : }
    1834             : 
    1835           0 : void SwXMLTableContext::ReplaceWithEmptyCell( sal_uInt32 nRow, sal_uInt32 nCol, bool bRows )
    1836             : {
    1837           0 :     const SwStartNode *pPrevSttNd = GetPrevStartNode( nRow, nCol );
    1838           0 :     const SwStartNode *pSttNd = InsertTableSection( pPrevSttNd );
    1839             : 
    1840           0 :     const SwXMLTableCell_Impl *pCell = GetCell( nRow, nCol );
    1841           0 :     sal_uInt32 nLastRow = bRows ? nRow + pCell->GetRowSpan() : nRow + 1;
    1842           0 :     sal_uInt32 nLastCol = nCol + pCell->GetColSpan();
    1843             : 
    1844           0 :     for( sal_uInt32 i=nRow; i<nLastRow; i++ )
    1845             :     {
    1846           0 :         SwXMLTableRow_Impl *pRow = &(*pRows)[(sal_uInt16)i];
    1847           0 :         for( sal_uInt32 j=nCol; j<nLastCol; j++ )
    1848           0 :             pRow->GetCell( j )->SetStartNode( pSttNd );
    1849             :     }
    1850             : 
    1851           0 : }
    1852             : 
    1853         115 : SwTableBox *SwXMLTableContext::NewTableBox( const SwStartNode *pStNd,
    1854             :                                              SwTableLine *pUpper )
    1855             : {
    1856             :     // The topmost table is the only table that maintains the two members
    1857             :     // pBox1 and bFirstSection.
    1858         115 :     if( xParentTable.Is() )
    1859           0 :         return ((SwXMLTableContext *)&xParentTable)->NewTableBox( pStNd,
    1860           0 :                                                                   pUpper );
    1861             : 
    1862             :     SwTableBox *pBox;
    1863             : 
    1864         116 :     if( pBox1 &&
    1865           1 :         pBox1->GetSttNd() == pStNd )
    1866             :     {
    1867             :         // if the StartNode is equal to the StartNode of the initially
    1868             :         // created box, we use this box
    1869           1 :         pBox = pBox1;
    1870           1 :         pBox->SetUpper( pUpper );
    1871           1 :         pBox1 = 0;
    1872             :     }
    1873             :     else
    1874         114 :         pBox = new SwTableBox( pBoxFmt, *pStNd, pUpper );
    1875             : 
    1876         115 :     return pBox;
    1877             : }
    1878             : 
    1879         115 : SwTableBoxFmt* SwXMLTableContext::GetSharedBoxFormat(
    1880             :     SwTableBox* pBox,
    1881             :     const OUString& rStyleName,
    1882             :     sal_Int32 nColumnWidth,
    1883             :     sal_Bool bProtected,
    1884             :     sal_Bool bMayShare,
    1885             :     sal_Bool& bNew,
    1886             :     bool* pModifyLocked )
    1887             : {
    1888         115 :     if ( pSharedBoxFormats == NULL )
    1889           1 :         pSharedBoxFormats = new map_BoxFmt();
    1890             : 
    1891             :     SwTableBoxFmt* pBoxFmt2;
    1892             : 
    1893         115 :     TableBoxIndex aKey( rStyleName, nColumnWidth, bProtected );
    1894         115 :     map_BoxFmt::iterator aIter = pSharedBoxFormats->find( aKey );
    1895         115 :     if ( aIter == pSharedBoxFormats->end() )
    1896             :     {
    1897             :         // unknown format so far -> construct a new one
    1898             : 
    1899             :         // get the old format, and reset all attributes
    1900             :         // (but preserve FillOrder)
    1901          18 :         pBoxFmt2 = (SwTableBoxFmt*)pBox->ClaimFrmFmt();
    1902          18 :         SwFmtFillOrder aFillOrder( pBoxFmt2->GetFillOrder() );
    1903          18 :         pBoxFmt2->ResetAllFmtAttr(); // #i73790# - method renamed
    1904          18 :         pBoxFmt2->SetFmtAttr( aFillOrder );
    1905          18 :         bNew = sal_True;    // it's a new format now
    1906             : 
    1907             :         // share this format, if allowed
    1908          18 :         if ( bMayShare )
    1909          18 :             (*pSharedBoxFormats)[ aKey ] = pBoxFmt2;
    1910             :     }
    1911             :     else
    1912             :     {
    1913             :         // set the shared format
    1914          97 :         pBoxFmt2 = aIter->second;
    1915          97 :         pBox->ChgFrmFmt( pBoxFmt2 );
    1916          97 :         bNew = sal_False;   // copied from an existing format
    1917             : 
    1918             :         // claim it, if we are not allowed to share
    1919          97 :         if ( !bMayShare )
    1920           0 :             pBoxFmt2 = (SwTableBoxFmt*)pBox->ClaimFrmFmt();
    1921             :     }
    1922             : 
    1923             :     // lock format (if so desired)
    1924         115 :     if ( pModifyLocked != NULL )
    1925             :     {
    1926         115 :         (*pModifyLocked) = pBoxFmt2->IsModifyLocked();
    1927         115 :         pBoxFmt2->LockModify();
    1928             :     }
    1929             : 
    1930         115 :     return pBoxFmt2;
    1931             : }
    1932             : 
    1933           0 : SwTableBox *SwXMLTableContext::MakeTableBox( SwTableLine *pUpper,
    1934             :                                              sal_uInt32 nTopRow,
    1935             :                                              sal_uInt32 nLeftCol,
    1936             :                                              sal_uInt32 nBottomRow,
    1937             :                                              sal_uInt32 nRightCol )
    1938             : {
    1939             : //FIXME: here would be a great place to handle XmlId for cell
    1940           0 :     SwTableBox *pBox = new SwTableBox( pBoxFmt, 0, pUpper );
    1941             : 
    1942           0 :     sal_uInt32 nColSpan = nRightCol - nLeftCol;
    1943           0 :     sal_Int32 nColWidth = GetColumnWidth( nLeftCol, nColSpan );
    1944             : 
    1945             :     // TODO: Share formats!
    1946           0 :     SwFrmFmt *pFrmFmt = pBox->ClaimFrmFmt();
    1947           0 :     SwFmtFillOrder aFillOrder( pFrmFmt->GetFillOrder() );
    1948           0 :     pFrmFmt->ResetAllFmtAttr(); // #i73790# - method renamed
    1949           0 :     pFrmFmt->SetFmtAttr( aFillOrder );
    1950             : 
    1951           0 :     pFrmFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, nColWidth ) );
    1952             : 
    1953           0 :     SwTableLines& rLines = pBox->GetTabLines();
    1954           0 :     sal_Bool bSplitted = sal_False;
    1955             : 
    1956           0 :     while( !bSplitted )
    1957             :     {
    1958           0 :         sal_uInt32 nStartRow = nTopRow;
    1959             :         sal_uInt32 i;
    1960             : 
    1961           0 :         for( i = nTopRow; i < nBottomRow; i++ )
    1962             :         {
    1963             :             // Could the table be splitted behind the current row?
    1964           0 :             sal_Bool bSplit = sal_True;
    1965           0 :             SwXMLTableRow_Impl *pRow = &(*pRows)[(sal_uInt16)i];
    1966           0 :             for( sal_uInt32 j=nLeftCol; j<nRightCol; j++ )
    1967             :             {
    1968           0 :                 bSplit = ( 1UL == pRow->GetCell(j)->GetRowSpan() );
    1969           0 :                 if( !bSplit )
    1970           0 :                     break;
    1971             :             }
    1972           0 :             if( bSplit && (nStartRow>nTopRow || i+1UL<nBottomRow) )
    1973             :             {
    1974             :                 SwTableLine *pLine =
    1975             :                     MakeTableLine( pBox, nStartRow, nLeftCol, i+1UL,
    1976           0 :                                    nRightCol );
    1977             : 
    1978           0 :                 rLines.push_back( pLine );
    1979             : 
    1980           0 :                 nStartRow = i+1UL;
    1981           0 :                 bSplitted = sal_True;
    1982             :             }
    1983             :         }
    1984           0 :         if( !bSplitted )
    1985             :         {
    1986             :             // No splitting was possible. That for, we have to force it.
    1987             :             // Ruthless!
    1988             : 
    1989           0 :             nStartRow = nTopRow;
    1990           0 :             while( nStartRow < nBottomRow )
    1991             :             {
    1992           0 :                 sal_uInt32 nMaxRowSpan = 0UL;
    1993           0 :                 SwXMLTableRow_Impl *pStartRow = &(*pRows)[(sal_uInt16)nStartRow];
    1994             :                 const SwXMLTableCell_Impl *pCell;
    1995           0 :                 for( i=nLeftCol; i<nRightCol; i++ )
    1996           0 :                     if( ( pCell=pStartRow->GetCell(i),
    1997           0 :                           pCell->GetRowSpan() > nMaxRowSpan ) )
    1998           0 :                         nMaxRowSpan = pCell->GetRowSpan();
    1999             : 
    2000           0 :                 nStartRow += nMaxRowSpan;
    2001           0 :                 if( nStartRow<nBottomRow )
    2002             :                 {
    2003             :                     SwXMLTableRow_Impl *pPrevRow =
    2004           0 :                                         &(*pRows)[(sal_uInt16)nStartRow-1U];
    2005           0 :                     i = nLeftCol;
    2006           0 :                     while( i < nRightCol )
    2007             :                     {
    2008           0 :                         if( pPrevRow->GetCell(i)->GetRowSpan() > 1UL )
    2009             :                         {
    2010             :                             const SwXMLTableCell_Impl *pCell2 =
    2011           0 :                                 GetCell( nStartRow, i );
    2012           0 :                             const sal_uInt32 nColSpan2 = pCell2->GetColSpan();
    2013           0 :                             FixRowSpan( nStartRow-1UL, i, nColSpan2 );
    2014           0 :                             ReplaceWithEmptyCell( nStartRow, i, true );
    2015           0 :                             i += nColSpan2;
    2016             :                         }
    2017             :                         else
    2018             :                         {
    2019           0 :                             i++;
    2020             :                         }
    2021             :                     }
    2022             :                 }
    2023             :             }
    2024             :             // und jetzt nochmal von vorne ...
    2025             :         }
    2026             :     }
    2027             : 
    2028           0 :     return pBox;
    2029             : }
    2030             : 
    2031         115 : SwTableBox *SwXMLTableContext::MakeTableBox(
    2032             :         SwTableLine *pUpper, const SwXMLTableCell_Impl *pCell,
    2033             :         sal_uInt32 /*nTopRow*/, sal_uInt32 nLeftCol, sal_uInt32 /*nBottomRow*/,
    2034             :         sal_uInt32 nRightCol )
    2035             : {
    2036             : //FIXME: here would be a great place to handle XmlId for cell
    2037             :     SwTableBox *pBox;
    2038         115 :     sal_uInt32 nColSpan = nRightCol - nLeftCol;
    2039         115 :     sal_Int32 nColWidth = GetColumnWidth( nLeftCol, nColSpan );
    2040             : 
    2041         115 :     if( pCell->GetStartNode() )
    2042             :     {
    2043         115 :         pBox = NewTableBox( pCell->GetStartNode(), pUpper );
    2044             :     }
    2045             :     else
    2046             :     {
    2047             :         // and it is a table: therefore we build a new box and
    2048             :         // put the rows of the table into the rows of the box
    2049           0 :         pBox = new SwTableBox( pBoxFmt, 0, pUpper );
    2050           0 :         pCell->GetSubTable()->MakeTable( pBox, nColWidth );
    2051             :     }
    2052             : 
    2053             :     // Share formats!
    2054         115 :     OUString sStyleName = pCell->GetStyleName();
    2055             :     bool bModifyLocked;
    2056             :     sal_Bool bNew;
    2057             :     SwTableBoxFmt *pBoxFmt2 = GetSharedBoxFormat(
    2058         115 :         pBox, sStyleName, nColWidth, pCell->IsProtected(),
    2059         230 :         pCell->GetStartNode() && pCell->GetFormula().isEmpty() &&
    2060         115 :             ! pCell->HasValue(),
    2061         460 :         bNew, &bModifyLocked  );
    2062             : 
    2063             :     // if a new format was created, then we need to set the style
    2064         115 :     if ( bNew )
    2065             :     {
    2066             :         // set style
    2067          18 :         const SfxItemSet *pAutoItemSet = 0;
    2068          35 :         if( pCell->GetStartNode() && !sStyleName.isEmpty() &&
    2069          17 :             GetSwImport().FindAutomaticStyle(
    2070          17 :                 XML_STYLE_FAMILY_TABLE_CELL, sStyleName, &pAutoItemSet ) )
    2071             :         {
    2072          17 :             if( pAutoItemSet )
    2073          17 :                 pBoxFmt2->SetFmtAttr( *pAutoItemSet );
    2074             :         }
    2075             :     }
    2076             : 
    2077         115 :     if( pCell->GetStartNode() )
    2078             :     {
    2079             : 
    2080             :         // try to rescue broken documents with a certain pattern
    2081             :         // if: 1) the cell has a default number format (number 0)
    2082             :         //     2) the call has no formula
    2083             :         //     3) the value is 0.0
    2084             :         //     4) the text doesn't look anything like 0.0
    2085             :         //        [read: length > 10, or length smaller 10 and no 0 in it]
    2086             :         // then make it a text cell!
    2087         115 :         bool bSuppressNumericContent = false;
    2088         115 :         if( pCell->HasValue() && (pCell->GetValue() == 0.0) &&
    2089           0 :             pCell->GetFormula().isEmpty() &&
    2090           0 :             !sStyleName.isEmpty() )
    2091             :         {
    2092             :             // default num format?
    2093           0 :             const SfxPoolItem* pItem = NULL;
    2094           0 :             if( pBoxFmt2->GetItemState( RES_BOXATR_FORMAT, sal_False, &pItem )
    2095             :                             == SFX_ITEM_SET )
    2096             :             {
    2097             :                 const SwTblBoxNumFormat* pNumFormat =
    2098           0 :                     static_cast<const SwTblBoxNumFormat*>( pItem );
    2099           0 :                 if( ( pNumFormat != NULL ) && ( pNumFormat->GetValue() == 0 ) )
    2100             :                 {
    2101             :                     // only one text node?
    2102           0 :                     SwNodeIndex aNodeIndex( *(pCell->GetStartNode()), 1 );
    2103           0 :                     if( ( aNodeIndex.GetNode().EndOfSectionIndex() -
    2104           0 :                           aNodeIndex.GetNode().StartOfSectionIndex() ) == 2 )
    2105             :                     {
    2106           0 :                         SwTxtNode* pTxtNode= aNodeIndex.GetNode().GetTxtNode();
    2107           0 :                         if( pTxtNode != NULL )
    2108             :                         {
    2109             :                             // check text: does it look like some form of 0.0?
    2110           0 :                             const String& rText = pTxtNode->GetTxt();
    2111           0 :                             if( ( rText.Len() > 10 ) ||
    2112           0 :                                 ( rText.Search( '0' ) == STRING_NOTFOUND ) )
    2113             :                             {
    2114           0 :                                 bSuppressNumericContent = true;
    2115             :                             }
    2116             :                         }
    2117             :                     }
    2118             :                     else
    2119           0 :                         bSuppressNumericContent = true; // several nodes
    2120             :                 }
    2121             :             }
    2122             :         }
    2123             : 
    2124         115 :         if( bSuppressNumericContent )
    2125             :         {
    2126             :             // suppress numeric content? Then reset number format!
    2127           0 :             pBoxFmt2->ResetFmtAttr( RES_BOXATR_FORMULA );
    2128           0 :             pBoxFmt2->ResetFmtAttr( RES_BOXATR_FORMAT );
    2129           0 :             pBoxFmt2->ResetFmtAttr( RES_BOXATR_VALUE );
    2130             :         }
    2131             :         else
    2132             :         {
    2133             :             // the normal case: set formula and value (if available)
    2134             : 
    2135         115 :             const OUString& rFormula = pCell->GetFormula();
    2136         115 :             if (!rFormula.isEmpty())
    2137             :             {
    2138             :                 // formula cell: insert formula if valid
    2139           0 :                 SwTblBoxFormula aFormulaItem( rFormula );
    2140           0 :                 pBoxFmt2->SetFmtAttr( aFormulaItem );
    2141             :             }
    2142         115 :             else if( !pCell->HasValue() && pCell->HasTextValue() )
    2143             :             {
    2144             :                 // Check for another inconsistency:
    2145             :                 // No value but a non-textual format, i.e. a number format
    2146             :                 // Solution: the number format will be removed,
    2147             :                 // the cell gets the default text format.
    2148           0 :                 const SfxPoolItem* pItem = NULL;
    2149           0 :                 if( pBoxFmt->GetItemState( RES_BOXATR_FORMAT, sal_False, &pItem )
    2150             :                     == SFX_ITEM_SET )
    2151             :                 {
    2152           0 :                     const SwDoc* pDoc = pBoxFmt->GetDoc();
    2153             :                     const SvNumberFormatter* pNumberFormatter = pDoc ?
    2154           0 :                         pDoc->GetNumberFormatter() : 0;
    2155             :                     const SwTblBoxNumFormat* pNumFormat =
    2156           0 :                         static_cast<const SwTblBoxNumFormat*>( pItem );
    2157           0 :                     if( pNumFormat != NULL && pNumberFormatter &&
    2158           0 :                         !pNumberFormatter->GetEntry( pNumFormat->GetValue() )->IsTextFormat() )
    2159           0 :                         pBoxFmt->ResetFmtAttr( RES_BOXATR_FORMAT );
    2160             :                 }
    2161             :             }
    2162             :             // always insert value, even if default
    2163         115 :             if( pCell->HasValue() )
    2164             :             {
    2165           0 :                 SwTblBoxValue aValueItem( pCell->GetValue() );
    2166           0 :                 pBoxFmt2->SetFmtAttr( aValueItem );
    2167             :             }
    2168             :         }
    2169             : 
    2170             :         // update cell content depend on the default language
    2171         115 :         pBox->ActualiseValueBox();
    2172             :     }
    2173             : 
    2174             :     // table cell protection
    2175         115 :     if( pCell->IsProtected() )
    2176             :     {
    2177           0 :         SvxProtectItem aProtectItem( RES_PROTECT );
    2178           0 :         aProtectItem.SetCntntProtect( sal_True );
    2179           0 :         pBoxFmt2->SetFmtAttr( aProtectItem );
    2180             :     }
    2181             : 
    2182             :     // restore old modify-lock state
    2183         115 :     if (! bModifyLocked)
    2184         115 :         pBoxFmt2->UnlockModify();
    2185             : 
    2186         115 :     pBoxFmt2->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, nColWidth ) );
    2187             : 
    2188         115 :     return pBox;
    2189             : }
    2190             : 
    2191          23 : SwTableLine *SwXMLTableContext::MakeTableLine( SwTableBox *pUpper,
    2192             :                                                sal_uInt32 nTopRow,
    2193             :                                                sal_uInt32 nLeftCol,
    2194             :                                                sal_uInt32 nBottomRow,
    2195             :                                                sal_uInt32 nRightCol )
    2196             : {
    2197             : //FIXME: here would be a great place to handle XmlId for row
    2198             :     SwTableLine *pLine;
    2199          23 :     if( !pUpper && 0UL==nTopRow )
    2200             :     {
    2201           1 :         pLine = pTableNode->GetTable().GetTabLines()[0U];
    2202             :     }
    2203             :     else
    2204             :     {
    2205          22 :         pLine = new SwTableLine( pLineFmt, 0, pUpper );
    2206             :     }
    2207             : 
    2208             :     // TODO: Share formats!
    2209          23 :     SwFrmFmt *pFrmFmt = pLine->ClaimFrmFmt();
    2210          23 :     SwFmtFillOrder aFillOrder( pFrmFmt->GetFillOrder() );
    2211          23 :     pFrmFmt->ResetAllFmtAttr(); // #i73790# - method renamed
    2212          23 :     pFrmFmt->SetFmtAttr( aFillOrder );
    2213             : 
    2214          23 :     const SfxItemSet *pAutoItemSet = 0;
    2215          23 :     const OUString& rStyleName = (*pRows)[(sal_uInt16)nTopRow].GetStyleName();
    2216          46 :     if( 1UL == (nBottomRow - nTopRow) &&
    2217          23 :         !rStyleName.isEmpty() &&
    2218           0 :         GetSwImport().FindAutomaticStyle(
    2219           0 :             XML_STYLE_FAMILY_TABLE_ROW, rStyleName, &pAutoItemSet ) )
    2220             :     {
    2221           0 :         if( pAutoItemSet )
    2222           0 :             pFrmFmt->SetFmtAttr( *pAutoItemSet );
    2223             :     }
    2224             : 
    2225          23 :     SwTableBoxes& rBoxes = pLine->GetTabBoxes();
    2226             : 
    2227          23 :     sal_uInt32 nStartCol = nLeftCol;
    2228         161 :     while( nStartCol < nRightCol )
    2229             :     {
    2230         230 :         for( sal_uInt32 nRow=nTopRow; nRow<nBottomRow; nRow++ )
    2231         115 :             (*pRows)[(sal_uInt16)nRow].SetSplitable( sal_True );
    2232             : 
    2233         115 :         sal_uInt32 nCol = nStartCol;
    2234         115 :         sal_uInt32 nSplitCol = nRightCol;
    2235         115 :         sal_Bool bSplitted = sal_False;
    2236         345 :         while( !bSplitted )
    2237             :         {
    2238             :             OSL_ENSURE( nCol < nRightCol, "Zu weit gelaufen" );
    2239             : 
    2240             :             // Can be split after current HTML table column?
    2241             :             // If yes, can the created region still be split to
    2242             :             // rows if the next column is added to it?
    2243         115 :             sal_Bool bSplit = sal_True;
    2244         115 :             sal_Bool bHoriSplitMayContinue = sal_False;
    2245         115 :             sal_Bool bHoriSplitPossible = sal_False;
    2246             : 
    2247         115 :             if ( bHasSubTables )
    2248             :             {
    2249             :                 // Convert row spans if the table has subtables:
    2250           0 :                 for( sal_uInt32 nRow=nTopRow; nRow<nBottomRow; nRow++ )
    2251             :                 {
    2252           0 :                     SwXMLTableCell_Impl *pCell = GetCell(nRow,nCol);
    2253             :                     // Could the table fragment be splitted horizontally behind
    2254             :                     // the current line?
    2255           0 :                     sal_Bool bHoriSplit = (*pRows)[(sal_uInt16)nRow].IsSplitable() &&
    2256             :                                       nRow+1UL < nBottomRow &&
    2257           0 :                                       1UL == pCell->GetRowSpan();
    2258           0 :                     (*pRows)[(sal_uInt16)nRow].SetSplitable( bHoriSplit );
    2259             : 
    2260             :                     // Could the table fragment be splitted vertically behind the
    2261             :                     // current column (uptp the current line?
    2262           0 :                     bSplit &= ( 1UL == pCell->GetColSpan() );
    2263           0 :                     if( bSplit )
    2264             :                     {
    2265           0 :                         bHoriSplitPossible |= bHoriSplit;
    2266             : 
    2267             :                         // Could the current table fragment be splitted
    2268             :                         // horizontally behind the next collumn, too?
    2269             :                         bHoriSplit &= (nCol+1UL < nRightCol &&
    2270           0 :                                        1UL == GetCell(nRow,nCol+1UL)->GetRowSpan());
    2271           0 :                         bHoriSplitMayContinue |= bHoriSplit;
    2272             :                     }
    2273             :                 }
    2274             :             }
    2275             :             else
    2276             :             {
    2277             :                 // No subtabels: We use the new table model.
    2278         115 :                 SwXMLTableCell_Impl *pCell = GetCell(nTopRow,nCol);
    2279             : 
    2280             :                 // #i95726# - some fault tolerance
    2281         115 :                 if ( pCell == 0 )
    2282             :                 {
    2283             :                     OSL_FAIL( "table seems to be corrupt." );
    2284           0 :                     break;
    2285             :                 }
    2286             : 
    2287             :                 // Could the table fragment be splitted vertically behind the
    2288             :                 // current column (uptp the current line?
    2289         115 :                 bSplit = 1UL == pCell->GetColSpan();
    2290             :             }
    2291             : 
    2292             : #if OSL_DEBUG_LEVEL > 0
    2293             :             if( nCol == nRightCol-1UL )
    2294             :             {
    2295             :                 OSL_ENSURE( bSplit, "Split-Flag falsch" );
    2296             :                 if ( bHasSubTables )
    2297             :                 {
    2298             :                     OSL_ENSURE( !bHoriSplitMayContinue,
    2299             :                             "HoriSplitMayContinue-Flag falsch" );
    2300             :                     SwXMLTableCell_Impl *pTmpCell = GetCell( nTopRow, nStartCol );
    2301             :                     OSL_ENSURE( pTmpCell->GetRowSpan() != (nBottomRow-nTopRow) ||
    2302             :                             !bHoriSplitPossible, "HoriSplitPossible-Flag falsch" );
    2303             :                 }
    2304             :             }
    2305             : #endif
    2306             : 
    2307             :             OSL_ENSURE( !bHasSubTables || !bHoriSplitMayContinue || bHoriSplitPossible,
    2308             :                     "bHoriSplitMayContinue, aber nicht bHoriSplitPossible" );
    2309             : 
    2310         115 :             if( bSplit )
    2311             :             {
    2312         115 :                 SwTableBox* pBox = 0;
    2313         115 :                 SwXMLTableCell_Impl *pCell = GetCell( nTopRow, nStartCol );
    2314             :                 // #i95726# - some fault tolerance
    2315         345 :                 if( ( !bHasSubTables || ( pCell->GetRowSpan() == (nBottomRow-nTopRow) ) ) &&
    2316         115 :                     pCell->GetColSpan() == (nCol+1UL-nStartCol) &&
    2317         115 :                     ( pCell->GetStartNode() || pCell->GetSubTable() ) )
    2318             :                 {
    2319             :                     // insert new empty cell for covered cells:
    2320         115 :                     long nBoxRowSpan = 1;
    2321         115 :                     if ( !bHasSubTables )
    2322             :                     {
    2323         115 :                         nBoxRowSpan = pCell->GetRowSpan();
    2324         115 :                         if ( pCell->IsCovered() )
    2325             :                         {
    2326           0 :                             nBoxRowSpan = -1 * nBoxRowSpan;
    2327           0 :                             ReplaceWithEmptyCell( nTopRow, nStartCol, false );
    2328             :                         }
    2329             :                     }
    2330             : 
    2331             :                     // The remaining box neither contains lines nor rows (i.e.
    2332             :                     // is a content box
    2333         115 :                     nSplitCol = nCol + 1UL;
    2334             : 
    2335             :                     pBox = MakeTableBox( pLine, pCell,
    2336             :                                          nTopRow, nStartCol,
    2337         115 :                                          nBottomRow, nSplitCol );
    2338             : 
    2339         115 :                     if ( 1 != nBoxRowSpan )
    2340           0 :                         pBox->setRowSpan( nBoxRowSpan );
    2341             : 
    2342         115 :                     bSplitted = sal_True;
    2343             :                 }
    2344           0 :                 else if( bHasSubTables && bHoriSplitPossible && bHoriSplitMayContinue )
    2345             :                 {
    2346             :                     // The table fragment could be splitted behind the current
    2347             :                     // column, and the remaining fragment could be divided
    2348             :                     // into lines. Anyway, it could be that this applies to
    2349             :                     // the next column, too. That for, we check the next
    2350             :                     // column but rememeber the current one as a good place to
    2351             :                     // split.
    2352           0 :                     nSplitCol = nCol + 1UL;
    2353             :                 }
    2354           0 :                 else if ( bHasSubTables )
    2355             :                 {
    2356             :                     // If the table resulting table fragment could be divided
    2357             :                     // into lines if spllitting behind the current column, but
    2358             :                     // this doesn't apply for thr next column, we split begind
    2359             :                     // the current column. This applies for the last column,
    2360             :                     // too.
    2361             :                     // If the resulting box cannot be splitted into rows,
    2362             :                     // the split at the last split position we remembered.
    2363           0 :                     if( bHoriSplitPossible || nSplitCol > nCol+1 )
    2364             :                     {
    2365             :                         OSL_ENSURE( !bHoriSplitMayContinue,
    2366             :                                 "bHoriSplitMayContinue==sal_True" );
    2367             :                         OSL_ENSURE( bHoriSplitPossible || nSplitCol == nRightCol,
    2368             :                                 "bHoriSplitPossible-Flag sollte gesetzt sein" );
    2369             : 
    2370           0 :                         nSplitCol = nCol + 1UL;
    2371             :                     }
    2372             : 
    2373             :                     pBox = MakeTableBox( pLine, nTopRow, nStartCol,
    2374           0 :                                          nBottomRow, nSplitCol );
    2375           0 :                     bSplitted = sal_True;
    2376             :                 }
    2377             : 
    2378             :                 OSL_ENSURE( bHasSubTables || pBox, "Colspan trouble" );
    2379             : 
    2380         115 :                 if( pBox )
    2381         115 :                     rBoxes.push_back( pBox );
    2382             :             }
    2383         115 :             nCol++;
    2384             :         }
    2385         115 :         nStartCol = nSplitCol;
    2386             :     }
    2387             : 
    2388          23 :     return pLine;
    2389             : }
    2390             : 
    2391           1 : void SwXMLTableContext::_MakeTable( SwTableBox *pBox )
    2392             : {
    2393             :     // fix column widths
    2394           1 :     std::vector<ColumnWidthInfo>::iterator colIter;
    2395           1 :     sal_uInt32 nCols = GetColumnCount();
    2396             : 
    2397             :     // If there are empty rows (because of some row span of previous rows)
    2398             :     // the have to be deleted. The previous rows have to be truncated.
    2399             : 
    2400           1 :     if( pRows->size() > nCurRow )
    2401             :     {
    2402           0 :         SwXMLTableRow_Impl *pPrevRow = &(*pRows)[(sal_uInt16)nCurRow-1U];
    2403             :         const SwXMLTableCell_Impl *pCell;
    2404           0 :         for( sal_uLong i = 0; i < aColumnWidths.size(); ++i )
    2405             :         {
    2406           0 :             if( ( pCell=pPrevRow->GetCell(i), pCell->GetRowSpan() > 1UL ) )
    2407             :             {
    2408           0 :                 FixRowSpan( nCurRow-1UL, i, 1UL );
    2409             :             }
    2410             :         }
    2411           0 :         for( sal_uLong i = pRows->size()-1UL; i>=nCurRow; --i )
    2412           0 :             pRows->pop_back();
    2413             :     }
    2414             : 
    2415           1 :     if( pRows->empty() )
    2416             :     {
    2417           0 :         OUString aStyleName2;
    2418           0 :         InsertCell( aStyleName2, 1U, nCols, InsertTableSection() );
    2419             :     }
    2420             : 
    2421             :     // TODO: Do we have to keep both values, the relative and the absolute
    2422             :     // width?
    2423           1 :     sal_Int32 nAbsWidth = 0L;
    2424           1 :     sal_Int32 nMinAbsColWidth = 0L;
    2425           1 :     sal_Int32 nRelWidth = 0L;
    2426           1 :     sal_Int32 nMinRelColWidth = 0L;
    2427           1 :     sal_uInt32 nRelCols = 0UL;
    2428           6 :     for( colIter = aColumnWidths.begin(); colIter < aColumnWidths.end(); ++colIter)
    2429             :     {
    2430           5 :         if( colIter->isRelative )
    2431             :         {
    2432           5 :             nRelWidth += colIter->width;
    2433           5 :             if( 0L == nMinRelColWidth || colIter->width < nMinRelColWidth )
    2434           1 :                 nMinRelColWidth = colIter->width;
    2435           5 :             nRelCols++;
    2436             :         }
    2437             :         else
    2438             :         {
    2439           0 :             nAbsWidth += colIter->width;
    2440           0 :             if( 0L == nMinAbsColWidth || colIter->width < nMinAbsColWidth )
    2441           0 :                 nMinAbsColWidth = colIter->width;
    2442             :         }
    2443             :     }
    2444           1 :     sal_uInt32 nAbsCols = nCols - nRelCols;
    2445             : 
    2446           1 :     if( bRelWidth )
    2447             :     {
    2448             :         // If there a columns that have an absolute width, we have to
    2449             :         // calculate a relative one for them.
    2450           1 :         if( nAbsCols > 0UL )
    2451             :         {
    2452             :             // All column that have absolute widths get relative widths;
    2453             :             // these widths relate to each over like the original absolute
    2454             :             // widths. The smallest column gets a width that hat the same
    2455             :             // value as the smallest column that has an relative width
    2456             :             // already.
    2457           0 :             if( 0L == nMinRelColWidth )
    2458           0 :                 nMinRelColWidth = nMinAbsColWidth;
    2459             : 
    2460           0 :             for( colIter = aColumnWidths.begin(); nAbsCols > 0UL && colIter < aColumnWidths.end(); ++colIter)
    2461             :             {
    2462           0 :                 if( !colIter->isRelative )
    2463             :                 {
    2464           0 :                     sal_Int32 nRelCol = ( colIter->width * nMinRelColWidth) / nMinAbsColWidth;
    2465           0 :                     colIter->width = nRelCol;
    2466           0 :                     colIter->isRelative = true;
    2467           0 :                     nRelWidth += nRelCol;
    2468           0 :                     nAbsCols--;
    2469             :                 }
    2470             :             }
    2471             :         }
    2472             : 
    2473           1 :         if( !nWidth )
    2474             :         {
    2475             :             // This happens only for percentage values for the table itself.
    2476             :             // In this case, the columns get the correct width even if the
    2477             :             // the sum of the relative withs is smaller than the available
    2478             :             // width in TWIP. Therfore, we can use the relative width.
    2479             :             //
    2480           0 :             nWidth = nRelWidth > USHRT_MAX ? USHRT_MAX : nRelWidth;
    2481             :         }
    2482           1 :         if( nRelWidth != nWidth && nRelWidth && nCols )
    2483             :         {
    2484           0 :             double n = (double)nWidth / (double)nRelWidth;
    2485           0 :             nRelWidth = 0L;
    2486           0 :             for( colIter = aColumnWidths.begin(); colIter < aColumnWidths.end() - 1; ++colIter)
    2487             :             {
    2488           0 :                 sal_Int32 nW = (sal_Int32)( colIter->width * n);
    2489           0 :                 colIter->width = (sal_uInt16)nW;
    2490           0 :                 nRelWidth += nW;
    2491             :             }
    2492           0 :             aColumnWidths.back().width = (nWidth-nRelWidth);
    2493             :         }
    2494             :     }
    2495             :     else
    2496             :     {
    2497             :         // If there are columns that have relative widths, we have to
    2498             :         // calculate a absolute widths for them.
    2499           0 :         if( nRelCols > 0UL )
    2500             :         {
    2501             :             // The absolute space that is available for all columns with a
    2502             :             // relative width.
    2503             :             sal_Int32 nAbsForRelWidth =
    2504           0 :                     nWidth > nAbsWidth ? nWidth - nAbsWidth : (sal_Int32)0L;
    2505             : 
    2506             :             // The relative width that has to be distributed in addition to
    2507             :             // equally widthed columns.
    2508           0 :             sal_Int32 nExtraRel = nRelWidth - (nRelCols * nMinRelColWidth);
    2509             : 
    2510             :             // The absolute space that may be distributed in addition to
    2511             :             // minumum widthed columns.
    2512           0 :             sal_Int32 nMinAbs = nRelCols * MINLAY;
    2513             :             sal_Int32 nExtraAbs =
    2514           0 :                     nAbsForRelWidth > nMinAbs ? nAbsForRelWidth - nMinAbs : (sal_Int32)0L;
    2515             : 
    2516           0 :             sal_Bool bMin = sal_False;      // Do all columns get the mininum width?
    2517           0 :             sal_Bool bMinExtra = sal_False; // Do all columns get the minimum width plus
    2518             :                                     // some extra space?
    2519             : 
    2520           0 :             if( nAbsForRelWidth <= nMinAbs )
    2521             :             {
    2522             :                 // If there is not enough space left for all columns to
    2523             :                 // get the minimum width, they get the minimum width, anyway.
    2524           0 :                 nAbsForRelWidth = nMinAbs;
    2525           0 :                 bMin = sal_True;
    2526             :             }
    2527           0 :             else if( nAbsForRelWidth <= (nRelWidth * MINLAY) /
    2528             :                                         nMinRelColWidth )
    2529             :             {
    2530             :                 // If there is enougth space for all columns to get the
    2531             :                 // minimum width, but not to get a width that takes the
    2532             :                 // relative width into account, each column gets the minimum
    2533             :                 // width plus some extra space that is based on the additional
    2534             :                 // space that is available.
    2535           0 :                 bMinExtra = sal_True;
    2536             :             }
    2537             :             // Otherwise, if there is enouth space for every column, every
    2538             :             // column gets this space.
    2539             : 
    2540           0 :             for( colIter = aColumnWidths.begin(); nRelCols > 0UL && colIter < aColumnWidths.end(); ++colIter )
    2541             :             {
    2542           0 :                 if( colIter->isRelative )
    2543             :                 {
    2544             :                     sal_Int32 nAbsCol;
    2545           0 :                     if( 1UL == nRelCols )
    2546             :                     {
    2547             :                         // The last column that has a relative width gets
    2548             :                         // all absolute space that is left.
    2549           0 :                         nAbsCol = nAbsForRelWidth;
    2550             :                     }
    2551             :                     else
    2552             :                     {
    2553           0 :                         if( bMin )
    2554             :                         {
    2555           0 :                             nAbsCol = MINLAY;
    2556             :                         }
    2557           0 :                         else if( bMinExtra )
    2558             :                         {
    2559           0 :                             sal_Int32 nExtraRelCol = colIter->width - nMinRelColWidth;
    2560             :                             nAbsCol = MINLAY + (nExtraRelCol * nExtraAbs) /
    2561           0 :                                                  nExtraRel;
    2562             :                         }
    2563             :                         else
    2564             :                         {
    2565           0 :                             nAbsCol = ( colIter->width * nAbsForRelWidth) / nRelWidth;
    2566             :                         }
    2567             :                     }
    2568           0 :                     colIter->width = nAbsCol;
    2569           0 :                     colIter->isRelative = false;
    2570           0 :                     nAbsForRelWidth -= nAbsCol;
    2571           0 :                     nAbsWidth += nAbsCol;
    2572           0 :                     nRelCols--;
    2573             :                 }
    2574             :             }
    2575             :         }
    2576             : 
    2577           0 :         if( nCols && nAbsWidth )
    2578             :         {
    2579           0 :             if( nAbsWidth < nWidth )
    2580             :             {
    2581             :                 // If the table's width is larger than the sum of the absolute
    2582             :                 // column widths, every column get some extra width.
    2583           0 :                 sal_Int32 nExtraAbs = nWidth - nAbsWidth;
    2584           0 :                 sal_Int32 nAbsLastCol = aColumnWidths.back().width + nExtraAbs;
    2585           0 :                 for( colIter = aColumnWidths.begin(); colIter < aColumnWidths.end()-1UL; ++colIter )
    2586             :                 {
    2587           0 :                     sal_Int32 nAbsCol = colIter->width;
    2588             :                     sal_Int32 nExtraAbsCol = (nAbsCol * nExtraAbs) /
    2589           0 :                                              nAbsWidth;
    2590           0 :                     nAbsCol += nExtraAbsCol;
    2591           0 :                     colIter->width = nAbsCol;
    2592           0 :                     nAbsLastCol -= nExtraAbsCol;
    2593             :                 }
    2594           0 :                 aColumnWidths.back().width = nAbsLastCol;
    2595             :             }
    2596           0 :             else if( nAbsWidth > nWidth )
    2597             :             {
    2598             :                 // If the table's width is smaller than the sum of the absolute
    2599             :                 // column widths, every column needs to shrink.
    2600             :                 // Every column gets the minimum width plus some extra width.
    2601           0 :                 sal_Int32 nExtraAbs = nWidth - (nCols * MINLAY);
    2602           0 :                 sal_Int32 nAbsLastCol = MINLAY + nExtraAbs;
    2603           0 :                 for( colIter = aColumnWidths.begin(); colIter < aColumnWidths.end()-1UL; ++colIter )
    2604             :                 {
    2605           0 :                     sal_Int32 nAbsCol = colIter->width;
    2606             :                     sal_Int32 nExtraAbsCol = (nAbsCol * nExtraAbs) /
    2607           0 :                                              nAbsWidth;
    2608           0 :                     nAbsCol = MINLAY + nExtraAbsCol;
    2609           0 :                     colIter->width = nAbsCol;
    2610           0 :                     nAbsLastCol -= nExtraAbsCol;
    2611             :                 }
    2612           0 :                 aColumnWidths.back().width = nAbsLastCol;
    2613             :             }
    2614             :         }
    2615             :     }
    2616             : 
    2617             :     SwTableLines& rLines =
    2618             :         pBox ? pBox->GetTabLines()
    2619           1 :              : pTableNode->GetTable().GetTabLines();
    2620             : 
    2621           1 :     sal_uInt32 nStartRow = 0UL;
    2622           1 :     sal_uInt32 nRows = pRows->size();
    2623          24 :     for(sal_uInt32 i=0UL; i<nRows; ++i )
    2624             :     {
    2625             :         // Could we split the table behind the current line?
    2626          23 :         sal_Bool bSplit = sal_True;
    2627          23 :         if ( bHasSubTables )
    2628             :         {
    2629           0 :             SwXMLTableRow_Impl *pRow = &(*pRows)[(sal_uInt16)i];
    2630           0 :             for( sal_uInt32 j=0UL; j<nCols; j++ )
    2631             :             {
    2632           0 :                 bSplit = ( 1UL == pRow->GetCell(j)->GetRowSpan() );
    2633           0 :                 if( !bSplit )
    2634           0 :                     break;
    2635             :             }
    2636             :         }
    2637             : 
    2638          23 :         if( bSplit )
    2639             :         {
    2640             :             SwTableLine *pLine =
    2641          23 :                 MakeTableLine( pBox, nStartRow, 0UL, i+1UL, nCols );
    2642          23 :             if( pBox || nStartRow>0UL )
    2643          22 :                 rLines.push_back( pLine );
    2644          23 :             nStartRow = i+1UL;
    2645             :         }
    2646             :     }
    2647           1 : }
    2648             : 
    2649           1 : void SwXMLTableContext::MakeTable()
    2650             : {
    2651             :     // this method will modify the document directly -> lock SolarMutex
    2652             :     // This will call all other MakeTable*(..) methods, so
    2653             :     // those don't need to be locked separately.
    2654           1 :     SolarMutexGuard aGuard;
    2655             : 
    2656             :     // #i97274# handle invalid tables
    2657           1 :     if (!pRows || pRows->empty() || !GetColumnCount())
    2658             :     {
    2659             :         OSL_FAIL("invalid table: no cells; deleting...");
    2660           0 :         pTableNode->GetDoc()->DeleteSection( pTableNode );
    2661           0 :         pTableNode = 0;
    2662           0 :         pBox1 = 0;
    2663           0 :         pSttNd1 = 0;
    2664           1 :         return;
    2665             :     }
    2666             : 
    2667           1 :     SwXMLImport& rSwImport = GetSwImport();
    2668             : 
    2669           1 :     SwFrmFmt *pFrmFmt = pTableNode->GetTable().GetFrmFmt();
    2670             : 
    2671           1 :     sal_Int16 eHoriOrient = text::HoriOrientation::FULL;
    2672           1 :     sal_Bool bSetHoriOrient = sal_False;
    2673             : 
    2674           1 :     sal_uInt16 nPrcWidth = 0U;
    2675             : 
    2676           1 :     pTableNode->GetTable().SetRowsToRepeat( nHeaderRows );
    2677           1 :     pTableNode->GetTable().SetTableModel( !bHasSubTables );
    2678             : 
    2679           1 :     const SfxItemSet *pAutoItemSet = 0;
    2680           2 :     if( !aStyleName.isEmpty() &&
    2681             :         rSwImport.FindAutomaticStyle(
    2682           1 :             XML_STYLE_FAMILY_TABLE_TABLE, aStyleName, &pAutoItemSet ) &&
    2683             :          pAutoItemSet )
    2684             :     {
    2685             :         const SfxPoolItem *pItem;
    2686           1 :         const SvxLRSpaceItem *pLRSpace = 0;
    2687           1 :         if( SFX_ITEM_SET == pAutoItemSet->GetItemState( RES_LR_SPACE, sal_False,
    2688           1 :                                                         &pItem ) )
    2689           0 :             pLRSpace = (const SvxLRSpaceItem *)pItem;
    2690             : 
    2691           1 :         if( SFX_ITEM_SET == pAutoItemSet->GetItemState( RES_HORI_ORIENT, sal_False,
    2692           1 :                                                         &pItem ) )
    2693             :         {
    2694           1 :             eHoriOrient = ((const SwFmtHoriOrient *)pItem)->GetHoriOrient();
    2695           1 :             switch( eHoriOrient )
    2696             :             {
    2697             :             case text::HoriOrientation::FULL:
    2698           1 :                 if( pLRSpace )
    2699             :                 {
    2700           0 :                     eHoriOrient = text::HoriOrientation::NONE;
    2701           0 :                     bSetHoriOrient = sal_True;
    2702             :                 }
    2703           1 :                 break;
    2704             :             case text::HoriOrientation::LEFT:
    2705           0 :                 if( pLRSpace )
    2706             :                 {
    2707           0 :                     eHoriOrient = text::HoriOrientation::LEFT_AND_WIDTH;
    2708           0 :                     bSetHoriOrient = sal_True;
    2709             :                 }
    2710           0 :                 break;
    2711             :             default:
    2712             :                 ;
    2713             :             }
    2714             :         }
    2715             :         else
    2716             :         {
    2717           0 :             bSetHoriOrient = sal_True;
    2718             :         }
    2719             : 
    2720           1 :         const SwFmtFrmSize *pSize = 0;
    2721           1 :         if( SFX_ITEM_SET == pAutoItemSet->GetItemState( RES_FRM_SIZE, sal_False,
    2722           1 :                                                         &pItem ) )
    2723           1 :             pSize = (const SwFmtFrmSize *)pItem;
    2724             : 
    2725           1 :         switch( eHoriOrient )
    2726             :         {
    2727             :         case text::HoriOrientation::FULL:
    2728             :         case text::HoriOrientation::NONE:
    2729             :             // For text::HoriOrientation::NONE we would prefere to use the sum
    2730             :             // of the relative column widths as reference width.
    2731             :             // Unfortunately this works only if this sum interpreted as
    2732             :             // twip value is larger than the space that is avaialable.
    2733             :             // We don't know that space, so we have to use USHRT_MAX, too.
    2734             :             // Even if a size is speczified, it will be ignored!
    2735           1 :             nWidth = USHRT_MAX;
    2736           1 :             break;
    2737             :         default:
    2738           0 :             if( pSize )
    2739             :             {
    2740           0 :                 if( pSize->GetWidthPercent() )
    2741             :                 {
    2742             :                     // The width will be set in _MakeTable
    2743           0 :                     nPrcWidth = pSize->GetWidthPercent();
    2744             :                 }
    2745             :                 else
    2746             :                 {
    2747           0 :                     nWidth = pSize->GetWidth();
    2748           0 :                     if( nWidth < (sal_Int32)GetColumnCount() * MINLAY )
    2749             :                     {
    2750           0 :                         nWidth = GetColumnCount() * MINLAY;
    2751             :                     }
    2752           0 :                     else if( nWidth > USHRT_MAX )
    2753             :                     {
    2754           0 :                         nWidth = USHRT_MAX;
    2755             :                     }
    2756           0 :                     bRelWidth = sal_False;
    2757             :                 }
    2758             :             }
    2759             :             else
    2760             :             {
    2761             :                 eHoriOrient = text::HoriOrientation::LEFT_AND_WIDTH == eHoriOrient
    2762           0 :                                     ? text::HoriOrientation::NONE : text::HoriOrientation::FULL;
    2763           0 :                 bSetHoriOrient = sal_True;
    2764           0 :                 nWidth = USHRT_MAX;
    2765             :             }
    2766           0 :             break;
    2767             :         }
    2768             : 
    2769           1 :         pFrmFmt->SetFmtAttr( *pAutoItemSet );
    2770             :     }
    2771             :     else
    2772             :     {
    2773           0 :         bSetHoriOrient = sal_True;
    2774           0 :         nWidth = USHRT_MAX;
    2775             :     }
    2776             : 
    2777           1 :     SwTableLine *pLine1 = pTableNode->GetTable().GetTabLines()[0U];
    2778             :     OSL_ENSURE( pBox1 == pLine1->GetTabBoxes()[0U],
    2779             :                 "Why is box 1 change?" );
    2780           1 :     pBox1->pSttNd = pSttNd1;
    2781           1 :     pLine1->GetTabBoxes().erase( pLine1->GetTabBoxes().begin() );
    2782             : 
    2783           1 :     pLineFmt = (SwTableLineFmt*)pLine1->GetFrmFmt();
    2784           1 :     pBoxFmt = (SwTableBoxFmt*)pBox1->GetFrmFmt();
    2785             : 
    2786           1 :     _MakeTable( 0 );
    2787             : 
    2788           1 :     if( bSetHoriOrient )
    2789           0 :         pFrmFmt->SetFmtAttr( SwFmtHoriOrient( 0, eHoriOrient ) );
    2790             : 
    2791             :     // This must be after the call to _MakeTable, because nWidth might be
    2792             :     // changed there.
    2793           1 :     pFrmFmt->LockModify();
    2794           1 :     SwFmtFrmSize aSize( ATT_VAR_SIZE, nWidth );
    2795           1 :     aSize.SetWidthPercent( (sal_Int8)nPrcWidth );
    2796           1 :     pFrmFmt->SetFmtAttr( aSize );
    2797           1 :     pFrmFmt->UnlockModify();
    2798             : 
    2799             : 
    2800          24 :     for( sal_uInt16 i=0; i<pRows->size(); i++ )
    2801          23 :         (*pRows)[i].Dispose();
    2802             : 
    2803             :     // now that table is complete, change into DDE table (if appropriate)
    2804           1 :     if (NULL != pDDESource)
    2805             :     {
    2806             :         // change existing table into DDE table:
    2807             :         // 1) Get DDE field type (get data from dde-source context),
    2808             :         SwDDEFieldType* pFldType = lcl_GetDDEFieldType( pDDESource,
    2809           0 :                                                         pTableNode );
    2810             : 
    2811             :         // 2) release the DDE source context,
    2812           0 :         pDDESource->ReleaseRef();
    2813             : 
    2814             :         // 3) create new DDE table, and
    2815           0 :         SwDDETable* pDDETable = new SwDDETable( pTableNode->GetTable(),
    2816           0 :                                                 pFldType, sal_False );
    2817             : 
    2818             :         // 4) set new (DDE)table at node.
    2819           0 :         pTableNode->SetNewTable(pDDETable, sal_False);
    2820             :     }
    2821             : 
    2822             :     // ??? this is always false: root frame is only created in ViewShell::Init
    2823           1 :     if( pTableNode->GetDoc()->GetCurrentViewShell() )   //swmod 071108//swmod 071225
    2824             :     {
    2825           0 :         pTableNode->DelFrms();
    2826           0 :         SwNodeIndex aIdx( *pTableNode->EndOfSectionNode(), 1 );
    2827           0 :         pTableNode->MakeFrms( &aIdx );
    2828           1 :     }
    2829             : }
    2830             : 
    2831           0 : void SwXMLTableContext::MakeTable( SwTableBox *pBox, sal_Int32 nW )
    2832             : {
    2833             : //FIXME: here would be a great place to handle XmlId for subtable
    2834           0 :     pLineFmt = GetParentTable()->pLineFmt;
    2835           0 :     pBoxFmt = GetParentTable()->pBoxFmt;
    2836           0 :     nWidth = nW;
    2837           0 :     bRelWidth = GetParentTable()->bRelWidth;
    2838             : 
    2839           0 :     _MakeTable( pBox );
    2840           0 : }
    2841             : 
    2842         115 : const SwStartNode *SwXMLTableContext::InsertTableSection(
    2843             :                                             const SwStartNode *pPrevSttNd )
    2844             : {
    2845             :     // The topmost table is the only table that maintains the two members
    2846             :     // pBox1 and bFirstSection.
    2847         115 :     if( xParentTable.Is() )
    2848           0 :         return ((SwXMLTableContext *)&xParentTable)->InsertTableSection( pPrevSttNd );
    2849             : 
    2850             :     const SwStartNode *pStNd;
    2851         230 :     Reference<XUnoTunnel> xCrsrTunnel( GetImport().GetTextImport()->GetCursor(),
    2852         115 :                                        UNO_QUERY);
    2853             :     OSL_ENSURE( xCrsrTunnel.is(), "missing XUnoTunnel for Cursor" );
    2854             :     OTextCursorHelper *pTxtCrsr = reinterpret_cast< OTextCursorHelper * >(
    2855         115 :             sal::static_int_cast< sal_IntPtr >( xCrsrTunnel->getSomething( OTextCursorHelper::getUnoTunnelId() )));
    2856             :     OSL_ENSURE( pTxtCrsr, "SwXTextCursor missing" );
    2857             : 
    2858         115 :     if( bFirstSection )
    2859             :     {
    2860             :         // The Cursor already is in the first section
    2861           1 :         pStNd = pTxtCrsr->GetPaM()->GetNode()->FindTableBoxStartNode();
    2862           1 :         bFirstSection = sal_False;
    2863           1 :         OUString sStyleName( RTL_CONSTASCII_USTRINGPARAM("Standard") );
    2864           1 :         GetImport().GetTextImport()->SetStyleAndAttrs( GetImport(),
    2865           2 :             GetImport().GetTextImport()->GetCursor(), sStyleName, sal_True );
    2866             :     }
    2867             :     else
    2868             :     {
    2869         114 :         SwDoc* pDoc = SwImport::GetDocFromXMLImport( GetSwImport() );
    2870           0 :         const SwEndNode *pEndNd = pPrevSttNd ? pPrevSttNd->EndOfSectionNode()
    2871         114 :                                              : pTableNode->EndOfSectionNode();
    2872             :         // #i78921# - make code robust
    2873             :         OSL_ENSURE( pDoc, "<SwXMLTableContext::InsertTableSection(..)> - no <pDoc> at <SwXTextCursor> instance - <SwXTextCurosr> doesn't seem to be registered at a <SwUnoCrsr> instance." );
    2874         114 :         if ( !pDoc )
    2875             :         {
    2876           0 :             pDoc = const_cast<SwDoc*>(pEndNd->GetDoc());
    2877             :         }
    2878         114 :         sal_uInt32 nOffset = pPrevSttNd ? 1UL : 0UL;
    2879         114 :         SwNodeIndex aIdx( *pEndNd, nOffset );
    2880             :         SwTxtFmtColl *pColl =
    2881         114 :             pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false );
    2882         114 :         pStNd = pDoc->GetNodes().MakeTextSection( aIdx, SwTableBoxStartNode,
    2883         114 :                                                  pColl );
    2884             :         // Consider the case that a table is defined without a row.
    2885         114 :         if( !pPrevSttNd && pBox1 != NULL )
    2886             : 
    2887             :         {
    2888         114 :             pBox1->pSttNd = pStNd;
    2889         228 :             SwCntntNode *pCNd = pDoc->GetNodes()[ pStNd->GetIndex() + 1 ]
    2890         228 :                                                             ->GetCntntNode();
    2891         114 :             SwPosition aPos( *pCNd );
    2892         114 :             aPos.nContent.Assign( pCNd, 0U );
    2893             : 
    2894             :             const uno::Reference< text::XTextRange > xTextRange =
    2895         114 :                 SwXTextRange::CreateXTextRange( *pDoc, aPos, 0 );
    2896         114 :             Reference < XText > xText = xTextRange->getText();
    2897             :             Reference < XTextCursor > xTextCursor =
    2898         114 :                 xText->createTextCursorByRange( xTextRange );
    2899         114 :             GetImport().GetTextImport()->SetCursor( xTextCursor );
    2900         114 :         }
    2901             :     }
    2902             : 
    2903         115 :     return pStNd;
    2904             : }
    2905             : 
    2906           1 : void SwXMLTableContext::EndElement()
    2907             : {
    2908           1 :     if( IsValid() && !xParentTable.Is() )
    2909             :     {
    2910           1 :         MakeTable();
    2911           1 :         GetImport().GetTextImport()->SetCursor( xOldCursor );
    2912             :     }
    2913           1 : }
    2914             : 
    2915           0 : Reference < XTextContent > SwXMLTableContext::GetXTextContent() const
    2916             : {
    2917           0 :     return xTextContent;
    2918             : }
    2919             : 
    2920             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10