LCOV - code coverage report
Current view: top level - libreoffice/writerfilter/source/dmapper - DomainMapperTableHandler.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 308 343 89.8 %
Date: 2012-12-17 Functions: 19 20 95.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : #include <DomainMapperTableHandler.hxx>
      20             : #include <DomainMapper_Impl.hxx>
      21             : #include <StyleSheetTable.hxx>
      22             : #include <com/sun/star/table/TableBorderDistances.hpp>
      23             : #include <com/sun/star/table/TableBorder.hpp>
      24             : #include <com/sun/star/table/BorderLine2.hpp>
      25             : #include <com/sun/star/text/HoriOrientation.hpp>
      26             : #include <com/sun/star/text/RelOrientation.hpp>
      27             : #include <dmapperLoggers.hxx>
      28             : 
      29             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
      30             : #include <PropertyMapHelper.hxx>
      31             : #include <rtl/ustring.hxx>
      32             : #endif
      33             : 
      34             : namespace writerfilter {
      35             : namespace dmapper {
      36             : 
      37             : using namespace ::com::sun::star;
      38             : using namespace ::std;
      39             : 
      40             : #define DEF_BORDER_DIST 190  //0,19cm
      41             : 
      42             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
      43             : static void  lcl_printProperties( PropertyMapPtr pProps )
      44             : {
      45             :     if( pProps.get() )
      46             :     {
      47             :         dmapper_logger->startElement("properties");
      48             : 
      49             :         PropertyMap::const_iterator aMapIter = pProps->begin();
      50             :         PropertyMap::const_iterator aEndIter = pProps->end();
      51             :         PropertyNameSupplier& rPropSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
      52             :         for( ; aMapIter != aEndIter; ++aMapIter )
      53             :         {
      54             :             SAL_INFO("writerfilter", rPropSupplier.GetName(aMapIter->first.eId));
      55             : 
      56             :             table::BorderLine2 aLine;
      57             :             sal_Int32 nColor;
      58             :             if ( aMapIter->second >>= aLine )
      59             :             {
      60             :                 dmapper_logger->startElement("borderline");
      61             :                 dmapper_logger->attribute("color", aLine.Color);
      62             :                 dmapper_logger->attribute("inner", aLine.InnerLineWidth);
      63             :                 dmapper_logger->attribute("outer", aLine.OuterLineWidth);
      64             :                 dmapper_logger->endElement();
      65             :             }
      66             :             else if ( aMapIter->second >>= nColor )
      67             :             {
      68             :                 dmapper_logger->startElement("color");
      69             :                 dmapper_logger->attribute("number", nColor);
      70             :                 dmapper_logger->endElement();
      71             :             }
      72             :         }
      73             : 
      74             :         dmapper_logger->endElement();
      75             :     }
      76             : }
      77             : #endif
      78             : 
      79         438 : DomainMapperTableHandler::DomainMapperTableHandler(TextReference_t xText, DomainMapper_Impl& rDMapper_Impl)
      80             :     : m_xText(xText),
      81             :         m_rDMapper_Impl( rDMapper_Impl ),
      82             :         m_nCellIndex(0),
      83         438 :         m_nRowIndex(0)
      84             : {
      85         438 : }
      86             : 
      87         876 : DomainMapperTableHandler::~DomainMapperTableHandler()
      88             : {
      89         876 : }
      90             : 
      91         708 : void DomainMapperTableHandler::startTable(unsigned int nRows,
      92             :                                           unsigned int /*nDepth*/,
      93             :                                           TablePropertyMapPtr pProps)
      94             : {
      95         708 :     m_aTableProperties = pProps;
      96         708 :     m_pTableSeq = TableSequencePointer_t(new TableSequence_t(nRows));
      97         708 :     m_nRowIndex = 0;
      98             : 
      99             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     100             :     dmapper_logger->startElement("tablehandler.table");
     101             :     dmapper_logger->attribute("rows", nRows);
     102             : 
     103             :     if (pProps.get() != NULL)
     104             :         pProps->dumpXml( dmapper_logger );
     105             : #endif
     106         708 : }
     107             : 
     108             : 
     109             : 
     110           0 : PropertyMapPtr lcl_SearchParentStyleSheetAndMergeProperties(const StyleSheetEntryPtr pStyleSheet, StyleSheetTablePtr pStyleSheetTable)
     111             : {
     112           0 :     PropertyMapPtr pRet;
     113           0 :     if(!pStyleSheet->sBaseStyleIdentifier.isEmpty())
     114             :     {
     115           0 :         const StyleSheetEntryPtr pParentStyleSheet = pStyleSheetTable->FindStyleSheetByISTD( pStyleSheet->sBaseStyleIdentifier );
     116           0 :         pRet = lcl_SearchParentStyleSheetAndMergeProperties( pParentStyleSheet, pStyleSheetTable );
     117             :     }
     118             :     else
     119             :     {
     120           0 :         pRet.reset( new PropertyMap );
     121             :     }
     122             : 
     123           0 :     pRet->InsertProps(pStyleSheet->pProperties);
     124             : 
     125           0 :     return pRet;
     126             : }
     127             : 
     128        1156 : void lcl_mergeBorder( PropertyIds nId, PropertyMapPtr pOrig, PropertyMapPtr pDest )
     129             : {
     130        1156 :     PropertyDefinition aDef( nId, false );
     131        1156 :     PropertyMap::iterator pOrigIt = pOrig->find( aDef );
     132             : 
     133        1156 :     if ( pOrigIt != pOrig->end( ) )
     134             :     {
     135         450 :         pDest->Insert( nId, false, pOrigIt->second, false );
     136             :     }
     137        1156 : }
     138             : 
     139         580 : void lcl_computeCellBorders( PropertyMapPtr pTableBorders, PropertyMapPtr pCellProps,
     140             :         sal_Int32 nCell, sal_Int32 nRow, bool bIsEndCol, bool bIsEndRow )
     141             : {
     142         580 :     PropertyDefinition aVertPDef( META_PROP_VERTICAL_BORDER, false );
     143         580 :     PropertyDefinition aHorizPDef( META_PROP_HORIZONTAL_BORDER, false );
     144             : 
     145         580 :     PropertyMap::iterator aVerticalIter = pCellProps->find( aVertPDef );
     146         580 :     PropertyMap::iterator aHorizontalIter = pCellProps->find( aHorizPDef );
     147             : 
     148             :     // Handle the vertical and horizontal borders
     149         580 :     bool bHasVert = ( aVerticalIter != pCellProps->end(  ) );
     150         580 :     uno::Any aVertProp;
     151         580 :     if ( !bHasVert )
     152             :     {
     153         580 :         aVerticalIter = pTableBorders->find( aVertPDef );
     154         580 :         bHasVert = ( aVerticalIter != pTableBorders->end( ) );
     155         580 :         if ( bHasVert )
     156         252 :             aVertProp = aVerticalIter->second;
     157             :     }
     158             :     else
     159             :     {
     160           0 :         aVertProp = aVerticalIter->second;
     161           0 :         pCellProps->erase( aVerticalIter );
     162             :     }
     163             : 
     164         580 :     bool bHasHoriz = ( aHorizontalIter != pCellProps->end(  ) );
     165         580 :     uno::Any aHorizProp;
     166         580 :     if ( !bHasHoriz )
     167             :     {
     168         580 :         aHorizontalIter = pTableBorders->find( aHorizPDef );
     169         580 :         bHasHoriz = ( aHorizontalIter != pTableBorders->end( ) );
     170         580 :         if ( bHasHoriz )
     171         240 :             aHorizProp = aHorizontalIter->second;
     172             :     }
     173             :     else
     174             :     {
     175           0 :         aHorizProp = aHorizontalIter->second;
     176           0 :         pCellProps->erase( aHorizontalIter );
     177             :     }
     178             : 
     179         580 :     if ( nCell == 0 )
     180             :     {
     181         154 :         lcl_mergeBorder( PROP_LEFT_BORDER, pTableBorders, pCellProps );
     182         154 :         if ( bHasVert )
     183          64 :             pCellProps->Insert( PROP_RIGHT_BORDER, false, aVertProp, false );
     184             :     }
     185             : 
     186         580 :     if ( bIsEndCol )
     187             :     {
     188         154 :         lcl_mergeBorder( PROP_RIGHT_BORDER, pTableBorders, pCellProps );
     189         154 :         if ( bHasVert )
     190          64 :             pCellProps->Insert( PROP_LEFT_BORDER, false, aVertProp, false );
     191             :     }
     192             : 
     193         580 :     if ( nCell > 0 && !bIsEndCol )
     194             :     {
     195         294 :         if ( bHasVert )
     196             :         {
     197         130 :             pCellProps->Insert( PROP_RIGHT_BORDER, false, aVertProp, false );
     198         130 :             pCellProps->Insert( PROP_LEFT_BORDER, false, aVertProp, false );
     199             :         }
     200             :     }
     201             : 
     202         580 :     if ( nRow == 0 )
     203             :     {
     204         428 :         lcl_mergeBorder( PROP_TOP_BORDER, pTableBorders, pCellProps );
     205         428 :         if ( bHasHoriz )
     206         152 :             pCellProps->Insert( PROP_BOTTOM_BORDER, false, aHorizProp, false );
     207             :     }
     208             : 
     209         580 :     if ( bIsEndRow )
     210             :     {
     211         420 :         lcl_mergeBorder( PROP_BOTTOM_BORDER, pTableBorders, pCellProps );
     212         420 :         if ( bHasHoriz )
     213         158 :             pCellProps->Insert( PROP_TOP_BORDER, false, aHorizProp, false );
     214             :     }
     215             : 
     216         580 :     if ( nRow > 0 && !bIsEndRow )
     217             :     {
     218          50 :         if ( bHasHoriz )
     219             :         {
     220          26 :             pCellProps->Insert( PROP_TOP_BORDER, false, aHorizProp, false );
     221          26 :             pCellProps->Insert( PROP_BOTTOM_BORDER, false, aHorizProp, false );
     222             :         }
     223         580 :     }
     224         580 : }
     225             : 
     226             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     227             : 
     228             : void lcl_debug_BorderLine(table::BorderLine & rLine)
     229             : {
     230             :     dmapper_logger->startElement("BorderLine");
     231             :     dmapper_logger->attribute("Color", rLine.Color);
     232             :     dmapper_logger->attribute("InnerLineWidth", rLine.InnerLineWidth);
     233             :     dmapper_logger->attribute("OuterLineWidth", rLine.OuterLineWidth);
     234             :     dmapper_logger->attribute("LineDistance", rLine.LineDistance);
     235             :     dmapper_logger->endElement();
     236             : }
     237             : 
     238             : void lcl_debug_TableBorder(table::TableBorder & rBorder)
     239             : {
     240             :     dmapper_logger->startElement("TableBorder");
     241             :     lcl_debug_BorderLine(rBorder.TopLine);
     242             :     dmapper_logger->attribute("IsTopLineValid", rBorder.IsTopLineValid);
     243             :     lcl_debug_BorderLine(rBorder.BottomLine);
     244             :     dmapper_logger->attribute("IsBottomLineValid", rBorder.IsBottomLineValid);
     245             :     lcl_debug_BorderLine(rBorder.LeftLine);
     246             :     dmapper_logger->attribute("IsLeftLineValid", rBorder.IsLeftLineValid);
     247             :     lcl_debug_BorderLine(rBorder.RightLine);
     248             :     dmapper_logger->attribute("IsRightLineValid", rBorder.IsRightLineValid);
     249             :     lcl_debug_BorderLine(rBorder.VerticalLine);
     250             :     dmapper_logger->attribute("IsVerticalLineValid", rBorder.IsVerticalLineValid);
     251             :     lcl_debug_BorderLine(rBorder.HorizontalLine);
     252             :     dmapper_logger->attribute("IsHorizontalLineValid", rBorder.IsHorizontalLineValid);
     253             :     dmapper_logger->attribute("Distance", rBorder.Distance);
     254             :     dmapper_logger->attribute("IsDistanceValid", rBorder.IsDistanceValid);
     255             :     dmapper_logger->endElement();
     256             : }
     257             : #endif
     258             : 
     259         708 : struct WRITERFILTER_DLLPRIVATE TableInfo
     260             : {
     261             :     sal_Int32 nLeftBorderDistance;
     262             :     sal_Int32 nRightBorderDistance;
     263             :     sal_Int32 nTopBorderDistance;
     264             :     sal_Int32 nBottomBorderDistance;
     265             :     sal_Int32 nNestLevel;
     266             :     PropertyMapPtr pTableDefaults;
     267             :     PropertyMapPtr pTableBorders;
     268             :     TableStyleSheetEntry* pTableStyle;
     269             :     TablePropertyValues_t aTableProperties;
     270             : 
     271         708 :     TableInfo()
     272             :     : nLeftBorderDistance(DEF_BORDER_DIST)
     273             :     , nRightBorderDistance(DEF_BORDER_DIST)
     274             :     , nTopBorderDistance(0)
     275             :     , nBottomBorderDistance(0)
     276             :     , nNestLevel(0)
     277         708 :     , pTableDefaults(new PropertyMap)
     278         708 :     , pTableBorders(new PropertyMap)
     279        2124 :     , pTableStyle(NULL)
     280             :     {
     281         708 :     }
     282             : 
     283             : };
     284             : 
     285             : namespace
     286             : {
     287             : 
     288         612 : bool lcl_extractTableBorderProperty(PropertyMapPtr pTableProperties, const PropertyIds nId, TableInfo& rInfo, table::BorderLine2& rLine)
     289             : {
     290         612 :     PropertyMap::iterator aTblBorderIter = pTableProperties->find( PropertyDefinition(nId, false) );
     291         612 :     if( aTblBorderIter != pTableProperties->end() )
     292             :     {
     293         200 :         OSL_VERIFY(aTblBorderIter->second >>= rLine);
     294             : 
     295         200 :         rInfo.pTableBorders->Insert( nId, false, uno::makeAny( rLine ) );
     296         200 :         PropertyMap::iterator pIt = rInfo.pTableDefaults->find( PropertyDefinition( nId, false ) );
     297         200 :         if ( pIt != rInfo.pTableDefaults->end( ) )
     298         200 :             rInfo.pTableDefaults->erase( pIt );
     299             : 
     300         200 :         return true;
     301             :     }
     302             : 
     303         412 :     return false;
     304             : }
     305             : 
     306             : }
     307             : 
     308         708 : TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo & rInfo)
     309             : {
     310             :     // will receive the table style if any
     311         708 :     TableStyleSheetEntry* pTableStyle = NULL;
     312             : 
     313         708 :     if( m_aTableProperties.get() )
     314             :     {
     315             :         //create properties from the table attributes
     316             :         //...pPropMap->Insert( PROP_LEFT_MARGIN, false, uno::makeAny( m_nLeftMargin - m_nGapHalf ));
     317             :         //pPropMap->Insert( PROP_HORI_ORIENT, false, uno::makeAny( text::HoriOrientation::RIGHT ));
     318         102 :         sal_Int32 nGapHalf = 0;
     319         102 :         sal_Int32 nLeftMargin = 0;
     320         102 :         sal_Int32 nTableWidth = 0;
     321             : 
     322             :         PropertyMap::iterator aTableStyleIter =
     323         102 :         m_aTableProperties->find( PropertyDefinition( META_PROP_TABLE_STYLE_NAME, false ) );
     324         102 :         if(aTableStyleIter != m_aTableProperties->end())
     325             :         {
     326             :             // Apply table style properties recursively
     327          50 :             OUString sTableStyleName;
     328          50 :             aTableStyleIter->second >>= sTableStyleName;
     329          50 :             StyleSheetTablePtr pStyleSheetTable = m_rDMapper_Impl.GetStyleSheetTable();
     330          50 :             const StyleSheetEntryPtr pStyleSheet = pStyleSheetTable->FindStyleSheetByISTD( sTableStyleName );
     331          50 :             pTableStyle = dynamic_cast<TableStyleSheetEntry*>( pStyleSheet.get( ) );
     332          50 :             m_aTableProperties->erase( aTableStyleIter );
     333             : 
     334          50 :             if( pStyleSheet )
     335             :             {
     336             :                 // First get the style properties, then the table ones
     337           0 :                 PropertyMapPtr pTableProps( m_aTableProperties );
     338           0 :                 TablePropertyMapPtr pEmptyProps( new TablePropertyMap );
     339             : 
     340           0 :                 m_aTableProperties = pEmptyProps;
     341             : 
     342           0 :                 PropertyMapPtr pMergedProperties = lcl_SearchParentStyleSheetAndMergeProperties(pStyleSheet, pStyleSheetTable);
     343             : 
     344             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     345             :                 dmapper_logger->startElement("mergedProps");
     346             :                 pMergedProperties->dumpXml( dmapper_logger );
     347             :                 dmapper_logger->endElement();
     348             : #endif
     349             : 
     350           0 :                 m_aTableProperties->InsertProps(pMergedProperties);
     351           0 :                 m_aTableProperties->InsertProps(pTableProps);
     352             : 
     353             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     354             :                 dmapper_logger->startElement("TableProperties");
     355             :                 m_aTableProperties->dumpXml( dmapper_logger );
     356             :                 dmapper_logger->endElement();
     357             : #endif
     358          50 :             }
     359             :         }
     360             : 
     361             :         // Set the table default attributes for the cells
     362         102 :         rInfo.pTableDefaults->InsertProps(m_aTableProperties);
     363             : 
     364             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     365             :         dmapper_logger->startElement("TableDefaults");
     366             :         rInfo.pTableDefaults->dumpXml( dmapper_logger );
     367             :         dmapper_logger->endElement();
     368             : #endif
     369             : 
     370         102 :         m_aTableProperties->getValue( TablePropertyMap::GAP_HALF, nGapHalf );
     371         102 :         m_aTableProperties->getValue( TablePropertyMap::LEFT_MARGIN, nLeftMargin );
     372             : 
     373             :         m_aTableProperties->getValue( TablePropertyMap::CELL_MAR_LEFT,
     374         102 :                                      rInfo.nLeftBorderDistance );
     375             :         m_aTableProperties->getValue( TablePropertyMap::CELL_MAR_RIGHT,
     376         102 :                                      rInfo.nRightBorderDistance );
     377             :         m_aTableProperties->getValue( TablePropertyMap::CELL_MAR_TOP,
     378         102 :                                      rInfo.nTopBorderDistance );
     379             :         m_aTableProperties->getValue( TablePropertyMap::CELL_MAR_BOTTOM,
     380         102 :                                      rInfo.nBottomBorderDistance );
     381             : 
     382         102 :         table::TableBorderDistances aDistances;
     383             :         aDistances.IsTopDistanceValid =
     384             :         aDistances.IsBottomDistanceValid =
     385             :         aDistances.IsLeftDistanceValid =
     386         102 :         aDistances.IsRightDistanceValid = sal_True;
     387         102 :         aDistances.TopDistance = static_cast<sal_Int16>( rInfo.nTopBorderDistance );
     388         102 :         aDistances.BottomDistance = static_cast<sal_Int16>( rInfo.nBottomBorderDistance );
     389         102 :         aDistances.LeftDistance = static_cast<sal_Int16>( rInfo.nLeftBorderDistance );
     390         102 :         aDistances.RightDistance = static_cast<sal_Int16>( rInfo.nRightBorderDistance );
     391             : 
     392         102 :         m_aTableProperties->Insert( PROP_TABLE_BORDER_DISTANCES, false, uno::makeAny( aDistances ) );
     393             : 
     394             :         // Set table above/bottom spacing to 0.
     395             :         // TODO: handle 'Around' text wrapping mode
     396         102 :         m_aTableProperties->Insert( PROP_TOP_MARGIN, true, uno::makeAny( sal_Int32( 0 ) ) );
     397         102 :         m_aTableProperties->Insert( PROP_BOTTOM_MARGIN, true, uno::makeAny( sal_Int32( 0 ) ) );
     398             : 
     399             :         //table border settings
     400         102 :         table::TableBorder aTableBorder;
     401         102 :         table::BorderLine2 aBorderLine, aLeftBorder;
     402             : 
     403         102 :         if (lcl_extractTableBorderProperty(m_aTableProperties, PROP_TOP_BORDER, rInfo, aBorderLine))
     404             :         {
     405          32 :             aTableBorder.TopLine = aBorderLine;
     406          32 :             aTableBorder.IsTopLineValid = sal_True;
     407             :         }
     408         102 :         if (lcl_extractTableBorderProperty(m_aTableProperties, PROP_BOTTOM_BORDER, rInfo, aBorderLine))
     409             :         {
     410          34 :             aTableBorder.BottomLine = aBorderLine;
     411          34 :             aTableBorder.IsBottomLineValid = sal_True;
     412             :         }
     413         102 :         if (lcl_extractTableBorderProperty(m_aTableProperties, PROP_LEFT_BORDER, rInfo, aLeftBorder))
     414             :         {
     415          34 :             aTableBorder.LeftLine = aLeftBorder;
     416          34 :             aTableBorder.IsLeftLineValid = sal_True;
     417          34 :             rInfo.nLeftBorderDistance += aLeftBorder.LineWidth * 0.5;
     418             :         }
     419         102 :         if (lcl_extractTableBorderProperty(m_aTableProperties, PROP_RIGHT_BORDER, rInfo, aBorderLine))
     420             :         {
     421          34 :             aTableBorder.RightLine = aBorderLine;
     422          34 :             aTableBorder.IsRightLineValid = sal_True;
     423             :         }
     424         102 :         if (lcl_extractTableBorderProperty(m_aTableProperties, META_PROP_HORIZONTAL_BORDER, rInfo, aBorderLine))
     425             :         {
     426          32 :             aTableBorder.HorizontalLine = aBorderLine;
     427          32 :             aTableBorder.IsHorizontalLineValid = sal_True;
     428             :         }
     429         102 :         if (lcl_extractTableBorderProperty(m_aTableProperties, META_PROP_VERTICAL_BORDER, rInfo, aBorderLine))
     430             :         {
     431          34 :             aTableBorder.VerticalLine = aBorderLine;
     432          34 :             aTableBorder.IsVerticalLineValid = sal_True;
     433             :         }
     434             : 
     435         102 :         aTableBorder.Distance = 0;
     436         102 :         aTableBorder.IsDistanceValid = sal_False;
     437             : 
     438         102 :         m_aTableProperties->Insert( PROP_TABLE_BORDER, false, uno::makeAny( aTableBorder ) );
     439             : 
     440             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     441             :         lcl_debug_TableBorder(aTableBorder);
     442             : #endif
     443             : 
     444             :         // Table position in Office is computed in 2 different ways :
     445             :         // - top level tables: the goal is to have in-cell text starting at table indent pos (tblInd),
     446             :         //   so table's position depends on table's cells margin
     447             :         // - nested tables: the goal is to have left-most border starting at table_indent pos
     448         102 :         if (rInfo.nNestLevel > 1)
     449             :         {
     450          10 :             m_aTableProperties->Insert( PROP_LEFT_MARGIN, false, uno::makeAny( nLeftMargin - nGapHalf ));
     451             :         }
     452             :         else
     453             :         {
     454          92 :             m_aTableProperties->Insert( PROP_LEFT_MARGIN, false, uno::makeAny( nLeftMargin - nGapHalf - rInfo.nLeftBorderDistance ));
     455             :         }
     456             : 
     457         102 :         m_aTableProperties->getValue( TablePropertyMap::TABLE_WIDTH, nTableWidth );
     458         102 :         if( nTableWidth > 0 )
     459         102 :             m_aTableProperties->Insert( PROP_WIDTH, false, uno::makeAny( nTableWidth ));
     460             : 
     461         102 :         sal_Int32 nHoriOrient = text::HoriOrientation::LEFT_AND_WIDTH;
     462         102 :         m_aTableProperties->getValue( TablePropertyMap::HORI_ORIENT, nHoriOrient ) ;
     463         102 :         m_aTableProperties->Insert( PROP_HORI_ORIENT, false, uno::makeAny( sal_Int16(nHoriOrient) ) );
     464             : 
     465             :         //fill default value - if not available
     466             :         const PropertyMap::const_iterator aRepeatIter =
     467         102 :         m_aTableProperties->find( PropertyDefinition( PROP_HEADER_ROW_COUNT, false ) );
     468         102 :         if( aRepeatIter == m_aTableProperties->end() )
     469         102 :             m_aTableProperties->Insert( PROP_HEADER_ROW_COUNT, false, uno::makeAny( (sal_Int32)0 ));
     470             : 
     471         102 :         rInfo.aTableProperties = m_aTableProperties->GetPropertyValues();
     472             : 
     473             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     474             :         dmapper_logger->startElement("debug.tableprops");
     475             :         m_aTableProperties->dumpXml( dmapper_logger );
     476             :         dmapper_logger->endElement();
     477             : #endif
     478             : 
     479             :     }
     480             : 
     481         708 :     return pTableStyle;
     482             : }
     483             : 
     484         708 : CellPropertyValuesSeq_t DomainMapperTableHandler::endTableGetCellProperties(TableInfo & rInfo)
     485             : {
     486             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     487             :     dmapper_logger->startElement("getCellProperties");
     488             : #endif
     489             : 
     490         708 :     CellPropertyValuesSeq_t aCellProperties( m_aCellProperties.size() );
     491             : 
     492         708 :     if ( !m_aCellProperties.size() )
     493             :     {
     494             :         #ifdef DEBUG_DOMAINMAPPER
     495             :         dmapper_logger->endElement();
     496             :         #endif
     497             :         return aCellProperties;
     498             :     }
     499             :     // std::vector< std::vector<PropertyMapPtr> > m_aCellProperties
     500         116 :     PropertyMapVector2::const_iterator aRowOfCellsIterator = m_aCellProperties.begin();
     501         116 :     PropertyMapVector2::const_iterator aRowOfCellsIteratorEnd = m_aCellProperties.end();
     502         116 :     PropertyMapVector2::const_iterator aLastRowIterator = m_aCellProperties.end() - 1;
     503         116 :     sal_Int32 nRow = 0;
     504             : 
     505             :     //it's a uno::Sequence< beans::PropertyValues >*
     506         116 :     RowPropertyValuesSeq_t* pCellProperties = aCellProperties.getArray();
     507         400 :     while( aRowOfCellsIterator != aRowOfCellsIteratorEnd )
     508             :     {
     509             :         //aRowOfCellsIterator points to a vector of PropertyMapPtr
     510         168 :         PropertyMapVector1::const_iterator aCellIterator = aRowOfCellsIterator->begin();
     511         168 :         PropertyMapVector1::const_iterator aCellIteratorEnd = aRowOfCellsIterator->end();
     512             : 
     513             :         // Get the row style properties
     514         168 :         sal_Int32 nRowStyleMask = sal_Int32( 0 );
     515         168 :         PropertyMapPtr pRowProps = m_aRowProperties[nRow];
     516         168 :         if ( pRowProps.get( ) )
     517             :         {
     518         154 :             PropertyMap::iterator pTcCnfStyleIt = pRowProps->find( PropertyDefinition( PROP_CNF_STYLE, true ) );
     519         154 :             if ( pTcCnfStyleIt != pRowProps->end( ) )
     520             :             {
     521           0 :                 if ( rInfo.pTableStyle )
     522             :                 {
     523           0 :                     OUString sMask;
     524           0 :                     pTcCnfStyleIt->second >>= sMask;
     525           0 :                     nRowStyleMask = sMask.toInt32( 2 );
     526             :                 }
     527           0 :                 pRowProps->erase( pTcCnfStyleIt );
     528             :             }
     529             :         }
     530             : 
     531         168 :         sal_Int32 nCell = 0;
     532         168 :         pCellProperties[nRow].realloc( aRowOfCellsIterator->size() );
     533         168 :         beans::PropertyValues* pSingleCellProperties = pCellProperties[nRow].getArray();
     534         916 :         while( aCellIterator != aCellIteratorEnd )
     535             :         {
     536         580 :             PropertyMapPtr pAllCellProps( new PropertyMap );
     537             : 
     538         580 :             PropertyMapVector1::const_iterator aLastCellIterator = aRowOfCellsIterator->end() - 1;
     539         580 :             bool bIsEndCol = aCellIterator == aLastCellIterator;
     540         580 :             bool bIsEndRow = aRowOfCellsIterator == aLastRowIterator;
     541             : 
     542             :             //aCellIterator points to a PropertyMapPtr;
     543         580 :             if( aCellIterator->get() )
     544             :             {
     545         580 :                 if ( rInfo.pTableDefaults->size( ) )
     546           0 :                     pAllCellProps->InsertProps(rInfo.pTableDefaults);
     547             : 
     548             :                 // Fill the cell properties with the ones of the style
     549         580 :                 sal_Int32 nCellStyleMask = 0;
     550             :                 const PropertyMap::iterator aCnfStyleIter =
     551         580 :                     aCellIterator->get()->find( PropertyDefinition( PROP_CNF_STYLE, false ) );
     552         580 :                 if ( aCnfStyleIter != aCellIterator->get( )->end( ) )
     553             :                 {
     554           0 :                     if ( rInfo.pTableStyle ) {
     555           0 :                         OUString sMask;
     556           0 :                         aCnfStyleIter->second >>= sMask;
     557           0 :                         nCellStyleMask = sMask.toInt32( 2 );
     558             :                     }
     559           0 :                     aCellIterator->get( )->erase( aCnfStyleIter );
     560             :                 }
     561             : 
     562         580 :                 if ( rInfo.pTableStyle )
     563             :                 {
     564           0 :                     PropertyMapPtr pStyleProps = rInfo.pTableStyle->GetProperties( nCellStyleMask + nRowStyleMask );
     565           0 :                     pAllCellProps->InsertProps(pStyleProps);
     566             :                 }
     567             : 
     568             :                 // Remove properties from style/row that aren't allowed in cells
     569             :                 const PropertyMap::iterator aDefaultRepeatIt =
     570         580 :                     pAllCellProps->find(
     571        1160 :                         PropertyDefinition( PROP_HEADER_ROW_COUNT, false ) );
     572         580 :                 if ( aDefaultRepeatIt != pAllCellProps->end( ) )
     573           0 :                     pAllCellProps->erase( aDefaultRepeatIt );
     574             : 
     575             :                 // Then add the cell properties
     576         580 :                 pAllCellProps->InsertProps(*aCellIterator);
     577         580 :                 aCellIterator->get( )->swap( *pAllCellProps.get( ) );
     578             : 
     579             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     580             :                 dmapper_logger->startElement("cell");
     581             :                 dmapper_logger->attribute("cell", nCell);
     582             :                 dmapper_logger->attribute("row", nRow);
     583             : #endif
     584             : 
     585         580 :                 lcl_computeCellBorders( rInfo.pTableBorders, *aCellIterator, nCell, nRow, bIsEndCol, bIsEndRow );
     586             : 
     587             :                 //now set the default left+right border distance TODO: there's an sprm containing the default distance!
     588             :                 const PropertyMap::const_iterator aLeftDistanceIter =
     589         580 :                 aCellIterator->get()->find( PropertyDefinition(PROP_LEFT_BORDER_DISTANCE, false) );
     590         580 :                 if( aLeftDistanceIter == aCellIterator->get()->end() )
     591             :                     aCellIterator->get()->Insert( PROP_LEFT_BORDER_DISTANCE, false,
     592         580 :                                                  uno::makeAny(rInfo.nLeftBorderDistance ) );
     593             :                 const PropertyMap::const_iterator aRightDistanceIter =
     594         580 :                 aCellIterator->get()->find( PropertyDefinition(PROP_RIGHT_BORDER_DISTANCE, false) );
     595         580 :                 if( aRightDistanceIter == aCellIterator->get()->end() )
     596             :                     aCellIterator->get()->Insert( PROP_RIGHT_BORDER_DISTANCE, false,
     597         580 :                                                  uno::makeAny((sal_Int32) rInfo.nRightBorderDistance ) );
     598             : 
     599             :                 const PropertyMap::const_iterator aTopDistanceIter =
     600         580 :                 aCellIterator->get()->find( PropertyDefinition(PROP_TOP_BORDER_DISTANCE, false) );
     601         580 :                 if( aTopDistanceIter == aCellIterator->get()->end() )
     602             :                     aCellIterator->get()->Insert( PROP_TOP_BORDER_DISTANCE, false,
     603         580 :                                                  uno::makeAny((sal_Int32) rInfo.nTopBorderDistance ) );
     604             : 
     605             :                 const PropertyMap::const_iterator aBottomDistanceIter =
     606         580 :                 aCellIterator->get()->find( PropertyDefinition(PROP_BOTTOM_BORDER_DISTANCE, false) );
     607         580 :                 if( aBottomDistanceIter == aCellIterator->get()->end() )
     608             :                     aCellIterator->get()->Insert( PROP_BOTTOM_BORDER_DISTANCE, false,
     609         580 :                                                  uno::makeAny((sal_Int32) rInfo.nBottomBorderDistance ) );
     610             : 
     611         580 :                 pSingleCellProperties[nCell] = aCellIterator->get()->GetPropertyValues();
     612             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     613             :                 dmapper_logger->endElement();
     614             : #endif
     615             :             }
     616         580 :             ++nCell;
     617         580 :             ++aCellIterator;
     618         580 :         }
     619             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     620             :         //-->debug cell properties
     621             :         {
     622             :             OUString sNames;
     623             :             const uno::Sequence< beans::PropertyValues > aDebugCurrentRow = aCellProperties[nRow];
     624             :             sal_Int32 nDebugCells = aDebugCurrentRow.getLength();
     625             :             (void) nDebugCells;
     626             :             for( sal_Int32  nDebugCell = 0; nDebugCell < nDebugCells; ++nDebugCell)
     627             :             {
     628             :                 const uno::Sequence< beans::PropertyValue >& aDebugCellProperties = aDebugCurrentRow[nDebugCell];
     629             :                 sal_Int32 nDebugCellProperties = aDebugCellProperties.getLength();
     630             :                 for( sal_Int32  nDebugProperty = 0; nDebugProperty < nDebugCellProperties; ++nDebugProperty)
     631             :                 {
     632             :                     const OUString sName = aDebugCellProperties[nDebugProperty].Name;
     633             :                     sNames += sName;
     634             :                     sNames += OUString('-');
     635             :                 }
     636             :                 sNames += OUString('\n');
     637             :             }
     638             :             (void)sNames;
     639             :         }
     640             :         //--<
     641             : #endif
     642         168 :         ++nRow;
     643         168 :         ++aRowOfCellsIterator;
     644         168 :     }
     645             : 
     646             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     647             :     dmapper_logger->endElement();
     648             : #endif
     649             : 
     650           0 :     return aCellProperties;
     651             : }
     652             : 
     653         708 : RowPropertyValuesSeq_t DomainMapperTableHandler::endTableGetRowProperties()
     654             : {
     655             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     656             :     dmapper_logger->startElement("getRowProperties");
     657             : #endif
     658             : 
     659         708 :     RowPropertyValuesSeq_t aRowProperties( m_aRowProperties.size() );
     660         708 :     PropertyMapVector1::const_iterator aRowIter = m_aRowProperties.begin();
     661         708 :     PropertyMapVector1::const_iterator aRowIterEnd = m_aRowProperties.end();
     662         708 :     sal_Int32 nRow = 0;
     663        1584 :     while( aRowIter != aRowIterEnd )
     664             :     {
     665             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     666             :         dmapper_logger->startElement("rowProps.row");
     667             : #endif
     668         168 :         if( aRowIter->get() )
     669             :         {
     670             :             //set default to 'break across pages"
     671         154 :             if( aRowIter->get()->find( PropertyDefinition( PROP_IS_SPLIT_ALLOWED, false )) == aRowIter->get()->end())
     672         126 :                 aRowIter->get()->Insert( PROP_IS_SPLIT_ALLOWED, false, uno::makeAny(sal_True ) );
     673             : 
     674         154 :             aRowProperties[nRow] = (*aRowIter)->GetPropertyValues();
     675             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     676             :             ((*aRowIter)->dumpXml( dmapper_logger ));
     677             :             lcl_DumpPropertyValues(dmapper_logger, aRowProperties[nRow]);
     678             : #endif
     679             :         }
     680         168 :         ++nRow;
     681         168 :         ++aRowIter;
     682             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     683             :         dmapper_logger->endElement();
     684             : #endif
     685             :     }
     686             : 
     687             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     688             :     dmapper_logger->endElement();
     689             : #endif
     690             : 
     691         708 :     return aRowProperties;
     692             : }
     693             : 
     694         708 : void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel)
     695             : {
     696             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     697             :     dmapper_logger->startElement("tablehandler.endTable");
     698             : #endif
     699             : 
     700         708 :     TableInfo aTableInfo;
     701         708 :     aTableInfo.nNestLevel = nestedTableLevel;
     702         708 :     aTableInfo.pTableStyle = endTableGetTableStyle(aTableInfo);
     703             :     //  expands to uno::Sequence< Sequence< beans::PropertyValues > >
     704             : 
     705         708 :     CellPropertyValuesSeq_t aCellProperties = endTableGetCellProperties(aTableInfo);
     706             : 
     707         708 :     RowPropertyValuesSeq_t aRowProperties = endTableGetRowProperties();
     708             : 
     709             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     710             :     lcl_DumpPropertyValueSeq(dmapper_logger, aRowProperties);
     711             : #endif
     712             : 
     713         708 :     if (m_pTableSeq->getLength() > 0)
     714             :     {
     715         116 :         uno::Reference<text::XTextRange> xStart;
     716         116 :         uno::Reference<text::XTextRange> xEnd;
     717             :         // If we want to make this table a floating one.
     718         116 :         bool bFloating = !m_rDMapper_Impl.getTableManager().getTableVertAnchor().isEmpty();
     719             :         // Additional checks: if we can do this.
     720         116 :         if (bFloating && (*m_pTableSeq)[0].getLength() > 0 && (*m_pTableSeq)[0][0].getLength() > 0)
     721             :         {
     722           2 :             xStart = (*m_pTableSeq)[0][0][0];
     723           2 :             uno::Sequence< uno::Sequence< uno::Reference<text::XTextRange> > >& rLastRow = (*m_pTableSeq)[m_pTableSeq->getLength() - 1];
     724           2 :             uno::Sequence< uno::Reference<text::XTextRange> >& rLastCell = rLastRow[rLastRow.getLength() - 1];
     725           2 :             xEnd = rLastCell[1];
     726             :         }
     727         116 :         uno::Reference<text::XTextTable> xTable;
     728             :         try
     729             :         {
     730         116 :             if (m_xText.is())
     731             :             {
     732         184 :                 xTable = m_xText->convertToTable(*m_pTableSeq,
     733             :                         aCellProperties,
     734             :                         aRowProperties,
     735         184 :                         aTableInfo.aTableProperties);
     736             : 
     737          92 :                 if (xTable.is())
     738          92 :                     m_xTableRange = xTable->getAnchor( );
     739             :             }
     740             :         }
     741           0 :         catch ( const lang::IllegalArgumentException &e )
     742             :         {
     743             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     744             :             fprintf( stderr, "Conversion to table error: %s\n",
     745             :                     OUStringToOString( e.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
     746             :             dmapper_logger->chars(std::string("failed to import table!"));
     747             : #else
     748             :             (void)e;
     749             : #endif
     750             :         }
     751           0 :         catch ( const uno::Exception &e )
     752             :         {
     753             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     754             :             fprintf( stderr, "Exception during table creation: %s\n",
     755             :                     OUStringToOString( e.Message, RTL_TEXTENCODING_UTF8 ).getStr( ) );
     756             : #else
     757             :             (void) e;
     758             : #endif
     759             :         }
     760             : 
     761             :         // If we have a table with a start and an end position, we should make it a floating one.
     762         116 :         if (xTable.is() && xStart.is() && xEnd.is())
     763             :         {
     764           2 :             uno::Reference<beans::XPropertySet> xTableProperties(xTable, uno::UNO_QUERY);
     765           2 :             uno::Sequence< beans::PropertyValue > aFrameProperties(16);
     766           2 :             beans::PropertyValue* pFrameProperties = aFrameProperties.getArray();
     767           2 :             pFrameProperties[0].Name = "Width";
     768           2 :             pFrameProperties[0].Value = xTableProperties->getPropertyValue("Width");
     769             : 
     770           2 :             pFrameProperties[1].Name = "LeftBorderDistance";
     771           2 :             pFrameProperties[1].Value <<= sal_Int32(0);
     772           2 :             pFrameProperties[2].Name = "RightBorderDistance";
     773           2 :             pFrameProperties[2].Value <<= sal_Int32(0);
     774           2 :             pFrameProperties[3].Name = "TopBorderDistance";
     775           2 :             pFrameProperties[3].Value <<= sal_Int32(0);
     776           2 :             pFrameProperties[4].Name = "BottomBorderDistance";
     777           2 :             pFrameProperties[4].Value <<= sal_Int32(0);
     778             : 
     779           2 :             pFrameProperties[5].Name = "LeftMargin";
     780           2 :             pFrameProperties[5].Value <<= sal_Int32(0);
     781           2 :             pFrameProperties[6].Name = "RightMargin";
     782           2 :             pFrameProperties[6].Value <<= sal_Int32(0);
     783           2 :             pFrameProperties[7].Name = "TopMargin";
     784           2 :             pFrameProperties[7].Value <<= sal_Int32(0);
     785           2 :             pFrameProperties[8].Name = "BottomMargin";
     786           2 :             pFrameProperties[8].Value <<= sal_Int32(0);
     787             : 
     788           2 :             table::BorderLine2 aEmptyBorder;
     789           2 :             pFrameProperties[9].Name = "TopBorder";
     790           2 :             pFrameProperties[9].Value <<= aEmptyBorder;
     791           2 :             pFrameProperties[10].Name = "BottomBorder";
     792           2 :             pFrameProperties[10].Value <<= aEmptyBorder;
     793           2 :             pFrameProperties[11].Name = "LeftBorder";
     794           2 :             pFrameProperties[11].Value <<= aEmptyBorder;
     795           2 :             pFrameProperties[12].Name = "RightBorder";
     796           2 :             pFrameProperties[12].Value <<= aEmptyBorder;
     797             : 
     798           2 :             pFrameProperties[13].Name = "HoriOrient";
     799           2 :             pFrameProperties[13].Value <<= text::HoriOrientation::NONE;
     800           2 :             pFrameProperties[14].Name = "HoriOrientRelation";
     801           2 :             pFrameProperties[14].Value <<= text::RelOrientation::FRAME;
     802             :             // A non-zero left margin would move the table out of the frame, move the frame itself instead.
     803           2 :             pFrameProperties[15].Name = "HoriOrientPosition";
     804           2 :             pFrameProperties[15].Value <<= xTableProperties->getPropertyValue("LeftMargin");
     805           2 :             xTableProperties->setPropertyValue("LeftMargin", uno::makeAny(sal_Int32(0)));
     806             : 
     807           2 :             uno::Reference< text::XTextContent > xFrame = m_xText->convertToTextFrame(xStart, xEnd, aFrameProperties);
     808         116 :         }
     809             :     }
     810             : 
     811         708 :     m_aTableProperties.reset();
     812         708 :     m_aCellProperties.clear();
     813         708 :     m_aRowProperties.clear();
     814             : 
     815             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     816             :     dmapper_logger->endElement();
     817             :     dmapper_logger->endElement();
     818             : #endif
     819         708 : }
     820             : 
     821         168 : void DomainMapperTableHandler::startRow(unsigned int nCells,
     822             :                                         TablePropertyMapPtr pProps)
     823             : {
     824         168 :     m_aRowProperties.push_back( pProps );
     825         168 :     m_aCellProperties.push_back( PropertyMapVector1() );
     826             : 
     827             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     828             :     dmapper_logger->startElement("table.row");
     829             :     dmapper_logger->attribute("cells", nCells);
     830             :     if (pProps != NULL)
     831             :         pProps->dumpXml(dmapper_logger);
     832             : #endif
     833             : 
     834         168 :     m_pRowSeq = RowSequencePointer_t(new RowSequence_t(nCells));
     835         168 :     m_nCellIndex = 0;
     836         168 : }
     837             : 
     838         168 : void DomainMapperTableHandler::endRow()
     839             : {
     840         168 :     (*m_pTableSeq)[m_nRowIndex] = *m_pRowSeq;
     841         168 :     ++m_nRowIndex;
     842         168 :     m_nCellIndex = 0;
     843             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     844             :     dmapper_logger->endElement();
     845             : #endif
     846         168 : }
     847             : 
     848         580 : void DomainMapperTableHandler::startCell(const Handle_t & start,
     849             :                                          TablePropertyMapPtr pProps )
     850             : {
     851         580 :     sal_uInt32 nRow = m_aRowProperties.size();
     852         580 :     if ( pProps.get( ) )
     853         430 :         m_aCellProperties[nRow - 1].push_back( pProps );
     854             :     else
     855             :     {
     856             :         // Adding an empty cell properties map to be able to get
     857             :         // the table defaults properties
     858         150 :         TablePropertyMapPtr pEmptyProps( new TablePropertyMap( ) );
     859         150 :         m_aCellProperties[nRow - 1].push_back( pEmptyProps );
     860             :     }
     861             : 
     862             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     863             :     dmapper_logger->startElement("table.cell");
     864             :     dmapper_logger->startElement("table.cell.start");
     865             :     dmapper_logger->chars(toString(start));
     866             :     dmapper_logger->endElement();
     867             :     lcl_printProperties( pProps );
     868             : #endif
     869             : 
     870             :     //add a new 'row' of properties
     871         580 :     m_pCellSeq = CellSequencePointer_t(new CellSequence_t(2));
     872         580 :     if (!start.get())
     873         632 :         return;
     874         528 :     (*m_pCellSeq)[0] = start->getStart();
     875             : }
     876             : 
     877         580 : void DomainMapperTableHandler::endCell(const Handle_t & end)
     878             : {
     879             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     880             :     dmapper_logger->startElement("table.cell.end");
     881             :     dmapper_logger->chars(toString(end));
     882             :     dmapper_logger->endElement();
     883             :     dmapper_logger->endElement();
     884             : #endif
     885             : 
     886         580 :     if (!end.get())
     887         632 :         return;
     888         528 :     (*m_pCellSeq)[1] = end->getEnd();
     889         528 :     (*m_pRowSeq)[m_nCellIndex] = *m_pCellSeq;
     890         528 :     ++m_nCellIndex;
     891             : }
     892             : 
     893          30 : }}
     894             : 
     895             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10