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

Generated by: LCOV version 1.10