LCOV - code coverage report
Current view: top level - writerfilter/source/dmapper - DomainMapperTableHandler.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 444 0.0 %
Date: 2014-04-14 Functions: 0 20 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10