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