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