xref: /AOO41X/main/xmloff/source/chart/SchXMLTableContext.cxx (revision 56df9a41f5bf3665e6e9154f65f8aff3e6417c65)
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