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