LCOV - code coverage report
Current view: top level - writerfilter/source/dmapper - DomainMapperTableManager.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 300 345 87.0 %
Date: 2014-04-11 Functions: 13 13 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 <boost/optional.hpp>
      20             : #include <DomainMapperTableManager.hxx>
      21             : #include <resourcemodel/WW8ResourceModel.hxx>
      22             : #include <BorderHandler.hxx>
      23             : #include <CellColorHandler.hxx>
      24             : #include <CellMarginHandler.hxx>
      25             : #include <ConversionHelper.hxx>
      26             : #include <MeasureHandler.hxx>
      27             : #include <TDefTableHandler.hxx>
      28             : #include <com/sun/star/text/HoriOrientation.hpp>
      29             : #include <com/sun/star/text/SizeType.hpp>
      30             : #include <com/sun/star/text/TableColumnSeparator.hpp>
      31             : #include <com/sun/star/text/VertOrientation.hpp>
      32             : #include <com/sun/star/text/WritingMode2.hpp>
      33             : #include <ooxml/resourceids.hxx>
      34             : #include <dmapperLoggers.hxx>
      35             : 
      36             : namespace writerfilter {
      37             : namespace dmapper {
      38             : 
      39             : using namespace ::com::sun::star;
      40             : using namespace ::std;
      41             : 
      42             : 
      43        3009 : DomainMapperTableManager::DomainMapperTableManager(bool bOOXML) :
      44             :     m_nRow(0),
      45             :     m_nCell(),
      46             :     m_nGridSpan(1),
      47             :     m_nGridBefore(0),
      48             :     m_nGridAfter(0),
      49             :     m_nCellBorderIndex(0),
      50             :     m_nHeaderRepeat(0),
      51             :     m_nTableWidth(0),
      52             :     m_bOOXML( bOOXML ),
      53             :     m_aTmpPosition(),
      54             :     m_aTmpTableProperties(),
      55             :     m_bPushCurrentWidth(false),
      56             :     m_bRowSizeTypeInserted(false),
      57             :     m_bHasBtlrCell(false),
      58             :     m_bTableSizeTypeInserted(false),
      59             :     m_nLayoutType(0),
      60             :     m_nMaxFixedWidth(0),
      61        3009 :     m_pTablePropsHandler( new TablePropertiesHandler( bOOXML ) )
      62             : {
      63        3009 :     m_pTablePropsHandler->SetTableManager( this );
      64             : 
      65             : #ifdef DEBUG_DOMAINMAPPER
      66             : #ifdef DEBUG_TABLE
      67             :     setTagLogger(dmapper_logger);
      68             : #endif
      69             : #endif
      70        3009 : }
      71             : 
      72             : 
      73        9027 : DomainMapperTableManager::~DomainMapperTableManager()
      74             : {
      75        3009 :     if ( m_pTablePropsHandler )
      76        3009 :         delete m_pTablePropsHandler, m_pTablePropsHandler = NULL;
      77        6018 : }
      78             : 
      79             : 
      80      323658 : bool DomainMapperTableManager::sprm(Sprm & rSprm)
      81             : {
      82             : #ifdef DEBUG_DOMAINMAPPER
      83             :     dmapper_logger->startElement("tablemanager.sprm");
      84             :     string sSprm = rSprm.toString();
      85             :     dmapper_logger->chars(sSprm);
      86             :     dmapper_logger->endElement();
      87             : #endif
      88      323658 :     bool bRet = DomainMapperTableManager_Base_t::sprm(rSprm);
      89      323658 :     if( !bRet )
      90             :     {
      91      282688 :         bRet = m_pTablePropsHandler->sprm( rSprm );
      92             :     }
      93             : 
      94      323658 :     if ( !bRet )
      95             :     {
      96      268953 :         bRet = true;
      97      268953 :         sal_uInt32 nSprmId = rSprm.getId();
      98      268953 :         Value::Pointer_t pValue = rSprm.getValue();
      99      268953 :         sal_Int32 nIntValue = ((pValue.get() != NULL) ? pValue->getInt() : 0);
     100      268953 :         switch ( nSprmId )
     101             :         {
     102             :             case 0xf661: //sprmTTRLeft left table indent
     103             :             case 0xf614: // sprmTTPreferredWidth - preferred table width
     104             :             case NS_ooxml::LN_CT_TblPrBase_tblW:  //90722;
     105             :             case NS_ooxml::LN_CT_TblPrBase_tblInd: //90725
     106             :             {
     107             :                 //contains unit and value
     108        2179 :                 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
     109        2179 :                 if( pProperties.get())
     110             :                 {   //contains attributes x2902 (LN_unit) and x17e2 (LN_trleft)
     111        2179 :                     MeasureHandlerPtr pMeasureHandler( new MeasureHandler );
     112        2179 :                     pProperties->resolve(*pMeasureHandler);
     113        4358 :                     TablePropertyMapPtr pPropMap( new TablePropertyMap );
     114        2179 :                     if( nSprmId == 0xf661 || nSprmId == sal_uInt32(NS_ooxml::LN_CT_TblPrBase_tblInd ))
     115             :                     {
     116           0 :                         pPropMap->setValue( TablePropertyMap::LEFT_MARGIN, pMeasureHandler->getMeasureValue() );
     117             :                     }
     118             :                     else
     119             :                     {
     120        2179 :                         m_nTableWidth = pMeasureHandler->getMeasureValue();
     121        2179 :                         if( m_nTableWidth )
     122             :                         {
     123         914 :                             pPropMap->setValue( TablePropertyMap::TABLE_WIDTH_TYPE, text::SizeType::FIX );
     124         914 :                             pPropMap->setValue( TablePropertyMap::TABLE_WIDTH, m_nTableWidth );
     125             :                         }
     126        1265 :                         else if( sal::static_int_cast<Id>(pMeasureHandler->getUnit()) == NS_ooxml::LN_Value_ST_TblWidth_pct )
     127             :                         {
     128         102 :                             sal_Int32 nPercent = pMeasureHandler->getValue() / 50;
     129         102 :                             if(nPercent > 100)
     130           0 :                                 nPercent = 100;
     131         102 :                             pPropMap->setValue( TablePropertyMap::TABLE_WIDTH_TYPE, text::SizeType::VARIABLE );
     132         102 :                             pPropMap->setValue( TablePropertyMap::TABLE_WIDTH, nPercent );
     133             :                         }
     134        1163 :                         else if( sal::static_int_cast<Id>(pMeasureHandler->getUnit()) == NS_ooxml::LN_Value_ST_TblWidth_auto )
     135             :                         {
     136             :                             /*
     137             :                             This attribute specifies the width type of table. This is used as part of the table layout
     138             :                             algorithm specified by the tblLayout element.(See 17.4.64 and 17.4.65 of the ISO/IEC 29500-1:2011.)
     139             :                             If this value is 'auto', the table layout has to use the preferred widths on the table items to generate
     140             :                             the final sizing of the table, but then must use the contents of each cell to determine final column widths.
     141             :                             (See 17.18.87 of the ISO/IEC 29500-1:2011.)
     142             :                             */
     143        1160 :                             bool bFixed = true;
     144        1160 :                             sal_Int32 nRowFixedWidth = 0;
     145        1160 :                             IntVectorPtr pCellWidths = getCurrentCellWidths();
     146             :                             // Step 1. Check whether all cells have fixed widths in the given row of table.
     147        4225 :                             for (std::vector<sal_Int32>::const_iterator aValIter = pCellWidths->begin(); aValIter != pCellWidths->end(); ++aValIter)
     148             :                             {
     149        3095 :                                 if (*aValIter == -1)
     150             :                                 {
     151          30 :                                     bFixed = false;
     152          30 :                                     break;
     153             :                                 }
     154             :                                 // Sum the width of cells to find the total width of given row
     155        3065 :                                 nRowFixedWidth += (*aValIter);
     156             :                             }
     157             : 
     158             :                             // Check whether the total width of given row is compared with the maximum value of rows (m_nMaxFixedWidth).
     159        1160 :                             if (bFixed )
     160             :                             {
     161             :                                 // Check if total width
     162        1130 :                                 if (m_nMaxFixedWidth < nRowFixedWidth)
     163         238 :                                     m_nMaxFixedWidth = nRowFixedWidth;
     164             : 
     165        1130 :                                 pPropMap->setValue( TablePropertyMap::TABLE_WIDTH_TYPE, text::SizeType::FIX );
     166        1130 :                                 pPropMap->setValue( TablePropertyMap::TABLE_WIDTH, m_nMaxFixedWidth );
     167             :                             }
     168             :                             else
     169             :                             {
     170             :                                 // Set the width type of table with 'Auto' and set the width value to 100(%)
     171          30 :                                 pPropMap->setValue( TablePropertyMap::TABLE_WIDTH_TYPE, text::SizeType::VARIABLE );
     172          30 :                                 pPropMap->setValue( TablePropertyMap::TABLE_WIDTH, 0 );
     173        1160 :                             }
     174             :                         }
     175        2179 :                         m_bTableSizeTypeInserted = true;
     176             :                     }
     177             : #ifdef DEBUG_DOMAINMAPPER
     178             :                     pPropMap->dumpXml( dmapper_logger );
     179             : #endif
     180        4358 :                     insertTableProps(pPropMap);
     181        2179 :                 }
     182             :             }
     183        2179 :             break;
     184             :             case 0x3404:// sprmTTableHeader
     185             :             case NS_ooxml::LN_CT_TrPrBase_tblHeader: //90704
     186             :                 // if nIntValue == 1 then the row is a repeated header line
     187             :                 // to prevent later rows from increasing the repeating m_nHeaderRepeat is set to NULL when repeating stops
     188          57 :                 if( nIntValue > 0 && m_nHeaderRepeat >= 0 )
     189             :                 {
     190          57 :                     ++m_nHeaderRepeat;
     191          57 :                     TablePropertyMapPtr pPropMap( new TablePropertyMap );
     192          57 :                     pPropMap->Insert( PROP_HEADER_ROW_COUNT, uno::makeAny( m_nHeaderRepeat ));
     193          57 :                     insertTableProps(pPropMap);
     194             :                 }
     195             :                 else
     196           0 :                     m_nHeaderRepeat = -1;
     197          57 :                 if (nIntValue)
     198             :                 {
     199             :                     // Store the info that this is a header, we'll need that when we apply table styles.
     200          57 :                     TablePropertyMapPtr pPropMap( new TablePropertyMap );
     201          57 :                     pPropMap->Insert( PROP_TBL_HEADER, uno::makeAny(nIntValue));
     202          57 :                     insertRowProps(pPropMap);
     203             :                 }
     204          57 :             break;
     205             :             case 0xd608: // TDefTable
     206             :             {
     207           0 :                 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
     208           0 :                 if( pProperties.get())
     209             :                 {
     210           0 :                     TDefTableHandlerPtr pTDefTableHandler( new TDefTableHandler(m_bOOXML) );
     211           0 :                     pProperties->resolve( *pTDefTableHandler );
     212             : 
     213           0 :                     TablePropertyMapPtr pRowPropMap( new TablePropertyMap );
     214           0 :                     pRowPropMap->InsertProps(pTDefTableHandler->getRowProperties());
     215           0 :                     insertRowProps( pRowPropMap );
     216           0 :                     if( !m_nTableWidth )
     217             :                     {
     218           0 :                         m_nTableWidth= pTDefTableHandler->getTableWidth();
     219           0 :                         if( m_nTableWidth )
     220             :                         {
     221           0 :                             TablePropertyMapPtr pPropMap( new TablePropertyMap );
     222           0 :                             pPropMap->setValue( TablePropertyMap::TABLE_WIDTH, m_nTableWidth );
     223           0 :                             insertTableProps(pPropMap);
     224             :                         }
     225             :                     }
     226           0 :                     for( size_t nCell = 0; nCell < pTDefTableHandler->getCellCount(); ++nCell )
     227             :                     {
     228           0 :                         TablePropertyMapPtr pCellPropMap( new TablePropertyMap );
     229           0 :                         pTDefTableHandler->fillCellProperties( nCell, pCellPropMap );
     230           0 :                         cellPropsByCell( nCell, pCellPropMap );
     231           0 :                     }
     232           0 :                 }
     233             :             }
     234           0 :             break;
     235             :             case 0xD605: // sprmTTableBorders
     236             :             {
     237           0 :                 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
     238           0 :                 if( pProperties.get())
     239             :                 {
     240           0 :                     BorderHandlerPtr pBorderHandler( new BorderHandler(m_bOOXML) );
     241           0 :                     pProperties->resolve(*pBorderHandler);
     242           0 :                     TablePropertyMapPtr pCellPropMap( new TablePropertyMap() );
     243           0 :                     pCellPropMap->InsertProps(pBorderHandler->getProperties());
     244           0 :                     cellPropsByCell( m_nCellBorderIndex, pCellPropMap );
     245           0 :                     ++m_nCellBorderIndex;
     246           0 :                 }
     247             :             }
     248           0 :             break;
     249             :             case 0xd632 : //sprmTNewSpacing
     250             :             case 0xd634 : //sprmTNewSpacing
     251             :                 //TODO: sprms contain default (TNew) and actual border spacing of cells - not resolvable yet
     252           0 :             break;
     253             :             case 0xd613: //sprmTGridLineProps
     254             :                 // TODO: needs a handler
     255             :                 /*contains:
     256             :                  GridLineProps">
     257             :                     rtf:LINEPROPSTOP
     258             :                     rtf:LINEPROPSLEFT
     259             :                     rtf:LINEPROPSBOTTOM
     260             :                     rtf:LINEPROPSRIGHT
     261             :                     rtf:LINEPROPSHORIZONTAL
     262             :                     rtf:LINEPROPSVERTICAL
     263             :                         rtf:LINECOLOR
     264             :                         rtf:LINEWIDTH
     265             :                         rtf:LINETYPE
     266             : 
     267             :                 */
     268           0 :             break;
     269             :             case 0x740a : //sprmTTlp
     270             :                 //TODO: Table look specifier
     271           0 :             break;
     272             :             case 0x6816 : //unknown
     273             :             case 0x3466 : //unknown
     274             :             case 0x3615 : //unknown
     275             :             case 0x646b : //unknown - expandable sprm - see ww8scan.cxx
     276             :             case 0x7479 : //unknown
     277             :             case 0xf617 : //unknown
     278             :             case 0xf618 : //unknown
     279           0 :                 bRet = false;
     280           0 :             break;
     281             :             case NS_ooxml::LN_CT_TblPrBase_tblStyle: //table style name
     282             :             {
     283        1247 :                 m_sTableStyleName = pValue->getString();
     284        1247 :                 TablePropertyMapPtr pPropMap( new TablePropertyMap );
     285        1247 :                 pPropMap->Insert( META_PROP_TABLE_STYLE_NAME, uno::makeAny( m_sTableStyleName ));
     286        1247 :                 insertTableProps(pPropMap);
     287             :             }
     288        1247 :             break;
     289             :             case NS_ooxml::LN_CT_TblGridBase_gridCol:
     290             :             {
     291        7728 :                 if (nIntValue == -1)
     292          85 :                     getCurrentGrid()->clear();
     293             :                 else
     294        7643 :                     getCurrentGrid()->push_back( ConversionHelper::convertTwipToMM100( nIntValue ) );
     295             :             }
     296        7728 :             break;
     297             :             case NS_ooxml::LN_CT_TcPrBase_vMerge : //vertical merge
     298             :             {
     299             :                 // values can be: LN_Value_ST_Merge_restart, LN_Value_ST_Merge_continue, in reality the second one is a 0
     300         129 :                 TablePropertyMapPtr pMergeProps( new TablePropertyMap );
     301         129 :                 pMergeProps->Insert( PROP_VERTICAL_MERGE, uno::makeAny( bool( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_ST_Merge_restart )) );
     302         129 :                 cellProps( pMergeProps);
     303             :             }
     304         129 :             break;
     305             :             case NS_ooxml::LN_CT_TcPrBase_hMerge:
     306             :             {
     307             :                 // values can be: LN_Value_ST_Merge_restart, LN_Value_ST_Merge_continue, in reality the second one is a 0
     308           4 :                 TablePropertyMapPtr pMergeProps(new TablePropertyMap());
     309           4 :                 pMergeProps->Insert(PROP_HORIZONTAL_MERGE, uno::makeAny(bool(sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_ST_Merge_restart)));
     310           4 :                 cellProps(pMergeProps);
     311             :             }
     312           4 :             break;
     313             :             case NS_ooxml::LN_CT_TcPrBase_gridSpan: //number of grid positions spanned by this cell
     314             :             {
     315             : #ifdef DEBUG_DOMAINMAPPER
     316             :                 dmapper_logger->startElement("tablemanager.GridSpan");
     317             :                 dmapper_logger->attribute("gridSpan", nIntValue);
     318             :                 dmapper_logger->endElement();
     319             : #endif
     320         463 :                 m_nGridSpan = nIntValue;
     321             :             }
     322         463 :             break;
     323             :             case NS_ooxml::LN_CT_TblPrBase_tblLook:
     324             :             {
     325        1606 :                 TablePropertyMapPtr pPropMap( new TablePropertyMap );
     326        1606 :                 pPropMap->Insert( PROP_TBL_LOOK, uno::makeAny( nIntValue ));
     327        1606 :                 insertTableProps(pPropMap);
     328             :             }
     329        1606 :             break;
     330             :             case NS_ooxml::LN_CT_TcPrBase_textDirection:
     331             :             {
     332         133 :                 TablePropertyMapPtr pPropMap( new TablePropertyMap );
     333         133 :                 bool bInsertCellProps = true;
     334         133 :                 switch ( nIntValue )
     335             :                 {
     336             :                     case 1:  // tbRl
     337             :                     // Binary filter takes BiDirection into account ( but I have no idea about that here )
     338             :                     // or even what it is. But... here's where to handle it if it becomes an issue
     339           1 :                         pPropMap->Insert( PROP_FRM_DIRECTION, uno::makeAny( text::WritingMode2::TB_RL ));
     340             :                         SAL_INFO( "writerfilter", "Have inserted textDirection " << nIntValue );
     341           1 :                         break;
     342             :                     case 3:  // btLr
     343             :                         {
     344             :                         // We have to fake this text direction
     345          31 :                          pPropMap->Insert( PROP_FRM_DIRECTION, uno::makeAny( text::WritingMode2::LR_TB ));
     346          31 :                          pPropMap->Insert( PROP_CHAR_ROTATION, uno::makeAny( sal_Int16( 900 ) ));
     347             :                         SAL_INFO( "writerfilter", "Have inserted textDirection " << nIntValue );
     348             : 
     349             :                         // We're faking a text direction, so don't allow multiple lines.
     350          31 :                         if (!getCellProps() || getCellProps()->find(PROP_VERTICAL_MERGE) == getCellProps()->end())
     351             :                         {
     352             :                             // Though in case there will be a vertical merge, don't do this, it hides text that is supposed to be visible.
     353          12 :                             TablePropertyMapPtr pRowPropMap( new TablePropertyMap );
     354          12 :                             pRowPropMap->Insert(PROP_SIZE_TYPE, uno::makeAny(text::SizeType::FIX));
     355          12 :                             m_bRowSizeTypeInserted = true;
     356          12 :                             insertRowProps(pRowPropMap);
     357             :                         }
     358          31 :                         m_bHasBtlrCell = true;
     359             :                         }
     360          31 :                         break;
     361             :                     case 4: // lrTbV
     362           0 :                         pPropMap->Insert( PROP_FRM_DIRECTION, uno::makeAny( text::WritingMode2::LR_TB ));
     363           0 :                         break;
     364             :                     case 5: // tbRlV
     365           0 :                         pPropMap->Insert( PROP_FRM_DIRECTION, uno::makeAny( text::WritingMode2::TB_RL ));
     366           0 :                         break;
     367             :                     case 0: // lrTb
     368             :                     case NS_ooxml::LN_Value_ST_TextDirection_tbLrV:
     369             :                     default:
     370             :                        // Ignore - we can't handle these
     371         101 :                        bInsertCellProps = false;
     372         101 :                        break;
     373             :                 }
     374         133 :                 if ( bInsertCellProps )
     375          32 :                     cellProps( pPropMap );
     376         133 :                 break;
     377             :             }
     378             :             case NS_ooxml::LN_CT_TcPrBase_tcW:
     379             :                 {
     380             :                     // Contains unit and value, but unit is not interesting for
     381             :                     // us, later we'll just distribute these values in a
     382             :                     // 0..10000 scale.
     383        6445 :                     writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
     384        6445 :                     if( pProperties.get())
     385             :                     {
     386        6445 :                         MeasureHandlerPtr pMeasureHandler(new MeasureHandler());
     387        6445 :                         pProperties->resolve(*pMeasureHandler);
     388        6445 :                         if (sal::static_int_cast<Id>(pMeasureHandler->getUnit()) == NS_ooxml::LN_Value_ST_TblWidth_auto)
     389         117 :                             getCurrentCellWidths()->push_back(sal_Int32(-1));
     390             :                         else
     391        6328 :                             getCurrentCellWidths()->push_back(pMeasureHandler->getMeasureValue());
     392        6445 :                         if (getTableDepthDifference() > 0)
     393         298 :                             m_bPushCurrentWidth = true;
     394        6445 :                     }
     395             :                 }
     396        6445 :                 break;
     397             :             case NS_ooxml::LN_CT_TrPrBase_cnfStyle:
     398         241 :                 break;  // the cnfStyle doesn't matter, instead the tblLook property is used to specify conditional styles that are to be used
     399             :             case NS_ooxml::LN_CT_PPrBase_cnfStyle:
     400             :                 // TODO cnfStyle on a paragraph
     401        1034 :                 break;
     402             :             case NS_ooxml::LN_CT_TcPrBase_cnfStyle:
     403         259 :                 break;  // the cnfStyle doesn't matter, instead the tblLook property is used to specify conditional styles that are to be used
     404             :             case NS_ooxml::LN_CT_TblPrBase_tblpPr:
     405             :                 {
     406         244 :                     writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
     407         244 :                     if (pProperties.get())
     408             :                     {
     409         244 :                         TablePositionHandlerPtr pHandler = m_aTmpPosition.back();
     410         244 :                         if ( !pHandler )
     411             :                         {
     412         244 :                             m_aTmpPosition.pop_back();
     413         244 :                             pHandler.reset( new TablePositionHandler );
     414         244 :                             m_aTmpPosition.push_back( pHandler );
     415             :                         }
     416         244 :                         pProperties->resolve(*m_aTmpPosition.back());
     417         244 :                     }
     418             :                 }
     419         244 :                 break;
     420             :             case NS_ooxml::LN_CT_TrPrBase_gridBefore:
     421           4 :                 m_nGridBefore = nIntValue;
     422           4 :                 break;
     423             :             case NS_ooxml::LN_CT_TrPrBase_gridAfter:
     424           9 :                 m_nGridAfter = nIntValue;
     425           9 :                 break;
     426             :             default:
     427      247171 :                 bRet = false;
     428             : 
     429             : #ifdef DEBUG_DOMAINMAPPER
     430             :                 dmapper_logger->element("unhandled");
     431             : #endif
     432      268953 :         }
     433             :     }
     434      323658 :     return bRet;
     435             : }
     436             : 
     437       12118 : boost::shared_ptr< vector<sal_Int32> > DomainMapperTableManager::getCurrentGrid( )
     438             : {
     439       12118 :     return m_aTableGrid.back( );
     440             : }
     441             : 
     442        8915 : boost::shared_ptr< vector< sal_Int32 > > DomainMapperTableManager::getCurrentSpans( )
     443             : {
     444        8915 :     return m_aGridSpans.back( );
     445             : }
     446             : 
     447        9800 : boost::shared_ptr< vector< sal_Int32 > > DomainMapperTableManager::getCurrentCellWidths( )
     448             : {
     449        9800 :     return m_aCellWidths.back( );
     450             : }
     451             : 
     452        3394 : const uno::Sequence<beans::PropertyValue> DomainMapperTableManager::getCurrentTablePosition( )
     453             : {
     454        3394 :     if ( !m_aTablePositions.empty( ) && m_aTablePositions.back() )
     455          31 :         return m_aTablePositions.back( )->getTablePosition();
     456             :     else
     457        3363 :         return uno::Sequence< beans::PropertyValue >( 0 );
     458             : }
     459             : 
     460        3411 : void DomainMapperTableManager::startLevel( )
     461             : {
     462        3411 :     DomainMapperTableManager_Base_t::startLevel( );
     463             : 
     464             :     // If requested, pop the value that was pushed too early.
     465        3411 :     boost::optional<sal_Int32> oCurrentWidth;
     466        3411 :     if (m_bPushCurrentWidth && !m_aCellWidths.empty() && !m_aCellWidths.back()->empty())
     467             :     {
     468         285 :         oCurrentWidth.reset(m_aCellWidths.back()->back());
     469         285 :         m_aCellWidths.back()->pop_back();
     470             :     }
     471             : 
     472        6822 :     IntVectorPtr pNewGrid( new vector<sal_Int32> );
     473        6822 :     IntVectorPtr pNewSpans( new vector<sal_Int32> );
     474        6822 :     IntVectorPtr pNewCellWidths( new vector<sal_Int32> );
     475        6822 :     TablePositionHandlerPtr pNewPositionHandler;
     476        3411 :     m_aTableGrid.push_back( pNewGrid );
     477        3411 :     m_aGridSpans.push_back( pNewSpans );
     478        3411 :     m_aCellWidths.push_back( pNewCellWidths );
     479        3411 :     m_aTablePositions.push_back( pNewPositionHandler );
     480             : 
     481        6822 :     TablePositionHandlerPtr pTmpPosition;
     482        6822 :     TablePropertyMapPtr pTmpProperties( new TablePropertyMap( ) );
     483        3411 :     m_aTmpPosition.push_back( pTmpPosition );
     484        3411 :     m_aTmpTableProperties.push_back( pTmpProperties );
     485        3411 :     m_nCell.push_back( 0 );
     486        3411 :     m_nTableWidth = 0;
     487        3411 :     m_nLayoutType = 0;
     488        3411 :     m_nMaxFixedWidth = 0;
     489             : 
     490             :     // And push it back to the right level.
     491        3411 :     if (oCurrentWidth)
     492        3696 :         m_aCellWidths.back()->push_back(*oCurrentWidth);
     493        3411 : }
     494             : 
     495        3394 : void DomainMapperTableManager::endLevel( )
     496             : {
     497        3394 :     m_aTableGrid.pop_back( );
     498        3394 :     m_aGridSpans.pop_back( );
     499             : 
     500             :     // Do the same trick as in startLevel(): pop the value that was pushed too early.
     501        3394 :     boost::optional<sal_Int32> oCurrentWidth;
     502        3394 :     if (m_bPushCurrentWidth && !m_aCellWidths.empty() && !m_aCellWidths.back()->empty())
     503          32 :         oCurrentWidth.reset(m_aCellWidths.back()->back());
     504        3394 :     m_aCellWidths.pop_back( );
     505             :     // And push it back to the right level.
     506        3394 :     if (oCurrentWidth)
     507          32 :         m_aCellWidths.back()->push_back(*oCurrentWidth);
     508             : 
     509        3394 :     m_nCell.pop_back( );
     510        3394 :     m_nTableWidth = 0;
     511        3394 :     m_nLayoutType = 0;
     512        3394 :     m_nMaxFixedWidth = 0;
     513             : 
     514        3394 :     m_aTmpPosition.pop_back( );
     515        3394 :     m_aTmpTableProperties.pop_back( );
     516             : 
     517        3394 :     DomainMapperTableManager_Base_t::endLevel( );
     518             : #ifdef DEBUG_DOMAINMAPPER
     519             :     dmapper_logger->startElement("dmappertablemanager.endLevel");
     520             :     PropertyMapPtr pProps = getTableProps();
     521             :     if (pProps.get() != NULL)
     522             :         getTableProps()->dumpXml( dmapper_logger );
     523             : 
     524             :     dmapper_logger->endElement();
     525             : #endif
     526             : 
     527             :     // Pop back the table position after endLevel as it's used
     528             :     // in the endTable method called in endLevel.
     529        3394 :     m_aTablePositions.pop_back();
     530        3394 : }
     531             : 
     532             : 
     533             : 
     534        6720 : void DomainMapperTableManager::endOfCellAction()
     535             : {
     536             : #ifdef DEBUG_DOMAINMAPPER
     537             :     dmapper_logger->element("endOFCellAction");
     538             : #endif
     539             : 
     540        6720 :     getCurrentSpans()->push_back(m_nGridSpan);
     541        6720 :     m_nGridSpan = 1;
     542        6720 :     ++m_nCell.back( );
     543        6720 : }
     544             : 
     545             : 
     546        2195 : void DomainMapperTableManager::endOfRowAction()
     547             : {
     548             : #ifdef DEBUG_DOMAINMAPPER
     549             :     dmapper_logger->startElement("endOfRowAction");
     550             : #endif
     551             : 
     552             :     // Compare the table position with the previous ones. We may need to split
     553             :     // into two tables if those are different. We surely don't want to do anything
     554             :     // if we don't have any row yet.
     555        2195 :     TablePositionHandlerPtr pTmpPosition = m_aTmpPosition.back();
     556        4390 :     TablePropertyMapPtr pTmpTableProperties = m_aTmpTableProperties.back( );
     557        4390 :     TablePositionHandlerPtr pCurrentPosition = m_aTablePositions.back();
     558        4603 :     bool bSamePosition = ( pTmpPosition == pCurrentPosition ) ||
     559        2686 :                          ( pTmpPosition && pCurrentPosition && *pTmpPosition == *pCurrentPosition );
     560        2195 :     if ( !bSamePosition && m_nRow > 0 )
     561             :     {
     562             :         // Save the grid infos to have them survive the end/start level
     563           5 :         IntVectorPtr pTmpTableGrid = m_aTableGrid.back();
     564          10 :         IntVectorPtr pTmpGridSpans = m_aGridSpans.back();
     565          10 :         IntVectorPtr pTmpCellWidths = m_aCellWidths.back();
     566             : 
     567             :         // endLevel and startLevel are taking care of the non finished row
     568             :         // to carry it over to the next table
     569           5 :         setKeepUnfinishedRow( true );
     570           5 :         endLevel();
     571           5 :         setKeepUnfinishedRow( false );
     572           5 :         startLevel();
     573             : 
     574           5 :         m_aTableGrid.pop_back();
     575           5 :         m_aGridSpans.pop_back();
     576           5 :         m_aCellWidths.pop_back();
     577           5 :         m_aTableGrid.push_back(pTmpTableGrid);
     578           5 :         m_aGridSpans.push_back(pTmpGridSpans);
     579          10 :         m_aCellWidths.push_back(pTmpCellWidths);
     580             :     }
     581             : 
     582             :     // Push the tmp position now that we compared it
     583        2195 :     m_aTablePositions.pop_back();
     584        2195 :     m_aTablePositions.push_back( pTmpPosition );
     585        2195 :     m_aTmpPosition.back().reset( );
     586             : 
     587             : 
     588        4390 :     IntVectorPtr pTableGrid = getCurrentGrid( );
     589        4390 :     IntVectorPtr pCellWidths = getCurrentCellWidths( );
     590        2195 :     if(!m_nTableWidth && pTableGrid->size())
     591             :     {
     592        1272 :         ::std::vector<sal_Int32>::const_iterator aCellIter = pTableGrid->begin();
     593             : 
     594             : #ifdef DEBUG_DOMAINMAPPER
     595             :         dmapper_logger->startElement("tableWidth");
     596             : #endif
     597             : 
     598        6559 :         while( aCellIter != pTableGrid->end() )
     599             :         {
     600             : #ifdef DEBUG_DOMAINMAPPER
     601             :             dmapper_logger->startElement("col");
     602             :             dmapper_logger->attribute("width", *aCellIter);
     603             :             dmapper_logger->endElement();
     604             : #endif
     605             : 
     606        4015 :              m_nTableWidth += *aCellIter++;
     607             :         }
     608             : 
     609        1272 :         if (m_nTableWidth > 0 && !m_bTableSizeTypeInserted)
     610             :         {
     611           6 :             TablePropertyMapPtr pPropMap( new TablePropertyMap );
     612           6 :             pPropMap->setValue( TablePropertyMap::TABLE_WIDTH, m_nTableWidth );
     613           6 :             insertTableProps(pPropMap);
     614             :         }
     615             : 
     616             : #ifdef DEBUG_DOMAINMAPPER
     617             :         dmapper_logger->endElement();
     618             : #endif
     619             :     }
     620             : 
     621        4390 :     IntVectorPtr pCurrentSpans = getCurrentSpans( );
     622        2195 :     if( pCurrentSpans->size() < m_nCell.back( ) )
     623             :     {
     624             :         //fill missing elements with '1'
     625           0 :         pCurrentSpans->insert( pCurrentSpans->end( ), m_nCell.back( ) - pCurrentSpans->size(), 1 );
     626             :     }
     627             : 
     628             : #ifdef DEBUG_DOMAINMAPPER
     629             :     dmapper_logger->startElement("gridSpans");
     630             :     {
     631             :         ::std::vector<sal_Int32>::const_iterator aGridSpanIter = pCurrentSpans->begin();
     632             :         ::std::vector<sal_Int32>::const_iterator aGridSpanIterEnd = pCurrentSpans->end();
     633             : 
     634             :         while (aGridSpanIter != aGridSpanIterEnd)
     635             :         {
     636             :             dmapper_logger->startElement("gridSpan");
     637             :             dmapper_logger->attribute("span", *aGridSpanIter);
     638             :             dmapper_logger->endElement();
     639             : 
     640             :             ++aGridSpanIter;
     641             :         }
     642             :     }
     643             :     dmapper_logger->endElement();
     644             : #endif
     645             : 
     646             :     //calculate number of used grids - it has to match the size of m_aTableGrid
     647        2195 :     size_t nGrids = 0;
     648        2195 :     ::std::vector<sal_Int32>::const_iterator aGridSpanIter = pCurrentSpans->begin();
     649        8915 :     for( ; aGridSpanIter != pCurrentSpans->end(); ++aGridSpanIter)
     650        6720 :         nGrids += *aGridSpanIter;
     651             : 
     652             :     // sj: the grid is having no units... they is containing only relative values.
     653             :     // a table with a grid of "1:2:1" looks identical as if the table is having
     654             :     // a grid of "20:40:20" and it doesn't have to do something with the tableWidth
     655             :     // -> so we have get the sum of each grid entry for the fullWidthRelative:
     656        2195 :     int nFullWidthRelative = 0;
     657        9838 :     for (unsigned int i = 0 ; i < (*pTableGrid.get()).size(); i++ )
     658        7643 :         nFullWidthRelative += (*pTableGrid.get())[ i ];
     659             : 
     660        2195 :     if( pTableGrid->size() == ( m_nGridBefore + nGrids + m_nGridAfter ) && m_nCell.back( ) > 0 )
     661             :     {
     662             :         /*
     663             :          * If table width property set earlier is smaller than the current table width,
     664             :          * then replace the TABLE_WIDTH property, set earlier.
     665             :          */
     666        2173 :         TablePropertyMapPtr propMap = m_aTmpTableProperties.back();
     667             :         sal_Int32 nTableWidth;
     668             :         sal_Int32 nTableWidthType;
     669        2173 :         propMap->getValue( TablePropertyMap::TABLE_WIDTH, nTableWidth );
     670        2173 :         propMap->getValue( TablePropertyMap::TABLE_WIDTH_TYPE, nTableWidthType );
     671        2173 :         if ((nTableWidthType == text::SizeType::FIX) && (nTableWidth < m_nTableWidth))
     672             :         {
     673          26 :             propMap->setValue( TablePropertyMap::TABLE_WIDTH, m_nTableWidth );
     674             :         }
     675        2173 :         if (nTableWidthType == text::SizeType::VARIABLE )
     676             :         {
     677         131 :             if(nTableWidth > 100 || nTableWidth <= 0)
     678             :             {
     679          30 :                 propMap->setValue( TablePropertyMap::TABLE_WIDTH, m_nTableWidth);
     680          30 :                 propMap->setValue( TablePropertyMap::TABLE_WIDTH_TYPE, text::SizeType::FIX);
     681             :             }
     682             :         }
     683        4346 :         uno::Sequence< text::TableColumnSeparator > aSeparators( m_nCell.back( ) - 1 );
     684        2173 :         text::TableColumnSeparator* pSeparators = aSeparators.getArray();
     685        2173 :         sal_Int16 nLastRelPos = 0;
     686        2173 :         sal_uInt32 nBorderGridIndex = m_nGridBefore;
     687             : 
     688        2173 :         ::std::vector< sal_Int32 >::const_iterator aSpansIter = pCurrentSpans->begin( );
     689        6681 :         for( sal_uInt32 nBorder = 0; nBorder < m_nCell.back( ) - 1; ++nBorder )
     690             :         {
     691        4508 :             double fGridWidth = 0.;
     692        9447 :             for ( sal_Int32 nGridCount = *aSpansIter; nGridCount > 0; --nGridCount )
     693        4939 :                 fGridWidth += (*pTableGrid.get())[nBorderGridIndex++];
     694             : 
     695             :             sal_Int16 nRelPos =
     696        4508 :                 sal::static_int_cast< sal_Int16 >((fGridWidth * 10000) / nFullWidthRelative);
     697             : 
     698        4508 :             pSeparators[nBorder].Position =  nRelPos + nLastRelPos;
     699        4508 :             pSeparators[nBorder].IsVisible = sal_True;
     700        4508 :             nLastRelPos = nLastRelPos + nRelPos;
     701        4508 :             ++aSpansIter;
     702             :         }
     703        4346 :         TablePropertyMapPtr pPropMap( new TablePropertyMap );
     704        2173 :         pPropMap->Insert( PROP_TABLE_COLUMN_SEPARATORS, uno::makeAny( aSeparators ) );
     705             : 
     706             : #ifdef DEBUG_DOMAINMAPPER
     707             :         dmapper_logger->startElement("rowProperties");
     708             :         pPropMap->dumpXml( dmapper_logger );
     709             :         dmapper_logger->endElement();
     710             : #endif
     711        4346 :         insertRowProps(pPropMap);
     712             :     }
     713          41 :     else if ( pCellWidths->size() > 0 &&
     714          10 :                ( m_nLayoutType == NS_ooxml::LN_Value_wordprocessingml_ST_TblLayout_fixed
     715           8 :                  || pCellWidths->size() == ( m_nGridBefore + nGrids + m_nGridAfter ) )
     716             :              )
     717             :     {
     718             :         // If we're here, then the number of cells does not equal to the amount
     719             :         // defined by the grid, even after taking care of
     720             :         // gridSpan/gridBefore/gridAfter. Handle this by ignoring the grid and
     721             :         // providing the separators based on the provided cell widths, as long
     722             :         // as we have a fixed layout;
     723             :         // On the other hand even if the layout is not fixed, but the cell widths
     724             :         // provided equal the total number of cells, and there are no after/before cells
     725             :         // then use the cell widths to calculate the column separators.
     726           9 :         uno::Sequence< text::TableColumnSeparator > aSeparators(pCellWidths->size() - 1);
     727           9 :         text::TableColumnSeparator* pSeparators = aSeparators.getArray();
     728           9 :         sal_Int16 nSum = 0;
     729           9 :         sal_uInt32 nPos = 0;
     730             :         // Avoid divide by zero (if there's no grid, position using cell widths).
     731           9 :         if( nFullWidthRelative == 0 )
     732           0 :             for (sal_uInt32 i = 0; i < pCellWidths->size(); ++i)
     733           0 :                 nFullWidthRelative += (*pCellWidths.get())[i];
     734             : 
     735          19 :         for (sal_uInt32 i = 0; i < pCellWidths->size() - 1; ++i)
     736             :         {
     737          10 :             nSum += (*pCellWidths.get())[i];
     738          10 :             pSeparators[nPos].Position = (nSum * 10000) / nFullWidthRelative; // Relative position
     739          10 :             pSeparators[nPos].IsVisible = sal_True;
     740          10 :             nPos++;
     741             :         }
     742             : 
     743          18 :         TablePropertyMapPtr pPropMap( new TablePropertyMap );
     744           9 :         pPropMap->Insert( PROP_TABLE_COLUMN_SEPARATORS, uno::makeAny( aSeparators ) );
     745             : #ifdef DEBUG_DOMAINMAPPER
     746             :         dmapper_logger->startElement("rowProperties");
     747             :         pPropMap->dumpXml( dmapper_logger );
     748             :         dmapper_logger->endElement();
     749             : #endif
     750          18 :         insertRowProps(pPropMap);
     751             :     }
     752             : 
     753             :     // Now that potentially opened table is closed, save the table properties
     754        2195 :     DomainMapperTableManager_Base_t::insertTableProps( pTmpTableProperties );
     755             : 
     756        2195 :     m_aTmpTableProperties.pop_back();
     757        4390 :     TablePropertyMapPtr pEmptyTableProps( new TablePropertyMap() );
     758        2195 :     m_aTmpTableProperties.push_back( pEmptyTableProps );
     759             : 
     760        2195 :     ++m_nRow;
     761        2195 :     m_nCell.back( ) = 0;
     762        2195 :     m_nCellBorderIndex = 0;
     763        2195 :     getCurrentGrid()->clear();
     764        2195 :     pCurrentSpans->clear();
     765        2195 :     pCellWidths->clear();
     766             : 
     767        2195 :     m_nGridBefore = m_nGridAfter = 0;
     768        2195 :     m_bRowSizeTypeInserted = false;
     769        2195 :     m_bHasBtlrCell = false;
     770        4390 :     m_bTableSizeTypeInserted = false;
     771             : 
     772             : #ifdef DEBUG_DOMAINMAPPER
     773             :     dmapper_logger->endElement();
     774             : #endif
     775        2195 : }
     776             : 
     777             : 
     778        3394 : void DomainMapperTableManager::clearData()
     779             : {
     780        3394 :     m_nRow = m_nCellBorderIndex = m_nHeaderRepeat = m_nTableWidth = m_nLayoutType = 0;
     781        3394 :     m_sTableStyleName = OUString();
     782        3394 :     m_pTableStyleTextProperies.reset();
     783        3394 : }
     784             : 
     785             : 
     786             : }}
     787             : 
     788             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10