LCOV - code coverage report
Current view: top level - writerfilter/source/dmapper - DomainMapperTableHandler.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 441 441 100.0 %
Date: 2014-04-11 Functions: 20 20 100.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/beans/XPropertyState.hpp>
      23             : #include <com/sun/star/container/XEnumerationAccess.hpp>
      24             : #include <com/sun/star/table/TableBorderDistances.hpp>
      25             : #include <com/sun/star/table/TableBorder.hpp>
      26             : #include <com/sun/star/table/BorderLine2.hpp>
      27             : #include <com/sun/star/table/XCellRange.hpp>
      28             : #include <com/sun/star/text/HoriOrientation.hpp>
      29             : #include <com/sun/star/text/RelOrientation.hpp>
      30             : #include <com/sun/star/text/SizeType.hpp>
      31             : #include <dmapperLoggers.hxx>
      32             : 
      33             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
      34             : #include <PropertyMapHelper.hxx>
      35             : #include <rtl/ustring.hxx>
      36             : #endif
      37             : 
      38             : namespace writerfilter {
      39             : namespace dmapper {
      40             : 
      41             : using namespace ::com::sun::star;
      42             : using namespace ::std;
      43             : 
      44             : #define DEF_BORDER_DIST 190  //0,19cm
      45             : 
      46             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
      47             : static void  lcl_printProperties( PropertyMapPtr pProps )
      48             : {
      49             :     if( pProps.get() )
      50             :     {
      51             :         dmapper_logger->startElement("properties");
      52             : 
      53             :         PropertyMap::const_iterator aMapIter = pProps->begin();
      54             :         PropertyMap::const_iterator aEndIter = pProps->end();
      55             :         PropertyNameSupplier& rPropSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
      56             :         for( ; aMapIter != aEndIter; ++aMapIter )
      57             :         {
      58             :             SAL_INFO("writerfilter", rPropSupplier.GetName(aMapIter->first));
      59             : 
      60             :             table::BorderLine2 aLine;
      61             :             sal_Int32 nColor;
      62             :             if ( aMapIter->second.getValue() >>= aLine )
      63             :             {
      64             :                 dmapper_logger->startElement("borderline");
      65             :                 dmapper_logger->attribute("color", aLine.Color);
      66             :                 dmapper_logger->attribute("inner", aLine.InnerLineWidth);
      67             :                 dmapper_logger->attribute("outer", aLine.OuterLineWidth);
      68             :                 dmapper_logger->endElement();
      69             :             }
      70             :             else if ( aMapIter->second.getValue() >>= nColor )
      71             :             {
      72             :                 dmapper_logger->startElement("color");
      73             :                 dmapper_logger->attribute("number", nColor);
      74             :                 dmapper_logger->endElement();
      75             :             }
      76             :         }
      77             : 
      78             :         dmapper_logger->endElement();
      79             :     }
      80             : }
      81             : #endif
      82             : 
      83        1191 : DomainMapperTableHandler::DomainMapperTableHandler(TextReference_t xText, DomainMapper_Impl& rDMapper_Impl)
      84             :     : m_xText(xText),
      85             :         m_rDMapper_Impl( rDMapper_Impl ),
      86             :         m_nCellIndex(0),
      87        1191 :         m_nRowIndex(0)
      88             : {
      89        1191 : }
      90             : 
      91        2382 : DomainMapperTableHandler::~DomainMapperTableHandler()
      92             : {
      93        2382 : }
      94             : 
      95        3394 : void DomainMapperTableHandler::startTable(unsigned int nRows,
      96             :                                           unsigned int /*nDepth*/,
      97             :                                           TablePropertyMapPtr pProps)
      98             : {
      99        3394 :     m_aTableProperties = pProps;
     100        3394 :     m_pTableSeq = TableSequencePointer_t(new TableSequence_t(nRows));
     101        3394 :     m_nRowIndex = 0;
     102             : 
     103             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     104             :     dmapper_logger->startElement("tablehandler.table");
     105             :     dmapper_logger->attribute("rows", nRows);
     106             : 
     107             :     if (pProps.get() != NULL)
     108             :         pProps->dumpXml( dmapper_logger );
     109             : #endif
     110        3394 : }
     111             : 
     112             : 
     113             : 
     114         274 : PropertyMapPtr lcl_SearchParentStyleSheetAndMergeProperties(const StyleSheetEntryPtr pStyleSheet, StyleSheetTablePtr pStyleSheetTable)
     115             : {
     116         274 :     PropertyMapPtr pRet;
     117         274 :     if(!pStyleSheet->sBaseStyleIdentifier.isEmpty())
     118             :     {
     119         137 :         const StyleSheetEntryPtr pParentStyleSheet = pStyleSheetTable->FindStyleSheetByISTD( pStyleSheet->sBaseStyleIdentifier );
     120         137 :         pRet = lcl_SearchParentStyleSheetAndMergeProperties( pParentStyleSheet, pStyleSheetTable );
     121             :     }
     122             :     else
     123             :     {
     124         137 :         pRet.reset( new PropertyMap );
     125             :     }
     126             : 
     127         274 :     pRet->InsertProps(pStyleSheet->pProperties);
     128             : 
     129         274 :     return pRet;
     130             : }
     131             : 
     132        6450 : void lcl_mergeBorder( PropertyIds nId, PropertyMapPtr pOrig, PropertyMapPtr pDest )
     133             : {
     134        6450 :     PropertyMap::iterator pOrigIt = pOrig->find(nId);
     135             : 
     136        6450 :     if ( pOrigIt != pOrig->end( ) )
     137             :     {
     138        4519 :         pDest->Insert( nId, pOrigIt->second.getValue(), false );
     139             :     }
     140        6450 : }
     141             : 
     142        6720 : void lcl_computeCellBorders( PropertyMapPtr pTableBorders, PropertyMapPtr pCellProps,
     143             :         sal_Int32 nCell, sal_Int32 nRow, bool bIsEndCol, bool bIsEndRow )
     144             : {
     145        6720 :     PropertyMap::iterator aVerticalIter = pCellProps->find(META_PROP_VERTICAL_BORDER);
     146        6720 :     PropertyMap::iterator aHorizontalIter = pCellProps->find(META_PROP_HORIZONTAL_BORDER);
     147             : 
     148             :     // Handle the vertical and horizontal borders
     149        6720 :     bool bHasVert = ( aVerticalIter != pCellProps->end(  ) );
     150        6720 :     uno::Any aVertProp;
     151        6720 :     if ( !bHasVert )
     152             :     {
     153        5247 :         aVerticalIter = pTableBorders->find(META_PROP_VERTICAL_BORDER);
     154        5247 :         bHasVert = ( aVerticalIter != pTableBorders->end( ) );
     155        5247 :         if ( bHasVert )
     156        3436 :             aVertProp = aVerticalIter->second.getValue();
     157             :     }
     158             :     else
     159             :     {
     160        1473 :         aVertProp = aVerticalIter->second.getValue();
     161        1473 :         pCellProps->erase( aVerticalIter );
     162             :     }
     163             : 
     164        6720 :     bool bHasHoriz = ( aHorizontalIter != pCellProps->end(  ) );
     165       13440 :     uno::Any aHorizProp;
     166        6720 :     if ( !bHasHoriz )
     167             :     {
     168        5216 :         aHorizontalIter = pTableBorders->find(META_PROP_HORIZONTAL_BORDER);
     169        5216 :         bHasHoriz = ( aHorizontalIter != pTableBorders->end( ) );
     170        5216 :         if ( bHasHoriz )
     171        3328 :             aHorizProp = aHorizontalIter->second.getValue();
     172             :     }
     173             :     else
     174             :     {
     175        1504 :         aHorizProp = aHorizontalIter->second.getValue();
     176        1504 :         pCellProps->erase( aHorizontalIter );
     177             :     }
     178             : 
     179        6720 :     if ( nCell == 0 )
     180             :     {
     181        2188 :         lcl_mergeBorder( PROP_LEFT_BORDER, pTableBorders, pCellProps );
     182        2188 :         if ( bHasVert )
     183        1602 :             pCellProps->Insert( PROP_RIGHT_BORDER, aVertProp, false );
     184             :     }
     185             : 
     186        6720 :     if ( bIsEndCol )
     187             :     {
     188        2188 :         lcl_mergeBorder( PROP_RIGHT_BORDER, pTableBorders, pCellProps );
     189        2188 :         if ( bHasVert )
     190        1606 :             pCellProps->Insert( PROP_LEFT_BORDER, aVertProp, false );
     191             :     }
     192             : 
     193        6720 :     if ( nCell > 0 && !bIsEndCol )
     194             :     {
     195        2660 :         if ( bHasVert )
     196             :         {
     197        1882 :             pCellProps->Insert( PROP_RIGHT_BORDER, aVertProp, false );
     198        1882 :             pCellProps->Insert( PROP_LEFT_BORDER, aVertProp, false );
     199             :         }
     200             :     }
     201             : 
     202        6720 :     if ( nRow == 0 )
     203             :     {
     204         998 :         lcl_mergeBorder( PROP_TOP_BORDER, pTableBorders, pCellProps );
     205         998 :         if ( bHasHoriz )
     206         535 :             pCellProps->Insert( PROP_BOTTOM_BORDER, aHorizProp, false );
     207             :     }
     208             : 
     209        6720 :     if ( bIsEndRow )
     210             :     {
     211        1076 :         lcl_mergeBorder( PROP_BOTTOM_BORDER, pTableBorders, pCellProps );
     212        1076 :         if ( bHasHoriz )
     213         616 :             pCellProps->Insert( PROP_TOP_BORDER, aHorizProp, false );
     214             :     }
     215             : 
     216        6720 :     if ( nRow > 0 && !bIsEndRow )
     217             :     {
     218        5054 :         if ( bHasHoriz )
     219             :         {
     220        3841 :             pCellProps->Insert( PROP_TOP_BORDER, aHorizProp, false );
     221        3841 :             pCellProps->Insert( PROP_BOTTOM_BORDER, aHorizProp, false );
     222             :         }
     223        6720 :     }
     224        6720 : }
     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        3531 : struct TableInfo
     260             : {
     261             :     sal_Int32 nLeftBorderDistance;
     262             :     sal_Int32 nRightBorderDistance;
     263             :     sal_Int32 nTopBorderDistance;
     264             :     sal_Int32 nBottomBorderDistance;
     265             :     sal_Int32 nTblLook;
     266             :     sal_Int32 nNestLevel;
     267             :     PropertyMapPtr pTableDefaults;
     268             :     PropertyMapPtr pTableBorders;
     269             :     TableStyleSheetEntry* pTableStyle;
     270             :     TablePropertyValues_t aTableProperties;
     271             : 
     272        3531 :     TableInfo()
     273             :     : nLeftBorderDistance(DEF_BORDER_DIST)
     274             :     , nRightBorderDistance(DEF_BORDER_DIST)
     275             :     , nTopBorderDistance(0)
     276             :     , nBottomBorderDistance(0)
     277             :     , nTblLook(0x4a0)
     278             :     , nNestLevel(0)
     279        3531 :     , pTableDefaults(new PropertyMap)
     280        3531 :     , pTableBorders(new PropertyMap)
     281       10593 :     , pTableStyle(NULL)
     282             :     {
     283        3531 :     }
     284             : 
     285             : };
     286             : 
     287             : namespace
     288             : {
     289             : 
     290        2924 : bool lcl_extractTableBorderProperty(PropertyMapPtr pTableProperties, const PropertyIds nId, TableInfo& rInfo, table::BorderLine2& rLine)
     291             : {
     292        2924 :     PropertyMap::iterator aTblBorderIter = pTableProperties->find(nId);
     293        2924 :     if( aTblBorderIter != pTableProperties->end() )
     294             :     {
     295        1719 :         OSL_VERIFY(aTblBorderIter->second.getValue() >>= rLine);
     296             : 
     297        1719 :         rInfo.pTableBorders->Insert( nId, uno::makeAny( rLine ) );
     298        1719 :         PropertyMap::iterator pIt = rInfo.pTableDefaults->find(nId);
     299        1719 :         if ( pIt != rInfo.pTableDefaults->end( ) )
     300        1219 :             rInfo.pTableDefaults->erase( pIt );
     301             : 
     302        1719 :         return true;
     303             :     }
     304             : 
     305        1205 :     return false;
     306             : }
     307             : 
     308             : }
     309             : 
     310          53 : void lcl_DecrementHoriOrientPosition(uno::Sequence<beans::PropertyValue>& rFrameProperties, sal_Int32 nAmount)
     311             : {
     312             :     // Shifts the frame left by the given value.
     313         795 :     for (sal_Int32 i = 0; i < rFrameProperties.getLength(); ++i)
     314             :     {
     315         795 :         beans::PropertyValue& rPropertyValue = rFrameProperties[i];
     316         795 :         if (rPropertyValue.Name == "HoriOrientPosition")
     317             :         {
     318          53 :             sal_Int32 nValue = rPropertyValue.Value.get<sal_Int32>();
     319          53 :             nValue -= nAmount;
     320          53 :             rPropertyValue.Value <<= nValue;
     321         106 :             return;
     322             :         }
     323             :     }
     324             : }
     325             : 
     326        3394 : TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo & rInfo, uno::Sequence<beans::PropertyValue>& rFrameProperties)
     327             : {
     328             :     // will receive the table style if any
     329        3394 :     TableStyleSheetEntry* pTableStyle = NULL;
     330             : 
     331        3394 :     if( m_aTableProperties.get() )
     332             :     {
     333             :         //create properties from the table attributes
     334             :         //...pPropMap->Insert( PROP_LEFT_MARGIN, uno::makeAny( m_nLeftMargin - m_nGapHalf ));
     335             :         //pPropMap->Insert( PROP_HORI_ORIENT, uno::makeAny( text::HoriOrientation::RIGHT ));
     336         396 :         sal_Int32 nGapHalf = 0;
     337         396 :         sal_Int32 nLeftMargin = 0;
     338         396 :         sal_Int32 nTableWidth = 0;
     339         396 :         sal_Int32 nTableWidthType = text::SizeType::FIX;
     340             : 
     341             :         PropertyMap::iterator aTableStyleIter =
     342         396 :         m_aTableProperties->find(META_PROP_TABLE_STYLE_NAME);
     343         396 :         uno::Sequence< beans::PropertyValue > aGrabBag( 5 );
     344         396 :         sal_Int32 nGrabBagSize = 0;
     345         396 :         if(aTableStyleIter != m_aTableProperties->end())
     346             :         {
     347             :             // Apply table style properties recursively
     348         140 :             OUString sTableStyleName;
     349         140 :             aTableStyleIter->second.getValue() >>= sTableStyleName;
     350         280 :             StyleSheetTablePtr pStyleSheetTable = m_rDMapper_Impl.GetStyleSheetTable();
     351         280 :             const StyleSheetEntryPtr pStyleSheet = pStyleSheetTable->FindStyleSheetByISTD( sTableStyleName );
     352         140 :             pTableStyle = dynamic_cast<TableStyleSheetEntry*>( pStyleSheet.get( ) );
     353         140 :             m_aTableProperties->erase( aTableStyleIter );
     354             : 
     355         140 :             aGrabBag[0].Name = "TableStyleName";
     356         140 :             aGrabBag[0].Value = uno::makeAny( sTableStyleName );
     357         140 :             nGrabBagSize++;
     358             : 
     359         140 :             if( pStyleSheet )
     360             :             {
     361             :                 // First get the style properties, then the table ones
     362         137 :                 PropertyMapPtr pTableProps( m_aTableProperties );
     363         274 :                 TablePropertyMapPtr pEmptyProps( new TablePropertyMap );
     364             : 
     365         137 :                 m_aTableProperties = pEmptyProps;
     366             : 
     367         274 :                 PropertyMapPtr pMergedProperties = lcl_SearchParentStyleSheetAndMergeProperties(pStyleSheet, pStyleSheetTable);
     368             : 
     369         137 :                 table::BorderLine2 aBorderLine;
     370         274 :                 TableInfo rStyleInfo;
     371         137 :                 if (lcl_extractTableBorderProperty(pMergedProperties, PROP_TOP_BORDER, rStyleInfo, aBorderLine))
     372             :                 {
     373         128 :                     aGrabBag[1].Name = "TableStyleTopBorder";
     374         128 :                     aGrabBag[1].Value = uno::makeAny( aBorderLine );
     375         128 :                     nGrabBagSize++;
     376             :                 }
     377         137 :                 if (lcl_extractTableBorderProperty(pMergedProperties, PROP_BOTTOM_BORDER, rStyleInfo, aBorderLine))
     378             :                 {
     379         128 :                     aGrabBag[2].Name = "TableStyleBottomBorder";
     380         128 :                     aGrabBag[2].Value = uno::makeAny( aBorderLine );
     381         128 :                     nGrabBagSize++;
     382             :                 }
     383         137 :                 if (lcl_extractTableBorderProperty(pMergedProperties, PROP_LEFT_BORDER, rStyleInfo, aBorderLine))
     384             :                 {
     385         122 :                     aGrabBag[3].Name = "TableStyleLeftBorder";
     386         122 :                     aGrabBag[3].Value = uno::makeAny( aBorderLine );
     387         122 :                     nGrabBagSize++;
     388             :                 }
     389         137 :                 if (lcl_extractTableBorderProperty(pMergedProperties, PROP_RIGHT_BORDER, rStyleInfo, aBorderLine))
     390             :                 {
     391         122 :                     aGrabBag[4].Name = "TableStyleRightBorder";
     392         122 :                     aGrabBag[4].Value = uno::makeAny( aBorderLine );
     393         122 :                     nGrabBagSize++;
     394             :                 }
     395             : 
     396             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     397             :                 dmapper_logger->startElement("mergedProps");
     398             :                 pMergedProperties->dumpXml( dmapper_logger );
     399             :                 dmapper_logger->endElement();
     400             : #endif
     401             : 
     402         137 :                 m_aTableProperties->InsertProps(pMergedProperties);
     403         274 :                 m_aTableProperties->InsertProps(pTableProps);
     404             : 
     405             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     406             :                 dmapper_logger->startElement("TableProperties");
     407             :                 m_aTableProperties->dumpXml( dmapper_logger );
     408             :                 dmapper_logger->endElement();
     409             : #endif
     410         140 :             }
     411             :         }
     412             : 
     413             :         PropertyMap::iterator const aTblLookIter =
     414         396 :             m_aTableProperties->find(PROP_TBL_LOOK);
     415         396 :         if(aTblLookIter != m_aTableProperties->end())
     416             :         {
     417         236 :             aTblLookIter->second.getValue() >>= rInfo.nTblLook;
     418         236 :             m_aTableProperties->erase( aTblLookIter );
     419             :         }
     420             : 
     421             :         // Set the table default attributes for the cells
     422         396 :         rInfo.pTableDefaults->InsertProps(m_aTableProperties);
     423             : 
     424             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     425             :         dmapper_logger->startElement("TableDefaults");
     426             :         rInfo.pTableDefaults->dumpXml( dmapper_logger );
     427             :         dmapper_logger->endElement();
     428             : #endif
     429             : 
     430         396 :         if( nGrabBagSize > 0 )
     431             :         {
     432         140 :             aGrabBag.realloc( nGrabBagSize );
     433         140 :             m_aTableProperties->Insert( PROP_TABLE_INTEROP_GRAB_BAG, uno::makeAny( aGrabBag ) );
     434             :         }
     435             : 
     436         396 :         m_aTableProperties->getValue( TablePropertyMap::GAP_HALF, nGapHalf );
     437         396 :         m_aTableProperties->getValue( TablePropertyMap::LEFT_MARGIN, nLeftMargin );
     438             : 
     439             :         m_aTableProperties->getValue( TablePropertyMap::CELL_MAR_LEFT,
     440         396 :                                      rInfo.nLeftBorderDistance );
     441             :         m_aTableProperties->getValue( TablePropertyMap::CELL_MAR_RIGHT,
     442         396 :                                      rInfo.nRightBorderDistance );
     443             :         m_aTableProperties->getValue( TablePropertyMap::CELL_MAR_TOP,
     444         396 :                                      rInfo.nTopBorderDistance );
     445             :         m_aTableProperties->getValue( TablePropertyMap::CELL_MAR_BOTTOM,
     446         396 :                                      rInfo.nBottomBorderDistance );
     447             : 
     448         396 :         table::TableBorderDistances aDistances;
     449             :         aDistances.IsTopDistanceValid =
     450             :         aDistances.IsBottomDistanceValid =
     451             :         aDistances.IsLeftDistanceValid =
     452         396 :         aDistances.IsRightDistanceValid = sal_True;
     453         396 :         aDistances.TopDistance = static_cast<sal_Int16>( rInfo.nTopBorderDistance );
     454         396 :         aDistances.BottomDistance = static_cast<sal_Int16>( rInfo.nBottomBorderDistance );
     455         396 :         aDistances.LeftDistance = static_cast<sal_Int16>( rInfo.nLeftBorderDistance );
     456         396 :         aDistances.RightDistance = static_cast<sal_Int16>( rInfo.nRightBorderDistance );
     457             : 
     458         396 :         m_aTableProperties->Insert( PROP_TABLE_BORDER_DISTANCES, uno::makeAny( aDistances ) );
     459             : 
     460         396 :         if (rFrameProperties.hasElements())
     461          31 :             lcl_DecrementHoriOrientPosition(rFrameProperties, rInfo.nLeftBorderDistance);
     462             : 
     463             :         // Set table above/bottom spacing to 0.
     464         396 :         m_aTableProperties->Insert( PROP_TOP_MARGIN, uno::makeAny( sal_Int32( 0 ) ) );
     465         396 :         m_aTableProperties->Insert( PROP_BOTTOM_MARGIN, uno::makeAny( sal_Int32( 0 ) ) );
     466             : 
     467             :         //table border settings
     468         396 :         table::TableBorder aTableBorder;
     469         396 :         table::BorderLine2 aBorderLine, aLeftBorder;
     470             : 
     471         396 :         if (lcl_extractTableBorderProperty(m_aTableProperties, PROP_TOP_BORDER, rInfo, aBorderLine))
     472             :         {
     473         211 :             aTableBorder.TopLine = aBorderLine;
     474         211 :             aTableBorder.IsTopLineValid = sal_True;
     475             :         }
     476         396 :         if (lcl_extractTableBorderProperty(m_aTableProperties, PROP_BOTTOM_BORDER, rInfo, aBorderLine))
     477             :         {
     478         209 :             aTableBorder.BottomLine = aBorderLine;
     479         209 :             aTableBorder.IsBottomLineValid = sal_True;
     480             :         }
     481         396 :         if (lcl_extractTableBorderProperty(m_aTableProperties, PROP_LEFT_BORDER, rInfo, aLeftBorder))
     482             :         {
     483         205 :             aTableBorder.LeftLine = aLeftBorder;
     484         205 :             aTableBorder.IsLeftLineValid = sal_True;
     485             :             // Only top level table position depends on border width
     486         205 :             if (rInfo.nNestLevel == 1)
     487             :             {
     488         194 :                 if (!rFrameProperties.hasElements())
     489         172 :                     rInfo.nLeftBorderDistance += aLeftBorder.LineWidth * 0.5;
     490             :                 else
     491          22 :                     lcl_DecrementHoriOrientPosition(rFrameProperties, aLeftBorder.LineWidth * 0.5);
     492             :             }
     493             :         }
     494         396 :         if (lcl_extractTableBorderProperty(m_aTableProperties, PROP_RIGHT_BORDER, rInfo, aBorderLine))
     495             :         {
     496         202 :             aTableBorder.RightLine = aBorderLine;
     497         202 :             aTableBorder.IsRightLineValid = sal_True;
     498             :         }
     499         396 :         if (lcl_extractTableBorderProperty(m_aTableProperties, META_PROP_HORIZONTAL_BORDER, rInfo, aBorderLine))
     500             :         {
     501         194 :             aTableBorder.HorizontalLine = aBorderLine;
     502         194 :             aTableBorder.IsHorizontalLineValid = sal_True;
     503             :         }
     504         396 :         if (lcl_extractTableBorderProperty(m_aTableProperties, META_PROP_VERTICAL_BORDER, rInfo, aBorderLine))
     505             :         {
     506         198 :             aTableBorder.VerticalLine = aBorderLine;
     507         198 :             aTableBorder.IsVerticalLineValid = sal_True;
     508             :         }
     509             : 
     510         396 :         aTableBorder.Distance = 0;
     511         396 :         aTableBorder.IsDistanceValid = sal_False;
     512             : 
     513         396 :         m_aTableProperties->Insert( PROP_TABLE_BORDER, uno::makeAny( aTableBorder ) );
     514             : 
     515             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     516             :         lcl_debug_TableBorder(aTableBorder);
     517             : #endif
     518             : 
     519             :         // Table position in Office is computed in 2 different ways :
     520             :         // - top level tables: the goal is to have in-cell text starting at table indent pos (tblInd),
     521             :         //   so table's position depends on table's cells margin
     522             :         // - nested tables: the goal is to have left-most border starting at table_indent pos
     523         396 :         if (rInfo.nNestLevel > 1)
     524             :         {
     525          32 :             m_aTableProperties->Insert( PROP_LEFT_MARGIN, uno::makeAny( nLeftMargin - nGapHalf ));
     526             :         }
     527             :         else
     528             :         {
     529         364 :             m_aTableProperties->Insert( PROP_LEFT_MARGIN, uno::makeAny( nLeftMargin - nGapHalf - rInfo.nLeftBorderDistance ));
     530             :         }
     531             : 
     532         396 :         m_aTableProperties->getValue( TablePropertyMap::TABLE_WIDTH, nTableWidth );
     533         396 :         m_aTableProperties->getValue( TablePropertyMap::TABLE_WIDTH_TYPE, nTableWidthType );
     534         396 :         if( nTableWidthType == text::SizeType::FIX )
     535             :         {
     536         370 :             if( nTableWidth > 0 )
     537         362 :                 m_aTableProperties->Insert( PROP_WIDTH, uno::makeAny( nTableWidth ));
     538             :         }
     539             :         else
     540             :         {
     541          26 :             m_aTableProperties->Insert( PROP_RELATIVE_WIDTH, uno::makeAny( sal_Int16( nTableWidth ) ) );
     542          26 :             m_aTableProperties->Insert( PROP_IS_WIDTH_RELATIVE, uno::makeAny( sal_Bool( sal_True ) ) );
     543             :         }
     544             : 
     545         396 :         sal_Int32 nHoriOrient = text::HoriOrientation::LEFT_AND_WIDTH;
     546         396 :         m_aTableProperties->getValue( TablePropertyMap::HORI_ORIENT, nHoriOrient ) ;
     547         396 :         m_aTableProperties->Insert( PROP_HORI_ORIENT, uno::makeAny( sal_Int16(nHoriOrient) ) );
     548             : 
     549             :         //fill default value - if not available
     550             :         const PropertyMap::const_iterator aRepeatIter =
     551         396 :         m_aTableProperties->find(PROP_HEADER_ROW_COUNT);
     552         396 :         if( aRepeatIter == m_aTableProperties->end() )
     553         390 :             m_aTableProperties->Insert( PROP_HEADER_ROW_COUNT, uno::makeAny( (sal_Int32)0 ));
     554             : 
     555         396 :         rInfo.aTableProperties = m_aTableProperties->GetPropertyValues();
     556             : 
     557             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     558             :         dmapper_logger->startElement("debug.tableprops");
     559             :         m_aTableProperties->dumpXml( dmapper_logger );
     560             :         dmapper_logger->endElement();
     561             : #endif
     562             : 
     563             :     }
     564             : 
     565        3394 :     return pTableStyle;
     566             : }
     567             : 
     568             : #define CNF_FIRST_ROW               0x800
     569             : #define CNF_LAST_ROW                0x400
     570             : #define CNF_FIRST_COLUMN            0x200
     571             : #define CNF_LAST_COLUMN             0x100
     572             : #define CNF_ODD_VBAND               0x080
     573             : #define CNF_EVEN_VBAND              0x040
     574             : #define CNF_ODD_HBAND               0x020
     575             : #define CNF_EVEN_HBAND              0x010
     576             : #define CNF_FIRST_ROW_LAST_COLUMN   0x008
     577             : #define CNF_FIRST_ROW_FIRST_COLUMN  0x004
     578             : #define CNF_LAST_ROW_LAST_COLUMN    0x002
     579             : #define CNF_LAST_ROW_FIRST_COLUMN   0x001
     580             : 
     581        3394 : CellPropertyValuesSeq_t DomainMapperTableHandler::endTableGetCellProperties(TableInfo & rInfo, std::vector<HorizontallyMergedCell>& rMerges)
     582             : {
     583             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     584             :     dmapper_logger->startElement("getCellProperties");
     585             : #endif
     586             : 
     587        3394 :     CellPropertyValuesSeq_t aCellProperties( m_aCellProperties.size() );
     588             : 
     589        3394 :     if ( !m_aCellProperties.size() )
     590             :     {
     591             :         #ifdef DEBUG_DOMAINMAPPER
     592             :         dmapper_logger->endElement();
     593             :         #endif
     594        2998 :         return aCellProperties;
     595             :     }
     596             :     // std::vector< std::vector<PropertyMapPtr> > m_aCellProperties
     597         396 :     PropertyMapVector2::const_iterator aRowOfCellsIterator = m_aCellProperties.begin();
     598         396 :     PropertyMapVector2::const_iterator aRowOfCellsIteratorEnd = m_aCellProperties.end();
     599         396 :     PropertyMapVector2::const_iterator aLastRowIterator = m_aCellProperties.end() - 1;
     600         396 :     sal_Int32 nRow = 0;
     601             : 
     602             :     //it's a uno::Sequence< beans::PropertyValues >*
     603         396 :     RowPropertyValuesSeq_t* pCellProperties = aCellProperties.getArray();
     604         396 :     PropertyMapVector1::const_iterator aRowIter = m_aRowProperties.begin();
     605        2987 :     while( aRowOfCellsIterator != aRowOfCellsIteratorEnd )
     606             :     {
     607             :         //aRowOfCellsIterator points to a vector of PropertyMapPtr
     608        2195 :         PropertyMapVector1::const_iterator aCellIterator = aRowOfCellsIterator->begin();
     609        2195 :         PropertyMapVector1::const_iterator aCellIteratorEnd = aRowOfCellsIterator->end();
     610             : 
     611        2195 :         sal_Int32 nRowStyleMask = 0;
     612             : 
     613        2195 :         if (aRowOfCellsIterator==m_aCellProperties.begin())
     614             :         {
     615         396 :             if(rInfo.nTblLook&0x20)
     616         332 :                 nRowStyleMask |= CNF_FIRST_ROW;     // first row style used
     617             :         }
     618        1799 :         else if (aRowOfCellsIterator==aLastRowIterator)
     619             :         {
     620         217 :             if(rInfo.nTblLook&0x40)
     621           2 :                 nRowStyleMask |= CNF_LAST_ROW;      // last row style used
     622             :         }
     623        1582 :         else if (aRowIter->get() && aRowIter->get()->find(PROP_TBL_HEADER) != aRowIter->get()->end())
     624          40 :             nRowStyleMask |= CNF_FIRST_ROW; // table header implies first row
     625        2195 :         if(!nRowStyleMask)                          // if no row style used yet
     626             :         {
     627             :             // banding used only if not first and or last row style used
     628        1821 :             if(!(rInfo.nTblLook&0x200))
     629             :             {   // hbanding used
     630        1821 :                 int n = nRow + 1;
     631        1821 :                 if(rInfo.nTblLook&0x20)
     632        1460 :                     n++;
     633        1821 :                 if(n & 1)
     634         989 :                     nRowStyleMask = CNF_ODD_HBAND;
     635             :                 else
     636         832 :                     nRowStyleMask = CNF_EVEN_HBAND;
     637             :             }
     638             :         }
     639             : 
     640        2195 :         sal_Int32 nCell = 0;
     641        2195 :         pCellProperties[nRow].realloc( aRowOfCellsIterator->size() );
     642        2195 :         beans::PropertyValues* pSingleCellProperties = pCellProperties[nRow].getArray();
     643       11110 :         while( aCellIterator != aCellIteratorEnd )
     644             :         {
     645        6720 :             PropertyMapPtr pAllCellProps( new PropertyMap );
     646             : 
     647        6720 :             PropertyMapVector1::const_iterator aLastCellIterator = aRowOfCellsIterator->end() - 1;
     648        6720 :             bool bIsEndCol = aCellIterator == aLastCellIterator;
     649        6720 :             bool bIsEndRow = aRowOfCellsIterator == aLastRowIterator;
     650             : 
     651             :             //aCellIterator points to a PropertyMapPtr;
     652        6720 :             if( aCellIterator->get() )
     653             :             {
     654        6720 :                 if ( rInfo.pTableDefaults->size( ) )
     655        3692 :                     pAllCellProps->InsertProps(rInfo.pTableDefaults);
     656             : 
     657        6720 :                 sal_Int32 nCellStyleMask = 0;
     658        6720 :                 if (aCellIterator==aRowOfCellsIterator->begin())
     659             :                 {
     660        2188 :                     if(rInfo.nTblLook&0x80)
     661        1819 :                         nCellStyleMask = CNF_FIRST_COLUMN;      // first col style used
     662             :                 }
     663        4532 :                 else if (bIsEndCol)
     664             :                 {
     665        1872 :                     if(rInfo.nTblLook&0x100)
     666          13 :                         nCellStyleMask = CNF_LAST_COLUMN;       // last col style used
     667             :                 }
     668        6720 :                 if(!nCellStyleMask)                 // if no cell style is used yet
     669             :                 {
     670        4888 :                     if(!(rInfo.nTblLook&0x400))
     671             :                     {   // vbanding used
     672        1335 :                         int n = nCell + 1;
     673        1335 :                         if(rInfo.nTblLook&0x80)
     674          40 :                             n++;
     675        1335 :                         if(n & 1)
     676         731 :                             nCellStyleMask = CNF_ODD_VBAND;
     677             :                         else
     678         604 :                             nCellStyleMask = CNF_EVEN_VBAND;
     679             :                     }
     680             :                 }
     681        6720 :                 sal_Int32 nCnfStyleMask = nCellStyleMask + nRowStyleMask;
     682        6720 :                 if(nCnfStyleMask == CNF_FIRST_COLUMN + CNF_FIRST_ROW)
     683         364 :                     nCnfStyleMask |= CNF_FIRST_ROW_FIRST_COLUMN;
     684        6356 :                 else if(nCnfStyleMask == CNF_FIRST_COLUMN + CNF_LAST_ROW)
     685           2 :                     nCnfStyleMask |= CNF_LAST_ROW_FIRST_COLUMN;
     686        6354 :                 else if(nCnfStyleMask == CNF_LAST_COLUMN + CNF_FIRST_ROW)
     687           6 :                     nCnfStyleMask |= CNF_FIRST_ROW_LAST_COLUMN;
     688        6348 :                 else if(nCnfStyleMask == CNF_LAST_COLUMN + CNF_LAST_ROW)
     689           2 :                     nCnfStyleMask |= CNF_LAST_ROW_LAST_COLUMN;
     690             : 
     691        6720 :                 if ( rInfo.pTableStyle )
     692             :                 {
     693        3755 :                     PropertyMapPtr pStyleProps = rInfo.pTableStyle->GetProperties( nCnfStyleMask );
     694        3755 :                     pAllCellProps->InsertProps( pStyleProps );
     695             :                 }
     696             : 
     697             :                 // Remove properties from style/row that aren't allowed in cells
     698        6720 :                 const PropertyMap::iterator aDefaultRepeatIt = pAllCellProps->find(PROP_HEADER_ROW_COUNT);
     699        6720 :                 if ( aDefaultRepeatIt != pAllCellProps->end( ) )
     700         355 :                     pAllCellProps->erase( aDefaultRepeatIt );
     701        6720 :                 const PropertyMap::iterator aDefaultRepeatIt2 = pAllCellProps->find(PROP_PARA_LINE_SPACING);
     702        6720 :                 if ( aDefaultRepeatIt2 != pAllCellProps->end( ) )
     703        2629 :                     pAllCellProps->erase( aDefaultRepeatIt2 );
     704             : 
     705             :                 // Then add the cell properties
     706        6720 :                 pAllCellProps->InsertProps(*aCellIterator);
     707        6720 :                 aCellIterator->get( )->swap( *pAllCellProps.get( ) );
     708             : 
     709             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     710             :                 dmapper_logger->startElement("cell");
     711             :                 dmapper_logger->attribute("cell", nCell);
     712             :                 dmapper_logger->attribute("row", nRow);
     713             : #endif
     714             : 
     715        6720 :                 lcl_computeCellBorders( rInfo.pTableBorders, *aCellIterator, nCell, nRow, bIsEndCol, bIsEndRow );
     716             : 
     717             :                 //now set the default left+right border distance TODO: there's an sprm containing the default distance!
     718             :                 const PropertyMap::const_iterator aLeftDistanceIter =
     719        6720 :                 aCellIterator->get()->find(PROP_LEFT_BORDER_DISTANCE);
     720        6720 :                 if( aLeftDistanceIter == aCellIterator->get()->end() )
     721             :                     aCellIterator->get()->Insert( PROP_LEFT_BORDER_DISTANCE,
     722        6588 :                                                  uno::makeAny(rInfo.nLeftBorderDistance ) );
     723             :                 const PropertyMap::const_iterator aRightDistanceIter =
     724        6720 :                 aCellIterator->get()->find(PROP_RIGHT_BORDER_DISTANCE);
     725        6720 :                 if( aRightDistanceIter == aCellIterator->get()->end() )
     726             :                     aCellIterator->get()->Insert( PROP_RIGHT_BORDER_DISTANCE,
     727        6341 :                                                  uno::makeAny((sal_Int32) rInfo.nRightBorderDistance ) );
     728             : 
     729             :                 const PropertyMap::const_iterator aTopDistanceIter =
     730        6720 :                 aCellIterator->get()->find(PROP_TOP_BORDER_DISTANCE);
     731        6720 :                 if( aTopDistanceIter == aCellIterator->get()->end() )
     732             :                     aCellIterator->get()->Insert( PROP_TOP_BORDER_DISTANCE,
     733        6322 :                                                  uno::makeAny((sal_Int32) rInfo.nTopBorderDistance ) );
     734             : 
     735             :                 const PropertyMap::const_iterator aBottomDistanceIter =
     736        6720 :                 aCellIterator->get()->find(PROP_BOTTOM_BORDER_DISTANCE);
     737        6720 :                 if( aBottomDistanceIter == aCellIterator->get()->end() )
     738             :                     aCellIterator->get()->Insert( PROP_BOTTOM_BORDER_DISTANCE,
     739        6634 :                                                  uno::makeAny((sal_Int32) rInfo.nBottomBorderDistance ) );
     740             : 
     741             :                 // Horizontal merge is not an UNO property, extract that info here to rMerges, and then remove it from the map.
     742        6720 :                 const PropertyMap::const_iterator aHorizontalMergeIter = aCellIterator->get()->find(PROP_HORIZONTAL_MERGE);
     743        6720 :                 if (aHorizontalMergeIter != aCellIterator->get()->end())
     744             :                 {
     745           4 :                     if (aHorizontalMergeIter->second.getValue().get<sal_Bool>())
     746             :                     {
     747             :                         // first cell in a merge
     748           2 :                         HorizontallyMergedCell aMerge(nRow, nCell);
     749           2 :                         rMerges.push_back(aMerge);
     750             :                     }
     751           2 :                     else if (!rMerges.empty())
     752             :                     {
     753             :                         // resuming an earlier merge
     754           2 :                         HorizontallyMergedCell& rMerge = rMerges.back();
     755           2 :                         rMerge.m_nLastRow = nRow;
     756           2 :                         rMerge.m_nLastCol = nCell;
     757             :                     }
     758           4 :                     aCellIterator->get()->erase(PROP_HORIZONTAL_MERGE);
     759             :                 }
     760        6720 :                 pSingleCellProperties[nCell] = aCellIterator->get()->GetPropertyValues();
     761             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     762             :                 dmapper_logger->endElement();
     763             : #endif
     764             :             }
     765        6720 :             ++nCell;
     766        6720 :             ++aCellIterator;
     767        6720 :         }
     768             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     769             :         //-->debug cell properties
     770             :         {
     771             :             OUString sNames;
     772             :             const uno::Sequence< beans::PropertyValues > aDebugCurrentRow = aCellProperties[nRow];
     773             :             sal_Int32 nDebugCells = aDebugCurrentRow.getLength();
     774             :             (void) nDebugCells;
     775             :             for( sal_Int32  nDebugCell = 0; nDebugCell < nDebugCells; ++nDebugCell)
     776             :             {
     777             :                 const uno::Sequence< beans::PropertyValue >& aDebugCellProperties = aDebugCurrentRow[nDebugCell];
     778             :                 sal_Int32 nDebugCellProperties = aDebugCellProperties.getLength();
     779             :                 for( sal_Int32  nDebugProperty = 0; nDebugProperty < nDebugCellProperties; ++nDebugProperty)
     780             :                 {
     781             :                     const OUString sName = aDebugCellProperties[nDebugProperty].Name;
     782             :                     sNames += sName;
     783             :                     sNames += OUString('-');
     784             :                 }
     785             :                 sNames += OUString('\n');
     786             :             }
     787             :             (void)sNames;
     788             :         }
     789             :         //--<
     790             : #endif
     791        2195 :         ++nRow;
     792        2195 :         ++aRowOfCellsIterator;
     793        2195 :         ++aRowIter;
     794             :     }
     795             : 
     796             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     797             :     dmapper_logger->endElement();
     798             : #endif
     799             : 
     800         396 :     return aCellProperties;
     801             : }
     802             : 
     803        3394 : RowPropertyValuesSeq_t DomainMapperTableHandler::endTableGetRowProperties()
     804             : {
     805             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     806             :     dmapper_logger->startElement("getRowProperties");
     807             : #endif
     808             : 
     809        3394 :     RowPropertyValuesSeq_t aRowProperties( m_aRowProperties.size() );
     810        3394 :     PropertyMapVector1::const_iterator aRowIter = m_aRowProperties.begin();
     811        3394 :     PropertyMapVector1::const_iterator aRowIterEnd = m_aRowProperties.end();
     812        3394 :     sal_Int32 nRow = 0;
     813        8983 :     while( aRowIter != aRowIterEnd )
     814             :     {
     815             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     816             :         dmapper_logger->startElement("rowProps.row");
     817             : #endif
     818        2195 :         if( aRowIter->get() )
     819             :         {
     820             :             //set default to 'break across pages"
     821        2183 :             if( aRowIter->get()->find(PROP_IS_SPLIT_ALLOWED) == aRowIter->get()->end())
     822        2059 :                 aRowIter->get()->Insert( PROP_IS_SPLIT_ALLOWED, uno::makeAny(sal_True ) );
     823             :             // tblHeader is only our property, remove before the property map hits UNO
     824        2183 :             PropertyMap::iterator const aIter = aRowIter->get()->find(PROP_TBL_HEADER);
     825        2183 :             if (aIter != aRowIter->get()->end())
     826          49 :                 aRowIter->get()->erase(aIter);
     827             : 
     828        2183 :             aRowProperties[nRow] = (*aRowIter)->GetPropertyValues();
     829             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     830             :             ((*aRowIter)->dumpXml( dmapper_logger ));
     831             :             lcl_DumpPropertyValues(dmapper_logger, aRowProperties[nRow]);
     832             : #endif
     833             :         }
     834        2195 :         ++nRow;
     835        2195 :         ++aRowIter;
     836             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     837             :         dmapper_logger->endElement();
     838             : #endif
     839             :     }
     840             : 
     841             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     842             :     dmapper_logger->endElement();
     843             : #endif
     844             : 
     845        3394 :     return aRowProperties;
     846             : }
     847             : 
     848             : // Apply paragraph property to each paragraph within a cell.
     849        2605 : static void lcl_ApplyCellParaProps(uno::Reference<table::XCell> xCell, uno::Any aBottomMargin)
     850             : {
     851        2605 :     uno::Reference<container::XEnumerationAccess> xEnumerationAccess(xCell, uno::UNO_QUERY);
     852        5210 :     uno::Reference<container::XEnumeration> xEnumeration = xEnumerationAccess->createEnumeration();
     853        7854 :     while (xEnumeration->hasMoreElements())
     854             :     {
     855        2644 :         uno::Reference<beans::XPropertySet> xParagraph(xEnumeration->nextElement(), uno::UNO_QUERY);
     856        5288 :         uno::Reference<beans::XPropertyState> xPropertyState(xParagraph, uno::UNO_QUERY);
     857             :         // Don't apply in case direct formatting is already present.
     858             :         // TODO: probably paragraph style has priority over table style here.
     859        2644 :         if (xPropertyState.is() && xPropertyState->getPropertyState("ParaBottomMargin") == beans::PropertyState_DEFAULT_VALUE)
     860           9 :             xParagraph->setPropertyValue("ParaBottomMargin", aBottomMargin);
     861        5249 :     }
     862        2605 : }
     863             : 
     864        3394 : void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel)
     865             : {
     866             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     867             :     dmapper_logger->startElement("tablehandler.endTable");
     868             : #endif
     869             : 
     870             :     // If we want to make this table a floating one.
     871        3394 :     uno::Sequence<beans::PropertyValue> aFrameProperties = m_rDMapper_Impl.getTableManager().getCurrentTablePosition();
     872        6788 :     TableInfo aTableInfo;
     873        3394 :     aTableInfo.nNestLevel = nestedTableLevel;
     874        3394 :     aTableInfo.pTableStyle = endTableGetTableStyle(aTableInfo, aFrameProperties);
     875             :     //  expands to uno::Sequence< Sequence< beans::PropertyValues > >
     876             : 
     877        6788 :     std::vector<HorizontallyMergedCell> aMerges;
     878        6788 :     CellPropertyValuesSeq_t aCellProperties = endTableGetCellProperties(aTableInfo, aMerges);
     879             : 
     880        6788 :     RowPropertyValuesSeq_t aRowProperties = endTableGetRowProperties();
     881             : 
     882             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     883             :     lcl_DumpPropertyValueSeq(dmapper_logger, aRowProperties);
     884             : #endif
     885             : 
     886        3394 :     if (m_pTableSeq->getLength() > 0)
     887             :     {
     888         396 :         uno::Reference<text::XTextRange> xStart;
     889         792 :         uno::Reference<text::XTextRange> xEnd;
     890             : 
     891         396 :         bool bFloating = aFrameProperties.hasElements();
     892             :         // Additional checks: if we can do this.
     893         396 :         if (bFloating && (*m_pTableSeq)[0].getLength() > 0 && (*m_pTableSeq)[0][0].getLength() > 0)
     894             :         {
     895          31 :             xStart = (*m_pTableSeq)[0][0][0];
     896          31 :             uno::Sequence< uno::Sequence< uno::Reference<text::XTextRange> > >& rLastRow = (*m_pTableSeq)[m_pTableSeq->getLength() - 1];
     897          31 :             uno::Sequence< uno::Reference<text::XTextRange> >& rLastCell = rLastRow[rLastRow.getLength() - 1];
     898          31 :             xEnd = rLastCell[1];
     899             :         }
     900         792 :         uno::Reference<text::XTextTable> xTable;
     901             :         try
     902             :         {
     903         396 :             if (m_xText.is())
     904             :             {
     905        1151 :                 xTable = m_xText->convertToTable(*m_pTableSeq,
     906             :                         aCellProperties,
     907             :                         aRowProperties,
     908         767 :                         aTableInfo.aTableProperties);
     909             : 
     910         383 :                 if (xTable.is())
     911             :                 {
     912         383 :                     m_xTableRange = xTable->getAnchor( );
     913             : 
     914         383 :                     if (!aMerges.empty())
     915             :                     {
     916             :                         // Perform horizontal merges in reverse order, so the fact that merging changes the position of cells won't cause a problem for us.
     917           4 :                         for (std::vector<HorizontallyMergedCell>::reverse_iterator it = aMerges.rbegin(); it != aMerges.rend(); ++it)
     918             :                         {
     919           2 :                             uno::Reference<table::XCellRange> xCellRange(xTable, uno::UNO_QUERY_THROW);
     920           4 :                             uno::Reference<beans::XPropertySet> xCell(xCellRange->getCellByPosition(it->m_nFirstCol, it->m_nFirstRow), uno::UNO_QUERY_THROW);
     921           4 :                             OUString aFirst = xCell->getPropertyValue("CellName").get<OUString>();
     922           2 :                             xCell.set(xCellRange->getCellByPosition(it->m_nLastCol, it->m_nLastRow), uno::UNO_QUERY_THROW);
     923           4 :                             OUString aLast = xCell->getPropertyValue("CellName").get<OUString>();
     924             : 
     925           4 :                             uno::Reference<text::XTextTableCursor> xCursor = xTable->createCursorByCellName(aFirst);
     926           2 :                             xCursor->gotoCellByName(aLast, true);
     927           2 :                             xCursor->mergeRange();
     928           2 :                         }
     929             :                     }
     930             :                 }
     931             : 
     932             :                 // OOXML table style may container paragraph properties, apply these now.
     933        4169 :                 for (int i = 0; i < aTableInfo.aTableProperties.getLength(); ++i)
     934             :                 {
     935        3894 :                     if (aTableInfo.aTableProperties[i].Name == "ParaBottomMargin")
     936             :                     {
     937         108 :                         uno::Reference<table::XCellRange> xCellRange(xTable, uno::UNO_QUERY);
     938         216 :                         uno::Any aBottomMargin = aTableInfo.aTableProperties[i].Value;
     939         108 :                         sal_Int32 nRows = aCellProperties.getLength();
     940        1175 :                         for (sal_Int32 nRow = 0; nRow < nRows; ++nRow)
     941             :                         {
     942        1068 :                             const uno::Sequence< beans::PropertyValues > aCurrentRow = aCellProperties[nRow];
     943        1068 :                             sal_Int32 nCells = aCurrentRow.getLength();
     944        3673 :                             for (sal_Int32 nCell = 0; nCell < nCells; ++nCell)
     945        2606 :                                 lcl_ApplyCellParaProps(xCellRange->getCellByPosition(nCell, nRow), aBottomMargin);
     946        1068 :                         }
     947         215 :                         break;
     948             :                     }
     949             :                 }
     950             :             }
     951             :         }
     952           1 :         catch ( const lang::IllegalArgumentException &e )
     953             :         {
     954             :             SAL_INFO("writerfilter.dmapper",
     955             :                     "Conversion to table error: " << e.Message);
     956             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     957             :             dmapper_logger->chars(std::string("failed to import table!"));
     958             : #endif
     959             :         }
     960           1 :         catch ( const uno::Exception &e )
     961             :         {
     962             :             SAL_INFO("writerfilter.dmapper",
     963             :                     "Exception during table creation: " << e.Message);
     964             :         }
     965             : 
     966             :         // If we have a table with a start and an end position, we should make it a floating one.
     967         396 :         if (xTable.is() && xStart.is() && xEnd.is())
     968             :         {
     969          31 :             uno::Reference<beans::XPropertySet> xTableProperties(xTable, uno::UNO_QUERY);
     970          31 :             sal_Bool bIsRelative = sal_False;
     971          31 :             xTableProperties->getPropertyValue("IsWidthRelative") >>= bIsRelative;
     972          31 :             if (!bIsRelative)
     973             :             {
     974          28 :                 aFrameProperties.realloc(aFrameProperties.getLength() + 1);
     975          28 :                 aFrameProperties[aFrameProperties.getLength() - 1].Name = "Width";
     976          28 :                 aFrameProperties[aFrameProperties.getLength() - 1].Value = xTableProperties->getPropertyValue("Width");
     977             :             }
     978             :             else
     979             :             {
     980           3 :                 aFrameProperties.realloc(aFrameProperties.getLength() + 1);
     981           3 :                 aFrameProperties[aFrameProperties.getLength() - 1].Name = "FrameWidthPercent";
     982           3 :                 aFrameProperties[aFrameProperties.getLength() - 1].Value = xTableProperties->getPropertyValue("RelativeWidth");
     983             : 
     984             :                 // Applying the relative width to the frame, needs to have the table width to be 100% of the frame width
     985           3 :                 xTableProperties->setPropertyValue("RelativeWidth", uno::makeAny(sal_Int16(100)));
     986             :             }
     987             : 
     988             :             // A non-zero left margin would move the table out of the frame, move the frame itself instead.
     989          31 :             xTableProperties->setPropertyValue("LeftMargin", uno::makeAny(sal_Int32(0)));
     990             : 
     991             :             // In case the document ends with a table, we're called after
     992             :             // SectionPropertyMap::CloseSectionGroup(), so we'll have no idea
     993             :             // about the text area width, nor can fix this by delaying the text
     994             :             // frame conversion: just do it here.
     995             :             // Also, when the anchor is within a table, then do it here as well,
     996             :             // as xStart/xEnd would not point to the start/end at conversion
     997             :             // time anyway.
     998          31 :             sal_Int32 nTableWidth = 0;
     999          31 :             m_aTableProperties->getValue(TablePropertyMap::TABLE_WIDTH, nTableWidth);
    1000          31 :             if (m_rDMapper_Impl.GetSectionContext() && nestedTableLevel <= 1)
    1001          29 :                 m_rDMapper_Impl.m_aPendingFloatingTables.push_back(FloatingTableInfo(xStart, xEnd, aFrameProperties, nTableWidth));
    1002             :             else
    1003           2 :                 m_xText->convertToTextFrame(xStart, xEnd, aFrameProperties);
    1004         396 :         }
    1005             :     }
    1006             : 
    1007        3394 :     m_aTableProperties.reset();
    1008        3394 :     m_aCellProperties.clear();
    1009        6788 :     m_aRowProperties.clear();
    1010             : 
    1011             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
    1012             :     dmapper_logger->endElement();
    1013             :     dmapper_logger->endElement();
    1014             : #endif
    1015        3394 : }
    1016             : 
    1017        2195 : void DomainMapperTableHandler::startRow(unsigned int nCells,
    1018             :                                         TablePropertyMapPtr pProps)
    1019             : {
    1020        2195 :     m_aRowProperties.push_back( pProps );
    1021        2195 :     m_aCellProperties.push_back( PropertyMapVector1() );
    1022             : 
    1023             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
    1024             :     dmapper_logger->startElement("table.row");
    1025             :     dmapper_logger->attribute("cells", nCells);
    1026             :     if (pProps != NULL)
    1027             :         pProps->dumpXml(dmapper_logger);
    1028             : #endif
    1029             : 
    1030        2195 :     m_pRowSeq = RowSequencePointer_t(new RowSequence_t(nCells));
    1031        2195 :     m_nCellIndex = 0;
    1032        2195 : }
    1033             : 
    1034        2195 : void DomainMapperTableHandler::endRow()
    1035             : {
    1036        2195 :     (*m_pTableSeq)[m_nRowIndex] = *m_pRowSeq;
    1037        2195 :     ++m_nRowIndex;
    1038        2195 :     m_nCellIndex = 0;
    1039             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
    1040             :     dmapper_logger->endElement();
    1041             : #endif
    1042        2195 : }
    1043             : 
    1044        6720 : void DomainMapperTableHandler::startCell(const Handle_t & start,
    1045             :                                          TablePropertyMapPtr pProps )
    1046             : {
    1047        6720 :     sal_uInt32 nRow = m_aRowProperties.size();
    1048        6720 :     if ( pProps.get( ) )
    1049        4241 :         m_aCellProperties[nRow - 1].push_back( pProps );
    1050             :     else
    1051             :     {
    1052             :         // Adding an empty cell properties map to be able to get
    1053             :         // the table defaults properties
    1054        2479 :         TablePropertyMapPtr pEmptyProps( new TablePropertyMap( ) );
    1055        2479 :         m_aCellProperties[nRow - 1].push_back( pEmptyProps );
    1056             :     }
    1057             : 
    1058             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
    1059             :     dmapper_logger->startElement("table.cell");
    1060             :     dmapper_logger->startElement("table.cell.start");
    1061             :     dmapper_logger->chars(toString(start));
    1062             :     dmapper_logger->endElement();
    1063             :     lcl_printProperties( pProps );
    1064             : #endif
    1065             : 
    1066             :     //add a new 'row' of properties
    1067        6720 :     m_pCellSeq = CellSequencePointer_t(new CellSequence_t(2));
    1068        6720 :     if (!start.get())
    1069        6747 :         return;
    1070        6693 :     (*m_pCellSeq)[0] = start->getStart();
    1071             : }
    1072             : 
    1073        6720 : void DomainMapperTableHandler::endCell(const Handle_t & end)
    1074             : {
    1075             : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
    1076             :     dmapper_logger->startElement("table.cell.end");
    1077             :     dmapper_logger->chars(toString(end));
    1078             :     dmapper_logger->endElement();
    1079             :     dmapper_logger->endElement();
    1080             : #endif
    1081             : 
    1082        6720 :     if (!end.get())
    1083        6747 :         return;
    1084        6693 :     (*m_pCellSeq)[1] = end->getEnd();
    1085        6693 :     (*m_pRowSeq)[m_nCellIndex] = *m_pCellSeq;
    1086        6693 :     ++m_nCellIndex;
    1087             : }
    1088             : 
    1089             : }}
    1090             : 
    1091             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10