xref: /trunk/main/xmloff/source/chart/SchXMLImport.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_xmloff.hxx"
30 
31 #include "SchXMLImport.hxx"
32 #include "SchXMLChartContext.hxx"
33 #include "contexts.hxx"
34 #include "XMLChartPropertySetMapper.hxx"
35 #include "SchXMLTools.hxx"
36 
37 #include <tools/debug.hxx>
38 #include <rtl/ustrbuf.hxx>
39 // header for class ByteString
40 #include <tools/string.hxx>
41 #include <comphelper/processfactory.hxx>
42 #include "xmloff/xmlnmspe.hxx"
43 #include <xmloff/xmltoken.hxx>
44 #include <xmloff/xmluconv.hxx>
45 #include <xmloff/nmspmap.hxx>
46 #include <xmloff/xmlictxt.hxx>
47 #include <xmloff/xmlstyle.hxx>
48 #include <com/sun/star/task/XStatusIndicatorSupplier.hpp>
49 #include <com/sun/star/chart/XChartDocument.hpp>
50 #include <com/sun/star/chart/ChartDataRowSource.hpp>
51 #include <com/sun/star/container/XChild.hpp>
52 #include <com/sun/star/uno/XComponentContext.hpp>
53 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
54 #include <com/sun/star/chart2/data/XDataProvider.hpp>
55 #include <com/sun/star/chart2/XChartDocument.hpp>
56 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
57 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
58 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
59 
60 #include <com/sun/star/document/XDocumentProperties.hpp>
61 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
62 
63 #include <typeinfo>
64 
65 using namespace com::sun::star;
66 using namespace ::xmloff::token;
67 
68 using ::rtl::OUString;
69 using ::rtl::OUStringBuffer;
70 using ::rtl::OUStringToOString;
71 using ::com::sun::star::uno::Reference;
72 using ::com::sun::star::uno::Sequence;
73 
74 namespace
75 {
76 Reference< uno::XComponentContext > lcl_getComponentContext()
77 {
78     Reference< uno::XComponentContext > xContext;
79     try
80     {
81         Reference< beans::XPropertySet > xFactProp( comphelper::getProcessServiceFactory(), uno::UNO_QUERY );
82         if( xFactProp.is())
83             xFactProp->getPropertyValue(OUString::createFromAscii("DefaultContext")) >>= xContext;
84     }
85     catch( uno::Exception& )
86     {}
87 
88     return xContext;
89 }
90 
91 class lcl_MatchesChartType : public ::std::unary_function< Reference< chart2::XChartType >, bool >
92 {
93 public:
94     explicit lcl_MatchesChartType( const OUString & aChartTypeName ) :
95             m_aChartTypeName( aChartTypeName )
96     {}
97 
98     bool operator () ( const Reference< chart2::XChartType > & xChartType ) const
99     {
100         return (xChartType.is() &&
101                 xChartType->getChartType().equals( m_aChartTypeName ));
102     }
103 
104 private:
105     OUString m_aChartTypeName;
106 };
107 } // anonymous namespace
108 
109 /* ----------------------------------------
110    TokenMaps for distinguishing different
111    tokens in different contexts
112    ----------------------------------------*/
113 
114 // ----------------------------------------
115 // element maps
116 // ----------------------------------------
117 
118 
119 
120 
121 
122 
123 
124 // ----------------------------------------
125 // attribute maps
126 // ----------------------------------------
127 
128 
129 
130 
131 
132 
133 
134 
135 
136 // ========================================
137 
138 SchXMLImportHelper::SchXMLImportHelper() :
139         mpAutoStyles( 0 ),
140 
141         mpChartDocElemTokenMap( 0 ),
142         mpTableElemTokenMap( 0 ),
143         mpChartElemTokenMap( 0 ),
144         mpPlotAreaElemTokenMap( 0 ),
145         mpSeriesElemTokenMap( 0 ),
146 
147         mpChartAttrTokenMap( 0 ),
148         mpPlotAreaAttrTokenMap( 0 ),
149         mpAutoStyleAttrTokenMap( 0 ),
150         mpCellAttrTokenMap( 0 ),
151         mpSeriesAttrTokenMap( 0 ),
152         mpRegEquationAttrTokenMap( 0 )
153 {
154 }
155 
156 SchXMLImportHelper::~SchXMLImportHelper()
157 {
158         // delete token maps
159     if( mpChartDocElemTokenMap )
160         delete mpChartDocElemTokenMap;
161     if( mpTableElemTokenMap )
162         delete mpTableElemTokenMap;
163     if( mpChartElemTokenMap )
164         delete mpChartElemTokenMap;
165     if( mpPlotAreaElemTokenMap )
166         delete mpPlotAreaElemTokenMap;
167     if( mpSeriesElemTokenMap )
168         delete mpSeriesElemTokenMap;
169 
170     if( mpChartAttrTokenMap )
171         delete mpChartAttrTokenMap;
172     if( mpPlotAreaAttrTokenMap )
173         delete mpPlotAreaAttrTokenMap;
174     if( mpAutoStyleAttrTokenMap )
175         delete mpAutoStyleAttrTokenMap;
176     if( mpCellAttrTokenMap )
177         delete mpCellAttrTokenMap;
178     if( mpSeriesAttrTokenMap )
179         delete mpSeriesAttrTokenMap;
180 }
181 
182 SvXMLImportContext* SchXMLImportHelper::CreateChartContext(
183     SvXMLImport& rImport,
184     sal_uInt16 nPrefix, const OUString& rLocalName,
185     const Reference< frame::XModel > xChartModel,
186     const Reference< xml::sax::XAttributeList >& )
187 {
188     SvXMLImportContext* pContext = 0;
189 
190     Reference< chart::XChartDocument > xDoc( xChartModel, uno::UNO_QUERY );
191     if( xDoc.is())
192     {
193         mxChartDoc = xDoc;
194         pContext = new SchXMLChartContext( *this, rImport, rLocalName );
195     }
196     else
197     {
198         DBG_ERROR( "No valid XChartDocument given as XModel" );
199         pContext = new SvXMLImportContext( rImport, nPrefix, rLocalName );
200     }
201 
202     return pContext;
203 }
204 
205 /* ----------------------------------------
206    get various token maps
207    ----------------------------------------*/
208 
209 const SvXMLTokenMap& SchXMLImportHelper::GetDocElemTokenMap()
210 {
211     if( ! mpChartDocElemTokenMap )
212     {
213         static __FAR_DATA SvXMLTokenMapEntry aDocElemTokenMap[] =
214         {
215             { XML_NAMESPACE_OFFICE, XML_AUTOMATIC_STYLES,   XML_TOK_DOC_AUTOSTYLES  },
216             { XML_NAMESPACE_OFFICE, XML_STYLES,             XML_TOK_DOC_STYLES  },
217             { XML_NAMESPACE_OFFICE, XML_META,               XML_TOK_DOC_META    },
218             { XML_NAMESPACE_OFFICE, XML_BODY,               XML_TOK_DOC_BODY    },
219             XML_TOKEN_MAP_END
220         };
221 
222         mpChartDocElemTokenMap = new SvXMLTokenMap( aDocElemTokenMap );
223     } // if( ! mpChartDocElemTokenMap )
224 
225     return *mpChartDocElemTokenMap;
226 }
227 
228 const SvXMLTokenMap& SchXMLImportHelper::GetTableElemTokenMap()
229 {
230     if( ! mpTableElemTokenMap )
231     {
232         static __FAR_DATA SvXMLTokenMapEntry aTableElemTokenMap[] =
233     {
234         { XML_NAMESPACE_TABLE,  XML_TABLE_HEADER_COLUMNS,   XML_TOK_TABLE_HEADER_COLS   },
235         { XML_NAMESPACE_TABLE,  XML_TABLE_COLUMNS,          XML_TOK_TABLE_COLUMNS       },
236         { XML_NAMESPACE_TABLE,  XML_TABLE_COLUMN,           XML_TOK_TABLE_COLUMN        },
237         { XML_NAMESPACE_TABLE,  XML_TABLE_HEADER_ROWS,      XML_TOK_TABLE_HEADER_ROWS   },
238         { XML_NAMESPACE_TABLE,  XML_TABLE_ROWS,             XML_TOK_TABLE_ROWS          },
239         { XML_NAMESPACE_TABLE,  XML_TABLE_ROW,              XML_TOK_TABLE_ROW           },
240         XML_TOKEN_MAP_END
241     };
242 
243         mpTableElemTokenMap = new SvXMLTokenMap( aTableElemTokenMap );
244     } // if( ! mpTableElemTokenMap )
245 
246     return *mpTableElemTokenMap;
247 }
248 
249 const SvXMLTokenMap& SchXMLImportHelper::GetChartElemTokenMap()
250 {
251     if( ! mpChartElemTokenMap )
252     {
253         static __FAR_DATA SvXMLTokenMapEntry aChartElemTokenMap[] =
254         {
255             { XML_NAMESPACE_CHART,  XML_PLOT_AREA,              XML_TOK_CHART_PLOT_AREA     },
256             { XML_NAMESPACE_CHART,  XML_TITLE,                  XML_TOK_CHART_TITLE         },
257             { XML_NAMESPACE_CHART,  XML_SUBTITLE,               XML_TOK_CHART_SUBTITLE      },
258             { XML_NAMESPACE_CHART,  XML_LEGEND,             XML_TOK_CHART_LEGEND        },
259             { XML_NAMESPACE_TABLE,  XML_TABLE,                  XML_TOK_CHART_TABLE         },
260             XML_TOKEN_MAP_END
261         };
262 
263         mpChartElemTokenMap = new SvXMLTokenMap( aChartElemTokenMap );
264     } // if( ! mpChartElemTokenMap )
265 
266     return *mpChartElemTokenMap;
267 }
268 
269 const SvXMLTokenMap& SchXMLImportHelper::GetPlotAreaElemTokenMap()
270 {
271     if( ! mpPlotAreaElemTokenMap )
272     {
273         static __FAR_DATA SvXMLTokenMapEntry aPlotAreaElemTokenMap[] =
274 {
275     { XML_NAMESPACE_CHART_EXT,  XML_COORDINATE_REGION,      XML_TOK_PA_COORDINATE_REGION_EXT },
276     { XML_NAMESPACE_CHART,  XML_COORDINATE_REGION,      XML_TOK_PA_COORDINATE_REGION },
277     { XML_NAMESPACE_CHART,  XML_AXIS,                   XML_TOK_PA_AXIS             },
278     { XML_NAMESPACE_CHART,  XML_SERIES,                 XML_TOK_PA_SERIES           },
279     { XML_NAMESPACE_CHART,  XML_WALL,                   XML_TOK_PA_WALL             },
280     { XML_NAMESPACE_CHART,  XML_FLOOR,                  XML_TOK_PA_FLOOR            },
281     { XML_NAMESPACE_DR3D,   XML_LIGHT,                  XML_TOK_PA_LIGHT_SOURCE     },
282     { XML_NAMESPACE_CHART,  XML_STOCK_GAIN_MARKER,      XML_TOK_PA_STOCK_GAIN       },
283     { XML_NAMESPACE_CHART,  XML_STOCK_LOSS_MARKER,      XML_TOK_PA_STOCK_LOSS       },
284     { XML_NAMESPACE_CHART,  XML_STOCK_RANGE_LINE,       XML_TOK_PA_STOCK_RANGE      },
285     XML_TOKEN_MAP_END
286 };
287 
288         mpPlotAreaElemTokenMap = new SvXMLTokenMap( aPlotAreaElemTokenMap );
289     } // if( ! mpPlotAreaElemTokenMap )
290 
291     return *mpPlotAreaElemTokenMap;
292 }
293 
294 const SvXMLTokenMap& SchXMLImportHelper::GetSeriesElemTokenMap()
295 {
296     if( ! mpSeriesElemTokenMap )
297     {
298         static __FAR_DATA SvXMLTokenMapEntry aSeriesElemTokenMap[] =
299 {
300     { XML_NAMESPACE_CHART,  XML_DATA_POINT,       XML_TOK_SERIES_DATA_POINT       },
301     { XML_NAMESPACE_CHART,  XML_DOMAIN,           XML_TOK_SERIES_DOMAIN           },
302     { XML_NAMESPACE_CHART,  XML_MEAN_VALUE,       XML_TOK_SERIES_MEAN_VALUE_LINE  },
303     { XML_NAMESPACE_CHART,  XML_REGRESSION_CURVE, XML_TOK_SERIES_REGRESSION_CURVE },
304     { XML_NAMESPACE_CHART,  XML_ERROR_INDICATOR,  XML_TOK_SERIES_ERROR_INDICATOR  },
305     XML_TOKEN_MAP_END
306 };
307 
308         mpSeriesElemTokenMap = new SvXMLTokenMap( aSeriesElemTokenMap );
309     } // if( ! mpSeriesElemTokenMap )
310 
311     return *mpSeriesElemTokenMap;
312 }
313 
314 // ----------------------------------------
315 
316 const SvXMLTokenMap& SchXMLImportHelper::GetChartAttrTokenMap()
317 {
318     if( ! mpChartAttrTokenMap )
319     {
320         static __FAR_DATA SvXMLTokenMapEntry aChartAttrTokenMap[] =
321 {
322     { XML_NAMESPACE_XLINK,  XML_HREF,                   XML_TOK_CHART_HREF          },
323     { XML_NAMESPACE_CHART,  XML_CLASS,                  XML_TOK_CHART_CLASS         },
324     { XML_NAMESPACE_SVG,    XML_WIDTH,                  XML_TOK_CHART_WIDTH         },
325     { XML_NAMESPACE_SVG,    XML_HEIGHT,                 XML_TOK_CHART_HEIGHT        },
326     { XML_NAMESPACE_CHART,  XML_STYLE_NAME,             XML_TOK_CHART_STYLE_NAME    },
327     { XML_NAMESPACE_CHART,  XML_COLUMN_MAPPING,         XML_TOK_CHART_COL_MAPPING   },
328     { XML_NAMESPACE_CHART,  XML_ROW_MAPPING,            XML_TOK_CHART_ROW_MAPPING   },
329     XML_TOKEN_MAP_END
330 };
331 
332         mpChartAttrTokenMap = new SvXMLTokenMap( aChartAttrTokenMap );
333     } // if( ! mpChartAttrTokenMap )
334 
335     return *mpChartAttrTokenMap;
336 }
337 
338 const SvXMLTokenMap& SchXMLImportHelper::GetPlotAreaAttrTokenMap()
339 {
340     if( ! mpPlotAreaAttrTokenMap )
341     {
342         static __FAR_DATA SvXMLTokenMapEntry aPlotAreaAttrTokenMap[] =
343 {
344     { XML_NAMESPACE_SVG,    XML_X,                      XML_TOK_PA_X                 },
345     { XML_NAMESPACE_SVG,    XML_Y,                      XML_TOK_PA_Y                 },
346     { XML_NAMESPACE_SVG,    XML_WIDTH,                  XML_TOK_PA_WIDTH             },
347     { XML_NAMESPACE_SVG,    XML_HEIGHT,                 XML_TOK_PA_HEIGHT            },
348     { XML_NAMESPACE_CHART,  XML_STYLE_NAME,             XML_TOK_PA_STYLE_NAME        },
349     { XML_NAMESPACE_TABLE,  XML_CELL_RANGE_ADDRESS,     XML_TOK_PA_CHART_ADDRESS     },
350     { XML_NAMESPACE_CHART,  XML_DATA_SOURCE_HAS_LABELS, XML_TOK_PA_DS_HAS_LABELS     },
351     { XML_NAMESPACE_DR3D,   XML_TRANSFORM,              XML_TOK_PA_TRANSFORM         },
352     { XML_NAMESPACE_DR3D,   XML_VRP,                    XML_TOK_PA_VRP               },
353     { XML_NAMESPACE_DR3D,   XML_VPN,                    XML_TOK_PA_VPN               },
354     { XML_NAMESPACE_DR3D,   XML_VUP,                    XML_TOK_PA_VUP               },
355     { XML_NAMESPACE_DR3D,   XML_PROJECTION,             XML_TOK_PA_PROJECTION        },
356     { XML_NAMESPACE_DR3D,   XML_DISTANCE,               XML_TOK_PA_DISTANCE          },
357     { XML_NAMESPACE_DR3D,   XML_FOCAL_LENGTH,           XML_TOK_PA_FOCAL_LENGTH      },
358     { XML_NAMESPACE_DR3D,   XML_SHADOW_SLANT,           XML_TOK_PA_SHADOW_SLANT      },
359     { XML_NAMESPACE_DR3D,   XML_SHADE_MODE,             XML_TOK_PA_SHADE_MODE        },
360     { XML_NAMESPACE_DR3D,   XML_AMBIENT_COLOR,          XML_TOK_PA_AMBIENT_COLOR     },
361     { XML_NAMESPACE_DR3D,   XML_LIGHTING_MODE,          XML_TOK_PA_LIGHTING_MODE     },
362     XML_TOKEN_MAP_END
363 };
364 
365         mpPlotAreaAttrTokenMap = new SvXMLTokenMap( aPlotAreaAttrTokenMap );
366     } // if( ! mpPlotAreaAttrTokenMap )
367 
368     return *mpPlotAreaAttrTokenMap;
369 }
370 
371 const SvXMLTokenMap& SchXMLImportHelper::GetAutoStyleAttrTokenMap()
372 {
373     if( ! mpAutoStyleAttrTokenMap )
374     {
375         static __FAR_DATA SvXMLTokenMapEntry aAutoStyleAttrTokenMap[] =
376 {
377     { XML_NAMESPACE_STYLE,  XML_FAMILY,                 XML_TOK_AS_FAMILY           },
378     { XML_NAMESPACE_STYLE,  XML_NAME,                   XML_TOK_AS_NAME             },
379     XML_TOKEN_MAP_END
380 };
381 
382         mpAutoStyleAttrTokenMap = new SvXMLTokenMap( aAutoStyleAttrTokenMap );
383     } // if( ! mpAutoStyleAttrTokenMap )
384 
385     return *mpAutoStyleAttrTokenMap;
386 }
387 
388 const SvXMLTokenMap& SchXMLImportHelper::GetCellAttrTokenMap()
389 {
390     if( ! mpCellAttrTokenMap )
391     {
392         static __FAR_DATA SvXMLTokenMapEntry aCellAttrTokenMap[] =
393 {
394     { XML_NAMESPACE_OFFICE, XML_VALUE_TYPE,             XML_TOK_CELL_VAL_TYPE       },
395     { XML_NAMESPACE_OFFICE, XML_VALUE,                  XML_TOK_CELL_VALUE          },
396     XML_TOKEN_MAP_END
397 };
398 
399         mpCellAttrTokenMap = new SvXMLTokenMap( aCellAttrTokenMap );
400     } // if( ! mpCellAttrTokenMap )
401 
402     return *mpCellAttrTokenMap;
403 }
404 
405 const SvXMLTokenMap& SchXMLImportHelper::GetSeriesAttrTokenMap()
406 {
407     if( ! mpSeriesAttrTokenMap )
408     {
409         static __FAR_DATA SvXMLTokenMapEntry aSeriesAttrTokenMap[] =
410 {
411     { XML_NAMESPACE_CHART,  XML_VALUES_CELL_RANGE_ADDRESS,  XML_TOK_SERIES_CELL_RANGE    },
412     { XML_NAMESPACE_CHART,  XML_LABEL_CELL_ADDRESS,         XML_TOK_SERIES_LABEL_ADDRESS },
413     { XML_NAMESPACE_CHART,  XML_ATTACHED_AXIS,              XML_TOK_SERIES_ATTACHED_AXIS },
414     { XML_NAMESPACE_CHART,  XML_STYLE_NAME,                 XML_TOK_SERIES_STYLE_NAME    },
415     { XML_NAMESPACE_CHART,  XML_CLASS,                      XML_TOK_SERIES_CHART_CLASS   },
416     XML_TOKEN_MAP_END
417 };
418 
419         mpSeriesAttrTokenMap = new SvXMLTokenMap( aSeriesAttrTokenMap );
420     } // if( ! mpSeriesAttrTokenMap )
421 
422     return *mpSeriesAttrTokenMap;
423 }
424 
425 const SvXMLTokenMap& SchXMLImportHelper::GetRegEquationAttrTokenMap()
426 {
427     if( ! mpRegEquationAttrTokenMap )
428     {
429         static __FAR_DATA SvXMLTokenMapEntry aRegressionEquationAttrTokenMap[] =
430 {
431     { XML_NAMESPACE_CHART,  XML_STYLE_NAME,             XML_TOK_REGEQ_STYLE_NAME         },
432     { XML_NAMESPACE_CHART,  XML_DISPLAY_EQUATION,       XML_TOK_REGEQ_DISPLAY_EQUATION   },
433     { XML_NAMESPACE_CHART,  XML_DISPLAY_R_SQUARE,       XML_TOK_REGEQ_DISPLAY_R_SQUARE   },
434     { XML_NAMESPACE_SVG,    XML_X,                      XML_TOK_REGEQ_POS_X              },
435     { XML_NAMESPACE_SVG,    XML_Y,                      XML_TOK_REGEQ_POS_Y              },
436     XML_TOKEN_MAP_END
437 };
438 
439         mpRegEquationAttrTokenMap = new SvXMLTokenMap( aRegressionEquationAttrTokenMap );
440     } // if( ! mpRegEquationAttrTokenMap )
441 
442     return *mpRegEquationAttrTokenMap;
443 }
444 
445 // ----------------------------------------
446 
447 //static
448 void SchXMLImportHelper::DeleteDataSeries(
449                     const Reference< chart2::XDataSeries > & xSeries,
450                     const Reference< chart2::XChartDocument > & xDoc )
451 {
452     if( xDoc.is() )
453     try
454     {
455         Reference< chart2::XCoordinateSystemContainer > xCooSysCnt(
456             xDoc->getFirstDiagram(), uno::UNO_QUERY_THROW );
457         Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq(
458             xCooSysCnt->getCoordinateSystems());
459 
460         sal_Int32 nCooSysIndex = 0;
461         for( nCooSysIndex=0; nCooSysIndex<aCooSysSeq.getLength(); nCooSysIndex++ )
462         {
463             Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[ nCooSysIndex ], uno::UNO_QUERY_THROW );
464             Sequence< Reference< chart2::XChartType > > aChartTypes( xCTCnt->getChartTypes());
465 
466             sal_Int32 nChartTypeIndex = 0;
467             for( nChartTypeIndex=0; nChartTypeIndex<aChartTypes.getLength(); nChartTypeIndex++ )
468             {
469                 Reference< chart2::XDataSeriesContainer > xSeriesCnt( aChartTypes[nChartTypeIndex], uno::UNO_QUERY_THROW );
470                 Sequence< Reference< chart2::XDataSeries > > aSeriesSeq( xSeriesCnt->getDataSeries());
471 
472                 sal_Int32 nSeriesIndex = 0;
473                 for( nSeriesIndex=0; nSeriesIndex<aSeriesSeq.getLength(); nSeriesIndex++ )
474                 {
475                     if( xSeries==aSeriesSeq[nSeriesIndex] )
476                     {
477                         xSeriesCnt->removeDataSeries(xSeries);
478                         return;
479                     }
480                 }
481             }
482         }
483     }
484     catch( uno::Exception & ex )
485     {
486         (void)ex; // avoid warning for pro build
487         OSL_ENSURE( false, OUStringToOString(
488                         OUString( RTL_CONSTASCII_USTRINGPARAM( "Exception caught. Type: " )) +
489                         OUString::createFromAscii( typeid( ex ).name()) +
490                         OUString( RTL_CONSTASCII_USTRINGPARAM( ", Message: " )) +
491                         ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
492     }
493 }
494 
495 // static
496 Reference< chart2::XDataSeries > SchXMLImportHelper::GetNewDataSeries(
497     const Reference< chart2::XChartDocument > & xDoc,
498     sal_Int32 nCoordinateSystemIndex,
499     const OUString & rChartTypeName,
500     bool bPushLastChartType /* = false */ )
501 {
502     Reference< chart2::XDataSeries > xResult;
503     if(!xDoc.is())
504         return xResult;
505 
506     try
507     {
508         Reference< chart2::XCoordinateSystemContainer > xCooSysCnt(
509             xDoc->getFirstDiagram(), uno::UNO_QUERY_THROW );
510         Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq(
511             xCooSysCnt->getCoordinateSystems());
512         Reference< uno::XComponentContext > xContext( lcl_getComponentContext());
513 
514         if( nCoordinateSystemIndex < aCooSysSeq.getLength())
515         {
516             Reference< chart2::XChartType > xCurrentType;
517             {
518                 Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[ nCoordinateSystemIndex ], uno::UNO_QUERY_THROW );
519                 Sequence< Reference< chart2::XChartType > > aChartTypes( xCTCnt->getChartTypes());
520                 // find matching chart type group
521                 const Reference< chart2::XChartType > * pBegin = aChartTypes.getConstArray();
522                 const Reference< chart2::XChartType > * pEnd = pBegin + aChartTypes.getLength();
523                 const Reference< chart2::XChartType > * pIt =
524                     ::std::find_if( pBegin, pEnd, lcl_MatchesChartType( rChartTypeName ));
525                 if( pIt != pEnd )
526                     xCurrentType.set( *pIt );
527                 // if chart type is set at series and differs from current one,
528                 // create a new chart type
529                 if( !xCurrentType.is())
530                 {
531                     xCurrentType.set(
532                         xContext->getServiceManager()->createInstanceWithContext( rChartTypeName, xContext ),
533                         uno::UNO_QUERY );
534                     if( xCurrentType.is())
535                     {
536                         if( bPushLastChartType && aChartTypes.getLength())
537                         {
538                             sal_Int32 nIndex( aChartTypes.getLength() - 1 );
539                             aChartTypes.realloc( aChartTypes.getLength() + 1 );
540                             aChartTypes[ nIndex + 1 ] = aChartTypes[ nIndex ];
541                             aChartTypes[ nIndex ] = xCurrentType;
542                             xCTCnt->setChartTypes( aChartTypes );
543                         }
544                         else
545                             xCTCnt->addChartType( xCurrentType );
546                     }
547                 }
548             }
549 
550             if( xCurrentType.is())
551             {
552                 Reference< chart2::XDataSeriesContainer > xSeriesCnt( xCurrentType, uno::UNO_QUERY_THROW );
553                 Sequence< Reference< chart2::XDataSeries > > aSeriesSeq( xSeriesCnt->getDataSeries());
554 
555                 if( xContext.is() )
556                 {
557                     xResult.set(
558                         xContext->getServiceManager()->createInstanceWithContext(
559                             OUString::createFromAscii("com.sun.star.chart2.DataSeries"),
560                             xContext ), uno::UNO_QUERY_THROW );
561                 }
562                 if( xResult.is() )
563                     xSeriesCnt->addDataSeries( xResult );
564             }
565         }
566     }
567     catch( uno::Exception & ex )
568     {
569         (void)ex; // avoid warning for pro build
570         OSL_ENSURE( false, OUStringToOString(
571                         OUString( RTL_CONSTASCII_USTRINGPARAM( "Exception caught. Type: " )) +
572                         OUString::createFromAscii( typeid( ex ).name()) +
573                         OUString( RTL_CONSTASCII_USTRINGPARAM( ", Message: " )) +
574                         ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
575     }
576     return xResult;
577 }
578 
579 // static
580 Reference< chart2::data::XLabeledDataSequence > SchXMLImportHelper::GetNewLabeledDataSequence()
581 {
582     // @todo: remove this asap
583     OSL_ENSURE( false, "Do not call this method" );
584     Reference< chart2::data::XLabeledDataSequence >  xResult;
585     // DO NOT USED -- DEPRECATED. Use SchXMLTools::GetNewLabeledDataSequence() instead
586     return xResult;
587 }
588 
589 // ========================================
590 
591 // #110680#
592 SchXMLImport::SchXMLImport(
593     const Reference< lang::XMultiServiceFactory >& xServiceFactory,
594     sal_uInt16 nImportFlags ) :
595         SvXMLImport( xServiceFactory, nImportFlags )
596 {
597     GetNamespaceMap().Add( GetXMLToken(XML_NP_XLINK), GetXMLToken(XML_N_XLINK), XML_NAMESPACE_XLINK );
598     GetNamespaceMap().Add( GetXMLToken(XML_NP_CHART_EXT), GetXMLToken(XML_N_CHART_EXT), XML_NAMESPACE_CHART_EXT);
599 
600     mbIsGraphicLoadOnDemandSupported = false;
601 }
602 
603 // #110680#
604 SchXMLImport::SchXMLImport(
605     const Reference< lang::XMultiServiceFactory >& xServiceFactory,
606     Reference< frame::XModel > xModel,
607     Reference< document::XGraphicObjectResolver >& rGrfContainer,
608     sal_Bool /*bLoadDoc*/, sal_Bool bShowProgress )
609 :   SvXMLImport( xServiceFactory, xModel, rGrfContainer )
610 {
611     GetNamespaceMap().Add( GetXMLToken(XML_NP_XLINK), GetXMLToken(XML_N_XLINK), XML_NAMESPACE_XLINK );
612     GetNamespaceMap().Add( GetXMLToken(XML_NP_CHART_EXT), GetXMLToken(XML_N_CHART_EXT), XML_NAMESPACE_CHART_EXT);
613 
614     // get status indicator (if requested)
615     if( bShowProgress )
616     {
617         Reference< frame::XController > xController( xModel->getCurrentController());
618         if( xController.is())
619         {
620             Reference< frame::XFrame > xFrame( xController->getFrame());
621             if( xFrame.is())
622             {
623                 Reference< task::XStatusIndicatorSupplier > xFactory( xFrame, uno::UNO_QUERY );
624                 if( xFactory.is())
625                 {
626                     mxStatusIndicator = xFactory->getStatusIndicator();
627                 }
628             }
629         }
630     }
631 
632     // add progress view
633     if( mxStatusIndicator.is())
634     {
635         const OUString aText( RTL_CONSTASCII_USTRINGPARAM( "XML Import" ));
636         mxStatusIndicator->start( aText, 100 );     // use percentage as values
637     }
638 }
639 
640 SchXMLImport::~SchXMLImport() throw ()
641 {
642     // stop progress view
643     if( mxStatusIndicator.is())
644     {
645         mxStatusIndicator->end();
646         mxStatusIndicator->reset();
647     }
648 
649     uno::Reference< chart2::XChartDocument > xChartDoc( GetModel(), uno::UNO_QUERY );
650     if( xChartDoc.is() && xChartDoc->hasControllersLocked() )
651         xChartDoc->unlockControllers();
652 }
653 
654 // create the main context (subcontexts are created
655 // by the one created here)
656 SvXMLImportContext *SchXMLImport::CreateContext( sal_uInt16 nPrefix, const OUString& rLocalName,
657     const Reference< xml::sax::XAttributeList >& xAttrList )
658 {
659     SvXMLImportContext* pContext = 0;
660 
661     // accept <office:document>
662     if( XML_NAMESPACE_OFFICE == nPrefix &&
663         ( IsXMLToken( rLocalName, XML_DOCUMENT_STYLES) ||
664           IsXMLToken( rLocalName, XML_DOCUMENT_CONTENT) ))
665     {
666         pContext = new SchXMLDocContext( maImportHelper, *this, nPrefix, rLocalName );
667     } else if ( (XML_NAMESPACE_OFFICE == nPrefix) &&
668                 ( IsXMLToken(rLocalName, XML_DOCUMENT) ||
669                   (IsXMLToken(rLocalName, XML_DOCUMENT_META)
670                    && (getImportFlags() & IMPORT_META) )) )
671     {
672         uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
673             GetModel(), uno::UNO_QUERY);
674         // mst@: right now, this seems to be not supported, so it is untested
675         if (xDPS.is()) {
676             uno::Reference<xml::sax::XDocumentHandler> xDocBuilder(
677                 mxServiceFactory->createInstance(
678                     ::rtl::OUString::createFromAscii(
679                         "com.sun.star.xml.dom.SAXDocumentBuilder")),
680                     uno::UNO_QUERY_THROW);
681             pContext = (IsXMLToken(rLocalName, XML_DOCUMENT_META))
682                 ? new SvXMLMetaDocumentContext(*this,
683                             XML_NAMESPACE_OFFICE, rLocalName,
684                             xDPS->getDocumentProperties(), xDocBuilder)
685                 // flat OpenDocument file format
686                 : new SchXMLFlatDocContext_Impl(
687                             maImportHelper, *this, nPrefix, rLocalName,
688                             xDPS->getDocumentProperties(), xDocBuilder);
689         } else {
690             pContext = (IsXMLToken(rLocalName, XML_DOCUMENT_META))
691                 ? SvXMLImport::CreateContext( nPrefix, rLocalName, xAttrList )
692                 : new SchXMLDocContext( maImportHelper, *this,
693                                         nPrefix, rLocalName );
694         }
695     } else {
696         pContext = SvXMLImport::CreateContext( nPrefix, rLocalName, xAttrList );
697     }
698 
699     return pContext;
700 }
701 
702 SvXMLImportContext* SchXMLImport::CreateStylesContext(
703     const OUString& rLocalName,
704     const Reference<xml::sax::XAttributeList>& xAttrList )
705 {
706     //#i103287# make sure that the version information is set before importing all the properties (especially stroke-opacity!)
707     SchXMLTools::setBuildIDAtImportInfo( GetModel(), getImportInfo() );
708 
709     SvXMLStylesContext* pStylesCtxt =
710         new SvXMLStylesContext( *(this), XML_NAMESPACE_OFFICE, rLocalName, xAttrList );
711 
712     // set context at base class, so that all auto-style classes are imported
713     SetAutoStyles( pStylesCtxt );
714     maImportHelper.SetAutoStylesContext( pStylesCtxt );
715 
716     return pStylesCtxt;
717 }
718 
719 void SAL_CALL SchXMLImport::setTargetDocument( const uno::Reference< lang::XComponent >& xDoc )
720     throw(lang::IllegalArgumentException, uno::RuntimeException)
721 {
722     uno::Reference< chart2::XChartDocument > xOldDoc( GetModel(), uno::UNO_QUERY );
723     if( xOldDoc.is() && xOldDoc->hasControllersLocked() )
724         xOldDoc->unlockControllers();
725 
726     SvXMLImport::setTargetDocument( xDoc );
727 
728     //set data provider and number formatter
729     // try to get an XDataProvider and set it
730     // @todo: if we have our own data, we must not use the parent as data provider
731     uno::Reference< chart2::XChartDocument > xChartDoc( GetModel(), uno::UNO_QUERY );
732 
733     if( xChartDoc.is() )
734     try
735     {
736         //prevent rebuild of view during load ( necesarry especially if loaded not via load api, which is the case for example if binary files are loaded )
737         xChartDoc->lockControllers();
738 
739         uno::Reference< container::XChild > xChild( xChartDoc, uno::UNO_QUERY );
740         uno::Reference< chart2::data::XDataReceiver > xDataReceiver( xChartDoc, uno::UNO_QUERY );
741         bool bHasOwnData = true;
742         if( xChild.is() && xDataReceiver.is())
743         {
744             Reference< lang::XMultiServiceFactory > xFact( xChild->getParent(), uno::UNO_QUERY );
745             if( xFact.is() )
746             {
747                 //if the parent has a number formatter we will use the numberformatter of the parent
748                 Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( xFact, uno::UNO_QUERY );
749                 xDataReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier );
750 
751                 if ( !xChartDoc->getDataProvider().is() )
752                 {
753                     const OUString aDataProviderServiceName( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.chart2.data.DataProvider"));
754                     const uno::Sequence< OUString > aServiceNames( xFact->getAvailableServiceNames());
755                     const OUString * pBegin = aServiceNames.getConstArray();
756                     const OUString * pEnd = pBegin + aServiceNames.getLength();
757                     if( ::std::find( pBegin, pEnd, aDataProviderServiceName ) != pEnd )
758                     {
759                         Reference< chart2::data::XDataProvider > xProvider(
760                             xFact->createInstance( aDataProviderServiceName ), uno::UNO_QUERY );
761                         if( xProvider.is())
762                         {
763                             xDataReceiver->attachDataProvider( xProvider );
764                             bHasOwnData = false;
765                         }
766                     }
767                 }
768                 else
769                     bHasOwnData = false;
770             }
771 //             else we have no parent => we have our own data
772 
773             if( bHasOwnData && ! xChartDoc->hasInternalDataProvider() )
774                 xChartDoc->createInternalDataProvider( sal_False );
775         }
776     }
777     catch( uno::Exception & rEx )
778     {
779 #ifdef DBG_UTIL
780         String aStr( rEx.Message );
781         ByteString aBStr( aStr, RTL_TEXTENCODING_ASCII_US );
782         DBG_ERROR1( "SchXMLChartContext::StartElement(): Exception caught: %s", aBStr.GetBuffer());
783 #else
784         (void)rEx; // avoid warning for pro build
785 #endif
786     }
787 }
788 
789 // export components ========================================
790 
791 // first version: everything comes from one storage
792 
793 Sequence< OUString > SAL_CALL SchXMLImport_getSupportedServiceNames() throw()
794 {
795     const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Chart.XMLOasisImporter" ) );
796     const Sequence< OUString > aSeq( &aServiceName, 1 );
797     return aSeq;
798 }
799 
800 OUString SAL_CALL SchXMLImport_getImplementationName() throw()
801 {
802     return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLImport" ) );
803 }
804 
805 Reference< uno::XInterface > SAL_CALL SchXMLImport_createInstance(const Reference< lang::XMultiServiceFactory > & rSMgr) throw( uno::Exception )
806 {
807     // #110680#
808     // return (cppu::OWeakObject*)new SchXMLImport();
809     return (cppu::OWeakObject*)new SchXMLImport(rSMgr);
810 }
811 
812 // ============================================================
813 
814 // multiple storage version: one for content / styles / meta
815 
816 Sequence< OUString > SAL_CALL SchXMLImport_Styles_getSupportedServiceNames() throw()
817 {
818     const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Chart.XMLOasisStylesImporter" ) );
819     const Sequence< OUString > aSeq( &aServiceName, 1 );
820     return aSeq;
821 }
822 
823 OUString SAL_CALL SchXMLImport_Styles_getImplementationName() throw()
824 {
825     return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLImport.Styles" ) );
826 }
827 
828 Reference< uno::XInterface > SAL_CALL SchXMLImport_Styles_createInstance(const Reference< lang::XMultiServiceFactory > & rSMgr) throw( uno::Exception )
829 {
830     // #110680#
831     // return (cppu::OWeakObject*)new SchXMLImport( IMPORT_STYLES );
832     return (cppu::OWeakObject*)new SchXMLImport( rSMgr, IMPORT_STYLES );
833 }
834 
835 // ------------------------------------------------------------
836 
837 Sequence< OUString > SAL_CALL SchXMLImport_Content_getSupportedServiceNames() throw()
838 {
839     const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Chart.XMLOasisContentImporter" ) );
840     const Sequence< OUString > aSeq( &aServiceName, 1 );
841     return aSeq;
842 }
843 
844 OUString SAL_CALL SchXMLImport_Content_getImplementationName() throw()
845 {
846     return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLImport.Content" ) );
847 }
848 
849 Reference< uno::XInterface > SAL_CALL SchXMLImport_Content_createInstance(const Reference< lang::XMultiServiceFactory > & rSMgr) throw( uno::Exception )
850 {
851     // #110680#
852     // return (cppu::OWeakObject*)new SchXMLImport( IMPORT_CONTENT | IMPORT_AUTOSTYLES | IMPORT_FONTDECLS );
853     return (cppu::OWeakObject*)new SchXMLImport( rSMgr, IMPORT_CONTENT | IMPORT_AUTOSTYLES | IMPORT_FONTDECLS );
854 }
855 
856 // ------------------------------------------------------------
857 
858 Sequence< OUString > SAL_CALL SchXMLImport_Meta_getSupportedServiceNames() throw()
859 {
860     const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Chart.XMLOasisMetaImporter" ) );
861     const Sequence< OUString > aSeq( &aServiceName, 1 );
862     return aSeq;
863 }
864 
865 OUString SAL_CALL SchXMLImport_Meta_getImplementationName() throw()
866 {
867     return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLImport.Meta" ) );
868 }
869 
870 Reference< uno::XInterface > SAL_CALL SchXMLImport_Meta_createInstance(const Reference< lang::XMultiServiceFactory > & rSMgr) throw( uno::Exception )
871 {
872     // #110680#
873     // return (cppu::OWeakObject*)new SchXMLImport( IMPORT_META );
874     return (cppu::OWeakObject*)new SchXMLImport( rSMgr, IMPORT_META );
875 }
876 
877 // XServiceInfo
878 OUString SAL_CALL SchXMLImport::getImplementationName() throw( uno::RuntimeException )
879 {
880     switch( getImportFlags())
881     {
882         case IMPORT_ALL:
883             return SchXMLImport_getImplementationName();
884         case IMPORT_STYLES:
885             return SchXMLImport_Styles_getImplementationName();
886         case ( IMPORT_CONTENT | IMPORT_AUTOSTYLES | IMPORT_FONTDECLS ):
887             return SchXMLImport_Content_getImplementationName();
888         case IMPORT_META:
889             return SchXMLImport_Meta_getImplementationName();
890 
891         case IMPORT_SETTINGS:
892         // there is no settings component in chart
893         default:
894             return OUString::createFromAscii( "SchXMLImport" );
895     }
896 }
897