LCOV - code coverage report
Current view: top level - libreoffice/xmloff/source/chart - SchXMLTableContext.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 507 0.0 %
Date: 2012-12-27 Functions: 0 46 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             : 
      20             : 
      21             : #include <sax/tools/converter.hxx>
      22             : 
      23             : #include "SchXMLTableContext.hxx"
      24             : #include "SchXMLParagraphContext.hxx"
      25             : #include "SchXMLTextListContext.hxx"
      26             : #include "SchXMLImport.hxx"
      27             : #include "SchXMLTools.hxx"
      28             : #include "transporttypes.hxx"
      29             : #include "XMLStringBufferImportContext.hxx"
      30             : #include <rtl/math.hxx>
      31             : #include "xmloff/xmlnmspe.hxx"
      32             : #include <xmloff/xmltoken.hxx>
      33             : #include <xmloff/nmspmap.hxx>
      34             : #include <com/sun/star/frame/XModel.hpp>
      35             : #include <com/sun/star/chart2/XAnyDescriptionAccess.hpp>
      36             : #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
      37             : #include <com/sun/star/chart2/XChartDocument.hpp>
      38             : #include <com/sun/star/chart2/XChartTypeContainer.hpp>
      39             : #include <com/sun/star/chart2/XInternalDataProvider.hpp>
      40             : #include <com/sun/star/chart/ChartSeriesAddress.hpp>
      41             : #include <com/sun/star/beans/XPropertySet.hpp>
      42             : #include <com/sun/star/beans/XPropertySetInfo.hpp>
      43             : #include <com/sun/star/beans/PropertyAttribute.hpp>
      44             : 
      45             : #include <com/sun/star/chart2/XDiagram.hpp>
      46             : #include <com/sun/star/chart2/XAxis.hpp>
      47             : #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
      48             : #include <com/sun/star/chart2/AxisType.hpp>
      49             : 
      50             : #include <vector>
      51             : #include <algorithm>
      52             : 
      53             : using namespace com::sun::star;
      54             : using namespace ::xmloff::token;
      55             : using ::com::sun::star::uno::Sequence;
      56             : using ::com::sun::star::uno::Reference;
      57             : using ::rtl::OUString;
      58             : 
      59             : namespace
      60             : {
      61             : 
      62             : const char aLabelPrefix[] = "label ";
      63             : const char aCategoriesRange[] = "categories";
      64             : 
      65             : typedef ::std::multimap< ::rtl::OUString, ::rtl::OUString >
      66             :     lcl_tOriginalRangeToInternalRangeMap;
      67             : 
      68             : struct lcl_ApplyCellToData : public ::std::unary_function< SchXMLCell, void >
      69             : {
      70           0 :     lcl_ApplyCellToData( Sequence< double > & rOutData ) :
      71             :             m_rData( rOutData ),
      72             :             m_nIndex( 0 ),
      73           0 :             m_nSize( rOutData.getLength()),
      74           0 :             m_fNaN( 0.0 )
      75             :     {
      76           0 :         ::rtl::math::setNan( &m_fNaN );
      77           0 :     }
      78             : 
      79           0 :     void operator() ( const SchXMLCell & rCell )
      80             :     {
      81           0 :         if( m_nIndex < m_nSize )
      82             :         {
      83           0 :             if( rCell.eType == SCH_CELL_TYPE_FLOAT )
      84           0 :                 m_rData[m_nIndex] = rCell.fValue;
      85             :             else
      86           0 :                 m_rData[m_nIndex] = m_fNaN;
      87             :         }
      88           0 :         ++m_nIndex;
      89           0 :     }
      90             : 
      91           0 :     sal_Int32 getCurrentIndex() const
      92             :     {
      93           0 :         return m_nIndex;
      94             :     }
      95             : 
      96             : private:
      97             :     Sequence< double > & m_rData;
      98             :     sal_Int32 m_nIndex;
      99             :     sal_Int32 m_nSize;
     100             :     double m_fNaN;
     101             : };
     102             : 
     103           0 : void lcl_fillRangeMapping(
     104             :     const SchXMLTable & rTable,
     105             :     lcl_tOriginalRangeToInternalRangeMap & rOutRangeMap,
     106             :     chart::ChartDataRowSource eDataRowSource )
     107             : {
     108           0 :     sal_Int32 nRowOffset = ( rTable.bHasHeaderRow ? 1 : 0 );
     109           0 :     sal_Int32 nColOffset = ( rTable.bHasHeaderColumn ? 1 : 0 );
     110             : 
     111           0 :     const OUString lcl_aCategoriesRange(aCategoriesRange);
     112           0 :     const OUString lcl_aLabelPrefix(aLabelPrefix);
     113             : 
     114             :     // Fill range mapping
     115           0 :     const size_t nTableRowCount( rTable.aData.size());
     116           0 :     for( size_t nRow = 0; nRow < nTableRowCount; ++nRow )
     117             :     {
     118           0 :         const ::std::vector< SchXMLCell > & rRow( rTable.aData[nRow] );
     119           0 :         const size_t nTableColCount( rRow.size());
     120           0 :         for( size_t nCol = 0; nCol < nTableColCount; ++nCol )
     121             :         {
     122           0 :             const OUString aRangeId( rRow[nCol].aRangeId );
     123           0 :             if( !aRangeId.isEmpty())
     124             :             {
     125           0 :                 if( eDataRowSource == chart::ChartDataRowSource_COLUMNS )
     126             :                 {
     127           0 :                     if( nCol == 0 && rTable.bHasHeaderColumn )
     128             :                     {
     129             :                         OSL_ASSERT( static_cast< sal_Int32 >( nRow ) == nRowOffset );
     130             :                         rOutRangeMap.insert( lcl_tOriginalRangeToInternalRangeMap::value_type(
     131           0 :                                                  aRangeId, lcl_aCategoriesRange ));
     132             :                     }
     133             :                     else
     134             :                     {
     135           0 :                         OUString aColNumStr = OUString::valueOf( static_cast< sal_Int32 >( nCol - nColOffset ));
     136           0 :                         if( nRow == 0 && rTable.bHasHeaderRow )
     137             :                             rOutRangeMap.insert( lcl_tOriginalRangeToInternalRangeMap::value_type(
     138           0 :                                                      aRangeId, lcl_aLabelPrefix + aColNumStr ));
     139             :                         else
     140             :                             rOutRangeMap.insert( lcl_tOriginalRangeToInternalRangeMap::value_type(
     141           0 :                                                      aRangeId, aColNumStr ));
     142             :                     }
     143             :                 }
     144             :                 else // eDataRowSource == chart::ChartDataRowSource_ROWS
     145             :                 {
     146           0 :                     if( nRow == 0 && rTable.bHasHeaderRow )
     147             :                     {
     148             :                         OSL_ASSERT( static_cast< sal_Int32 >( nCol ) == nColOffset );
     149             :                         rOutRangeMap.insert( lcl_tOriginalRangeToInternalRangeMap::value_type(
     150           0 :                                                  aRangeId, lcl_aCategoriesRange ));
     151             :                     }
     152             :                     else
     153             :                     {
     154           0 :                         OUString aRowNumStr = OUString::valueOf( static_cast< sal_Int32 >( nRow - nRowOffset ));
     155           0 :                         if( nCol == 0 && rTable.bHasHeaderColumn )
     156             :                             rOutRangeMap.insert( lcl_tOriginalRangeToInternalRangeMap::value_type(
     157           0 :                                                      aRangeId, lcl_aLabelPrefix + aRowNumStr ));
     158             :                         else
     159             :                             rOutRangeMap.insert( lcl_tOriginalRangeToInternalRangeMap::value_type(
     160           0 :                                                      aRangeId, aRowNumStr ));
     161             :                     }
     162             :                 }
     163             :             }
     164           0 :         }
     165           0 :     }
     166           0 : }
     167             : 
     168             : Reference< chart2::data::XDataSequence >
     169           0 :     lcl_reassignDataSequence(
     170             :         const Reference< chart2::data::XDataSequence > & xSequence,
     171             :         const Reference< chart2::data::XDataProvider > & xDataProvider,
     172             :         lcl_tOriginalRangeToInternalRangeMap & rRangeMap,
     173             :         const OUString & rRange )
     174             : {
     175           0 :     Reference< chart2::data::XDataSequence > xResult( xSequence );
     176           0 :     lcl_tOriginalRangeToInternalRangeMap::iterator aIt( rRangeMap.find( rRange ));
     177           0 :     if( aIt != rRangeMap.end())
     178             :     {
     179             :         // set sequence with correct data
     180           0 :         xResult.set( xDataProvider->createDataSequenceByRangeRepresentation( aIt->second ));
     181             :         // remove translation, because it was used
     182           0 :         rRangeMap.erase( aIt );
     183             :     }
     184             : 
     185           0 :     return xResult;
     186             : }
     187             : 
     188           0 : bool lcl_mapContainsRange(
     189             :     lcl_tOriginalRangeToInternalRangeMap & rRangeMap,
     190             :     const OUString & rRange )
     191             : {
     192           0 :     lcl_tOriginalRangeToInternalRangeMap::iterator aIt( rRangeMap.find( rRange ));
     193           0 :     return ( aIt != rRangeMap.end());
     194             : }
     195             : 
     196           0 : bool lcl_tableOfRangeMatches(
     197             :     const ::rtl::OUString & rRange,
     198             :     const ::rtl::OUString & rTableName )
     199             : {
     200             :     // both strings are non-empty and the table name is part of the range
     201           0 :     return ( !rRange.isEmpty() &&
     202           0 :              !rTableName.isEmpty() &&
     203           0 :              (rRange.indexOf( rTableName ) != -1 ));
     204             : }
     205             : 
     206             : template< typename T >
     207           0 : ::std::vector< T > lcl_SequenceToVector( const uno::Sequence< T > & rSequence )
     208             : {
     209           0 :     ::std::vector< T > aResult( rSequence.getLength());
     210           0 :     ::std::copy( rSequence.getConstArray(), rSequence.getConstArray() + rSequence.getLength(),
     211             :                  aResult.begin());
     212           0 :     return aResult;
     213             : }
     214             : 
     215             : } // anonymous namespace
     216             : 
     217             : 
     218             : // ----------------------------------------
     219             : // class SchXMLTableContext
     220             : // ----------------------------------------
     221             : 
     222           0 : SchXMLTableContext::SchXMLTableContext( SchXMLImportHelper& rImpHelper,
     223             :                                         SvXMLImport& rImport,
     224             :                                         const rtl::OUString& rLName,
     225             :                                         SchXMLTable& aTable ) :
     226             :         SvXMLImportContext( rImport, XML_NAMESPACE_TABLE, rLName ),
     227             :         mrImportHelper( rImpHelper ),
     228             :         mrTable( aTable ),
     229             :         mbHasRowPermutation( false ),
     230           0 :         mbHasColumnPermutation( false )
     231             : {
     232           0 :     mrTable.nColumnIndex = -1;
     233           0 :     mrTable.nMaxColumnIndex = -1;
     234           0 :     mrTable.nRowIndex = -1;
     235           0 :     mrTable.aData.clear();
     236           0 : }
     237             : 
     238           0 : SchXMLTableContext::~SchXMLTableContext()
     239             : {
     240           0 : }
     241             : 
     242           0 : SvXMLImportContext *SchXMLTableContext::CreateChildContext(
     243             :     sal_uInt16 nPrefix,
     244             :     const rtl::OUString& rLocalName,
     245             :     const uno::Reference< xml::sax::XAttributeList >& )
     246             : {
     247           0 :     SvXMLImportContext* pContext = 0;
     248           0 :     const SvXMLTokenMap& rTokenMap = mrImportHelper.GetTableElemTokenMap();
     249             : 
     250           0 :     switch( rTokenMap.Get( nPrefix, rLocalName ))
     251             :     {
     252             :         case XML_TOK_TABLE_HEADER_COLS:
     253           0 :             mrTable.bHasHeaderColumn = true;
     254             :             // fall through intended
     255             :         case XML_TOK_TABLE_COLUMNS:
     256           0 :             pContext = new SchXMLTableColumnsContext( GetImport(), rLocalName, mrTable );
     257           0 :             break;
     258             : 
     259             :         case XML_TOK_TABLE_COLUMN:
     260           0 :             pContext = new SchXMLTableColumnContext( GetImport(), rLocalName, mrTable );
     261           0 :             break;
     262             : 
     263             :         case XML_TOK_TABLE_HEADER_ROWS:
     264           0 :             mrTable.bHasHeaderRow = true;
     265             :             // fall through intended
     266             :         case XML_TOK_TABLE_ROWS:
     267           0 :             pContext = new SchXMLTableRowsContext( mrImportHelper, GetImport(), rLocalName, mrTable );
     268           0 :             break;
     269             : 
     270             :         case XML_TOK_TABLE_ROW:
     271           0 :             pContext = new SchXMLTableRowContext( mrImportHelper, GetImport(), rLocalName, mrTable );
     272           0 :             break;
     273             : 
     274             :         default:
     275           0 :             pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
     276             :     }
     277             : 
     278           0 :     return pContext;
     279             : }
     280             : 
     281           0 : void SchXMLTableContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
     282             : {
     283             :     // get table-name
     284           0 :     sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;
     285             : 
     286           0 :     for( sal_Int16 i = 0; i < nAttrCount; i++ )
     287             :     {
     288           0 :         rtl::OUString sAttrName = xAttrList->getNameByIndex( i );
     289           0 :         rtl::OUString aLocalName;
     290           0 :         sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
     291           0 :         if ( nPrefix == XML_NAMESPACE_TABLE )
     292             :         {
     293           0 :             if ( IsXMLToken( aLocalName, XML_NAME ) )
     294             :             {
     295           0 :                 mrTable.aTableNameOfFile = xAttrList->getValueByIndex( i );
     296             :             }
     297           0 :             else if ( IsXMLToken( aLocalName, XML_PROTECTED ) )
     298             :             {
     299           0 :                 if ( IsXMLToken( xAttrList->getValueByIndex( i ), XML_TRUE ) )
     300             :                 {
     301           0 :                     mrTable.bProtected = true;
     302             :                 }
     303             :             }
     304             :         }
     305           0 :     }
     306           0 : }
     307             : 
     308           0 : void SchXMLTableContext::EndElement()
     309             : {
     310           0 :     if( mbHasColumnPermutation )
     311             :     {
     312             :         OSL_ASSERT( !mbHasRowPermutation );
     313           0 :         ::std::vector< sal_Int32 > aPermutation( lcl_SequenceToVector( maColumnPermutation ));
     314             :         OSL_ASSERT( !aPermutation.empty());
     315           0 :         if( aPermutation.empty())
     316             :             return;
     317             : 
     318             :         // permute the values of all rows according to aPermutation
     319           0 :         for( ::std::vector< ::std::vector< SchXMLCell > >::iterator aRowIt( mrTable.aData.begin());
     320           0 :              aRowIt != mrTable.aData.end(); ++aRowIt )
     321             :         {
     322           0 :             bool bModified = false;
     323           0 :             ::std::vector< SchXMLCell > aModifiedRow;
     324           0 :             const size_t nPermSize = aPermutation.size();
     325             :             OSL_ASSERT( static_cast< sal_Int32 >( nPermSize ) - 1 == *(::std::max_element( aPermutation.begin(), aPermutation.end())));
     326           0 :             const size_t nRowSize = aRowIt->size();
     327           0 :             const size_t nDestSize = ::std::min( nPermSize, nRowSize );
     328           0 :             for( size_t nDestinationIndex = 0; nDestinationIndex < nDestSize; ++nDestinationIndex )
     329             :             {
     330           0 :                 const size_t nSourceIndex = static_cast< size_t >( aPermutation[ nDestinationIndex ] );
     331           0 :                 if( nSourceIndex != nDestinationIndex &&
     332             :                     nSourceIndex < nRowSize )
     333             :                 {
     334             :                     // copy original on first real permutation
     335           0 :                     if( !bModified )
     336             :                     {
     337             :                         OSL_ASSERT( aModifiedRow.empty());
     338           0 :                         aModifiedRow.reserve( aRowIt->size());
     339           0 :                         ::std::copy( aRowIt->begin(), aRowIt->end(), ::std::back_inserter( aModifiedRow ));
     340             :                         OSL_ASSERT( !aModifiedRow.empty());
     341             :                     }
     342             :                     OSL_ASSERT( nDestinationIndex < aModifiedRow.size());
     343           0 :                     aModifiedRow[ nDestinationIndex ] = (*aRowIt)[ nSourceIndex ];
     344           0 :                     bModified = true;
     345             :                 }
     346             :             }
     347             :             // copy back
     348           0 :             if( bModified )
     349           0 :                 ::std::copy( aModifiedRow.begin(), aModifiedRow.end(), aRowIt->begin());
     350           0 :         }
     351             :     }
     352           0 :     else if( mbHasRowPermutation )
     353             :     {
     354           0 :         ::std::vector< sal_Int32 > aPermutation( lcl_SequenceToVector( maRowPermutation ));
     355             :         OSL_ASSERT( !aPermutation.empty());
     356           0 :         if( aPermutation.empty())
     357             :             return;
     358             : 
     359           0 :         bool bModified = false;
     360           0 :         const size_t nPermSize = aPermutation.size();
     361             :         OSL_ASSERT( static_cast< sal_Int32 >( nPermSize ) - 1 == *(::std::max_element( aPermutation.begin(), aPermutation.end())));
     362           0 :         const size_t nTableRowCount = mrTable.aData.size();
     363           0 :         const size_t nDestSize = ::std::min( nPermSize, nTableRowCount );
     364           0 :         ::std::vector< ::std::vector< SchXMLCell > > aDestination;
     365           0 :         for( size_t nDestinationIndex = 0; nDestinationIndex < nDestSize; ++nDestinationIndex )
     366             :         {
     367           0 :             const size_t nSourceIndex = static_cast< size_t >( aPermutation[ nDestinationIndex ] );
     368           0 :             if( nSourceIndex != nDestinationIndex &&
     369             :                 nSourceIndex < nTableRowCount )
     370             :             {
     371             :                 // copy original on first real permutation
     372           0 :                 if( !bModified )
     373             :                 {
     374             :                     OSL_ASSERT( aDestination.empty());
     375           0 :                     aDestination.reserve( mrTable.aData.size());
     376           0 :                     ::std::copy( mrTable.aData.begin(), mrTable.aData.end(), ::std::back_inserter( aDestination ));
     377             :                     OSL_ASSERT( !aDestination.empty());
     378             :                 }
     379             :                 OSL_ASSERT( nDestinationIndex < aDestination.size());
     380           0 :                 aDestination[ nDestinationIndex ] = mrTable.aData[ nSourceIndex ];
     381           0 :                 bModified = true;
     382             :             }
     383             :         }
     384           0 :         if( bModified )
     385             :         {
     386             :             // copy back
     387           0 :             ::std::copy( aDestination.begin(), aDestination.end(), mrTable.aData.begin());
     388           0 :         }
     389             :     }
     390             : }
     391             : 
     392           0 : void SchXMLTableContext::setRowPermutation( const uno::Sequence< sal_Int32 > & rPermutation )
     393             : {
     394           0 :     maRowPermutation = rPermutation;
     395           0 :     mbHasRowPermutation = ( rPermutation.getLength() > 0 );
     396             : 
     397           0 :     if( mbHasRowPermutation && mbHasColumnPermutation )
     398             :     {
     399           0 :         mbHasColumnPermutation = false;
     400           0 :         maColumnPermutation.realloc( 0 );
     401             :     }
     402           0 : }
     403             : 
     404           0 : void SchXMLTableContext::setColumnPermutation( const uno::Sequence< sal_Int32 > & rPermutation )
     405             : {
     406           0 :     maColumnPermutation = rPermutation;
     407           0 :     mbHasColumnPermutation = ( rPermutation.getLength() > 0 );
     408             : 
     409           0 :     if( mbHasColumnPermutation && mbHasRowPermutation )
     410             :     {
     411           0 :         mbHasRowPermutation = false;
     412           0 :         maRowPermutation.realloc( 0 );
     413             :     }
     414           0 : }
     415             : 
     416             : // ========================================
     417             : // classes for columns
     418             : // ========================================
     419             : 
     420             : // ----------------------------------------
     421             : // class SchXMLTableColumnsContext
     422             : // ----------------------------------------
     423             : 
     424           0 : SchXMLTableColumnsContext::SchXMLTableColumnsContext(
     425             :     SvXMLImport& rImport,
     426             :     const rtl::OUString& rLocalName,
     427             :     SchXMLTable& aTable ) :
     428             :         SvXMLImportContext( rImport, XML_NAMESPACE_TABLE, rLocalName ),
     429           0 :         mrTable( aTable )
     430             : {
     431           0 : }
     432             : 
     433           0 : SchXMLTableColumnsContext::~SchXMLTableColumnsContext()
     434             : {
     435           0 : }
     436             : 
     437           0 : SvXMLImportContext* SchXMLTableColumnsContext::CreateChildContext(
     438             :     sal_uInt16 nPrefix,
     439             :     const rtl::OUString& rLocalName,
     440             :     const uno::Reference< xml::sax::XAttributeList >& )
     441             : {
     442           0 :     SvXMLImportContext* pContext = 0;
     443             : 
     444           0 :     if( nPrefix == XML_NAMESPACE_TABLE &&
     445           0 :         IsXMLToken( rLocalName, XML_TABLE_COLUMN ) )
     446             :     {
     447           0 :         pContext = new SchXMLTableColumnContext( GetImport(), rLocalName, mrTable );
     448             :     }
     449             :     else
     450           0 :         pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
     451             : 
     452           0 :     return pContext;
     453             : }
     454             : 
     455             : // ----------------------------------------
     456             : // class SchXMLTableColumnContext
     457             : // ----------------------------------------
     458             : 
     459           0 : SchXMLTableColumnContext::SchXMLTableColumnContext(
     460             :     SvXMLImport& rImport,
     461             :     const rtl::OUString& rLocalName,
     462             :     SchXMLTable& aTable ) :
     463             :         SvXMLImportContext( rImport, XML_NAMESPACE_TABLE, rLocalName ),
     464           0 :         mrTable( aTable )
     465             : {
     466           0 : }
     467             : 
     468           0 : void SchXMLTableColumnContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
     469             : {
     470             :     // get number-columns-repeated attribute
     471           0 :     sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;
     472           0 :     sal_Int32 nRepeated = 1;
     473           0 :     bool bHidden = false;
     474             : 
     475           0 :     for( sal_Int16 i = 0; i < nAttrCount; i++ )
     476             :     {
     477           0 :         rtl::OUString sAttrName = xAttrList->getNameByIndex( i );
     478           0 :         rtl::OUString aLocalName;
     479           0 :         sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
     480             : 
     481           0 :         if( nPrefix == XML_NAMESPACE_TABLE &&
     482           0 :             IsXMLToken( aLocalName, XML_NUMBER_COLUMNS_REPEATED ) )
     483             :         {
     484           0 :             rtl::OUString aValue = xAttrList->getValueByIndex( i );
     485           0 :             if( !aValue.isEmpty())
     486           0 :                 nRepeated = aValue.toInt32();
     487             :         }
     488           0 :         else if( nPrefix == XML_NAMESPACE_TABLE &&
     489           0 :             IsXMLToken( aLocalName, XML_VISIBILITY ) )
     490             :         {
     491           0 :             rtl::OUString aVisibility = xAttrList->getValueByIndex( i );
     492           0 :             bHidden = aVisibility.equals( GetXMLToken( XML_COLLAPSE ) );
     493             :         }
     494           0 :     }
     495             : 
     496           0 :     sal_Int32 nOldCount = mrTable.nNumberOfColsEstimate;
     497           0 :     sal_Int32 nNewCount = nOldCount + nRepeated;
     498           0 :     mrTable.nNumberOfColsEstimate = nNewCount;
     499             : 
     500           0 :     if( bHidden )
     501             :     {
     502             :         //i91578 display of hidden values (copy paste scenario; use hidden flag during migration to locale table upon paste )
     503           0 :         sal_Int32 nColOffset = ( mrTable.bHasHeaderColumn ? 1 : 0 );
     504           0 :         for( sal_Int32 nN = nOldCount; nN<nNewCount; nN++ )
     505             :         {
     506           0 :             sal_Int32 nHiddenColumnIndex = nN-nColOffset;
     507           0 :             if( nHiddenColumnIndex>=0 )
     508           0 :                 mrTable.aHiddenColumns.push_back(nHiddenColumnIndex);
     509             :         }
     510             :     }
     511           0 : }
     512             : 
     513           0 : SchXMLTableColumnContext::~SchXMLTableColumnContext()
     514             : {
     515           0 : }
     516             : 
     517             : // ========================================
     518             : // classes for rows
     519             : // ========================================
     520             : 
     521             : // ----------------------------------------
     522             : // class SchXMLTableRowsContext
     523             : // ----------------------------------------
     524             : 
     525           0 : SchXMLTableRowsContext::SchXMLTableRowsContext(
     526             :     SchXMLImportHelper& rImpHelper,
     527             :     SvXMLImport& rImport,
     528             :     const rtl::OUString& rLocalName,
     529             :     SchXMLTable& aTable ) :
     530             :         SvXMLImportContext( rImport, XML_NAMESPACE_TABLE, rLocalName ),
     531             :         mrImportHelper( rImpHelper ),
     532           0 :         mrTable( aTable )
     533             : {
     534           0 : }
     535             : 
     536           0 : SchXMLTableRowsContext::~SchXMLTableRowsContext()
     537             : {
     538           0 : }
     539             : 
     540           0 : SvXMLImportContext* SchXMLTableRowsContext::CreateChildContext(
     541             :     sal_uInt16 nPrefix,
     542             :     const rtl::OUString& rLocalName,
     543             :     const uno::Reference< xml::sax::XAttributeList >& )
     544             : {
     545           0 :     SvXMLImportContext* pContext = 0;
     546             : 
     547           0 :     if( nPrefix == XML_NAMESPACE_TABLE &&
     548           0 :         IsXMLToken( rLocalName, XML_TABLE_ROW ) )
     549             :     {
     550           0 :         pContext = new SchXMLTableRowContext( mrImportHelper, GetImport(), rLocalName, mrTable );
     551             :     }
     552             :     else
     553             :     {
     554           0 :         pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
     555             :     }
     556             : 
     557           0 :     return pContext;
     558             : }
     559             : 
     560             : // ----------------------------------------
     561             : // class SchXMLTableRowContext
     562             : // ----------------------------------------
     563             : 
     564           0 : SchXMLTableRowContext::SchXMLTableRowContext(
     565             :     SchXMLImportHelper& rImpHelper,
     566             :     SvXMLImport& rImport,
     567             :     const rtl::OUString& rLocalName,
     568             :     SchXMLTable& aTable ) :
     569             :         SvXMLImportContext( rImport, XML_NAMESPACE_TABLE, rLocalName ),
     570             :         mrImportHelper( rImpHelper ),
     571           0 :         mrTable( aTable )
     572             : {
     573           0 :     mrTable.nColumnIndex = -1;
     574           0 :     mrTable.nRowIndex++;
     575             : 
     576           0 :     std::vector< SchXMLCell > aNewRow;
     577           0 :     aNewRow.reserve( mrTable.nNumberOfColsEstimate );
     578           0 :     while( mrTable.aData.size() <= (unsigned long)mrTable.nRowIndex )
     579           0 :         mrTable.aData.push_back( aNewRow );
     580           0 : }
     581             : 
     582           0 : SchXMLTableRowContext::~SchXMLTableRowContext()
     583             : {
     584           0 : }
     585             : 
     586           0 : SvXMLImportContext* SchXMLTableRowContext::CreateChildContext(
     587             :     sal_uInt16 nPrefix,
     588             :     const rtl::OUString& rLocalName,
     589             :     const uno::Reference< xml::sax::XAttributeList >& )
     590             : {
     591           0 :     SvXMLImportContext* pContext = 0;
     592             : 
     593             :     // <table:table-cell> element
     594           0 :     if( nPrefix == XML_NAMESPACE_TABLE &&
     595           0 :         IsXMLToken(rLocalName, XML_TABLE_CELL ) )
     596             :     {
     597           0 :         pContext = new SchXMLTableCellContext( mrImportHelper, GetImport(), rLocalName, mrTable );
     598             :     }
     599             :     else
     600             :     {
     601           0 :         pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
     602             :     }
     603             : 
     604           0 :     return pContext;
     605             : }
     606             : 
     607             : //---------------------------------------------------------------------------------------------------
     608             : //---------------------------------------------------------------------------------------------------
     609             : 
     610             : class SchXMLRangeSomewhereContext : public SvXMLImportContext
     611             : {
     612             : //#i113950# previously the range was exported to attribute text:id,
     613             : //but that attribute does not allow arbitrary strings anymore
     614             : //so we need to find an alternative to save that range info for copy/paste scenario ...
     615             : //-> use description at an empty group element for now
     616             : 
     617             : private:
     618             :     ::rtl::OUString& mrRangeString;
     619             :     ::rtl::OUStringBuffer maRangeStringBuffer;
     620             : 
     621             : public:
     622             :     SchXMLRangeSomewhereContext( SvXMLImport& rImport,
     623             :                             sal_uInt16 nPrefix,
     624             :                             const ::rtl::OUString& rLocalName,
     625             :                             ::rtl::OUString& rRangeString );
     626             :     virtual ~SchXMLRangeSomewhereContext();
     627             : 
     628             :     virtual SvXMLImportContext* CreateChildContext(
     629             :         sal_uInt16 nPrefix,
     630             :         const ::rtl::OUString& rLocalName,
     631             :         const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttrList );
     632             :     virtual void EndElement();
     633             : };
     634             : 
     635             : //---------------------------------------------------------------------------------------------------
     636             : //---------------------------------------------------------------------------------------------------
     637             : 
     638             : // ========================================
     639             : // classes for cells and their content
     640             : // ========================================
     641             : 
     642             : // ----------------------------------------
     643             : // class SchXMLTableCellContext
     644             : // ----------------------------------------
     645             : 
     646           0 : SchXMLTableCellContext::SchXMLTableCellContext(
     647             :     SchXMLImportHelper& rImpHelper,
     648             :     SvXMLImport& rImport,
     649             :     const rtl::OUString& rLocalName,
     650             :     SchXMLTable& aTable ) :
     651             :         SvXMLImportContext( rImport, XML_NAMESPACE_TABLE, rLocalName ),
     652             :         mrImportHelper( rImpHelper ),
     653           0 :         mrTable( aTable )
     654             : {
     655           0 : }
     656             : 
     657           0 : SchXMLTableCellContext::~SchXMLTableCellContext()
     658             : {
     659           0 : }
     660             : 
     661           0 : void SchXMLTableCellContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
     662             : {
     663           0 :     sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;
     664           0 :     rtl::OUString aValue;
     665           0 :     rtl::OUString aLocalName;
     666           0 :     rtl::OUString aCellContent;
     667           0 :     SchXMLCellType eValueType  = SCH_CELL_TYPE_UNKNOWN;
     668           0 :     const SvXMLTokenMap& rAttrTokenMap = mrImportHelper.GetCellAttrTokenMap();
     669             : 
     670           0 :     for( sal_Int16 i = 0; i < nAttrCount; i++ )
     671             :     {
     672           0 :         rtl::OUString sAttrName = xAttrList->getNameByIndex( i );
     673           0 :         sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
     674             : 
     675           0 :         switch( rAttrTokenMap.Get( nPrefix, aLocalName ))
     676             :         {
     677             :             case XML_TOK_CELL_VAL_TYPE:
     678           0 :                 aValue = xAttrList->getValueByIndex( i );
     679           0 :                 if( IsXMLToken( aValue, XML_FLOAT ) )
     680           0 :                     eValueType = SCH_CELL_TYPE_FLOAT;
     681           0 :                 else if( IsXMLToken( aValue, XML_STRING ) )
     682           0 :                     eValueType = SCH_CELL_TYPE_STRING;
     683           0 :                 break;
     684             : 
     685             :             case XML_TOK_CELL_VALUE:
     686           0 :                 aCellContent = xAttrList->getValueByIndex( i );
     687           0 :                 break;
     688             :         }
     689           0 :     }
     690             : 
     691           0 :     mbReadText = sal_True;
     692           0 :     SchXMLCell aCell;
     693           0 :     aCell.eType = eValueType;
     694             : 
     695           0 :     if( eValueType == SCH_CELL_TYPE_FLOAT )
     696             :     {
     697             :         double fData;
     698             :         // the result may be false if a NaN is read, but that's ok
     699           0 :         ::sax::Converter::convertDouble( fData, aCellContent );
     700             : 
     701           0 :         aCell.fValue = fData;
     702             :         // dont read text from following <text:p> or <text:list> element
     703           0 :         mbReadText = sal_False;
     704             :     }
     705             : 
     706           0 :     mrTable.aData[ mrTable.nRowIndex ].push_back( aCell );
     707           0 :     mrTable.nColumnIndex++;
     708           0 :     if( mrTable.nMaxColumnIndex < mrTable.nColumnIndex )
     709           0 :         mrTable.nMaxColumnIndex = mrTable.nColumnIndex;
     710           0 : }
     711             : 
     712           0 : SvXMLImportContext* SchXMLTableCellContext::CreateChildContext(
     713             :     sal_uInt16 nPrefix,
     714             :     const rtl::OUString& rLocalName,
     715             :     const uno::Reference< xml::sax::XAttributeList >& )
     716             : {
     717           0 :     SvXMLImportContext* pContext = 0;
     718             : 
     719             :     // <text:list> element
     720           0 :     if( nPrefix == XML_NAMESPACE_TEXT && IsXMLToken( rLocalName, XML_LIST ) && mbReadText )
     721             :     {
     722           0 :         SchXMLCell& rCell = mrTable.aData[ mrTable.nRowIndex ][ mrTable.nColumnIndex ];
     723           0 :         rCell.aComplexString = Sequence< OUString >();
     724           0 :         rCell.eType = SCH_CELL_TYPE_COMPLEX_STRING;
     725           0 :         pContext = new SchXMLTextListContext( GetImport(), rLocalName, rCell.aComplexString );
     726           0 :         mbReadText = sal_False;//don't apply text from <text:p>
     727             :     }
     728             :     // <text:p> element - read text (and range from text:id old version)
     729           0 :     else if( nPrefix == XML_NAMESPACE_TEXT && IsXMLToken( rLocalName, XML_P ) )
     730             :     {
     731           0 :         pContext = new SchXMLParagraphContext( GetImport(), rLocalName, maCellContent, &maRangeId );
     732             :     }
     733             :     // <draw:g> element - read range
     734           0 :     else if( nPrefix == XML_NAMESPACE_DRAW && IsXMLToken( rLocalName, XML_G ) )
     735             :     {
     736             :         //#i113950# previously the range was exported to attribute text:id, but that attribute does not allow arbitrary strings anymore
     737             :         //so we need to find an alternative to save that range info for copy/paste scenario ... -> use description at an empty group element for now
     738           0 :         pContext = new SchXMLRangeSomewhereContext( GetImport(), nPrefix, rLocalName, maRangeId );
     739             :     }
     740             :     else
     741             :     {
     742           0 :         pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
     743             :     }
     744             : 
     745           0 :     return pContext;
     746             : }
     747             : 
     748           0 : void SchXMLTableCellContext::EndElement()
     749             : {
     750           0 :     if( mbReadText && !maCellContent.isEmpty() ) //apply text from <text:p> element
     751           0 :         mrTable.aData[ mrTable.nRowIndex ][ mrTable.nColumnIndex ].aString = maCellContent;
     752           0 :     if( !maRangeId.isEmpty())
     753           0 :         mrTable.aData[ mrTable.nRowIndex ][ mrTable.nColumnIndex ].aRangeId = maRangeId;
     754           0 : }
     755             : 
     756             : // ========================================
     757             : 
     758           0 : static void lcl_ApplyCellToComplexLabel( const SchXMLCell& rCell, Sequence< uno::Any >& rComplexLabel )
     759             : {
     760           0 :     if( rCell.eType == SCH_CELL_TYPE_STRING )
     761             :     {
     762           0 :         rComplexLabel.realloc(1);
     763           0 :         rComplexLabel[0] = uno::makeAny( rCell.aString );
     764             :     }
     765           0 :     else if( rCell.aComplexString.getLength() && rCell.eType == SCH_CELL_TYPE_COMPLEX_STRING )
     766             :     {
     767           0 :         sal_Int32 nCount = rCell.aComplexString.getLength();
     768           0 :         rComplexLabel.realloc( nCount );
     769           0 :         for( sal_Int32 nN=0; nN<nCount; nN++)
     770           0 :             rComplexLabel[nN] = uno::makeAny((rCell.aComplexString)[nN]);
     771             :     }
     772           0 :     else if( rCell.eType == SCH_CELL_TYPE_FLOAT )
     773             :     {
     774           0 :         rComplexLabel.realloc(1);
     775           0 :         rComplexLabel[0] = uno::makeAny( rCell.fValue );
     776             :     }
     777           0 : }
     778             : 
     779           0 : void SchXMLTableHelper::applyTableToInternalDataProvider(
     780             :     const SchXMLTable& rTable,
     781             :     uno::Reference< chart2::XChartDocument > xChartDoc )
     782             : {
     783             :     // apply all data read from the local table to the internal data provider
     784           0 :     if( !xChartDoc.is() || !xChartDoc->hasInternalDataProvider() )
     785             :         return;
     786           0 :     Reference< chart2::data::XDataProvider >  xDataProv( xChartDoc->getDataProvider() );
     787           0 :     if( !xDataProv.is() )
     788             :         return;
     789             : 
     790             :     //prepare the read local table data
     791           0 :     sal_Int32 nNumRows( static_cast< sal_Int32 >( rTable.aData.size()));
     792           0 :     sal_Int32 nRowOffset = 0;
     793           0 :     if( rTable.bHasHeaderRow )
     794             :     {
     795           0 :         --nNumRows;
     796           0 :         nRowOffset = 1;
     797             :     }
     798           0 :     sal_Int32 nNumColumns( rTable.nMaxColumnIndex + 1 );
     799           0 :     sal_Int32 nColOffset = 0;
     800           0 :     if( rTable.bHasHeaderColumn )
     801             :     {
     802           0 :         --nNumColumns;
     803           0 :         nColOffset = 1;
     804             :     }
     805             : 
     806           0 :     Sequence< Sequence< double > > aDataInRows( nNumRows );
     807           0 :     Sequence< Sequence< uno::Any > > aComplexRowDescriptions( nNumRows );
     808           0 :     Sequence< Sequence< uno::Any > > aComplexColumnDescriptions( nNumColumns );
     809           0 :     for( sal_Int32 i=0; i<nNumRows; ++i )
     810           0 :         aDataInRows[i].realloc( nNumColumns );
     811             : 
     812           0 :     if( rTable.aData.begin() != rTable.aData.end())
     813             :     {
     814             :         //apply column labels
     815           0 :         if( rTable.bHasHeaderRow )
     816             :         {
     817           0 :             const ::std::vector< SchXMLCell >& rFirstRow = rTable.aData.front();
     818           0 :             const sal_Int32 nColumnLabelsSize = aComplexColumnDescriptions.getLength();
     819           0 :             const sal_Int32 nMax = ::std::min< sal_Int32 >( nColumnLabelsSize, static_cast< sal_Int32 >( rFirstRow.size()) - nColOffset );
     820             :             OSL_ASSERT( nMax == nColumnLabelsSize );
     821           0 :             for( sal_Int32 i=0; i<nMax; ++i )
     822           0 :                 lcl_ApplyCellToComplexLabel( rFirstRow[i+nColOffset], aComplexColumnDescriptions[i] );
     823             :         }
     824             : 
     825           0 :         std::vector< ::std::vector< SchXMLCell > >::const_iterator aRowIter( rTable.aData.begin() + nRowOffset );
     826           0 :         std::vector< ::std::vector< SchXMLCell > >::const_iterator aEnd( rTable.aData.end() );
     827           0 :         for( sal_Int32 nRow = 0; aRowIter != aEnd && nRow < nNumRows; ++aRowIter, ++nRow )
     828             :         {
     829           0 :             const ::std::vector< SchXMLCell >& rRow = *aRowIter;
     830           0 :             if( !rRow.empty() )
     831             :             {
     832             :                 // row label
     833           0 :                 if( rTable.bHasHeaderColumn )
     834           0 :                     lcl_ApplyCellToComplexLabel( rRow.front(), aComplexRowDescriptions[nRow] );
     835             : 
     836             :                 // values
     837           0 :                 Sequence< double >& rTargetRow = aDataInRows[nRow];
     838           0 :                 lcl_ApplyCellToData aApplyCellToData = ::std::for_each( rRow.begin() + nColOffset, rRow.end(), lcl_ApplyCellToData( rTargetRow ) );
     839           0 :                 double fNaN = 0.0;
     840           0 :                 ::rtl::math::setNan( &fNaN );
     841           0 :                 for( sal_Int32 nCurrentIndex = aApplyCellToData.getCurrentIndex(); nCurrentIndex<nNumColumns; nCurrentIndex++ )
     842           0 :                     rTargetRow[nCurrentIndex] = fNaN;//#i110615#
     843             :             }
     844             :         }
     845             :     }
     846             : 
     847             :     //apply the collected data to the chart
     848           0 :     Reference< chart2::XAnyDescriptionAccess > xDataAccess( xDataProv, uno::UNO_QUERY );
     849           0 :     if( !xDataAccess.is() )
     850             :         return;
     851             : 
     852           0 :     xDataAccess->setData( aDataInRows );
     853           0 :     if( rTable.bHasHeaderColumn )
     854           0 :         xDataAccess->setAnyRowDescriptions( aComplexRowDescriptions );
     855           0 :     if( rTable.bHasHeaderRow )
     856           0 :         xDataAccess->setAnyColumnDescriptions( aComplexColumnDescriptions );
     857             : 
     858           0 :     if ( rTable.bProtected )
     859             :     {
     860             :         try
     861             :         {
     862           0 :             Reference< beans::XPropertySet > xProps( xChartDoc, uno::UNO_QUERY_THROW );
     863           0 :             xProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "DisableDataTableDialog" ) ), uno::makeAny( sal_True ) );
     864           0 :             xProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "DisableComplexChartTypes" ) ), uno::makeAny( sal_True ) );
     865             :         }
     866           0 :         catch ( uno::Exception& )
     867             :         {
     868             :         }
     869           0 :     }
     870             : }
     871             : 
     872           0 : void SchXMLTableHelper::switchRangesFromOuterToInternalIfNecessary(
     873             :     const SchXMLTable& rTable,
     874             :     const tSchXMLLSequencesPerIndex & rLSequencesPerIndex,
     875             :     uno::Reference< chart2::XChartDocument > xChartDoc,
     876             :     chart::ChartDataRowSource eDataRowSource )
     877             : {
     878           0 :     if( ! (xChartDoc.is() && xChartDoc->hasInternalDataProvider()))
     879           0 :         return;
     880             : 
     881             :     // If the range-strings are valid (starting with "local-table") they should
     882             :     // be interpreted like given, otherwise (when the ranges refer to Calc- or
     883             :     // Writer-ranges, but the container is not available like when pasting a
     884             :     // chart from Calc to Impress) the range is ignored, and every object gets
     885             :     // one table column in the order of appearance, which is: 1. categories,
     886             :     // 2. data series: 2.a) domains, 2.b) values (main-role, usually y-values)
     887             : 
     888           0 :     Reference< chart2::data::XDataProvider >  xDataProv( xChartDoc->getDataProvider());
     889             : 
     890             :     // create a mapping from original ranges to new ranges
     891           0 :     lcl_tOriginalRangeToInternalRangeMap aRangeMap;
     892             : 
     893           0 :     lcl_fillRangeMapping( rTable, aRangeMap, eDataRowSource );
     894             : 
     895           0 :     const OUString lcl_aCategoriesRange(aCategoriesRange);
     896             : 
     897           0 :     bool bCategoriesApplied = false;
     898             :     // translate ranges (using the map created before)
     899           0 :     for( tSchXMLLSequencesPerIndex::const_iterator aLSeqIt( rLSequencesPerIndex.begin());
     900           0 :          aLSeqIt != rLSequencesPerIndex.end(); ++aLSeqIt )
     901             :     {
     902           0 :         if( aLSeqIt->second.is())
     903             :         {
     904             :             // values/error bars/categories
     905           0 :             if( aLSeqIt->first.second == SCH_XML_PART_VALUES ||
     906           0 :                 aLSeqIt->first.second == SCH_XML_PART_ERROR_BARS )
     907             :             {
     908           0 :                 Reference< chart2::data::XDataSequence > xSeq( aLSeqIt->second->getValues());
     909           0 :                 OUString aRange;
     910           0 :                 if( xSeq.is() &&
     911           0 :                     SchXMLTools::getXMLRangePropertyFromDataSequence( xSeq, aRange, /* bClearProp = */ true ) &&
     912           0 :                     lcl_mapContainsRange( aRangeMap, aRange ))
     913             :                 {
     914             :                     Reference< chart2::data::XDataSequence > xNewSeq(
     915           0 :                         lcl_reassignDataSequence( xSeq, xDataProv, aRangeMap, aRange ));
     916           0 :                     if( xNewSeq != xSeq )
     917             :                     {
     918             :                         SchXMLTools::copyProperties( Reference< beans::XPropertySet >( xSeq, uno::UNO_QUERY ),
     919           0 :                                             Reference< beans::XPropertySet >( xNewSeq, uno::UNO_QUERY ));
     920           0 :                         aLSeqIt->second->setValues( xNewSeq );
     921           0 :                     }
     922             :                 }
     923             :                 else
     924             :                 {
     925           0 :                     if( lcl_tableOfRangeMatches( aRange, rTable.aTableNameOfFile ))
     926             :                     {
     927           0 :                         if( aLSeqIt->first.first == SCH_XML_CATEGORIES_INDEX )
     928           0 :                             bCategoriesApplied = true;
     929             :                     }
     930             :                     else
     931             :                     {
     932           0 :                         if( aLSeqIt->first.first == SCH_XML_CATEGORIES_INDEX )
     933             :                         {
     934           0 :                             Reference< beans::XPropertySet > xOldSequenceProp( aLSeqIt->second->getValues(), uno::UNO_QUERY );
     935             :                             Reference< chart2::data::XDataSequence > xNewSequence(
     936           0 :                                 xDataProv->createDataSequenceByRangeRepresentation(
     937           0 :                                     OUString(RTL_CONSTASCII_USTRINGPARAM("categories"))));
     938             :                             SchXMLTools::copyProperties(
     939           0 :                                 xOldSequenceProp, Reference< beans::XPropertySet >( xNewSequence, uno::UNO_QUERY ));
     940           0 :                             aLSeqIt->second->setValues( xNewSequence );
     941           0 :                             bCategoriesApplied = true;
     942             :                         }
     943             :                         else
     944             :                         {
     945           0 :                             Reference< beans::XPropertySet > xOldSequenceProp( aLSeqIt->second->getValues(), uno::UNO_QUERY );
     946           0 :                             OUString aRep( OUString::valueOf( aLSeqIt->first.first ));
     947             :                             Reference< chart2::data::XDataSequence > xNewSequence(
     948           0 :                                 xDataProv->createDataSequenceByRangeRepresentation( aRep ));
     949             :                             SchXMLTools::copyProperties(
     950           0 :                                 xOldSequenceProp, Reference< beans::XPropertySet >( xNewSequence, uno::UNO_QUERY ));
     951           0 :                             aLSeqIt->second->setValues( xNewSequence );
     952             :                         }
     953             :                     }
     954           0 :                 }
     955             :             }
     956             :             else // labels
     957             :             {
     958             :                 OSL_ASSERT( aLSeqIt->first.second == SCH_XML_PART_LABEL );
     959             :                 // labels
     960           0 :                 Reference< chart2::data::XDataSequence > xSeq( aLSeqIt->second->getLabel());
     961           0 :                 OUString aRange;
     962           0 :                 if( xSeq.is() &&
     963           0 :                     SchXMLTools::getXMLRangePropertyFromDataSequence( xSeq, aRange, /* bClearProp = */ true ) &&
     964           0 :                     lcl_mapContainsRange( aRangeMap, aRange ))
     965             :                 {
     966             :                     Reference< chart2::data::XDataSequence > xNewSeq(
     967           0 :                         lcl_reassignDataSequence( xSeq, xDataProv, aRangeMap, aRange ));
     968           0 :                     if( xNewSeq != xSeq )
     969             :                     {
     970             :                         SchXMLTools::copyProperties( Reference< beans::XPropertySet >( xSeq, uno::UNO_QUERY ),
     971           0 :                                             Reference< beans::XPropertySet >( xNewSeq, uno::UNO_QUERY ));
     972           0 :                         aLSeqIt->second->setLabel( xNewSeq );
     973           0 :                     }
     974             :                 }
     975           0 :                 else if( ! lcl_tableOfRangeMatches( aRange, rTable.aTableNameOfFile ))
     976             :                 {
     977           0 :                     OUString aRep( RTL_CONSTASCII_USTRINGPARAM("label "));
     978           0 :                     aRep += OUString::valueOf( aLSeqIt->first.first );
     979             : 
     980             :                     Reference< chart2::data::XDataSequence > xNewSeq(
     981           0 :                         xDataProv->createDataSequenceByRangeRepresentation( aRep ));
     982             :                     SchXMLTools::copyProperties( Reference< beans::XPropertySet >( xSeq, uno::UNO_QUERY ),
     983           0 :                                         Reference< beans::XPropertySet >( xNewSeq, uno::UNO_QUERY ));
     984           0 :                     aLSeqIt->second->setLabel( xNewSeq );
     985           0 :                 }
     986             :             }
     987             :         }
     988             :     }
     989             : 
     990             :     // there exist files with own data without a categories element but with row
     991             :     // descriptions.  The row descriptions were used as categories even without
     992             :     // the categories element
     993           0 :     if( ! bCategoriesApplied )
     994             :     {
     995             :         SchXMLTools::CreateCategories(
     996             :             xDataProv, xChartDoc, OUString(RTL_CONSTASCII_USTRINGPARAM("categories")),
     997           0 :             0 /* nCooSysIndex */, 0 /* nDimension */ );
     998             :     }
     999             : 
    1000             :     //i91578 display of hidden values (copy paste scenario; use hidden flag during migration to locale table upon paste )
    1001             :     //remove series that consist only of hidden columns
    1002           0 :     Reference< chart2::XInternalDataProvider > xInternalDataProvider( xDataProv, uno::UNO_QUERY );
    1003           0 :     if( xInternalDataProvider.is() && !rTable.aHiddenColumns.empty() )
    1004             :     {
    1005             :         try
    1006             :         {
    1007           0 :             Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xChartDoc->getFirstDiagram(), uno::UNO_QUERY_THROW );
    1008           0 :             Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems() );
    1009           0 :             for( sal_Int32 nC=0; nC<aCooSysSeq.getLength(); ++nC )
    1010             :             {
    1011           0 :                 Reference< chart2::XChartTypeContainer > xCooSysContainer( aCooSysSeq[nC], uno::UNO_QUERY_THROW );
    1012           0 :                 Sequence< Reference< chart2::XChartType > > aChartTypeSeq( xCooSysContainer->getChartTypes());
    1013           0 :                 for( sal_Int32 nT=0; nT<aChartTypeSeq.getLength(); ++nT )
    1014             :                 {
    1015           0 :                     Reference< chart2::XDataSeriesContainer > xSeriesContainer( aChartTypeSeq[nT], uno::UNO_QUERY );
    1016           0 :                     if(!xSeriesContainer.is())
    1017           0 :                         continue;
    1018           0 :                     Sequence< Reference< chart2::XDataSeries > > aSeriesSeq( xSeriesContainer->getDataSeries() );
    1019           0 :                     std::vector< Reference< chart2::XDataSeries > > aRemainingSeries;
    1020             : 
    1021           0 :                     for( sal_Int32 nS = 0; nS < aSeriesSeq.getLength(); nS++ )
    1022             :                     {
    1023           0 :                         Reference< chart2::data::XDataSource > xDataSource( aSeriesSeq[nS], uno::UNO_QUERY );
    1024           0 :                         if( xDataSource.is() )
    1025             :                         {
    1026           0 :                             bool bHasUnhiddenColumns = false;
    1027           0 :                             rtl::OUString aRange;
    1028           0 :                             uno::Sequence< Reference< chart2::data::XLabeledDataSequence > > aSequences( xDataSource->getDataSequences() );
    1029           0 :                             for( sal_Int32 nN=0; nN< aSequences.getLength(); ++nN )
    1030             :                             {
    1031           0 :                                 Reference< chart2::data::XLabeledDataSequence > xLabeledSequence( aSequences[nN] );
    1032           0 :                                 if(!xLabeledSequence.is())
    1033           0 :                                     continue;
    1034           0 :                                 Reference< chart2::data::XDataSequence > xValues( xLabeledSequence->getValues() );
    1035           0 :                                 if( xValues.is() )
    1036             :                                 {
    1037           0 :                                     aRange = xValues->getSourceRangeRepresentation();
    1038           0 :                                     if( ::std::find( rTable.aHiddenColumns.begin(), rTable.aHiddenColumns.end(), aRange.toInt32() ) == rTable.aHiddenColumns.end() )
    1039           0 :                                         bHasUnhiddenColumns = true;
    1040             :                                 }
    1041           0 :                                 if( !bHasUnhiddenColumns )
    1042             :                                 {
    1043           0 :                                     Reference< chart2::data::XDataSequence > xLabel( xLabeledSequence->getLabel() );
    1044           0 :                                     if( xLabel.is() )
    1045             :                                     {
    1046           0 :                                         aRange = xLabel->getSourceRangeRepresentation();
    1047           0 :                                         sal_Int32 nSearchIndex = 0;
    1048           0 :                                         OUString aSecondToken = aRange.getToken( 1, ' ', nSearchIndex );
    1049           0 :                                         if( ::std::find( rTable.aHiddenColumns.begin(), rTable.aHiddenColumns.end(), aSecondToken.toInt32() ) == rTable.aHiddenColumns.end() )
    1050           0 :                                             bHasUnhiddenColumns = true;
    1051           0 :                                     }
    1052             :                                 }
    1053           0 :                             }
    1054           0 :                             if( bHasUnhiddenColumns )
    1055           0 :                                 aRemainingSeries.push_back( aSeriesSeq[nS] );
    1056             :                         }
    1057           0 :                     }
    1058             : 
    1059           0 :                     if( static_cast<sal_Int32>(aRemainingSeries.size()) != aSeriesSeq.getLength() )
    1060             :                     {
    1061             :                         //remove the series that have only hidden data
    1062           0 :                         Sequence< Reference< chart2::XDataSeries > > aRemainingSeriesSeq( aRemainingSeries.size());
    1063           0 :                         ::std::copy( aRemainingSeries.begin(), aRemainingSeries.end(), aRemainingSeriesSeq.getArray());
    1064           0 :                         xSeriesContainer->setDataSeries( aRemainingSeriesSeq );
    1065             : 
    1066             :                         //remove unused sequences
    1067           0 :                         Reference< chart2::data::XDataSource > xDataSource( xChartDoc, uno::UNO_QUERY );
    1068           0 :                         if( xDataSource.is() )
    1069             :                         {
    1070             :                             //first detect which collumns are really used
    1071           0 :                             std::map< sal_Int32, bool > aUsageMap;
    1072           0 :                             rtl::OUString aRange;
    1073           0 :                             Sequence< Reference< chart2::data::XLabeledDataSequence > > aUsedSequences( xDataSource->getDataSequences() );
    1074           0 :                             for( sal_Int32 nN=0; nN< aUsedSequences.getLength(); ++nN )
    1075             :                             {
    1076           0 :                                 Reference< chart2::data::XLabeledDataSequence > xLabeledSequence( aUsedSequences[nN] );
    1077           0 :                                 if(!xLabeledSequence.is())
    1078           0 :                                     continue;
    1079           0 :                                 Reference< chart2::data::XDataSequence > xValues( xLabeledSequence->getValues() );
    1080           0 :                                 if( xValues.is() )
    1081             :                                 {
    1082           0 :                                     aRange = xValues->getSourceRangeRepresentation();
    1083           0 :                                     sal_Int32 nIndex = aRange.toInt32();
    1084           0 :                                     if( nIndex!=0 || !aRange.equals(lcl_aCategoriesRange) )
    1085           0 :                                         aUsageMap[nIndex] = true;
    1086             :                                 }
    1087           0 :                                 Reference< chart2::data::XDataSequence > xLabel( xLabeledSequence->getLabel() );
    1088           0 :                                 if( xLabel.is() )
    1089             :                                 {
    1090           0 :                                     aRange = xLabel->getSourceRangeRepresentation();
    1091           0 :                                     sal_Int32 nSearchIndex = 0;
    1092           0 :                                     OUString aSecondToken = aRange.getToken( 1, ' ', nSearchIndex );
    1093           0 :                                     if( !aSecondToken.isEmpty() )
    1094           0 :                                         aUsageMap[aSecondToken.toInt32()] = true;
    1095             :                                 }
    1096           0 :                             }
    1097             : 
    1098           0 :                             ::std::vector< sal_Int32 > aSequenceIndexesToDelete;
    1099           0 :                             for( ::std::vector< sal_Int32 >::const_iterator aIt(
    1100           0 :                                      rTable.aHiddenColumns.begin()); aIt != rTable.aHiddenColumns.end(); ++aIt )
    1101             :                             {
    1102           0 :                                 sal_Int32 nSequenceIndex = *aIt;
    1103           0 :                                 if( aUsageMap.find(nSequenceIndex) != aUsageMap.end() )
    1104           0 :                                     continue;
    1105           0 :                                 aSequenceIndexesToDelete.push_back(nSequenceIndex);
    1106             :                             }
    1107             : 
    1108             :                             // delete unnecessary sequences of the internal data
    1109             :                             // iterate using greatest index first, so that deletion does not
    1110             :                             // shift other sequences that will be deleted later
    1111           0 :                             ::std::sort( aSequenceIndexesToDelete.begin(), aSequenceIndexesToDelete.end());
    1112           0 :                             for( ::std::vector< sal_Int32 >::reverse_iterator aIt(
    1113           0 :                                      aSequenceIndexesToDelete.rbegin()); aIt != aSequenceIndexesToDelete.rend(); ++aIt )
    1114             :                             {
    1115           0 :                                 if( *aIt != -1 )
    1116           0 :                                     xInternalDataProvider->deleteSequence( *aIt );
    1117           0 :                             }
    1118           0 :                         }
    1119             :                     }
    1120           0 :                 }
    1121           0 :             }
    1122             :         }
    1123           0 :         catch( const uno::Exception & )
    1124             :         {
    1125             :         }
    1126           0 :     }
    1127             : }
    1128             : 
    1129             : //---------------------------------------------------------------------------------------------------
    1130             : 
    1131           0 : SchXMLRangeSomewhereContext::SchXMLRangeSomewhereContext( SvXMLImport& rImport,
    1132             :                                                 sal_uInt16 nPrefix,
    1133             :                                                 const OUString& rLocalName,
    1134             :                                                 OUString& rRangeString ) :
    1135             :         SvXMLImportContext( rImport, nPrefix, rLocalName ),
    1136           0 :         mrRangeString( rRangeString )
    1137             : {
    1138           0 : }
    1139             : 
    1140           0 : SchXMLRangeSomewhereContext::~SchXMLRangeSomewhereContext()
    1141             : {
    1142           0 : }
    1143             : 
    1144           0 : SvXMLImportContext* SchXMLRangeSomewhereContext::CreateChildContext(
    1145             :     sal_uInt16 nPrefix,
    1146             :     const OUString& rLocalName,
    1147             :     const uno::Reference< xml::sax::XAttributeList >& )
    1148             : {
    1149           0 :     if( XML_NAMESPACE_SVG == nPrefix && IsXMLToken( rLocalName, XML_DESC ) )
    1150             :     {
    1151             :         return new XMLStringBufferImportContext(
    1152           0 :             GetImport(), nPrefix, rLocalName, maRangeStringBuffer );
    1153             :     }
    1154           0 :     return new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
    1155             : }
    1156             : 
    1157           0 : void SchXMLRangeSomewhereContext::EndElement()
    1158             : {
    1159           0 :     mrRangeString = maRangeStringBuffer.makeStringAndClear();
    1160           0 : }
    1161             : 
    1162             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10