xref: /AOO41X/main/sc/source/filter/xml/xmlexprt.cxx (revision 102b8ff7781b532aa1df1941db88b59ea9611485)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26 
27 // INCLUDE ---------------------------------------------------------------
28 
29 #include <editeng/eeitem.hxx>
30 
31 #include "xmlexprt.hxx"
32 #include "XMLConverter.hxx"
33 #include "xmlstyle.hxx"
34 #include "unonames.hxx"
35 #include "document.hxx"
36 #include "olinetab.hxx"
37 #include "cellsuno.hxx"
38 #include "cell.hxx"
39 #include "rangenam.hxx"
40 #include "XMLTableMasterPageExport.hxx"
41 #include "drwlayer.hxx"
42 #include "XMLExportDataPilot.hxx"
43 #include "XMLExportDatabaseRanges.hxx"
44 #include "XMLExportDDELinks.hxx"
45 #include "XMLExportIterator.hxx"
46 #include "XMLColumnRowGroupExport.hxx"
47 #include "XMLStylesExportHelper.hxx"
48 #include "XMLChangeTrackingExportHelper.hxx"
49 #include "sheetdata.hxx"
50 #include "docoptio.hxx"
51 #include "XMLExportSharedData.hxx"
52 #include "chgviset.hxx"
53 #include "docuno.hxx"
54 #include "textuno.hxx"
55 #include "chartlis.hxx"
56 #include "unoguard.hxx"
57 #include "scitems.hxx"
58 #include "docpool.hxx"
59 #include "userdat.hxx"
60 #include "dociter.hxx"
61 #include "chgtrack.hxx"
62 #include "rangeutl.hxx"
63 #include "convuno.hxx"
64 #include "postit.hxx"
65 #include "externalrefmgr.hxx"
66 #include "editutil.hxx"
67 #include "tabprotection.hxx"
68 
69 #include <xmloff/xmltoken.hxx>
70 #include <xmloff/xmlnmspe.hxx>
71 #include <xmloff/xmluconv.hxx>
72 #include <xmloff/nmspmap.hxx>
73 #include <xmloff/families.hxx>
74 #include <xmloff/numehelp.hxx>
75 #include <xmloff/xmluconv.hxx>
76 #include <xmloff/txtparae.hxx>
77 #include <xmloff/xmlcnitm.hxx>
78 #include <xmloff/xmlerror.hxx>
79 #include <xmloff/XMLEventExport.hxx>
80 
81 #include <rtl/ustring.hxx>
82 
83 #include <tools/debug.hxx>
84 #include "tools/color.hxx"
85 #include <rtl/math.hxx>
86 #include <svl/zforlist.hxx>
87 #include <svx/unoshape.hxx>
88 #include <comphelper/extract.hxx>
89 #include <editeng/eeitem.hxx>
90 #include <toolkit/helper/convert.hxx>
91 #include <svx/svdobj.hxx>
92 #include <svx/svdocapt.hxx>
93 #include <editeng/outlobj.hxx>
94 #include <svx/svditer.hxx>
95 #include <svx/svdpage.hxx>
96 
97 #include <comphelper/processfactory.hxx>
98 #include <com/sun/star/sheet/XUsedAreaCursor.hpp>
99 #include <com/sun/star/sheet/XCellRangeAddressable.hpp>
100 #include <com/sun/star/sheet/XAreaLinks.hpp>
101 #include <com/sun/star/sheet/XAreaLink.hpp>
102 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
103 #include <com/sun/star/table/XColumnRowRange.hpp>
104 #include <com/sun/star/sheet/XPrintAreas.hpp>
105 #include <com/sun/star/container/XNamed.hpp>
106 #include <com/sun/star/util/XProtectable.hpp>
107 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
108 #include <com/sun/star/sheet/XUniqueCellFormatRangesSupplier.hpp>
109 #include <com/sun/star/sheet/XCellRangesQuery.hpp>
110 #include <com/sun/star/sheet/CellFlags.hpp>
111 #include <com/sun/star/util/XMergeable.hpp>
112 #include <com/sun/star/sheet/XArrayFormulaRange.hpp>
113 #include <com/sun/star/text/XText.hpp>
114 #include <com/sun/star/sheet/XLabelRanges.hpp>
115 #include <com/sun/star/sheet/XLabelRange.hpp>
116 #include <com/sun/star/sheet/XNamedRanges2.hpp>
117 #include <com/sun/star/sheet/XNamedRange2.hpp>
118 #include <com/sun/star/sheet/XCellRangeReferrer.hpp>
119 #include <com/sun/star/sheet/NamedRangeFlag.hpp>
120 #include <com/sun/star/container/XNamed.hpp>
121 #include <com/sun/star/sheet/XSheetLinkable.hpp>
122 #include <com/sun/star/form/XFormsSupplier2.hpp>
123 #include <com/sun/star/io/XActiveDataSource.hpp>
124 #include <com/sun/star/io/XSeekable.hpp>
125 #include <com/sun/star/beans/XPropertySet.hpp>
126 
127 #include <com/sun/star/chart2/XChartDocument.hpp>
128 #include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
129 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
130 
131 #include <com/sun/star/document/XDocumentProperties.hpp>
132 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
133 
134 #include "XMLCodeNameProvider.hxx"
135 
136 #include <sfx2/objsh.hxx>
137 
138 #include <vector>
139 
140 //! not found in unonames.hxx
141 #define SC_STANDARDFORMAT "StandardFormat"
142 #define SC_LAYERID "LayerID"
143 
144 #define SC_DEFAULT_TABLE_COUNT                      3
145 #define SC_VIEWCHANGES_COUNT                        13
146 #define SC_SHOW_CHANGES                             0
147 #define SC_SHOW_ACCEPTED_CHANGES                    1
148 #define SC_SHOW_REJECTED_CHANGES                    2
149 #define SC_SHOW_CHANGES_BY_DATETIME                 3
150 #define SC_SHOW_CHANGES_BY_DATETIME_MODE            4
151 #define SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME  5
152 #define SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME 6
153 #define SC_SHOW_CHANGES_BY_AUTHOR                   7
154 #define SC_SHOW_CHANGES_BY_AUTHOR_NAME              8
155 #define SC_SHOW_CHANGES_BY_COMMENT                  9
156 #define SC_SHOW_CHANGES_BY_COMMENT_TEXT             10
157 #define SC_SHOW_CHANGES_BY_RANGES                   11
158 #define SC_SHOW_CHANGES_BY_RANGES_LIST              12
159 
160 using namespace rtl;
161 using namespace formula;
162 using namespace com::sun::star;
163 using namespace xmloff::token;
164 using ::std::vector;
165 using ::com::sun::star::uno::UNO_QUERY;
166 
167 //----------------------------------------------------------------------------
168 
169 namespace
170 {
lcl_RangeSequenceToString(const uno::Sequence<OUString> & rRanges,const uno::Reference<chart2::data::XRangeXMLConversion> & xFormatConverter)171 OUString lcl_RangeSequenceToString(
172     const uno::Sequence< OUString > & rRanges,
173     const uno::Reference< chart2::data::XRangeXMLConversion > & xFormatConverter )
174 {
175     OUStringBuffer aResult;
176     const sal_Int32 nMaxIndex( rRanges.getLength() - 1 );
177     const sal_Unicode cSep( sal_Char(' '));
178     for( sal_Int32 i=0; i<=nMaxIndex; ++i )
179     {
180         OUString aRange( rRanges[i] );
181         if( xFormatConverter.is())
182             aRange = xFormatConverter->convertRangeToXML( aRange );
183         aResult.append( aRange );
184         if( i < nMaxIndex )
185             aResult.append( cSep );
186     }
187     return aResult.makeStringAndClear();
188 }
189 
lcl_GetRawString(ScDocument * pDoc,const ScAddress & rPos)190 OUString lcl_GetRawString( ScDocument* pDoc, const ScAddress& rPos )
191 {
192     // return text/edit cell string content, with line feeds in edit cells
193 
194     String aVal;        // document uses tools-strings
195     if (pDoc)
196     {
197         ScBaseCell* pCell = pDoc->GetCell( rPos );
198         if (pCell)
199         {
200             CellType eType = pCell->GetCellType();
201             if ( eType == CELLTYPE_STRING )
202                 static_cast<ScStringCell*>(pCell)->GetString(aVal);     // string cell: content
203             else if ( eType == CELLTYPE_EDIT )
204             {
205                 // edit cell: text with line breaks
206                 const EditTextObject* pData = static_cast<ScEditCell*>(pCell)->GetData();
207                 if (pData)
208                 {
209                     EditEngine& rEngine = pDoc->GetEditEngine();
210                     rEngine.SetText( *pData );
211                     aVal = rEngine.GetText( LINEEND_LF );
212                 }
213             }
214         }
215     }
216     return aVal;
217 }
218 } // anonymous namespace
219 
220 //----------------------------------------------------------------------------
221 
ScXMLOOoExport_getImplementationName()222 OUString SAL_CALL ScXMLOOoExport_getImplementationName() throw()
223 {
224     return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLExporter" ) );
225 }
226 
ScXMLOOoExport_getSupportedServiceNames()227 uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_getSupportedServiceNames() throw()
228 {
229     const rtl::OUString aServiceName( ScXMLOOoExport_getImplementationName() );
230     return uno::Sequence< rtl::OUString >( &aServiceName, 1 );
231 }
232 
ScXMLOOoExport_createInstance(const uno::Reference<lang::XMultiServiceFactory> & rSMgr)233 uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_createInstance(
234                 const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
235 {
236     // #110680#
237     // return (cppu::OWeakObject*)new ScXMLExport(EXPORT_ALL);
238     return (cppu::OWeakObject*)new ScXMLExport( rSMgr, EXPORT_ALL );
239 }
240 
ScXMLOOoExport_Meta_getImplementationName()241 OUString SAL_CALL ScXMLOOoExport_Meta_getImplementationName() throw()
242 {
243     return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLMetaExporter" ) );
244 }
245 
ScXMLOOoExport_Meta_getSupportedServiceNames()246 uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_Meta_getSupportedServiceNames() throw()
247 {
248     const rtl::OUString aServiceName( ScXMLOOoExport_Meta_getImplementationName() );
249     return uno::Sequence< rtl::OUString > ( &aServiceName, 1 );
250 }
251 
ScXMLOOoExport_Meta_createInstance(const uno::Reference<lang::XMultiServiceFactory> & rSMgr)252 uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_Meta_createInstance(
253                 const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
254 {
255     // #110680#
256     // return (cppu::OWeakObject*)new ScXMLExport(EXPORT_META);
257     return (cppu::OWeakObject*)new ScXMLExport( rSMgr, EXPORT_META );
258 }
259 
ScXMLOOoExport_Styles_getImplementationName()260 OUString SAL_CALL ScXMLOOoExport_Styles_getImplementationName() throw()
261 {
262     return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLStylesExporter" ) );
263 }
264 
ScXMLOOoExport_Styles_getSupportedServiceNames()265 uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_Styles_getSupportedServiceNames() throw()
266 {
267     const rtl::OUString aServiceName( ScXMLOOoExport_Styles_getImplementationName() );
268     return uno::Sequence< rtl::OUString > ( &aServiceName, 1 );
269 }
270 
ScXMLOOoExport_Styles_createInstance(const uno::Reference<lang::XMultiServiceFactory> & rSMgr)271 uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_Styles_createInstance(
272                 const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
273 {
274     // #110680#
275     // return (cppu::OWeakObject*)new ScXMLExport(EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_FONTDECLS);
276     return (cppu::OWeakObject*)new ScXMLExport( rSMgr, EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_FONTDECLS);
277 }
278 
ScXMLOOoExport_Content_getImplementationName()279 OUString SAL_CALL ScXMLOOoExport_Content_getImplementationName() throw()
280 {
281     return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLContentExporter" ) );
282 }
283 
ScXMLOOoExport_Content_getSupportedServiceNames()284 uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_Content_getSupportedServiceNames() throw()
285 {
286     const rtl::OUString aServiceName( ScXMLOOoExport_Content_getImplementationName() );
287     return uno::Sequence< rtl::OUString > ( &aServiceName, 1 );
288 }
289 
ScXMLOOoExport_Content_createInstance(const uno::Reference<lang::XMultiServiceFactory> & rSMgr)290 uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_Content_createInstance(
291                 const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
292 {
293     // #110680#
294     // return (cppu::OWeakObject*)new ScXMLExport(EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS);
295     return (cppu::OWeakObject*)new ScXMLExport( rSMgr, EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS);
296 }
297 
ScXMLOOoExport_Settings_getImplementationName()298 OUString SAL_CALL ScXMLOOoExport_Settings_getImplementationName() throw()
299 {
300     return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLSettingsExporter" ) );
301 }
302 
ScXMLOOoExport_Settings_getSupportedServiceNames()303 uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_Settings_getSupportedServiceNames() throw()
304 {
305     const rtl::OUString aServiceName( ScXMLOOoExport_Settings_getImplementationName() );
306     return uno::Sequence< rtl::OUString > ( &aServiceName, 1 );
307 }
308 
ScXMLOOoExport_Settings_createInstance(const uno::Reference<lang::XMultiServiceFactory> & rSMgr)309 uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_Settings_createInstance(
310                 const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
311 {
312     // #110680#
313     // return (cppu::OWeakObject*)new ScXMLExport(EXPORT_SETTINGS);
314     return (cppu::OWeakObject*)new ScXMLExport( rSMgr, EXPORT_SETTINGS );
315 }
316 
317 // Oasis Filter
318 
ScXMLOasisExport_getImplementationName()319 OUString SAL_CALL ScXMLOasisExport_getImplementationName() throw()
320 {
321     return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisExporter" ) );
322 }
323 
ScXMLOasisExport_getSupportedServiceNames()324 uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_getSupportedServiceNames() throw()
325 {
326     const rtl::OUString aServiceName( ScXMLOasisExport_getImplementationName() );
327     const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 );
328     return aSeq;
329 }
330 
ScXMLOasisExport_createInstance(const uno::Reference<lang::XMultiServiceFactory> & rSMgr)331 uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_createInstance(
332                 const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
333 {
334     return (cppu::OWeakObject*)new ScXMLExport(rSMgr, EXPORT_ALL|EXPORT_OASIS);
335 }
336 
ScXMLOasisExport_Meta_getImplementationName()337 OUString SAL_CALL ScXMLOasisExport_Meta_getImplementationName() throw()
338 {
339     return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisMetaExporter" ) );
340 }
341 
ScXMLOasisExport_Meta_getSupportedServiceNames()342 uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_Meta_getSupportedServiceNames() throw()
343 {
344     const rtl::OUString aServiceName( ScXMLOasisExport_Meta_getImplementationName() );
345     const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 );
346     return aSeq;
347 }
348 
ScXMLOasisExport_Meta_createInstance(const uno::Reference<lang::XMultiServiceFactory> & rSMgr)349 uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_Meta_createInstance(
350                 const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
351 {
352     return (cppu::OWeakObject*)new ScXMLExport(rSMgr, EXPORT_META|EXPORT_OASIS);
353 }
354 
ScXMLOasisExport_Styles_getImplementationName()355 OUString SAL_CALL ScXMLOasisExport_Styles_getImplementationName() throw()
356 {
357     return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisStylesExporter" ) );
358 }
359 
ScXMLOasisExport_Styles_getSupportedServiceNames()360 uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_Styles_getSupportedServiceNames() throw()
361 {
362     const rtl::OUString aServiceName( ScXMLOasisExport_Styles_getImplementationName() );
363     const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 );
364     return aSeq;
365 }
366 
ScXMLOasisExport_Styles_createInstance(const uno::Reference<lang::XMultiServiceFactory> & rSMgr)367 uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_Styles_createInstance(
368                 const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
369 {
370     return (cppu::OWeakObject*)new ScXMLExport(rSMgr, EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_FONTDECLS|EXPORT_OASIS);
371 }
372 
ScXMLOasisExport_Content_getImplementationName()373 OUString SAL_CALL ScXMLOasisExport_Content_getImplementationName() throw()
374 {
375     return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisContentExporter" ) );
376 }
377 
ScXMLOasisExport_Content_getSupportedServiceNames()378 uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_Content_getSupportedServiceNames() throw()
379 {
380     const rtl::OUString aServiceName( ScXMLOasisExport_Content_getImplementationName() );
381     const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 );
382     return aSeq;
383 }
384 
ScXMLOasisExport_Content_createInstance(const uno::Reference<lang::XMultiServiceFactory> & rSMgr)385 uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_Content_createInstance(
386                 const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
387 {
388     return (cppu::OWeakObject*)new ScXMLExport(rSMgr, EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS|EXPORT_OASIS);
389 }
390 
ScXMLOasisExport_Settings_getImplementationName()391 OUString SAL_CALL ScXMLOasisExport_Settings_getImplementationName() throw()
392 {
393     return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisSettingsExporter" ) );
394 }
395 
ScXMLOasisExport_Settings_getSupportedServiceNames()396 uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_Settings_getSupportedServiceNames() throw()
397 {
398     const rtl::OUString aServiceName( ScXMLOasisExport_Settings_getImplementationName() );
399     const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 );
400     return aSeq;
401 }
402 
ScXMLOasisExport_Settings_createInstance(const uno::Reference<lang::XMultiServiceFactory> & rSMgr)403 uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_Settings_createInstance(
404                 const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
405 {
406     return (cppu::OWeakObject*)new ScXMLExport(rSMgr, EXPORT_SETTINGS|EXPORT_OASIS);
407 }
408 //----------------------------------------------------------------------------
409 
410 class ScXMLShapeExport : public XMLShapeExport
411 {
412 public:
ScXMLShapeExport(SvXMLExport & rExp)413     ScXMLShapeExport(SvXMLExport& rExp) : XMLShapeExport(rExp) {}
414     ~ScXMLShapeExport();
415 
416     /** is called before a shape element for the given XShape is exported */
417     virtual void onExport( const uno::Reference < drawing::XShape >& xShape );
418 };
419 
~ScXMLShapeExport()420 ScXMLShapeExport::~ScXMLShapeExport()
421 {
422 }
423 
onExport(const uno::Reference<drawing::XShape> & xShape)424 void ScXMLShapeExport::onExport( const uno::Reference < drawing::XShape >& xShape )
425 {
426     uno::Reference< beans::XPropertySet > xShapeProp( xShape, uno::UNO_QUERY );
427     if( xShapeProp.is() )
428     {
429         sal_Int16 nLayerID = 0;
430         if( (xShapeProp->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_LAYERID ))) >>= nLayerID) && (nLayerID == SC_LAYER_BACK) )
431             GetExport().AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_BACKGROUND, XML_TRUE);
432     }
433 }
434 
435 //----------------------------------------------------------------------------
436 
GetFieldUnit()437 sal_Int16 ScXMLExport::GetFieldUnit()
438 {
439     com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> xProperties(
440                 comphelper::getProcessServiceFactory()->createInstance(
441                     rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.GlobalSheetSettings" )) ),
442                 com::sun::star::uno::UNO_QUERY);
443     if (xProperties.is())
444     {
445         sal_Int16 nFieldUnit = 0;
446         if (xProperties->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Metric"))) >>= nFieldUnit)
447             return nFieldUnit;
448     }
449     return 0;
450 }
451 
452 
453 // #110680#
ScXMLExport(const::com::sun::star::uno::Reference<::com::sun::star::lang::XMultiServiceFactory> xServiceFactory,const sal_uInt16 nExportFlag)454 ScXMLExport::ScXMLExport(
455     const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
456     const sal_uInt16 nExportFlag)
457 :   SvXMLExport( xServiceFactory, SvXMLUnitConverter::GetMapUnit(GetFieldUnit()), XML_SPREADSHEET, nExportFlag ),
458     pDoc(NULL),
459     nSourceStreamPos(0),
460     pNumberFormatAttributesExportHelper(NULL),
461     pSharedData(NULL),
462     pColumnStyles(NULL),
463     pRowStyles(NULL),
464     pCellStyles(NULL),
465     pRowFormatRanges(NULL),
466     aTableStyles(),
467     pGroupColumns (NULL),
468     pGroupRows (NULL),
469     pDefaults(NULL),
470     pChartListener(NULL),
471     pCurrentCell(NULL),
472     pMergedRangesContainer(NULL),
473     pValidationsContainer(NULL),
474     pCellsItr(NULL),
475     pChangeTrackingExportHelper(NULL),
476     sLayerID(RTL_CONSTASCII_USTRINGPARAM( SC_LAYERID )),
477     sCaptionShape(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.CaptionShape")),
478     nOpenRow(-1),
479     nProgressCount(0),
480     nCurrentTable(0),
481     bHasRowHeader(sal_False),
482     bRowHeaderOpen(sal_False),
483     mbShowProgress( sal_False )
484 {
485     if (getExportFlags() & EXPORT_CONTENT)
486     {
487         pGroupColumns = new ScMyOpenCloseColumnRowGroup(*this, XML_TABLE_COLUMN_GROUP);
488         pGroupRows = new ScMyOpenCloseColumnRowGroup(*this, XML_TABLE_ROW_GROUP);
489         pColumnStyles = new ScColumnStyles();
490         pRowStyles = new ScRowStyles();
491         pRowFormatRanges = new ScRowFormatRanges();
492         pMergedRangesContainer = new ScMyMergedRangesContainer();
493         pValidationsContainer = new ScMyValidationsContainer();
494         pCellsItr = new ScMyNotEmptyCellsIterator(*this);
495         pDefaults = new ScMyDefaultStyles();
496     }
497     pCellStyles = new ScFormatRangeStyles();
498 
499     // document is not set here - create ScChangeTrackingExportHelper later
500 
501     xScPropHdlFactory = new XMLScPropHdlFactory;
502     xCellStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScCellStylesProperties, xScPropHdlFactory);
503     xColumnStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScColumnStylesProperties, xScPropHdlFactory);
504     xRowStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScRowStylesProperties, xScPropHdlFactory);
505     xTableStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScTableStylesProperties, xScPropHdlFactory);
506     xCellStylesExportPropertySetMapper = new ScXMLCellExportPropertyMapper(xCellStylesPropertySetMapper);
507     xCellStylesExportPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(*this));
508     xColumnStylesExportPropertySetMapper = new ScXMLColumnExportPropertyMapper(xColumnStylesPropertySetMapper);
509     xRowStylesExportPropertySetMapper = new ScXMLRowExportPropertyMapper(xRowStylesPropertySetMapper);
510     xTableStylesExportPropertySetMapper = new ScXMLTableExportPropertyMapper(xTableStylesPropertySetMapper);
511 
512     GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_CELL, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME)),
513         xCellStylesExportPropertySetMapper, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX)));
514     GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_COLUMN, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_NAME)),
515         xColumnStylesExportPropertySetMapper, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX)));
516     GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_ROW, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_ROW_STYLES_NAME)),
517         xRowStylesExportPropertySetMapper, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX)));
518     GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_TABLE, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_TABLE_STYLES_NAME)),
519         xTableStylesExportPropertySetMapper, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_TABLE_STYLES_PREFIX)));
520 
521     if( (getExportFlags() & (EXPORT_STYLES|EXPORT_AUTOSTYLES|EXPORT_MASTERSTYLES|EXPORT_CONTENT) ) != 0 )
522     {
523         // This name is reserved for the external ref cache tables.  This
524         // should not conflict with user-defined styles since this name is
525         // used for a table style which is not available in the UI.
526         sExternalRefTabStyleName = rtl::OUString::createFromAscii("ta_extref");
527         GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_TABLE, sExternalRefTabStyleName);
528 
529         sAttrName = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_NAME));
530         sAttrStyleName = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_STYLE_NAME));
531         sAttrColumnsRepeated = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_NUMBER_COLUMNS_REPEATED));
532         sAttrFormula = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_FORMULA));
533         sAttrStringValue = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_STRING_VALUE));
534         sAttrValueType = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_VALUE_TYPE));
535         sElemCell = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE_CELL));
536         sElemCoveredCell = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_COVERED_TABLE_CELL));
537         sElemCol = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE_COLUMN));
538         sElemRow = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE_ROW));
539         sElemTab = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE));
540         sElemP = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TEXT, GetXMLToken(XML_P));
541     }
542 }
543 
544 
~ScXMLExport()545 ScXMLExport::~ScXMLExport()
546 {
547     if (pGroupColumns)
548         delete pGroupColumns;
549     if (pGroupRows)
550         delete pGroupRows;
551     if (pColumnStyles)
552         delete pColumnStyles;
553     if (pRowStyles)
554         delete pRowStyles;
555     if (pCellStyles)
556         delete pCellStyles;
557     if (pRowFormatRanges)
558         delete pRowFormatRanges;
559     if (pMergedRangesContainer)
560         delete pMergedRangesContainer;
561     if (pValidationsContainer)
562         delete pValidationsContainer;
563     if (pChangeTrackingExportHelper)
564         delete pChangeTrackingExportHelper;
565     if (pChartListener)
566         delete pChartListener;
567     if (pCellsItr)
568         delete pCellsItr;
569     if (pDefaults)
570         delete pDefaults;
571     if (pNumberFormatAttributesExportHelper)
572         delete pNumberFormatAttributesExportHelper;
573 }
574 
SetSourceStream(const uno::Reference<io::XInputStream> & xNewStream)575 void ScXMLExport::SetSourceStream( const uno::Reference<io::XInputStream>& xNewStream )
576 {
577     xSourceStream = xNewStream;
578 
579     if ( xSourceStream.is() )
580     {
581         // make sure it's a plain UTF-8 stream as written by OOo itself
582 
583         const sal_Char pXmlHeader[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
584         sal_Int32 nLen = strlen(pXmlHeader);
585 
586         uno::Sequence<sal_Int8> aFileStart(nLen);
587         sal_Int32 nRead = xSourceStream->readBytes( aFileStart, nLen );
588 
589         if ( nRead != nLen || rtl_compareMemory( aFileStart.getConstArray(), pXmlHeader, nLen ) != 0 )
590         {
591             // invalid - ignore stream, save normally
592             xSourceStream.clear();
593         }
594         else
595         {
596             // keep track of the bytes already read
597             nSourceStreamPos = nRead;
598 
599             const ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetModel())->GetSheetSaveData();
600             if (pSheetData)
601             {
602                 // add the loaded namespaces to the name space map
603 
604                 if ( !pSheetData->AddLoadedNamespaces( _GetNamespaceMap() ) )
605                 {
606                     // conflicts in the namespaces - ignore the stream, save normally
607                     xSourceStream.clear();
608                 }
609             }
610         }
611     }
612 }
613 
GetNumberFormatStyleIndex(sal_Int32 nNumFmt) const614 sal_Int32 ScXMLExport::GetNumberFormatStyleIndex(sal_Int32 nNumFmt) const
615 {
616     NumberFormatIndexMap::const_iterator itr = aNumFmtIndexMap.find(nNumFmt);
617     if (itr == aNumFmtIndexMap.end())
618         return -1;
619 
620     return itr->second;
621 }
622 
HasDrawPages(uno::Reference<sheet::XSpreadsheetDocument> & xDoc)623 sal_Bool ScXMLExport::HasDrawPages(uno::Reference <sheet::XSpreadsheetDocument>& xDoc)
624 {
625     uno::Reference <beans::XPropertySet> xDocProps( xDoc, uno::UNO_QUERY );
626     return (xDocProps.is() && ::cppu::any2bool( xDocProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_HASDRAWPAGES))) ));
627 }
628 
CollectSharedData(sal_Int32 & nTableCount,sal_Int32 & nShapesCount,const sal_Int32 nCellCount)629 void ScXMLExport::CollectSharedData(sal_Int32& nTableCount, sal_Int32& nShapesCount, const sal_Int32 nCellCount)
630 {
631     if (GetModel().is())
632     {
633         uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY );
634         if ( xSpreadDoc.is())
635         {
636             uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY );
637             if ( xIndex.is() )
638             {
639                 nTableCount = xIndex->getCount();
640                 if (!pSharedData)
641                     CreateSharedData(nTableCount);
642                 pCellStyles->AddNewTable(nTableCount - 1);
643                 pDoc->InitializeAllNoteCaptions( true );
644                 if (HasDrawPages(xSpreadDoc))
645                 {
646                     rtl::OUString sCaptionPoint( RTL_CONSTASCII_USTRINGPARAM( "CaptionPoint" ));
647                     for (SCTAB nTable = 0; nTable < nTableCount; ++nTable)
648                     {
649                         nCurrentTable = sal::static_int_cast<sal_uInt16>( nTable );
650                         uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(xIndex->getByIndex(nTable), uno::UNO_QUERY);
651                         if (xDrawPageSupplier.is())
652                         {
653                             uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPageSupplier->getDrawPage());
654                             ScMyDrawPage aDrawPage;
655                             aDrawPage.bHasForms = sal_False;
656                             aDrawPage.xDrawPage.set(xDrawPage);
657                             pSharedData->AddDrawPage(aDrawPage, nTable);
658                             uno::Reference<container::XIndexAccess> xShapesIndex (xDrawPage, uno::UNO_QUERY);
659                             if (xShapesIndex.is())
660                             {
661                                 sal_Int32 nShapes(xShapesIndex->getCount());
662                                 for (sal_Int32 nShape = 0; nShape < nShapes; ++nShape)
663                                 {
664                                     uno::Reference<drawing::XShape> xShape(xShapesIndex->getByIndex(nShape), uno::UNO_QUERY);
665                                     if (xShape.is())
666                                     {
667                                         uno::Reference< beans::XPropertySet > xShapeProp( xShape, uno::UNO_QUERY );
668                                         if( xShapeProp.is() )
669                                         {
670                                             sal_Int16 nLayerID = 0;
671                                             if( xShapeProp->getPropertyValue(sLayerID) >>= nLayerID )
672                                             {
673                                                 if( (nLayerID == SC_LAYER_INTERN) || (nLayerID == SC_LAYER_HIDDEN) )
674                                                     CollectInternalShape( xShape );
675                                                 else
676                                                 {
677                                                     ++nShapesCount;
678                                                     SvxShape* pShapeImp(SvxShape::getImplementation(xShape));
679                                                     if (pShapeImp)
680                                                     {
681                                                         SdrObject *pSdrObj(pShapeImp->GetSdrObject());
682                                                         if (pSdrObj)
683                                                         {
684                                                             if (ScDrawLayer::GetAnchor(pSdrObj) == SCA_CELL)
685                                                             {
686                                                                 if (pDoc)
687                                                                 {
688 
689                                                                     awt::Point aPoint(xShape->getPosition());
690                                                                     awt::Size aSize(xShape->getSize());
691                                                                     rtl::OUString sType(xShape->getShapeType());
692                                                                     Rectangle aRectangle(aPoint.X, aPoint.Y, aPoint.X + aSize.Width, aPoint.Y + aSize.Height);
693                                                                     if ( sType.equals(sCaptionShape) )
694                                                                     {
695                                                                         awt::Point aRelativeCaptionPoint;
696                                                                         xShapeProp->getPropertyValue( sCaptionPoint ) >>= aRelativeCaptionPoint;
697                                                                         Point aCoreRelativeCaptionPoint(aRelativeCaptionPoint.X, aRelativeCaptionPoint.Y);
698                                                                         Point aCoreAbsoluteCaptionPoint(aPoint.X, aPoint.Y);
699                                                                         aCoreAbsoluteCaptionPoint += aCoreRelativeCaptionPoint;
700                                                                         aRectangle.Union(Rectangle(aCoreAbsoluteCaptionPoint, aCoreAbsoluteCaptionPoint));
701                                                                     }
702                                                                     ScRange aRange(pDoc->GetRange(static_cast<SCTAB>(nTable), aRectangle));
703                                                                     ScMyShape aMyShape;
704                                                                     aMyShape.aAddress = aRange.aStart;
705                                                                     aMyShape.aEndAddress = aRange.aEnd;
706                                                                     aMyShape.xShape = xShape;
707                                                                     pSharedData->AddNewShape(aMyShape);
708                                                                     pSharedData->SetLastColumn(nTable, aRange.aStart.Col());
709                                                                     pSharedData->SetLastRow(nTable, aRange.aStart.Row());
710                                                                 }
711                                                             }
712                                                             else
713                                                                 pSharedData->AddTableShape(nTable, xShape);
714                                                         }
715                                                     }
716                                                 }
717                                             }
718                                         }
719                                     }
720                                 }
721                             }
722                         }
723                     }
724                 }
725             }
726         }
727     }
728     sal_Int32 nRef(nCellCount + (2 * nTableCount) + (2 * nShapesCount));
729     GetProgressBarHelper()->SetReference(nRef);
730     GetProgressBarHelper()->SetValue(0);
731 }
732 
CollectShapesAutoStyles(const sal_Int32 nTableCount)733 void ScXMLExport::CollectShapesAutoStyles(const sal_Int32 nTableCount)
734 {
735     // #i84077# To avoid compiler warnings about uninitialized aShapeItr,
736     // it's initialized using this dummy list. The iterator contains shapes
737     // from all sheets, so it can't be declared inside the nTable loop where
738     // it is used.
739     ScMyShapeList aDummyInitList;
740 
741     pSharedData->SortShapesContainer();
742     pSharedData->SortNoteShapes();
743     const ScMyShapeList* pShapeList(NULL);
744     ScMyShapeList::const_iterator aShapeItr = aDummyInitList.end();
745     if (pSharedData->GetShapesContainer())
746     {
747         pShapeList = pSharedData->GetShapesContainer()->GetShapes();
748         aShapeItr = pShapeList->begin();
749     }
750     if (pSharedData->HasDrawPage())
751     {
752         for (SCTAB nTable = 0; nTable < nTableCount; ++nTable)
753         {
754             uno::Reference<drawing::XDrawPage> xDrawPage(pSharedData->GetDrawPage(nTable));
755             uno::Reference<drawing::XShapes> xShapes (xDrawPage, uno::UNO_QUERY);
756 
757             if (xShapes.is())
758             {
759                 GetShapeExport()->seekShapes(xShapes);
760                 uno::Reference< form::XFormsSupplier2 > xFormsSupplier( xDrawPage, uno::UNO_QUERY );
761                 if( xFormsSupplier.is() && xFormsSupplier->hasForms() )
762                 {
763                     GetFormExport()->examineForms(xDrawPage);
764                     pSharedData->SetDrawPageHasForms(nTable, sal_True);
765                 }
766                 ScMyTableShapes* pTableShapes(pSharedData->GetTableShapes());
767                 if (pTableShapes)
768                 {
769                     ScMyTableXShapes::iterator aItr((*pTableShapes)[nTable].begin());
770                     ScMyTableXShapes::iterator aEndItr((*pTableShapes)[nTable].end());
771                     while (aItr != aEndItr)
772                     {
773                         GetShapeExport()->collectShapeAutoStyles(*aItr);
774                         IncrementProgressBar(sal_False);
775                         ++aItr;
776                     }
777                 }
778                 if (pShapeList)
779                 {
780                     ScMyShapeList::const_iterator aEndItr(pShapeList->end());
781                     while (aShapeItr != aEndItr && (static_cast<sal_Int32>(aShapeItr->aAddress.Tab()) == nTable))
782                     {
783                         GetShapeExport()->collectShapeAutoStyles(aShapeItr->xShape);
784                         IncrementProgressBar(sal_False);
785                         ++aShapeItr;
786                     }
787                 }
788                 const ScMyNoteShapeList* pNoteShapes = NULL;
789                 ScMyNoteShapeList::const_iterator aNoteShapeItr;
790                 ScMyNoteShapeList::const_iterator aNoteShapeEndItr;
791                 if (pSharedData->GetNoteShapes())
792                 {
793                     pNoteShapes = pSharedData->GetNoteShapes()->GetNotes();
794                     if (pNoteShapes)
795                     {
796                         aNoteShapeItr = pNoteShapes->begin();
797                         aNoteShapeEndItr = pNoteShapes->end();
798                     }
799                 }
800                 if (pNoteShapes)
801                 {
802                     while (aNoteShapeItr != aNoteShapeEndItr)
803                     {
804                         if (static_cast<sal_Int32>(aNoteShapeItr->aPos.Tab()) == nTable)
805                             GetShapeExport()->collectShapeAutoStyles(aNoteShapeItr->xShape);
806                         ++aNoteShapeItr;
807                     }
808                 }
809             }
810         }
811     }
812     pSharedData->SortNoteShapes(); // sort twice, because some more shapes are added
813 }
814 
_ExportMeta()815 void ScXMLExport::_ExportMeta()
816 {
817     sal_Int32 nCellCount(pDoc ? pDoc->GetCellCount() : 0);
818     sal_Int32 nTableCount(0);
819     sal_Int32 nShapesCount(0);
820     GetAutoStylePool()->ClearEntries();
821     CollectSharedData(nTableCount, nShapesCount, nCellCount);
822 
823     uno::Sequence<beans::NamedValue> stats(3);
824     stats[0] = beans::NamedValue(::rtl::OUString::createFromAscii("TableCount"),
825                 uno::makeAny(nTableCount));
826     stats[1] = beans::NamedValue(::rtl::OUString::createFromAscii("CellCount"),
827                 uno::makeAny(nCellCount));
828     stats[2] = beans::NamedValue(::rtl::OUString::createFromAscii("ObjectCount"),
829                 uno::makeAny(nShapesCount));
830 
831     // update document statistics at the model
832     uno::Reference<document::XDocumentPropertiesSupplier> xPropSup(GetModel(),
833         uno::UNO_QUERY_THROW);
834     uno::Reference<document::XDocumentProperties> xDocProps(
835         xPropSup->getDocumentProperties());
836     if (xDocProps.is()) {
837         xDocProps->setDocumentStatistics(stats);
838     }
839 
840     // export document properties
841     SvXMLExport::_ExportMeta();
842 }
843 
_ExportFontDecls()844 void ScXMLExport::_ExportFontDecls()
845 {
846     GetFontAutoStylePool(); // make sure the pool is created
847     SvXMLExport::_ExportFontDecls();
848 }
849 
GetEndAddress(const uno::Reference<sheet::XSpreadsheet> & xTable,const sal_Int32)850 table::CellRangeAddress ScXMLExport::GetEndAddress(const uno::Reference<sheet::XSpreadsheet>& xTable, const sal_Int32 /* nTable */)
851 {
852     table::CellRangeAddress aCellAddress;
853     uno::Reference<sheet::XSheetCellCursor> xCursor(xTable->createCursor());
854     uno::Reference<sheet::XUsedAreaCursor> xUsedArea (xCursor, uno::UNO_QUERY);
855     uno::Reference<sheet::XCellRangeAddressable> xCellAddress (xCursor, uno::UNO_QUERY);
856     if (xUsedArea.is() && xCellAddress.is())
857     {
858         xUsedArea->gotoEndOfUsedArea(sal_True);
859         aCellAddress = xCellAddress->getRangeAddress();
860     }
861     return aCellAddress;
862 }
863 
GetAreaLinks(uno::Reference<sheet::XSpreadsheetDocument> & xSpreadDoc,ScMyAreaLinksContainer & rAreaLinks)864 void ScXMLExport::GetAreaLinks( uno::Reference< sheet::XSpreadsheetDocument>& xSpreadDoc,
865                                 ScMyAreaLinksContainer& rAreaLinks )
866 {
867     uno::Reference< beans::XPropertySet > xPropSet( xSpreadDoc, uno::UNO_QUERY );
868     if( !xPropSet.is() ) return;
869 
870     uno::Reference< container::XIndexAccess > xLinksIAccess( xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_AREALINKS ) ) ), uno::UNO_QUERY);
871     if( xLinksIAccess.is() )
872     {
873         const OUString sFilter( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_FILTER ) );
874         const OUString sFilterOpt( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_FILTOPT ) );
875         const OUString sURL( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_LINKURL ) );
876         const OUString sRefresh( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_REFDELAY ) );
877 
878         sal_Int32 nCount(xLinksIAccess->getCount());
879         for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
880         {
881             uno::Reference< sheet::XAreaLink > xAreaLink(xLinksIAccess->getByIndex( nIndex ), uno::UNO_QUERY);
882             if( xAreaLink.is() )
883             {
884                 ScMyAreaLink aAreaLink;
885                 aAreaLink.aDestRange = xAreaLink->getDestArea();
886                 aAreaLink.sSourceStr = xAreaLink->getSourceArea();
887                 uno::Reference< beans::XPropertySet > xLinkProp( xAreaLink, uno::UNO_QUERY );
888                 if( xLinkProp.is() )
889                 {
890                     xLinkProp->getPropertyValue( sFilter ) >>= aAreaLink.sFilter;
891                     xLinkProp->getPropertyValue( sFilterOpt ) >>= aAreaLink.sFilterOptions;
892                     xLinkProp->getPropertyValue( sURL ) >>= aAreaLink.sURL;
893                     xLinkProp->getPropertyValue( sRefresh ) >>= aAreaLink.nRefresh;
894                 }
895                 rAreaLinks.AddNewAreaLink( aAreaLink );
896             }
897         }
898     }
899     rAreaLinks.Sort();
900 }
901 
902 // core implementation
GetDetectiveOpList(ScMyDetectiveOpContainer & rDetOp)903 void ScXMLExport::GetDetectiveOpList( ScMyDetectiveOpContainer& rDetOp )
904 {
905     if (pDoc)
906     {
907         ScDetOpList* pOpList(pDoc->GetDetOpList());
908         if( pOpList )
909         {
910             sal_uInt32 nCount(pOpList->Count());
911             for( sal_uInt32 nIndex = 0; nIndex < nCount; ++nIndex )
912             {
913                 ScDetOpData* pDetData(pOpList->GetObject( static_cast<sal_uInt16>(nIndex) ));
914                 if( pDetData )
915                 {
916                     const ScAddress& rDetPos = pDetData->GetPos();
917                     SCTAB nTab = rDetPos.Tab();
918                     if ( nTab < pDoc->GetTableCount() )
919                     {
920                         rDetOp.AddOperation( pDetData->GetOperation(), rDetPos, nIndex );
921 
922                         // #123981# cells with detective operations are written even if empty
923                         pSharedData->SetLastColumn( nTab, rDetPos.Col() );
924                         pSharedData->SetLastRow( nTab, rDetPos.Row() );
925                     }
926                 }
927             }
928             rDetOp.Sort();
929         }
930     }
931 }
932 
WriteSingleColumn(const sal_Int32 nRepeatColumns,const sal_Int32 nStyleIndex,const sal_Int32 nIndex,const sal_Bool bIsAutoStyle,const sal_Bool bIsVisible)933 void ScXMLExport::WriteSingleColumn(const sal_Int32 nRepeatColumns, const sal_Int32 nStyleIndex,
934     const sal_Int32 nIndex, const sal_Bool bIsAutoStyle, const sal_Bool bIsVisible)
935 {
936     CheckAttrList();
937     AddAttribute(sAttrStyleName, *pColumnStyles->GetStyleNameByIndex(nStyleIndex));
938     if (!bIsVisible)
939         AddAttribute(XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_COLLAPSE);
940     if (nRepeatColumns > 1)
941     {
942         OUString sOUEndCol(OUString::valueOf(static_cast <sal_Int32> (nRepeatColumns)));
943         AddAttribute(sAttrColumnsRepeated, sOUEndCol);
944     }
945     if (nIndex != -1)
946         AddAttribute(XML_NAMESPACE_TABLE, XML_DEFAULT_CELL_STYLE_NAME, *pCellStyles->GetStyleNameByIndex(nIndex, bIsAutoStyle));
947     SvXMLElementExport aElemC(*this, sElemCol, sal_True, sal_True);
948 }
949 
WriteColumn(const sal_Int32 nColumn,const sal_Int32 nRepeatColumns,const sal_Int32 nStyleIndex,const sal_Bool bIsVisible)950 void ScXMLExport::WriteColumn(const sal_Int32 nColumn, const sal_Int32 nRepeatColumns,
951     const sal_Int32 nStyleIndex, const sal_Bool bIsVisible)
952 {
953     sal_Int32 nRepeat(1);
954     sal_Int32 nPrevIndex((*pDefaults->GetColDefaults())[nColumn].nIndex);
955     sal_Bool bPrevAutoStyle((*pDefaults->GetColDefaults())[nColumn].bIsAutoStyle);
956     for (sal_Int32 i = nColumn + 1; i < nColumn + nRepeatColumns; ++i)
957     {
958         if (((*pDefaults->GetColDefaults())[i].nIndex != nPrevIndex) ||
959             ((*pDefaults->GetColDefaults())[i].bIsAutoStyle != bPrevAutoStyle))
960         {
961             WriteSingleColumn(nRepeat, nStyleIndex, nPrevIndex, bPrevAutoStyle, bIsVisible);
962             nPrevIndex = (*pDefaults->GetColDefaults())[i].nIndex;
963             bPrevAutoStyle = (*pDefaults->GetColDefaults())[i].bIsAutoStyle;
964             nRepeat = 1;
965         }
966         else
967             ++nRepeat;
968     }
969     WriteSingleColumn(nRepeat, nStyleIndex, nPrevIndex, bPrevAutoStyle, bIsVisible);
970 }
971 
OpenHeaderColumn()972 void ScXMLExport::OpenHeaderColumn()
973 {
974     StartElement( XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS, sal_True );
975 }
976 
CloseHeaderColumn()977 void ScXMLExport::CloseHeaderColumn()
978 {
979     EndElement(XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS, sal_True);
980 }
981 
ExportColumns(const sal_Int32 nTable,const table::CellRangeAddress & aColumnHeaderRange,const sal_Bool bHasColumnHeader)982 void ScXMLExport::ExportColumns(const sal_Int32 nTable, const table::CellRangeAddress& aColumnHeaderRange, const sal_Bool bHasColumnHeader)
983 {
984     sal_Int32 nColsRepeated (1);
985     rtl::OUString sParent;
986     sal_Int32 nIndex;
987     sal_Int32 nPrevColumn(0);
988     sal_Bool bPrevIsVisible (sal_True);
989     sal_Bool bWasHeader (sal_False);
990     sal_Bool bIsHeader (sal_False);
991     sal_Bool bIsClosed (sal_True);
992     sal_Bool bIsFirst (sal_False);
993     sal_Int32 nPrevIndex (-1);
994     sal_Int32 nColumn;
995     for (nColumn = 0; nColumn <= pSharedData->GetLastColumn(nTable); ++nColumn)
996     {
997         CheckAttrList();
998         sal_Bool bIsVisible(sal_True);
999         nIndex = pColumnStyles->GetStyleNameIndex(nTable, nColumn, bIsVisible);
1000 
1001         bIsHeader = bHasColumnHeader && (aColumnHeaderRange.StartColumn <= nColumn) && (nColumn <= aColumnHeaderRange.EndColumn);
1002         if (bIsHeader != bWasHeader)
1003         {
1004             if (bIsHeader)
1005             {
1006                 bIsFirst = sal_False;
1007                 if (nColumn > 0)
1008                 {
1009                     WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible);
1010                     if (pGroupColumns->IsGroupEnd(nColumn - 1))
1011                         pGroupColumns->CloseGroups(nColumn - 1);
1012                 }
1013                 bPrevIsVisible = bIsVisible;
1014                 nPrevIndex = nIndex;
1015                 nPrevColumn = nColumn;
1016                 nColsRepeated = 1;
1017                 bIsFirst = sal_True;
1018                 if(pGroupColumns->IsGroupStart(nColumn))
1019                     pGroupColumns->OpenGroups(nColumn);
1020                 OpenHeaderColumn();
1021                 bWasHeader = sal_True;
1022                 bIsClosed = sal_False;
1023             }
1024             else
1025             {
1026                 WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible);
1027                 CloseHeaderColumn();
1028                 if (pGroupColumns->IsGroupEnd(nColumn - 1))
1029                     pGroupColumns->CloseGroups(nColumn - 1);
1030                 if(pGroupColumns->IsGroupStart(nColumn))
1031                     pGroupColumns->OpenGroups(nColumn);
1032                 bPrevIsVisible = bIsVisible;
1033                 nPrevIndex = nIndex;
1034                 nPrevColumn = nColumn;
1035                 nColsRepeated = 1;
1036                 bWasHeader = sal_False;
1037                 bIsClosed = sal_True;
1038             }
1039         }
1040         else if (nColumn == 0)
1041         {
1042             if (pGroupColumns->IsGroupStart(nColumn))
1043                 pGroupColumns->OpenGroups(nColumn);
1044             bPrevIsVisible = bIsVisible;
1045             nPrevIndex = nIndex;
1046             bIsFirst = sal_True;
1047         }
1048         else if ((bIsVisible == bPrevIsVisible) && (nIndex == nPrevIndex) &&
1049             !pGroupColumns->IsGroupStart(nColumn) && !pGroupColumns->IsGroupEnd(nColumn - 1))
1050             ++nColsRepeated;
1051         else
1052         {
1053             bIsFirst = sal_False;
1054             WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible);
1055             if (pGroupColumns->IsGroupEnd(nColumn - 1))
1056             {
1057                 if (bIsHeader)
1058                     CloseHeaderColumn();
1059                 pGroupColumns->CloseGroups(nColumn - 1);
1060                 if (bIsHeader)
1061                     OpenHeaderColumn();
1062             }
1063             if (pGroupColumns->IsGroupStart(nColumn))
1064             {
1065                 if (bIsHeader)
1066                     CloseHeaderColumn();
1067                 pGroupColumns->OpenGroups(nColumn);
1068                 if (bIsHeader)
1069                     OpenHeaderColumn();
1070             }
1071             bPrevIsVisible = bIsVisible;
1072             nPrevIndex = nIndex;
1073             nPrevColumn = nColumn;
1074             nColsRepeated = 1;
1075         }
1076     }
1077     //if (nColsRepeated > 1 || bIsFirst)
1078         WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible);
1079     if (!bIsClosed)
1080         CloseHeaderColumn();
1081     if (pGroupColumns->IsGroupEnd(nColumn - 1))
1082         pGroupColumns->CloseGroups(nColumn - 1);
1083 }
1084 
ExportExternalRefCacheStyles()1085 void ScXMLExport::ExportExternalRefCacheStyles()
1086 {
1087     sal_Int32 nEntryIndex = GetCellStylesPropertySetMapper()->FindEntryIndex(
1088         "NumberFormat", XML_NAMESPACE_STYLE, OUString::createFromAscii("data-style-name"));
1089 
1090     if (nEntryIndex < 0)
1091         // No entry index for the number format is found.
1092         return;
1093 
1094     ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
1095     if (!pRefMgr->hasExternalData())
1096         // No external reference data cached.
1097         return;
1098 
1099     // Export each unique number format used in the external ref cache.
1100     vector<sal_uInt32> aNumFmts;
1101     pRefMgr->getAllCachedNumberFormats(aNumFmts);
1102     const OUString aDefaultStyle = OUString::createFromAscii("Default").intern();
1103     for (vector<sal_uInt32>::const_iterator itr = aNumFmts.begin(), itrEnd = aNumFmts.end();
1104           itr != itrEnd; ++itr)
1105     {
1106         sal_Int32 nNumFmt = static_cast<sal_Int32>(*itr);
1107 
1108         addDataStyle(nNumFmt);
1109 
1110         uno::Any aVal;
1111         aVal <<= nNumFmt;
1112         vector<XMLPropertyState> aProps;
1113         aProps.push_back(XMLPropertyState(nEntryIndex, aVal));
1114         aVal <<= aDefaultStyle;
1115         aProps.push_back(XMLPropertyState(nEntryIndex, aVal));
1116 
1117         OUString aName;
1118         sal_Int32 nIndex;
1119         if (GetAutoStylePool()->Add(aName, XML_STYLE_FAMILY_TABLE_CELL, aDefaultStyle, aProps))
1120         {
1121             OUString* pTemp(new OUString(aName));
1122             if (!pCellStyles->AddStyleName(pTemp, nIndex, true))
1123                 delete pTemp;
1124         }
1125         else
1126         {
1127             sal_Bool bIsAuto;
1128             nIndex = pCellStyles->GetIndexOfStyleName(
1129                 aName, OUString::createFromAscii(XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX), bIsAuto);
1130         }
1131 
1132         // store the number format to index mapping for later use.
1133         aNumFmtIndexMap.insert(NumberFormatIndexMap::value_type(nNumFmt, nIndex));
1134     }
1135 }
1136 
WriteRowContent()1137 void ScXMLExport::WriteRowContent()
1138 {
1139     ScMyRowFormatRange aRange;
1140     sal_Int32 nIndex(-1);
1141 #ifdef DBG_UTIL
1142     sal_Int32 nPrevCol(0);
1143 #endif
1144     sal_Int32 nCols(0);
1145     sal_Int32 nPrevValidationIndex(-1);
1146     sal_Bool bIsAutoStyle(sal_True);
1147     sal_Bool bIsFirst(sal_True);
1148     while (pRowFormatRanges->GetNext(aRange))
1149     {
1150 #ifdef DBG_UTIL
1151         DBG_ASSERT(bIsFirst || (!bIsFirst && (nPrevCol + nCols == aRange.nStartColumn)), "here are some columns missing");
1152 #endif
1153         if (bIsFirst)
1154         {
1155             nIndex = aRange.nIndex;
1156             nPrevValidationIndex = aRange.nValidationIndex;
1157             bIsAutoStyle = aRange.bIsAutoStyle;
1158             nCols = aRange.nRepeatColumns;
1159             bIsFirst = sal_False;
1160 #ifdef DBG_UTIL
1161             nPrevCol = aRange.nStartColumn;
1162 #endif
1163         }
1164         else
1165         {
1166             if (((aRange.nIndex == nIndex && aRange.bIsAutoStyle == bIsAutoStyle) ||
1167                 (aRange.nIndex == nIndex && nIndex == -1)) &&
1168                 nPrevValidationIndex == aRange.nValidationIndex)
1169                 nCols += aRange.nRepeatColumns;
1170             else
1171             {
1172                 if (nIndex != -1)
1173                     AddAttribute(sAttrStyleName, *pCellStyles->GetStyleNameByIndex(nIndex, bIsAutoStyle));
1174                 if (nPrevValidationIndex > -1)
1175                     AddAttribute(XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION_NAME, pValidationsContainer->GetValidationName(nPrevValidationIndex));
1176                 if (nCols > 1)
1177                 {
1178                     rtl::OUStringBuffer aBuf;
1179                     GetMM100UnitConverter().convertNumber(aBuf, nCols);
1180                     AddAttribute(sAttrColumnsRepeated, aBuf.makeStringAndClear());
1181                 }
1182                 SvXMLElementExport aElemC(*this, sElemCell, sal_True, sal_True);
1183                 nIndex = aRange.nIndex;
1184                 bIsAutoStyle = aRange.bIsAutoStyle;
1185                 nCols = aRange.nRepeatColumns;
1186                 nPrevValidationIndex = aRange.nValidationIndex;
1187 #ifdef DBG_UTIL
1188                 nPrevCol = aRange.nStartColumn;
1189 #endif
1190             }
1191         }
1192     }
1193     if (!bIsFirst)
1194     {
1195         table::CellAddress aCellAddress;
1196         if (nIndex != -1)
1197             AddAttribute(sAttrStyleName, *pCellStyles->GetStyleNameByIndex(nIndex, bIsAutoStyle));
1198         if (nPrevValidationIndex > -1)
1199             AddAttribute(XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION_NAME, pValidationsContainer->GetValidationName(nPrevValidationIndex));
1200         if (nCols > 1)
1201         {
1202             rtl::OUStringBuffer aBuf;
1203             GetMM100UnitConverter().convertNumber(aBuf, nCols);
1204             AddAttribute(sAttrColumnsRepeated, aBuf.makeStringAndClear());
1205         }
1206         SvXMLElementExport aElemC(*this, sElemCell, sal_True, sal_True);
1207     }
1208 }
1209 
WriteRowStartTag(sal_Int32 nRow,const sal_Int32 nIndex,const sal_Int8 nFlag,const sal_Int32 nEqualRows)1210 void ScXMLExport::WriteRowStartTag(sal_Int32 nRow, const sal_Int32 nIndex,
1211     const sal_Int8 nFlag, const sal_Int32 nEqualRows)
1212 {
1213     AddAttribute(sAttrStyleName, *pRowStyles->GetStyleNameByIndex(nIndex));
1214     if (nFlag)
1215         if (nFlag & CR_HIDDEN)
1216         {
1217             if (nFlag & CR_FILTERED)
1218                 AddAttribute(XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_FILTER);
1219             else
1220                 AddAttribute(XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_COLLAPSE);
1221         }
1222     if (nEqualRows > 1)
1223     {
1224         rtl::OUStringBuffer aBuf;
1225         GetMM100UnitConverter().convertNumber(aBuf, nEqualRows);
1226         AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_REPEATED, aBuf.makeStringAndClear());
1227     }
1228 
1229     const ScMyDefaultStyleList& rRowDefaults = *pDefaults->GetRowDefaults();
1230     if ( nRow >= sal::static_int_cast<sal_Int32>( rRowDefaults.size() ) )
1231     {
1232         // #123981# used to happen with detective operations - if there are more cases, use the last row's style
1233         DBG_ERRORFILE("WriteRowStartTag: not enough defaults");
1234         nRow = rRowDefaults.size() - 1;
1235     }
1236     sal_Int32 nCellStyleIndex(rRowDefaults[nRow].nIndex);
1237     if (nCellStyleIndex != -1)
1238         AddAttribute(XML_NAMESPACE_TABLE, XML_DEFAULT_CELL_STYLE_NAME,
1239             *pCellStyles->GetStyleNameByIndex(nCellStyleIndex,
1240                 (*pDefaults->GetRowDefaults())[nRow].bIsAutoStyle));
1241     StartElement( sElemRow, sal_True);
1242 }
1243 
OpenHeaderRows()1244 void ScXMLExport::OpenHeaderRows()
1245 {
1246     StartElement( XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS, sal_True);
1247     bRowHeaderOpen = sal_True;
1248 }
1249 
CloseHeaderRows()1250 void ScXMLExport::CloseHeaderRows()
1251 {
1252     EndElement(XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS, sal_True);
1253 }
1254 
OpenNewRow(const sal_Int32 nIndex,const sal_Int8 nFlag,const sal_Int32 nStartRow,const sal_Int32 nEqualRows)1255 void ScXMLExport::OpenNewRow(const sal_Int32 nIndex, const sal_Int8 nFlag, const sal_Int32 nStartRow, const sal_Int32 nEqualRows)
1256 {
1257     nOpenRow = nStartRow;
1258     if (pGroupRows->IsGroupStart(nStartRow))
1259     {
1260         if (bHasRowHeader && bRowHeaderOpen)
1261             CloseHeaderRows();
1262         pGroupRows->OpenGroups(nStartRow);
1263         if (bHasRowHeader && bRowHeaderOpen)
1264             OpenHeaderRows();
1265     }
1266     if (bHasRowHeader && !bRowHeaderOpen && nStartRow >= aRowHeaderRange.StartRow && nStartRow <= aRowHeaderRange.EndRow)
1267     {
1268         if (nStartRow == aRowHeaderRange.StartRow)
1269             OpenHeaderRows();
1270         sal_Int32 nEquals;
1271         if (aRowHeaderRange.EndRow < nStartRow + nEqualRows - 1)
1272             nEquals = aRowHeaderRange.EndRow - nStartRow + 1;
1273         else
1274             nEquals = nEqualRows;
1275         WriteRowStartTag(nStartRow, nIndex, nFlag, nEquals);
1276         nOpenRow = nStartRow + nEquals - 1;
1277         if (nEquals < nEqualRows)
1278         {
1279             CloseRow(nStartRow + nEquals - 1);
1280             WriteRowStartTag(nStartRow, nIndex, nFlag, nEqualRows - nEquals);
1281             nOpenRow = nStartRow + nEqualRows - 1;
1282         }
1283     }
1284     else
1285         WriteRowStartTag(nStartRow, nIndex, nFlag, nEqualRows);
1286 }
1287 
OpenAndCloseRow(const sal_Int32 nIndex,const sal_Int8 nFlag,const sal_Int32 nStartRow,const sal_Int32 nEqualRows)1288 void ScXMLExport::OpenAndCloseRow(const sal_Int32 nIndex, const sal_Int8 nFlag,
1289     const sal_Int32 nStartRow, const sal_Int32 nEqualRows)
1290 {
1291     OpenNewRow(nIndex, nFlag, nStartRow, nEqualRows);
1292     WriteRowContent();
1293     CloseRow(nStartRow + nEqualRows - 1);
1294     pRowFormatRanges->Clear();
1295 }
1296 
OpenRow(const sal_Int32 nTable,const sal_Int32 nStartRow,const sal_Int32 nRepeatRow)1297 void ScXMLExport::OpenRow(const sal_Int32 nTable, const sal_Int32 nStartRow, const sal_Int32 nRepeatRow)
1298 {
1299     if (nRepeatRow > 1)
1300     {
1301         sal_Int32 nPrevIndex(0), nIndex;
1302         sal_Int8 nPrevFlag(0);
1303         sal_Int8 nFlag(0);
1304         sal_Int32 nEqualRows(1);
1305         sal_Int32 nEndRow(nStartRow + nRepeatRow);
1306         sal_Int32 nRow;
1307         for (nRow = nStartRow; nRow < nEndRow; ++nRow)
1308         {
1309             if (nRow == nStartRow)
1310             {
1311                 nPrevIndex = pRowStyles->GetStyleNameIndex(nTable, nRow);
1312                 if (pDoc)
1313                     nPrevFlag = (pDoc->GetRowFlags(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTable))) & (CR_HIDDEN | CR_FILTERED);
1314             }
1315             else
1316             {
1317                 nIndex = pRowStyles->GetStyleNameIndex(nTable, nRow);
1318                 if (pDoc)
1319                     nFlag = (pDoc->GetRowFlags(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTable))) & (CR_HIDDEN | CR_FILTERED);
1320                 if (nIndex == nPrevIndex && nFlag == nPrevFlag &&
1321                     !(bHasRowHeader && ((nRow == aRowHeaderRange.StartRow) || (nRow - 1 == aRowHeaderRange.EndRow))) &&
1322                     !(pGroupRows->IsGroupStart(nRow)) &&
1323                     !(pGroupRows->IsGroupEnd(nRow - 1)))
1324                     ++nEqualRows;
1325                 else
1326                 {
1327                     if (nRow < nEndRow)
1328                     {
1329                         ScRowFormatRanges* pTempRowFormatRanges = new ScRowFormatRanges(pRowFormatRanges);
1330                         OpenAndCloseRow(nPrevIndex, nPrevFlag, nRow - nEqualRows, nEqualRows);
1331                         delete pRowFormatRanges;
1332                         pRowFormatRanges = pTempRowFormatRanges;
1333                     }
1334                     else
1335                         OpenAndCloseRow(nPrevIndex, nPrevFlag, nRow - nEqualRows, nEqualRows);
1336                     nEqualRows = 1;
1337                     nPrevIndex = nIndex;
1338                     nPrevFlag = nFlag;
1339                 }
1340             }
1341         }
1342         OpenNewRow(nPrevIndex, nPrevFlag, nRow - nEqualRows, nEqualRows);
1343     }
1344     else
1345     {
1346         sal_Int32 nIndex = pRowStyles->GetStyleNameIndex(nTable, nStartRow);
1347         sal_Int8 nFlag(0);
1348         if (pDoc)
1349             nFlag = (pDoc->GetRowFlags(static_cast<SCROW>(nStartRow), static_cast<SCTAB>(nTable))) & (CR_HIDDEN | CR_FILTERED);
1350         OpenNewRow(nIndex, nFlag, nStartRow, 1);
1351     }
1352     nOpenRow = nStartRow + nRepeatRow - 1;
1353 }
1354 
CloseRow(const sal_Int32 nRow)1355 void ScXMLExport::CloseRow(const sal_Int32 nRow)
1356 {
1357     if (nOpenRow > -1)
1358     {
1359         EndElement(sElemRow, sal_True);
1360         if (bHasRowHeader && nRow == aRowHeaderRange.EndRow)
1361         {
1362             CloseHeaderRows();
1363             bRowHeaderOpen = sal_False;
1364         }
1365         if (pGroupRows->IsGroupEnd(nRow))
1366         {
1367             if (bHasRowHeader && bRowHeaderOpen)
1368                 CloseHeaderRows();
1369             pGroupRows->CloseGroups(nRow);
1370             if (bHasRowHeader && bRowHeaderOpen)
1371                 OpenHeaderRows();
1372         }
1373     }
1374     nOpenRow = -1;
1375 }
1376 
ExportFormatRanges(const sal_Int32 nStartCol,const sal_Int32 nStartRow,const sal_Int32 nEndCol,const sal_Int32 nEndRow,const sal_Int32 nSheet)1377 void ScXMLExport::ExportFormatRanges(const sal_Int32 nStartCol, const sal_Int32 nStartRow,
1378     const sal_Int32 nEndCol, const sal_Int32 nEndRow, const sal_Int32 nSheet)
1379 {
1380     pRowFormatRanges->Clear();
1381     if (nStartRow == nEndRow)
1382     {
1383         pCellStyles->GetFormatRanges(nStartCol, nEndCol, nStartRow, nSheet, pRowFormatRanges);
1384         if (nOpenRow == - 1)
1385             OpenRow(nSheet, nStartRow, 1);
1386         WriteRowContent();
1387         pRowFormatRanges->Clear();
1388     }
1389     else
1390     {
1391         if (nOpenRow > -1)
1392         {
1393             pCellStyles->GetFormatRanges(nStartCol, pSharedData->GetLastColumn(nSheet), nStartRow, nSheet, pRowFormatRanges);
1394             WriteRowContent();
1395             CloseRow(nStartRow);
1396             sal_Int32 nRows(1);
1397             sal_Int32 nTotalRows(nEndRow - nStartRow + 1 - 1);
1398             while (nRows < nTotalRows)
1399             {
1400                 pRowFormatRanges->Clear();
1401                 pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges);
1402                 sal_Int32 nMaxRows = pRowFormatRanges->GetMaxRows();
1403                 DBG_ASSERT(nMaxRows, "something wents wrong");
1404                 if (nMaxRows >= nTotalRows - nRows)
1405                 {
1406                     OpenRow(nSheet, nStartRow + nRows, nTotalRows - nRows);
1407                     nRows += nTotalRows - nRows;
1408                 }
1409                 else
1410                 {
1411                     OpenRow(nSheet, nStartRow + nRows, nMaxRows);
1412                     nRows += nMaxRows;
1413                 }
1414                 if (!pRowFormatRanges->GetSize())
1415                     pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges);
1416                 WriteRowContent();
1417                 CloseRow(nStartRow + nRows - 1);
1418             }
1419             if (nTotalRows == 1)
1420                 CloseRow(nStartRow);
1421             OpenRow(nSheet, nEndRow, 1);
1422             pRowFormatRanges->Clear();
1423             pCellStyles->GetFormatRanges(0, nEndCol, nEndRow, nSheet, pRowFormatRanges);
1424             WriteRowContent();
1425         }
1426         else
1427         {
1428             sal_Int32 nRows(0);
1429             sal_Int32 nTotalRows(nEndRow - nStartRow + 1 - 1);
1430             while (nRows < nTotalRows)
1431             {
1432                 pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges);
1433                 sal_Int32 nMaxRows = pRowFormatRanges->GetMaxRows();
1434                 if (nMaxRows >= nTotalRows - nRows)
1435                 {
1436                     OpenRow(nSheet, nStartRow + nRows, nTotalRows - nRows);
1437                     nRows += nTotalRows - nRows;
1438                 }
1439                 else
1440                 {
1441                     OpenRow(nSheet, nStartRow + nRows, nMaxRows);
1442                     nRows += nMaxRows;
1443                 }
1444                 if (!pRowFormatRanges->GetSize())
1445                     pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges);
1446                 WriteRowContent();
1447                 CloseRow(nStartRow + nRows - 1);
1448             }
1449             OpenRow(nSheet, nEndRow, 1);
1450             pRowFormatRanges->Clear();
1451             pCellStyles->GetFormatRanges(0, nEndCol, nEndRow, nSheet, pRowFormatRanges);
1452             WriteRowContent();
1453         }
1454     }
1455 }
1456 
GetColumnRowHeader(sal_Bool & rHasColumnHeader,table::CellRangeAddress & rColumnHeaderRange,sal_Bool & rHasRowHeader,table::CellRangeAddress & rRowHeaderRange,rtl::OUString & rPrintRanges) const1457 void ScXMLExport::GetColumnRowHeader(sal_Bool& rHasColumnHeader, table::CellRangeAddress& rColumnHeaderRange,
1458                                      sal_Bool& rHasRowHeader, table::CellRangeAddress& rRowHeaderRange,
1459                                      rtl::OUString& rPrintRanges) const
1460 {
1461     uno::Reference <sheet::XPrintAreas> xPrintAreas (xCurrentTable, uno::UNO_QUERY);
1462     if (xPrintAreas.is())
1463     {
1464         rHasRowHeader = xPrintAreas->getPrintTitleRows();
1465         rHasColumnHeader = xPrintAreas->getPrintTitleColumns();
1466         rRowHeaderRange = xPrintAreas->getTitleRows();
1467         rColumnHeaderRange = xPrintAreas->getTitleColumns();
1468         uno::Sequence< table::CellRangeAddress > aRangeList( xPrintAreas->getPrintAreas() );
1469         ScRangeStringConverter::GetStringFromRangeList( rPrintRanges, aRangeList, pDoc, FormulaGrammar::CONV_OOO );
1470     }
1471 }
1472 
FillFieldGroup(ScOutlineArray * pFields,ScMyOpenCloseColumnRowGroup * pGroups)1473 void ScXMLExport::FillFieldGroup(ScOutlineArray* pFields, ScMyOpenCloseColumnRowGroup* pGroups)
1474 {
1475     sal_Int32 nDepth(pFields->GetDepth());
1476     for(sal_Int32 i = 0; i < nDepth; ++i)
1477     {
1478         sal_Int32 nFields = pFields->GetCount(static_cast<sal_uInt16>(i));
1479         for (sal_Int32 j = 0; j < nFields; ++j)
1480         {
1481             ScMyColumnRowGroup aGroup;
1482             ScOutlineEntry* pEntry(pFields->GetEntry(static_cast<sal_uInt16>(i), static_cast<sal_uInt16>(j)));
1483             aGroup.nField = pEntry->GetStart();
1484             aGroup.nLevel = static_cast<sal_Int16>(i);
1485             aGroup.bDisplay = !(pEntry->IsHidden());
1486             pGroups->AddGroup(aGroup, pEntry->GetEnd());
1487         }
1488     }
1489     if (nDepth)
1490         pGroups->Sort();
1491 }
1492 
FillColumnRowGroups()1493 void ScXMLExport::FillColumnRowGroups()
1494 {
1495     if (pDoc)
1496     {
1497         ScOutlineTable* pOutlineTable = pDoc->GetOutlineTable( static_cast<SCTAB>(nCurrentTable), sal_False );
1498         if(pOutlineTable)
1499         {
1500             ScOutlineArray* pCols(pOutlineTable->GetColArray());
1501             ScOutlineArray* pRows(pOutlineTable->GetRowArray());
1502             if (pCols)
1503                 FillFieldGroup(pCols, pGroupColumns);
1504             if (pRows)
1505                 FillFieldGroup(pRows, pGroupRows);
1506             pSharedData->SetLastColumn(nCurrentTable, pGroupColumns->GetLast());
1507             pSharedData->SetLastRow(nCurrentTable, pGroupRows->GetLast());
1508         }
1509     }
1510 }
1511 
SetBodyAttributes()1512 void ScXMLExport::SetBodyAttributes()
1513 {
1514     if (pDoc && pDoc->IsDocProtected())
1515     {
1516         AddAttribute(XML_NAMESPACE_TABLE, XML_STRUCTURE_PROTECTED, XML_TRUE);
1517         rtl::OUStringBuffer aBuffer;
1518         uno::Sequence<sal_Int8> aPassHash;
1519         const ScDocProtection* p = pDoc->GetDocProtection();
1520         if (p)
1521             aPassHash = p->getPasswordHash(PASSHASH_OOO);
1522         SvXMLUnitConverter::encodeBase64(aBuffer, aPassHash);
1523         if (aBuffer.getLength())
1524             AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY, aBuffer.makeStringAndClear());
1525     }
1526 }
1527 
lcl_CopyStreamElement(const uno::Reference<io::XInputStream> & xInput,const uno::Reference<io::XOutputStream> & xOutput,sal_Int32 nCount)1528 static bool lcl_CopyStreamElement( const uno::Reference< io::XInputStream >& xInput,
1529                             const uno::Reference< io::XOutputStream >& xOutput,
1530                             sal_Int32 nCount )
1531 {
1532     const sal_Int32 nBufSize = 16*1024;
1533     uno::Sequence<sal_Int8> aSequence(nBufSize);
1534 
1535     sal_Int32 nRemaining = nCount;
1536     bool bFirst = true;
1537 
1538     while ( nRemaining > 0 )
1539     {
1540         sal_Int32 nRead = xInput->readBytes( aSequence, std::min( nRemaining, nBufSize ) );
1541         if (bFirst)
1542         {
1543             // safety check: Make sure the copied part actually points to the start of an element
1544             if ( nRead < 1 || aSequence[0] != static_cast<sal_Int8>('<') )
1545             {
1546                 return false;   // abort and set an error
1547             }
1548             bFirst = false;
1549         }
1550         if (nRead == nRemaining)
1551         {
1552             // safety check: Make sure the copied part also ends at the end of an element
1553             if ( aSequence[nRead-1] != static_cast<sal_Int8>('>') )
1554             {
1555                 return false;   // abort and set an error
1556             }
1557         }
1558 
1559         if ( nRead == nBufSize )
1560         {
1561             xOutput->writeBytes( aSequence );
1562             nRemaining -= nRead;
1563         }
1564         else
1565         {
1566             if ( nRead > 0 )
1567             {
1568                 uno::Sequence<sal_Int8> aTempBuf( aSequence.getConstArray(), nRead );
1569                 xOutput->writeBytes( aTempBuf );
1570             }
1571             nRemaining = 0;
1572         }
1573     }
1574     return true;    // successful
1575 }
1576 
lcl_SkipBytesInBlocks(const uno::Reference<io::XInputStream> & xInput,sal_Int32 nBytesToSkip)1577 static void lcl_SkipBytesInBlocks( const uno::Reference< io::XInputStream >& xInput, sal_Int32 nBytesToSkip )
1578 {
1579     // skipBytes in zip stream is implemented as reading.
1580     // For now, split into several calls to avoid allocating a large buffer.
1581     // Later, skipBytes should be changed.
1582 
1583     const sal_Int32 nMaxSize = 32*1024;
1584 
1585     if ( nBytesToSkip > 0 )
1586     {
1587         sal_Int32 nRemaining = nBytesToSkip;
1588         while ( nRemaining > 0 )
1589         {
1590             sal_Int32 nSkip = std::min( nRemaining, nMaxSize );
1591             xInput->skipBytes( nSkip );
1592             nRemaining -= nSkip;
1593         }
1594     }
1595 }
1596 
CopySourceStream(sal_Int32 nStartOffset,sal_Int32 nEndOffset,sal_Int32 & rNewStart,sal_Int32 & rNewEnd)1597 void ScXMLExport::CopySourceStream( sal_Int32 nStartOffset, sal_Int32 nEndOffset, sal_Int32& rNewStart, sal_Int32& rNewEnd )
1598 {
1599     uno::Reference<xml::sax::XDocumentHandler> xHandler = GetDocHandler();
1600     uno::Reference<io::XActiveDataSource> xDestSource( xHandler, uno::UNO_QUERY );
1601     if ( xDestSource.is() )
1602     {
1603         uno::Reference<io::XOutputStream> xDestStream = xDestSource->getOutputStream();
1604         uno::Reference<io::XSeekable> xDestSeek( xDestStream, uno::UNO_QUERY );
1605         if ( xDestSeek.is() )
1606         {
1607             // temporary: set same stream again to clear buffer
1608             xDestSource->setOutputStream( xDestStream );
1609 
1610             if ( getExportFlags() & EXPORT_PRETTY )
1611             {
1612                 ByteString aOutStr("\n   ");
1613                 uno::Sequence<sal_Int8> aOutSeq( (sal_Int8*)aOutStr.GetBuffer(), aOutStr.Len() );
1614                 xDestStream->writeBytes( aOutSeq );
1615             }
1616 
1617             rNewStart = (sal_Int32)xDestSeek->getPosition();
1618 
1619             if ( nStartOffset > nSourceStreamPos )
1620                 lcl_SkipBytesInBlocks( xSourceStream, nStartOffset - nSourceStreamPos );
1621 
1622             if ( !lcl_CopyStreamElement( xSourceStream, xDestStream, nEndOffset - nStartOffset ) )
1623             {
1624                 // If copying went wrong, set an error.
1625                 // ScXMLImportWrapper then resets all stream flags, so the next save attempt will use normal saving.
1626 
1627                 uno::Sequence<OUString> aEmptySeq;
1628                 SetError(XMLERROR_CANCEL|XMLERROR_FLAG_SEVERE, aEmptySeq);
1629             }
1630             nSourceStreamPos = nEndOffset;
1631 
1632             rNewEnd = (sal_Int32)xDestSeek->getPosition();
1633         }
1634     }
1635 }
1636 
_ExportContent()1637 void ScXMLExport::_ExportContent()
1638 {
1639     nCurrentTable = 0;
1640     if (!pSharedData)
1641     {
1642         sal_Int32 nTableCount(0);
1643         sal_Int32 nShapesCount(0);
1644         sal_Int32 nCellCount(pDoc ? pDoc->GetCellCount() : 0);
1645         CollectSharedData(nTableCount, nShapesCount, nCellCount);
1646         DBG_ERROR("no shared data setted");
1647     }
1648     ScXMLExportDatabaseRanges aExportDatabaseRanges(*this);
1649     if (!GetModel().is())
1650         return;
1651 
1652     uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY );
1653     if ( !xSpreadDoc.is() )
1654         return;
1655 
1656     ScSheetSaveData* pSheetData = ScModelObj::getImplementation(xSpreadDoc)->GetSheetSaveData();
1657     if (pSheetData)
1658         pSheetData->ResetSaveEntries();
1659 
1660     uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY );
1661     if ( xIndex.is() )
1662     {
1663         //_GetNamespaceMap().ClearQNamesCache();
1664         pChangeTrackingExportHelper->CollectAndWriteChanges();
1665         WriteCalculationSettings(xSpreadDoc);
1666         sal_Int32 nTableCount(xIndex->getCount());
1667         ScMyAreaLinksContainer aAreaLinks;
1668         GetAreaLinks( xSpreadDoc, aAreaLinks );
1669         ScMyEmptyDatabaseRangesContainer aEmptyRanges(aExportDatabaseRanges.GetEmptyDatabaseRanges());
1670         ScMyDetectiveOpContainer aDetectiveOpContainer;
1671         GetDetectiveOpList( aDetectiveOpContainer );
1672 
1673         pCellStyles->Sort();
1674         pMergedRangesContainer->Sort();
1675         pSharedData->GetDetectiveObjContainer()->Sort();
1676 
1677         pCellsItr->Clear();
1678         pCellsItr->SetShapes( pSharedData->GetShapesContainer() );
1679         pCellsItr->SetNoteShapes( pSharedData->GetNoteShapes() );
1680         pCellsItr->SetMergedRanges( pMergedRangesContainer );
1681         pCellsItr->SetAreaLinks( &aAreaLinks );
1682         pCellsItr->SetEmptyDatabaseRanges( &aEmptyRanges );
1683         pCellsItr->SetDetectiveObj( pSharedData->GetDetectiveObjContainer() );
1684         pCellsItr->SetDetectiveOp( &aDetectiveOpContainer );
1685 
1686         if (nTableCount > 0)
1687             pValidationsContainer->WriteValidations(*this);
1688         WriteTheLabelRanges( xSpreadDoc );
1689         for (sal_Int32 nTable = 0; nTable < nTableCount; ++nTable)
1690         {
1691             sal_Int32 nStartOffset = -1;
1692             sal_Int32 nEndOffset = -1;
1693             if (pSheetData && pDoc && pDoc->IsStreamValid((SCTAB)nTable))
1694                 pSheetData->GetStreamPos( nTable, nStartOffset, nEndOffset );
1695 
1696             if ( nStartOffset >= 0 && nEndOffset >= 0 && xSourceStream.is() )
1697             {
1698                 sal_Int32 nNewStart = -1;
1699                 sal_Int32 nNewEnd = -1;
1700                 CopySourceStream( nStartOffset, nEndOffset, nNewStart, nNewEnd );
1701 
1702                 // store position of copied sheet in output
1703                 pSheetData->AddSavePos( nTable, nNewStart, nNewEnd );
1704 
1705                 // skip iterator entries for this sheet
1706                 pCellsItr->SkipTable(static_cast<SCTAB>(nTable));
1707             }
1708             else
1709             {
1710                 uno::Reference<sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY);
1711                 if (xTable.is())
1712                 {
1713                     xCurrentTable.set(xTable);
1714                     xCurrentTableCellRange.set(xTable, uno::UNO_QUERY);
1715                     uno::Reference<container::XNamed> xName (xTable, uno::UNO_QUERY );
1716                     if ( xName.is() )
1717                     {
1718                         nCurrentTable = sal::static_int_cast<sal_uInt16>( nTable );
1719                         rtl::OUString sOUTableName(xName->getName());
1720                         AddAttribute(sAttrName, sOUTableName);
1721                         AddAttribute(sAttrStyleName, aTableStyles[nTable]);
1722 
1723                         uno::Reference<util::XProtectable> xProtectable (xTable, uno::UNO_QUERY);
1724                         if (xProtectable.is() && xProtectable->isProtected())
1725                         {
1726                             AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TRUE);
1727                             rtl::OUStringBuffer aBuffer;
1728                             if (pDoc)
1729                             {
1730                                 ScTableProtection* pProtect = pDoc->GetTabProtection(static_cast<SCTAB>(nTable));
1731                                 if (pProtect)
1732                                     SvXMLUnitConverter::encodeBase64(aBuffer, pProtect->getPasswordHash(PASSHASH_OOO));
1733                             }
1734                             if (aBuffer.getLength())
1735                                 AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY, aBuffer.makeStringAndClear());
1736                         }
1737                         rtl::OUString sPrintRanges;
1738                         table::CellRangeAddress aColumnHeaderRange;
1739                         sal_Bool bHasColumnHeader;
1740                         GetColumnRowHeader(bHasColumnHeader, aColumnHeaderRange, bHasRowHeader, aRowHeaderRange, sPrintRanges);
1741                         if( sPrintRanges.getLength() )
1742                             AddAttribute( XML_NAMESPACE_TABLE, XML_PRINT_RANGES, sPrintRanges );
1743                         else if (!pDoc->IsPrintEntireSheet(static_cast<SCTAB>(nTable)))
1744                             AddAttribute( XML_NAMESPACE_TABLE, XML_PRINT, XML_FALSE);
1745                         SvXMLElementExport aElemT(*this, sElemTab, sal_True, sal_True);
1746                         CheckAttrList();
1747 
1748                         if ( pDoc && pDoc->GetSheetEvents( static_cast<SCTAB>(nTable) ) &&
1749                              getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST )
1750                         {
1751                             // store sheet events
1752                             uno::Reference<document::XEventsSupplier> xSupplier(xTable, uno::UNO_QUERY);
1753                             uno::Reference<container::XNameAccess> xEvents(xSupplier->getEvents(), uno::UNO_QUERY);
1754                             GetEventExport().ExportExt( xEvents );
1755                         }
1756 
1757                         WriteTableSource();
1758                         WriteScenario();
1759                         uno::Reference<drawing::XDrawPage> xDrawPage;
1760                         if (pSharedData->HasForm(nTable, xDrawPage) && xDrawPage.is())
1761                         {
1762                             ::xmloff::OOfficeFormsExport aForms(*this);
1763                             GetFormExport()->exportForms( xDrawPage );
1764                             sal_Bool bRet(GetFormExport()->seekPage( xDrawPage ));
1765                             DBG_ASSERT( bRet, "OFormLayerXMLExport::seekPage failed!" );
1766                             (void)bRet;     // avoid warning in product version
1767                         }
1768                         if (pSharedData->HasDrawPage())
1769                         {
1770                             GetShapeExport()->seekShapes(uno::Reference<drawing::XShapes>(pSharedData->GetDrawPage(nTable), uno::UNO_QUERY));
1771                             WriteTableShapes();
1772                         }
1773                         table::CellRangeAddress aRange(GetEndAddress(xTable, nTable));
1774                         pSharedData->SetLastColumn(nTable, aRange.EndColumn);
1775                         pSharedData->SetLastRow(nTable, aRange.EndRow);
1776                         pCellsItr->SetCurrentTable(static_cast<SCTAB>(nTable), xCurrentTable);
1777                         pGroupColumns->NewTable();
1778                         pGroupRows->NewTable();
1779                         FillColumnRowGroups();
1780                         if (bHasColumnHeader)
1781                             pSharedData->SetLastColumn(nTable, aColumnHeaderRange.EndColumn);
1782                         bRowHeaderOpen = sal_False;
1783                         if (bHasRowHeader)
1784                             pSharedData->SetLastRow(nTable, aRowHeaderRange.EndRow);
1785                         pDefaults->FillDefaultStyles(nTable, pSharedData->GetLastRow(nTable),
1786                             pSharedData->GetLastColumn(nTable), pCellStyles, pDoc);
1787                         pRowFormatRanges->SetRowDefaults(pDefaults->GetRowDefaults());
1788                         pRowFormatRanges->SetColDefaults(pDefaults->GetColDefaults());
1789                         pCellStyles->SetRowDefaults(pDefaults->GetRowDefaults());
1790                         pCellStyles->SetColDefaults(pDefaults->GetColDefaults());
1791                         ExportColumns(nTable, aColumnHeaderRange, bHasColumnHeader);
1792                         sal_Bool bIsFirst(sal_True);
1793                         sal_Int32 nEqualCells(0);
1794                         ScMyCell aCell;
1795                         ScMyCell aPrevCell;
1796                         while(pCellsItr->GetNext(aCell, pCellStyles))
1797                         {
1798                             if (bIsFirst)
1799                             {
1800                                 ExportFormatRanges(0, 0, aCell.aCellAddress.Column - 1, aCell.aCellAddress.Row, nTable);
1801                                 aPrevCell = aCell;
1802                                 bIsFirst = sal_False;
1803                             }
1804                             else
1805                             {
1806                                 if ((aPrevCell.aCellAddress.Row == aCell.aCellAddress.Row) &&
1807                                     (aPrevCell.aCellAddress.Column + nEqualCells + 1 == aCell.aCellAddress.Column))
1808                                 {
1809                                     if(IsCellEqual(aPrevCell, aCell))
1810                                         ++nEqualCells;
1811                                     else
1812                                     {
1813                                         WriteCell(aPrevCell, nEqualCells);
1814                                         nEqualCells = 0;
1815                                         aPrevCell = aCell;
1816                                     }
1817                                 }
1818                                 else
1819                                 {
1820                                     WriteCell(aPrevCell, nEqualCells);
1821                                     ExportFormatRanges(aPrevCell.aCellAddress.Column + nEqualCells + 1, aPrevCell.aCellAddress.Row,
1822                                         aCell.aCellAddress.Column - 1, aCell.aCellAddress.Row, nTable);
1823                                     nEqualCells = 0;
1824                                     aPrevCell = aCell;
1825                                 }
1826                             }
1827                         }
1828                         if (!bIsFirst)
1829                         {
1830                             WriteCell(aPrevCell, nEqualCells);
1831                             ExportFormatRanges(aPrevCell.aCellAddress.Column + nEqualCells + 1, aPrevCell.aCellAddress.Row,
1832                                 pSharedData->GetLastColumn(nTable), pSharedData->GetLastRow(nTable), nTable);
1833                         }
1834                         else
1835                             ExportFormatRanges(0, 0, pSharedData->GetLastColumn(nTable), pSharedData->GetLastRow(nTable), nTable);
1836 
1837                         CloseRow(pSharedData->GetLastRow(nTable));
1838                         WriteNamedExpressions(xSpreadDoc, nTable);
1839                         nEqualCells = 0;
1840                     }
1841                 }
1842             }
1843 
1844             IncrementProgressBar(sal_False);
1845         }
1846     }
1847     WriteExternalRefCaches();
1848     WriteNamedExpressions(xSpreadDoc, MAXTABCOUNT);
1849     aExportDatabaseRanges.WriteDatabaseRanges(xSpreadDoc);
1850     ScXMLExportDataPilot aExportDataPilot(*this);
1851     aExportDataPilot.WriteDataPilots(xSpreadDoc);
1852     WriteConsolidation();
1853     ScXMLExportDDELinks aExportDDELinks(*this);
1854     aExportDDELinks.WriteDDELinks(xSpreadDoc);
1855     IncrementProgressBar(sal_True, 0);
1856     GetProgressBarHelper()->SetValue(GetProgressBarHelper()->GetReference());
1857 }
1858 
_ExportStyles(sal_Bool bUsed)1859 void ScXMLExport::_ExportStyles( sal_Bool bUsed )
1860 {
1861     if (!pSharedData)
1862     {
1863         sal_Int32 nTableCount(0);
1864         sal_Int32 nShapesCount(0);
1865         sal_Int32 nCellCount(pDoc ? pDoc->GetCellCount() : 0);
1866         CollectSharedData(nTableCount, nShapesCount, nCellCount);
1867         //DBG_ERROR("no shared data setted");
1868     }
1869     ScXMLStyleExport aStylesExp(*this, rtl::OUString(), GetAutoStylePool().get());
1870     if (GetModel().is())
1871     {
1872         uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY);
1873         if (xMultiServiceFactory.is())
1874         {
1875             uno::Reference <beans::XPropertySet> xProperties(xMultiServiceFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.Defaults"))), uno::UNO_QUERY);
1876             if (xProperties.is())
1877                 aStylesExp.exportDefaultStyle(xProperties, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME)), xCellStylesExportPropertySetMapper);
1878             if (pSharedData->HasShapes())
1879             {
1880                 GetShapeExport()->ExportGraphicDefaults();
1881 /*              xInterface = xMultiServiceFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.Defaults")));
1882                 uno::Reference <beans::XPropertySet> xDrawProperties(xInterface, uno::UNO_QUERY);
1883                 if (xDrawProperties.is())
1884                     aStylesExp.exportDefaultStyle(xDrawProperties, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_SD_GRAPHICS_NAME)), GetShapeExport()->CreateShapePropMapper(*this));*/
1885             }
1886         }
1887         uno::Reference <style::XStyleFamiliesSupplier> xStyleFamiliesSupplier (GetModel(), uno::UNO_QUERY);
1888         if (xStyleFamiliesSupplier.is())
1889         {
1890             uno::Reference <container::XNameAccess> xStylesFamilies(xStyleFamiliesSupplier->getStyleFamilies());
1891             if (xStylesFamilies.is())
1892             {
1893                 uno::Reference <container::XIndexAccess> xCellStyles(xStylesFamilies->getByName(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CellStyles"))), uno::UNO_QUERY);
1894                 if (xCellStyles.is())
1895                 {
1896                     sal_Int32 nCount(xCellStyles->getCount());
1897                     rtl::OUString sNumberFormat(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_NUMFMT));
1898                     for (sal_Int32 i = 0; i < nCount; ++i)
1899                     {
1900                         uno::Reference <beans::XPropertySet> xCellProperties(xCellStyles->getByIndex(i), uno::UNO_QUERY);
1901                         if (xCellProperties.is())
1902                         {
1903                             sal_Int32 nNumberFormat = 0;
1904                             if (xCellProperties->getPropertyValue(sNumberFormat) >>= nNumberFormat)
1905                                 addDataStyle(nNumberFormat);
1906                         }
1907                     }
1908                 }
1909             }
1910         }
1911     }
1912     exportDataStyles();
1913 
1914     aStylesExp.exportStyleFamily(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CellStyles")),
1915         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME)), xCellStylesExportPropertySetMapper, sal_False, XML_STYLE_FAMILY_TABLE_CELL);
1916 
1917     SvXMLExport::_ExportStyles(bUsed);
1918 }
1919 
AddStyleFromCells(const uno::Reference<beans::XPropertySet> & xProperties,const uno::Reference<sheet::XSpreadsheet> & xTable,sal_Int32 nTable,const rtl::OUString * pOldName)1920 void ScXMLExport::AddStyleFromCells(const uno::Reference<beans::XPropertySet>& xProperties,
1921                                     const uno::Reference<sheet::XSpreadsheet>& xTable,
1922                                     sal_Int32 nTable, const rtl::OUString* pOldName)
1923 {
1924     //! pass xCellRanges instead
1925     uno::Reference<sheet::XSheetCellRanges> xCellRanges( xProperties, uno::UNO_QUERY );
1926 
1927     rtl::OUString SC_SCELLPREFIX(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX));
1928     rtl::OUString SC_NUMBERFORMAT(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_NUMFMT));
1929 
1930     rtl::OUString sStyleName;
1931     sal_Int32 nNumberFormat(-1);
1932     sal_Int32 nValidationIndex(-1);
1933     std::vector< XMLPropertyState > xPropStates(xCellStylesExportPropertySetMapper->Filter( xProperties ));
1934     std::vector< XMLPropertyState >::iterator aItr(xPropStates.begin());
1935     std::vector< XMLPropertyState >::iterator aEndItr(xPropStates.end());
1936     sal_Int32 nCount(0);
1937     while (aItr != aEndItr)
1938     {
1939         if (aItr->mnIndex != -1)
1940         {
1941             switch (xCellStylesPropertySetMapper->GetEntryContextId(aItr->mnIndex))
1942             {
1943                 case CTF_SC_VALIDATION :
1944                 {
1945                     pValidationsContainer->AddValidation(aItr->maValue, nValidationIndex);
1946                     // this is not very slow, because it is most the last property or
1947                     // if it is not the last property it is the property before the last property,
1948                     // so in the worst case only one property has to be copied, but in the best case no
1949                     // property has to be copied
1950                     aItr = xPropStates.erase(aItr);
1951                     aEndItr = xPropStates.end();    // #120346# old aEndItr is invalidated!
1952                 }
1953                 break;
1954                 case CTF_SC_CELLSTYLE :
1955                 {
1956                     aItr->maValue >>= sStyleName;
1957                     aItr->mnIndex = -1;
1958                     ++aItr;
1959                     ++nCount;
1960                 }
1961                 break;
1962                 case CTF_SC_NUMBERFORMAT :
1963                 {
1964                     if (aItr->maValue >>= nNumberFormat)
1965                         addDataStyle(nNumberFormat);
1966                     ++aItr;
1967                     ++nCount;
1968                 }
1969                 break;
1970                 default:
1971                 {
1972                     ++aItr;
1973                     ++nCount;
1974                 }
1975                 break;
1976             }
1977         }
1978         else
1979         {
1980             ++aItr;
1981             ++nCount;
1982         }
1983     }
1984     if (nCount == 1) // this is the CellStyle and should be removed if alone
1985         xPropStates.clear();
1986     if (nNumberFormat == -1)
1987         xProperties->getPropertyValue(SC_NUMBERFORMAT) >>= nNumberFormat;
1988     if (sStyleName.getLength())
1989     {
1990         if (xPropStates.size())
1991         {
1992             sal_Int32 nIndex;
1993             if (pOldName)
1994             {
1995                 if (GetAutoStylePool()->AddNamed(*pOldName, XML_STYLE_FAMILY_TABLE_CELL, sStyleName, xPropStates))
1996                 {
1997                     GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_CELL, *pOldName);
1998                     // add to pCellStyles, so the name is found for normal sheets
1999                     rtl::OUString* pTemp(new rtl::OUString(*pOldName));
2000                     if (!pCellStyles->AddStyleName(pTemp, nIndex))
2001                         delete pTemp;
2002                 }
2003             }
2004             else
2005             {
2006                 rtl::OUString sName;
2007                 sal_Bool bIsAutoStyle(sal_True);
2008                 if (GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_CELL, sStyleName, xPropStates))
2009                 {
2010                     rtl::OUString* pTemp(new rtl::OUString(sName));
2011                     if (!pCellStyles->AddStyleName(pTemp, nIndex))
2012                         delete pTemp;
2013                 }
2014                 else
2015                     nIndex = pCellStyles->GetIndexOfStyleName(sName, SC_SCELLPREFIX, bIsAutoStyle);
2016 
2017                 uno::Sequence<table::CellRangeAddress> aAddresses(xCellRanges->getRangeAddresses());
2018                 table::CellRangeAddress* pAddresses(aAddresses.getArray());
2019                 sal_Bool bGetMerge(sal_True);
2020                 for (sal_Int32 i = 0; i < aAddresses.getLength(); ++i, ++pAddresses)
2021                 {
2022                     pSharedData->SetLastColumn(nTable, pAddresses->EndColumn);
2023                     pSharedData->SetLastRow(nTable, pAddresses->EndRow);
2024                     pCellStyles->AddRangeStyleName(*pAddresses, nIndex, bIsAutoStyle, nValidationIndex, nNumberFormat);
2025                     if (bGetMerge)
2026                         bGetMerge = GetMerged(pAddresses, xTable);
2027                 }
2028             }
2029         }
2030         else
2031         {
2032             rtl::OUString* pTemp(new rtl::OUString(EncodeStyleName(sStyleName)));
2033             sal_Int32 nIndex(0);
2034             if (!pCellStyles->AddStyleName(pTemp, nIndex, sal_False))
2035             {
2036                 delete pTemp;
2037                 pTemp = NULL;
2038             }
2039             if ( !pOldName )
2040             {
2041                 uno::Sequence<table::CellRangeAddress> aAddresses(xCellRanges->getRangeAddresses());
2042                 table::CellRangeAddress* pAddresses(aAddresses.getArray());
2043                 sal_Bool bGetMerge(sal_True);
2044                 for (sal_Int32 i = 0; i < aAddresses.getLength(); ++i, ++pAddresses)
2045                 {
2046                     if (bGetMerge)
2047                         bGetMerge = GetMerged(pAddresses, xTable);
2048                     pCellStyles->AddRangeStyleName(*pAddresses, nIndex, sal_False, nValidationIndex, nNumberFormat);
2049                     if (!sStyleName.equalsAsciiL("Default", 7) || nValidationIndex != -1)
2050                     {
2051                         pSharedData->SetLastColumn(nTable, pAddresses->EndColumn);
2052                         pSharedData->SetLastRow(nTable, pAddresses->EndRow);
2053                     }
2054                 }
2055             }
2056         }
2057     }
2058 }
2059 
AddStyleFromColumn(const uno::Reference<beans::XPropertySet> & xColumnProperties,const rtl::OUString * pOldName,sal_Int32 & rIndex,sal_Bool & rIsVisible)2060 void ScXMLExport::AddStyleFromColumn(const uno::Reference<beans::XPropertySet>& xColumnProperties,
2061                                      const rtl::OUString* pOldName, sal_Int32& rIndex, sal_Bool& rIsVisible)
2062 {
2063     rtl::OUString SC_SCOLUMNPREFIX(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX));
2064 
2065     std::vector<XMLPropertyState> xPropStates(xColumnStylesExportPropertySetMapper->Filter(xColumnProperties));
2066     if(xPropStates.size())
2067     {
2068         std::vector< XMLPropertyState >::iterator aItr(xPropStates.begin());
2069         std::vector< XMLPropertyState >::iterator aEndItr(xPropStates.end());
2070         while (aItr != aEndItr)
2071         {
2072             if (xColumnStylesPropertySetMapper->GetEntryContextId(aItr->mnIndex) == CTF_SC_ISVISIBLE)
2073             {
2074                 aItr->maValue >>= rIsVisible;
2075                 break;
2076             }
2077             ++aItr;
2078         }
2079 
2080         rtl::OUString sParent;
2081         if (pOldName)
2082         {
2083             if (GetAutoStylePool()->AddNamed(*pOldName, XML_STYLE_FAMILY_TABLE_COLUMN, sParent, xPropStates))
2084             {
2085                 GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_COLUMN, *pOldName);
2086                 // add to pColumnStyles, so the name is found for normal sheets
2087                 rtl::OUString* pTemp(new rtl::OUString(*pOldName));
2088                 rIndex = pColumnStyles->AddStyleName(pTemp);
2089             }
2090         }
2091         else
2092         {
2093             rtl::OUString sName;
2094             if (GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_COLUMN, sParent, xPropStates))
2095             {
2096                 rtl::OUString* pTemp(new rtl::OUString(sName));
2097                 rIndex = pColumnStyles->AddStyleName(pTemp);
2098             }
2099             else
2100                 rIndex = pColumnStyles->GetIndexOfStyleName(sName, SC_SCOLUMNPREFIX);
2101         }
2102     }
2103 }
2104 
AddStyleFromRow(const uno::Reference<beans::XPropertySet> & xRowProperties,const rtl::OUString * pOldName,sal_Int32 & rIndex)2105 void ScXMLExport::AddStyleFromRow(const uno::Reference<beans::XPropertySet>& xRowProperties,
2106                                   const rtl::OUString* pOldName, sal_Int32& rIndex)
2107 {
2108     rtl::OUString SC_SROWPREFIX(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX));
2109 
2110     std::vector<XMLPropertyState> xPropStates(xRowStylesExportPropertySetMapper->Filter(xRowProperties));
2111     if(xPropStates.size())
2112     {
2113         rtl::OUString sParent;
2114         if (pOldName)
2115         {
2116             if (GetAutoStylePool()->AddNamed(*pOldName, XML_STYLE_FAMILY_TABLE_ROW, sParent, xPropStates))
2117             {
2118                 GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_ROW, *pOldName);
2119                 // add to pRowStyles, so the name is found for normal sheets
2120                 rtl::OUString* pTemp(new rtl::OUString(*pOldName));
2121                 rIndex = pRowStyles->AddStyleName(pTemp);
2122             }
2123         }
2124         else
2125         {
2126             rtl::OUString sName;
2127             if (GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_ROW, sParent, xPropStates))
2128             {
2129                 rtl::OUString* pTemp(new rtl::OUString(sName));
2130                 rIndex = pRowStyles->AddStyleName(pTemp);
2131             }
2132             else
2133                 rIndex = pRowStyles->GetIndexOfStyleName(sName, SC_SROWPREFIX);
2134         }
2135     }
2136 }
2137 
lcl_GetEnumerated(uno::Reference<container::XEnumerationAccess> xEnumAccess,sal_Int32 nIndex)2138 uno::Any lcl_GetEnumerated( uno::Reference<container::XEnumerationAccess> xEnumAccess, sal_Int32 nIndex )
2139 {
2140     uno::Any aRet;
2141     uno::Reference<container::XEnumeration> xEnum( xEnumAccess->createEnumeration() );
2142     try
2143     {
2144         sal_Int32 nSkip = nIndex;
2145         while ( nSkip > 0 )
2146         {
2147             (void) xEnum->nextElement();
2148             --nSkip;
2149         }
2150         aRet = xEnum->nextElement();
2151     }
2152     catch (container::NoSuchElementException&)
2153     {
2154         // leave aRet empty
2155     }
2156     return aRet;
2157 }
2158 
_ExportAutoStyles()2159 void ScXMLExport::_ExportAutoStyles()
2160 {
2161     if (!GetModel().is())
2162         return;
2163 
2164     uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY );
2165     if (!xSpreadDoc.is())
2166         return;
2167 
2168     uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY );
2169     if (!xIndex.is())
2170         return;
2171 
2172     if (getExportFlags() & EXPORT_CONTENT)
2173     {
2174         //  re-create automatic styles with old names from stored data
2175         ScSheetSaveData* pSheetData = ScModelObj::getImplementation(xSpreadDoc)->GetSheetSaveData();
2176         if (pSheetData && pDoc)
2177         {
2178             // formulas have to be calculated now, to detect changed results
2179             // (during normal save, they will be calculated anyway)
2180             SCTAB nTabCount = pDoc->GetTableCount();
2181             for (SCTAB nTab=0; nTab<nTabCount; ++nTab)
2182                 if (pDoc->IsStreamValid(nTab))
2183                 {
2184                     ScCellIterator aIter( pDoc, 0,0,nTab, MAXCOL,MAXROW,nTab );
2185                     ScBaseCell* pCell = aIter.GetFirst();
2186                     while (pCell)
2187                     {
2188                         if (pCell->GetCellType() == CELLTYPE_FORMULA)
2189                             static_cast<ScFormulaCell*>(pCell)->IsValue();      // interpret if dirty
2190                         pCell = aIter.GetNext();
2191                     }
2192                 }
2193 
2194             // stored cell styles
2195             const std::vector<ScCellStyleEntry>& rCellEntries = pSheetData->GetCellStyles();
2196             std::vector<ScCellStyleEntry>::const_iterator aCellIter = rCellEntries.begin();
2197             std::vector<ScCellStyleEntry>::const_iterator aCellEnd = rCellEntries.end();
2198             while (aCellIter != aCellEnd)
2199             {
2200                 ScAddress aPos = aCellIter->maCellPos;
2201                 sal_Int32 nTable = aPos.Tab();
2202                 bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
2203                 if (bCopySheet)
2204                 {
2205                     uno::Reference <sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY);
2206                     uno::Reference <beans::XPropertySet> xProperties(
2207                         xTable->getCellByPosition( aPos.Col(), aPos.Row() ), uno::UNO_QUERY );
2208 
2209                     AddStyleFromCells(xProperties, xTable, nTable, &aCellIter->maName);
2210                 }
2211                 ++aCellIter;
2212             }
2213 
2214             // stored column styles
2215             const std::vector<ScCellStyleEntry>& rColumnEntries = pSheetData->GetColumnStyles();
2216             std::vector<ScCellStyleEntry>::const_iterator aColumnIter = rColumnEntries.begin();
2217             std::vector<ScCellStyleEntry>::const_iterator aColumnEnd = rColumnEntries.end();
2218             while (aColumnIter != aColumnEnd)
2219             {
2220                 ScAddress aPos = aColumnIter->maCellPos;
2221                 sal_Int32 nTable = aPos.Tab();
2222                 bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
2223                 if (bCopySheet)
2224                 {
2225                     uno::Reference<table::XColumnRowRange> xColumnRowRange(xIndex->getByIndex(nTable), uno::UNO_QUERY);
2226                     uno::Reference<table::XTableColumns> xTableColumns(xColumnRowRange->getColumns());
2227                     uno::Reference<beans::XPropertySet> xColumnProperties(xTableColumns->getByIndex( aPos.Col() ), uno::UNO_QUERY);
2228 
2229                     sal_Int32 nIndex(-1);
2230                     sal_Bool bIsVisible(sal_True);
2231                     AddStyleFromColumn( xColumnProperties, &aColumnIter->maName, nIndex, bIsVisible );
2232                 }
2233                 ++aColumnIter;
2234             }
2235 
2236             // stored row styles
2237             const std::vector<ScCellStyleEntry>& rRowEntries = pSheetData->GetRowStyles();
2238             std::vector<ScCellStyleEntry>::const_iterator aRowIter = rRowEntries.begin();
2239             std::vector<ScCellStyleEntry>::const_iterator aRowEnd = rRowEntries.end();
2240             while (aRowIter != aRowEnd)
2241             {
2242                 ScAddress aPos = aRowIter->maCellPos;
2243                 sal_Int32 nTable = aPos.Tab();
2244                 bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
2245                 if (bCopySheet)
2246                 {
2247                     uno::Reference<table::XColumnRowRange> xColumnRowRange(xIndex->getByIndex(nTable), uno::UNO_QUERY);
2248                     uno::Reference<table::XTableRows> xTableRows(xColumnRowRange->getRows());
2249                     uno::Reference<beans::XPropertySet> xRowProperties(xTableRows->getByIndex( aPos.Row() ), uno::UNO_QUERY);
2250 
2251                     sal_Int32 nIndex(-1);
2252                     AddStyleFromRow( xRowProperties, &aRowIter->maName, nIndex );
2253                 }
2254                 ++aRowIter;
2255             }
2256 
2257             // stored table styles
2258             const std::vector<ScCellStyleEntry>& rTableEntries = pSheetData->GetTableStyles();
2259             std::vector<ScCellStyleEntry>::const_iterator aTableIter = rTableEntries.begin();
2260             std::vector<ScCellStyleEntry>::const_iterator aTableEnd = rTableEntries.end();
2261             while (aTableIter != aTableEnd)
2262             {
2263                 ScAddress aPos = aTableIter->maCellPos;
2264                 sal_Int32 nTable = aPos.Tab();
2265                 bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
2266                 if (bCopySheet)
2267                 {
2268                     //! separate method AddStyleFromTable needed?
2269                     uno::Reference<beans::XPropertySet> xTableProperties(xIndex->getByIndex(nTable), uno::UNO_QUERY);
2270                     if (xTableProperties.is())
2271                     {
2272                         std::vector<XMLPropertyState> xPropStates(xTableStylesExportPropertySetMapper->Filter(xTableProperties));
2273                         rtl::OUString sParent;
2274                         rtl::OUString sName( aTableIter->maName );
2275                         GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TABLE_TABLE, sParent, xPropStates);
2276                         GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_TABLE, sName);
2277                     }
2278                 }
2279                 ++aTableIter;
2280             }
2281 
2282             // stored styles for notes
2283 
2284             UniReference<SvXMLExportPropertyMapper> xShapeMapper = XMLShapeExport::CreateShapePropMapper( *this );
2285             GetShapeExport(); // make sure the graphics styles family is added
2286 
2287             const std::vector<ScNoteStyleEntry>& rNoteEntries = pSheetData->GetNoteStyles();
2288             std::vector<ScNoteStyleEntry>::const_iterator aNoteIter = rNoteEntries.begin();
2289             std::vector<ScNoteStyleEntry>::const_iterator aNoteEnd = rNoteEntries.end();
2290             while (aNoteIter != aNoteEnd)
2291             {
2292                 ScAddress aPos = aNoteIter->maCellPos;
2293                 sal_Int32 nTable = aPos.Tab();
2294                 bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
2295                 if (bCopySheet)
2296                 {
2297                     //! separate method AddStyleFromNote needed?
2298 
2299                     ScPostIt* pNote = pDoc->GetNote( aPos );
2300                     DBG_ASSERT( pNote, "note not found" );
2301                     if (pNote)
2302                     {
2303                         SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos );
2304                         // all uno shapes are created anyway in CollectSharedData
2305                         uno::Reference<beans::XPropertySet> xShapeProperties( pDrawObj->getUnoShape(), uno::UNO_QUERY );
2306                         if (xShapeProperties.is())
2307                         {
2308                             if ( aNoteIter->maStyleName.getLength() )
2309                             {
2310                                 std::vector<XMLPropertyState> xPropStates(xShapeMapper->Filter(xShapeProperties));
2311                                 rtl::OUString sParent;
2312                                 rtl::OUString sName( aNoteIter->maStyleName );
2313                                 GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_SD_GRAPHICS_ID, sParent, xPropStates);
2314                                 GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_SD_GRAPHICS_ID, sName);
2315                             }
2316                             if ( aNoteIter->maTextStyle.getLength() )
2317                             {
2318                                 std::vector<XMLPropertyState> xPropStates(
2319                                     GetTextParagraphExport()->GetParagraphPropertyMapper()->Filter(xShapeProperties));
2320                                 rtl::OUString sParent;
2321                                 rtl::OUString sName( aNoteIter->maTextStyle );
2322                                 GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_PARAGRAPH, sParent, xPropStates);
2323                                 GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_PARAGRAPH, sName);
2324                             }
2325                         }
2326                     }
2327                 }
2328                 ++aNoteIter;
2329             }
2330 
2331             // note paragraph styles
2332 
2333             //UniReference<SvXMLExportPropertyMapper> xParaPropMapper = XMLTextParagraphExport::CreateParaExtPropMapper( *this );
2334             UniReference<SvXMLExportPropertyMapper> xParaPropMapper = GetTextParagraphExport()->GetParagraphPropertyMapper();
2335 
2336             const std::vector<ScTextStyleEntry>& rNoteParaEntries = pSheetData->GetNoteParaStyles();
2337             std::vector<ScTextStyleEntry>::const_iterator aNoteParaIter = rNoteParaEntries.begin();
2338             std::vector<ScTextStyleEntry>::const_iterator aNoteParaEnd = rNoteParaEntries.end();
2339             while (aNoteParaIter != aNoteParaEnd)
2340             {
2341                 ScAddress aPos = aNoteParaIter->maCellPos;
2342                 sal_Int32 nTable = aPos.Tab();
2343                 bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
2344                 if (bCopySheet)
2345                 {
2346                     ScPostIt* pNote = pDoc->GetNote( aPos );
2347                     DBG_ASSERT( pNote, "note not found" );
2348                     if (pNote)
2349                     {
2350                         SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos );
2351                         uno::Reference<container::XEnumerationAccess> xCellText(pDrawObj->getUnoShape(), uno::UNO_QUERY);
2352                         uno::Reference<beans::XPropertySet> xParaProp(
2353                             lcl_GetEnumerated( xCellText, aNoteParaIter->maSelection.nStartPara ), uno::UNO_QUERY );
2354                         if ( xParaProp.is() )
2355                         {
2356                             std::vector<XMLPropertyState> xPropStates(xParaPropMapper->Filter(xParaProp));
2357                             rtl::OUString sParent;
2358                             rtl::OUString sName( aNoteParaIter->maName );
2359                             GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_PARAGRAPH, sParent, xPropStates);
2360                             GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_PARAGRAPH, sName);
2361                         }
2362                     }
2363                 }
2364                 ++aNoteParaIter;
2365             }
2366 
2367             // note text styles
2368 
2369             UniReference<SvXMLExportPropertyMapper> xTextPropMapper = XMLTextParagraphExport::CreateCharExtPropMapper( *this );
2370 
2371             const std::vector<ScTextStyleEntry>& rNoteTextEntries = pSheetData->GetNoteTextStyles();
2372             std::vector<ScTextStyleEntry>::const_iterator aNoteTextIter = rNoteTextEntries.begin();
2373             std::vector<ScTextStyleEntry>::const_iterator aNoteTextEnd = rNoteTextEntries.end();
2374             while (aNoteTextIter != aNoteTextEnd)
2375             {
2376                 ScAddress aPos = aNoteTextIter->maCellPos;
2377                 sal_Int32 nTable = aPos.Tab();
2378                 bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
2379                 if (bCopySheet)
2380                 {
2381                     ScPostIt* pNote = pDoc->GetNote( aPos );
2382                     DBG_ASSERT( pNote, "note not found" );
2383                     if (pNote)
2384                     {
2385                         SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos );
2386                         uno::Reference<text::XSimpleText> xCellText(pDrawObj->getUnoShape(), uno::UNO_QUERY);
2387                         uno::Reference<beans::XPropertySet> xCursorProp(xCellText->createTextCursor(), uno::UNO_QUERY);
2388                         ScDrawTextCursor* pCursor = ScDrawTextCursor::getImplementation( xCursorProp );
2389                         if (pCursor)
2390                         {
2391                             pCursor->SetSelection( aNoteTextIter->maSelection );
2392 
2393                             std::vector<XMLPropertyState> xPropStates(xTextPropMapper->Filter(xCursorProp));
2394                             rtl::OUString sParent;
2395                             rtl::OUString sName( aNoteTextIter->maName );
2396                             GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_TEXT, sParent, xPropStates);
2397                             GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_TEXT, sName);
2398                         }
2399                     }
2400                 }
2401                 ++aNoteTextIter;
2402             }
2403 
2404             // stored text styles
2405 
2406             //UniReference<SvXMLExportPropertyMapper> xTextPropMapper = XMLTextParagraphExport::CreateCharExtPropMapper( *this );
2407 
2408             const std::vector<ScTextStyleEntry>& rTextEntries = pSheetData->GetTextStyles();
2409             std::vector<ScTextStyleEntry>::const_iterator aTextIter = rTextEntries.begin();
2410             std::vector<ScTextStyleEntry>::const_iterator aTextEnd = rTextEntries.end();
2411             while (aTextIter != aTextEnd)
2412             {
2413                 ScAddress aPos = aTextIter->maCellPos;
2414                 sal_Int32 nTable = aPos.Tab();
2415                 bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
2416                 if (bCopySheet)
2417                 {
2418                     //! separate method AddStyleFromText needed?
2419                     //! cache sheet object
2420 
2421                     uno::Reference<table::XCellRange> xCellRange(xIndex->getByIndex(nTable), uno::UNO_QUERY);
2422                     uno::Reference<text::XSimpleText> xCellText(xCellRange->getCellByPosition(aPos.Col(), aPos.Row()), uno::UNO_QUERY);
2423                     uno::Reference<beans::XPropertySet> xCursorProp(xCellText->createTextCursor(), uno::UNO_QUERY);
2424                     ScCellTextCursor* pCursor = ScCellTextCursor::getImplementation( xCursorProp );
2425                     if (pCursor)
2426                     {
2427                         pCursor->SetSelection( aTextIter->maSelection );
2428 
2429                         std::vector<XMLPropertyState> xPropStates(xTextPropMapper->Filter(xCursorProp));
2430                         rtl::OUString sParent;
2431                         rtl::OUString sName( aTextIter->maName );
2432                         GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_TEXT, sParent, xPropStates);
2433                         GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_TEXT, sName);
2434                     }
2435                 }
2436                 ++aTextIter;
2437             }
2438         }
2439 
2440         ExportExternalRefCacheStyles();
2441 
2442         if (!pSharedData)
2443         {
2444             sal_Int32 nTableCount(0);
2445             sal_Int32 nShapesCount(0);
2446             sal_Int32 nCellCount(pDoc ? pDoc->GetCellCount() : 0);
2447             CollectSharedData(nTableCount, nShapesCount, nCellCount);
2448             //DBG_ERROR("no shared data setted");
2449         }
2450         sal_Int32 nTableCount(xIndex->getCount());
2451         pCellStyles->AddNewTable(nTableCount - 1);
2452         CollectShapesAutoStyles(nTableCount);
2453         for (sal_Int32 nTable = 0; nTable < nTableCount; ++nTable)
2454         {
2455             bool bUseStream = pSheetData && pDoc && pDoc->IsStreamValid((SCTAB)nTable) &&
2456                               pSheetData->HasStreamPos(nTable) && xSourceStream.is();
2457 
2458             uno::Reference <sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY);
2459             if (xTable.is())
2460             {
2461                 // table styles array must be complete, including copied tables - Add should find the stored style
2462                 uno::Reference<beans::XPropertySet> xTableProperties(xTable, uno::UNO_QUERY);
2463                 if (xTableProperties.is())
2464                 {
2465                     std::vector<XMLPropertyState> xPropStates(xTableStylesExportPropertySetMapper->Filter(xTableProperties));
2466                     if(xPropStates.size())
2467                     {
2468                         rtl::OUString sParent;
2469                         rtl::OUString sName;
2470                         GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_TABLE, sParent, xPropStates);
2471                         aTableStyles.push_back(sName);
2472                     }
2473                 }
2474             }
2475             // collect other auto-styles only for non-copied sheets
2476             if (xTable.is() && !bUseStream)
2477             {
2478                 uno::Reference<sheet::XUniqueCellFormatRangesSupplier> xCellFormatRanges ( xTable, uno::UNO_QUERY );
2479                 if ( xCellFormatRanges.is() )
2480                 {
2481                     uno::Reference<container::XIndexAccess> xFormatRangesIndex(xCellFormatRanges->getUniqueCellFormatRanges());
2482                     if (xFormatRangesIndex.is())
2483                     {
2484                         sal_Int32 nFormatRangesCount(xFormatRangesIndex->getCount());
2485                         GetProgressBarHelper()->ChangeReference(GetProgressBarHelper()->GetReference() + nFormatRangesCount);
2486                         for (sal_Int32 nFormatRange = 0; nFormatRange < nFormatRangesCount; ++nFormatRange)
2487                         {
2488                             uno::Reference< sheet::XSheetCellRanges> xCellRanges(xFormatRangesIndex->getByIndex(nFormatRange), uno::UNO_QUERY);
2489                             if (xCellRanges.is())
2490                             {
2491                                 uno::Reference <beans::XPropertySet> xProperties (xCellRanges, uno::UNO_QUERY);
2492                                 if (xProperties.is())
2493                                 {
2494                                     AddStyleFromCells(xProperties, xTable, nTable, NULL);
2495                                     IncrementProgressBar(sal_False);
2496                                 }
2497                             }
2498                         }
2499                     }
2500                 }
2501                 uno::Reference<table::XColumnRowRange> xColumnRowRange (xTable, uno::UNO_QUERY);
2502                 if (xColumnRowRange.is())
2503                 {
2504                     if (pDoc)
2505                     {
2506                         pDoc->SyncColRowFlags();
2507                         uno::Reference<table::XTableColumns> xTableColumns(xColumnRowRange->getColumns());
2508                         if (xTableColumns.is())
2509                         {
2510                             sal_Int32 nColumns(pDoc->GetLastChangedCol(sal::static_int_cast<SCTAB>(nTable)));
2511                             pSharedData->SetLastColumn(nTable, nColumns);
2512                             table::CellRangeAddress aCellAddress(GetEndAddress(xTable, nTable));
2513                             if (aCellAddress.EndColumn > nColumns)
2514                             {
2515                                 ++nColumns;
2516                                 pColumnStyles->AddNewTable(nTable, aCellAddress.EndColumn);
2517                             }
2518 //                              else if (nColumns < MAXCOL)
2519 //                                  pColumnStyles->AddNewTable(nTable, ++nColumns);
2520                             else
2521                                 pColumnStyles->AddNewTable(nTable, nColumns);
2522                             sal_Int32 nColumn = 0;
2523                             while (/*nColumn <= nColumns && */nColumn <= MAXCOL)
2524                             {
2525                                 sal_Int32 nIndex(-1);
2526                                 sal_Bool bIsVisible(sal_True);
2527                                 uno::Reference <beans::XPropertySet> xColumnProperties(xTableColumns->getByIndex(nColumn), uno::UNO_QUERY);
2528                                 if (xColumnProperties.is())
2529                                 {
2530                                     AddStyleFromColumn( xColumnProperties, NULL, nIndex, bIsVisible );
2531                                     //if(xPropStates.size())
2532                                     pColumnStyles->AddFieldStyleName(nTable, nColumn, nIndex, bIsVisible);
2533                                 }
2534                                 sal_Int32 nOld(nColumn);
2535                                 nColumn = pDoc->GetNextDifferentChangedCol(sal::static_int_cast<SCTAB>(nTable), static_cast<SCCOL>(nColumn));
2536                                 for (sal_Int32 i = nOld + 1; i < nColumn; ++i)
2537                                     pColumnStyles->AddFieldStyleName(nTable, i, nIndex, bIsVisible);
2538                             }
2539                             if (aCellAddress.EndColumn > nColumns)
2540                             {
2541                                 sal_Bool bIsVisible(sal_True);
2542                                 sal_Int32 nIndex(pColumnStyles->GetStyleNameIndex(nTable, nColumns, bIsVisible));
2543                                 for (sal_Int32 i = nColumns + 1; i <= aCellAddress.EndColumn; ++i)
2544                                     pColumnStyles->AddFieldStyleName(nTable, i, nIndex, bIsVisible);
2545                             }
2546                         }
2547                         uno::Reference<table::XTableRows> xTableRows(xColumnRowRange->getRows());
2548                         if (xTableRows.is())
2549                         {
2550                             sal_Int32 nRows(pDoc->GetLastChangedRow(sal::static_int_cast<SCTAB>(nTable)));
2551                             pSharedData->SetLastRow(nTable, nRows);
2552                             table::CellRangeAddress aCellAddress(GetEndAddress(xTable, nTable));
2553                             if (aCellAddress.EndRow > nRows)
2554                             {
2555                                 ++nRows;
2556                                 pRowStyles->AddNewTable(nTable, aCellAddress.EndRow);
2557                             }
2558 //                              else if (nRows < MAXROW)
2559 //                                  pRowStyles->AddNewTable(nTable, ++nRows);
2560                             else
2561                                 pRowStyles->AddNewTable(nTable, nRows);
2562                             sal_Int32 nRow = 0;
2563                             while (nRow <= nRows && nRow <= MAXROW)
2564                             {
2565                                 sal_Int32 nIndex = 0;
2566                                 uno::Reference <beans::XPropertySet> xRowProperties(xTableRows->getByIndex(nRow), uno::UNO_QUERY);
2567                                 if(xRowProperties.is())
2568                                 {
2569                                     AddStyleFromRow( xRowProperties, NULL, nIndex );
2570                                     //if(xPropStates.size())
2571                                     pRowStyles->AddFieldStyleName(nTable, nRow, nIndex);
2572                                 }
2573                                 sal_Int32 nOld(nRow);
2574                                 nRow = pDoc->GetNextDifferentChangedRow(sal::static_int_cast<SCTAB>(nTable), static_cast<SCROW>(nRow), false);
2575                                 if (nRow > nOld + 1)
2576                                     pRowStyles->AddFieldStyleName(nTable, nOld + 1, nIndex, nRow - 1);
2577                             }
2578                             if (aCellAddress.EndRow > nRows)
2579                             {
2580                                 sal_Int32 nIndex(pRowStyles->GetStyleNameIndex(nTable, nRows));
2581                                 pRowStyles->AddFieldStyleName(nTable, nRows + 1, nIndex, aCellAddress.EndRow);
2582                             }
2583                         }
2584                     }
2585                 }
2586                 uno::Reference<sheet::XCellRangesQuery> xCellRangesQuery (xTable, uno::UNO_QUERY);
2587                 if (xCellRangesQuery.is())
2588                 {
2589                     uno::Reference<sheet::XSheetCellRanges> xSheetCellRanges(xCellRangesQuery->queryContentCells(sheet::CellFlags::FORMATTED));
2590                     uno::Reference<sheet::XSheetOperation> xSheetOperation(xSheetCellRanges, uno::UNO_QUERY);
2591                     if (xSheetCellRanges.is() && xSheetOperation.is())
2592                     {
2593                         sal_uInt32 nCount(sal_uInt32(xSheetOperation->computeFunction(sheet::GeneralFunction_COUNT)));
2594                         uno::Reference<container::XEnumerationAccess> xCellsAccess(xSheetCellRanges->getCells());
2595                         if (xCellsAccess.is())
2596                         {
2597                             GetProgressBarHelper()->ChangeReference(GetProgressBarHelper()->GetReference() + nCount);
2598                             uno::Reference<container::XEnumeration> xCells(xCellsAccess->createEnumeration());
2599                             if (xCells.is())
2600                             {
2601                                 sal_uInt32 nCount2(0);
2602                                 while (xCells->hasMoreElements())
2603                                 {
2604                                     uno::Reference<text::XText> xText(xCells->nextElement(), uno::UNO_QUERY);
2605                                     if (xText.is())
2606                                         GetTextParagraphExport()->collectTextAutoStyles(xText, sal_False, sal_False);
2607                                     ++nCount2;
2608                                     IncrementProgressBar(sal_False);
2609                                 }
2610                                 if(nCount2 > nCount)
2611                                     GetProgressBarHelper()->SetReference(GetProgressBarHelper()->GetReference() + nCount2 - nCount);
2612                             }
2613                         }
2614                     }
2615                 }
2616             }
2617             IncrementProgressBar(sal_False);
2618         }
2619         pChangeTrackingExportHelper->CollectAutoStyles();
2620 
2621         GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_COLUMN,
2622             GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap());
2623         GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_ROW,
2624             GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap());
2625         GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_TABLE,
2626             GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap());
2627         exportAutoDataStyles();
2628         GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_CELL,
2629             GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap());
2630 
2631         GetShapeExport()->exportAutoStyles();
2632         GetFormExport()->exportAutoStyles( );
2633 
2634         if (pDoc)
2635         {
2636             ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
2637             // #i100879# write the table style for cached tables only if there are cached tables
2638             // (same logic as in ExportExternalRefCacheStyles)
2639             if (pRefMgr->hasExternalData())
2640             {
2641                 // Special table style for the external ref cache tables.
2642                 AddAttribute(XML_NAMESPACE_STYLE, XML_NAME, sExternalRefTabStyleName);
2643                 AddAttribute(XML_NAMESPACE_STYLE, XML_FAMILY, XML_TABLE);
2644                 SvXMLElementExport aElemStyle(*this, XML_NAMESPACE_STYLE, XML_STYLE, sal_True, sal_True);
2645                 AddAttribute(XML_NAMESPACE_TABLE,  XML_DISPLAY, XML_FALSE);
2646                 SvXMLElementExport aElemStyleTabProps(*this, XML_NAMESPACE_STYLE, XML_TABLE_PROPERTIES, sal_True, sal_True);
2647             }
2648         }
2649     }
2650 
2651     if (getExportFlags() & EXPORT_MASTERSTYLES)
2652     {
2653         GetPageExport()->collectAutoStyles(sal_True);
2654         GetPageExport()->exportAutoStyles();
2655     }
2656 
2657     // #i30251#; only write Text Styles once
2658 
2659     if ((getExportFlags() & EXPORT_CONTENT) || (getExportFlags() & EXPORT_MASTERSTYLES))
2660         GetTextParagraphExport()->exportTextAutoStyles();
2661 }
2662 
_ExportMasterStyles()2663 void ScXMLExport::_ExportMasterStyles()
2664 {
2665     GetPageExport()->exportMasterStyles( sal_True );
2666 }
2667 
CollectInternalShape(uno::Reference<drawing::XShape> xShape)2668 void ScXMLExport::CollectInternalShape( uno::Reference< drawing::XShape > xShape )
2669 {
2670     // detective objects and notes
2671     if( SvxShape* pShapeImp = SvxShape::getImplementation( xShape ) )
2672     {
2673         if( SdrObject* pObject = pShapeImp->GetSdrObject() )
2674         {
2675             // collect note caption objects from all layers (internal or hidden)
2676             if( ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( pObject, static_cast< SCTAB >( nCurrentTable ) ) )
2677             {
2678                 pSharedData->AddNoteObj( xShape, pCaptData->maStart );
2679 
2680                 // #i60851# When the file is saved while editing a new note,
2681                 // the cell is still empty -> last column/row must be updated
2682                 DBG_ASSERT( pCaptData->maStart.Tab() == nCurrentTable, "invalid table in object data" );
2683                 pSharedData->SetLastColumn( nCurrentTable, pCaptData->maStart.Col() );
2684                 pSharedData->SetLastRow( nCurrentTable, pCaptData->maStart.Row() );
2685             }
2686             // other objects from internal layer only (detective)
2687             else if( pObject->GetLayer() == SC_LAYER_INTERN )
2688             {
2689                 ScDetectiveFunc aDetFunc( pDoc, static_cast<SCTAB>(nCurrentTable) );
2690                 ScAddress       aPosition;
2691                 ScRange         aSourceRange;
2692                 sal_Bool        bRedLine;
2693                 ScDetectiveObjType eObjType = aDetFunc.GetDetectiveObjectType(
2694                     pObject, nCurrentTable, aPosition, aSourceRange, bRedLine );
2695                 pSharedData->GetDetectiveObjContainer()->AddObject( eObjType, static_cast<SCTAB>(nCurrentTable), aPosition, aSourceRange, bRedLine );
2696             }
2697         }
2698     }
2699 }
2700 
2701 //UNUSED2008-05  sal_Bool ScXMLExport::GetMerge (const uno::Reference <sheet::XSpreadsheet>& xTable,
2702 //UNUSED2008-05                                  const sal_Int32 nCol, const sal_Int32 nRow,
2703 //UNUSED2008-05                                  table::CellRangeAddress& aCellAddress)
2704 //UNUSED2008-05  {
2705 //UNUSED2008-05      uno::Reference<sheet::XSheetCellRange> xSheetCellRange(xTable->getCellRangeByPosition(nCol, nRow, nCol, nRow), uno::UNO_QUERY);
2706 //UNUSED2008-05      if (xSheetCellRange.is())
2707 //UNUSED2008-05      {
2708 //UNUSED2008-05          uno::Reference<sheet::XSheetCellCursor> xCursor(xTable->createCursorByRange(xSheetCellRange));
2709 //UNUSED2008-05          if (xCursor.is())
2710 //UNUSED2008-05          {
2711 //UNUSED2008-05              uno::Reference<sheet::XCellRangeAddressable> xCellAddress (xCursor, uno::UNO_QUERY);
2712 //UNUSED2008-05              xCursor->collapseToMergedArea();
2713 //UNUSED2008-05              aCellAddress = xCellAddress->getRangeAddress();
2714 //UNUSED2008-05              return sal_True;
2715 //UNUSED2008-05          }
2716 //UNUSED2008-05      }
2717 //UNUSED2008-05      return sal_False;
2718 //UNUSED2008-05  }
2719 
GetMerged(const table::CellRangeAddress * pCellAddress,const uno::Reference<sheet::XSpreadsheet> & xTable)2720 sal_Bool ScXMLExport::GetMerged (const table::CellRangeAddress* pCellAddress,
2721                             const uno::Reference <sheet::XSpreadsheet>& xTable)
2722 {
2723     sal_Bool bReady(sal_False);
2724     sal_Int32 nRow(pCellAddress->StartRow);
2725     sal_Int32 nCol(pCellAddress->StartColumn);
2726     sal_Int32 nEndRow(pCellAddress->EndRow);
2727     sal_Int32 nEndCol(pCellAddress->EndColumn);
2728     sal_Bool bRowInc(nEndRow > nRow);
2729     while(!bReady && nRow <= nEndRow && nCol <= nEndCol)
2730     {
2731         uno::Reference<sheet::XSheetCellRange> xSheetCellRange(xTable->getCellRangeByPosition(nCol, nRow, nCol, nRow), uno::UNO_QUERY);
2732         if (xSheetCellRange.is())
2733         {
2734             uno::Reference<sheet::XSheetCellCursor> xCursor(xTable->createCursorByRange(xSheetCellRange));
2735             if(xCursor.is())
2736             {
2737                 uno::Reference<sheet::XCellRangeAddressable> xCellAddress (xCursor, uno::UNO_QUERY);
2738                 xCursor->collapseToMergedArea();
2739                 table::CellRangeAddress aCellAddress2(xCellAddress->getRangeAddress());
2740                 if ((aCellAddress2.EndRow > nRow ||
2741                     aCellAddress2.EndColumn > nCol) &&
2742                     aCellAddress2.StartRow == nRow &&
2743                     aCellAddress2.StartColumn == nCol)
2744                 {
2745                     pMergedRangesContainer->AddRange(aCellAddress2);
2746                     pSharedData->SetLastColumn(aCellAddress2.Sheet, aCellAddress2.EndColumn);
2747                     pSharedData->SetLastRow(aCellAddress2.Sheet, aCellAddress2.EndRow);
2748                 }
2749                 else
2750                     bReady = sal_True;
2751             }
2752         }
2753         if (!bReady)
2754         {
2755             if (bRowInc)
2756                 ++nRow;
2757             else
2758                 ++nCol;
2759         }
2760     }
2761     DBG_ASSERT(!(!bReady && nEndRow > nRow && nEndCol > nCol), "should not be possible");
2762     return !bReady;
2763 }
2764 
2765 //UNUSED2008-05  sal_Bool ScXMLExport::IsMatrix (const uno::Reference <table::XCellRange>& xCellRange,
2766 //UNUSED2008-05                                  const uno::Reference <sheet::XSpreadsheet>& xTable,
2767 //UNUSED2008-05                                  const sal_Int32 nCol, const sal_Int32 nRow,
2768 //UNUSED2008-05                                  table::CellRangeAddress& aCellAddress, sal_Bool& bIsFirst) const
2769 //UNUSED2008-05  {
2770 //UNUSED2008-05      bIsFirst = sal_False;
2771 //UNUSED2008-05      uno::Reference <sheet::XArrayFormulaRange> xArrayFormulaRange (xCellRange->getCellRangeByPosition(nCol,nRow,nCol,nRow), uno::UNO_QUERY);
2772 //UNUSED2008-05      if (xArrayFormulaRange.is())
2773 //UNUSED2008-05      {
2774 //UNUSED2008-05          rtl::OUString sArrayFormula(xArrayFormulaRange->getArrayFormula());
2775 //UNUSED2008-05          if (sArrayFormula.getLength())
2776 //UNUSED2008-05          {
2777 //UNUSED2008-05              uno::Reference<sheet::XSheetCellRange> xMatrixSheetCellRange (xArrayFormulaRange, uno::UNO_QUERY);
2778 //UNUSED2008-05              if (xMatrixSheetCellRange.is())
2779 //UNUSED2008-05              {
2780 //UNUSED2008-05                  uno::Reference<sheet::XSheetCellCursor> xMatrixSheetCursor(xTable->createCursorByRange(xMatrixSheetCellRange));
2781 //UNUSED2008-05                  if (xMatrixSheetCursor.is())
2782 //UNUSED2008-05                  {
2783 //UNUSED2008-05                      xMatrixSheetCursor->collapseToCurrentArray();
2784 //UNUSED2008-05                      uno::Reference<sheet::XCellRangeAddressable> xMatrixCellAddress (xMatrixSheetCursor, uno::UNO_QUERY);
2785 //UNUSED2008-05                      if (xMatrixCellAddress.is())
2786 //UNUSED2008-05                      {
2787 //UNUSED2008-05                          aCellAddress = xMatrixCellAddress->getRangeAddress();
2788 //UNUSED2008-05                          if ((aCellAddress.StartColumn == nCol && aCellAddress.StartRow == nRow) &&
2789 //UNUSED2008-05                              (aCellAddress.EndColumn > nCol || aCellAddress.EndRow > nRow))
2790 //UNUSED2008-05                          {
2791 //UNUSED2008-05                              bIsFirst = sal_True;
2792 //UNUSED2008-05                              return sal_True;
2793 //UNUSED2008-05                          }
2794 //UNUSED2008-05                          else if (aCellAddress.StartColumn != nCol || aCellAddress.StartRow != nRow ||
2795 //UNUSED2008-05                                   aCellAddress.EndColumn != nCol || aCellAddress.EndRow != nRow)
2796 //UNUSED2008-05                              return sal_True;
2797 //UNUSED2008-05                          else
2798 //UNUSED2008-05                          {
2799 //UNUSED2008-05                              bIsFirst = sal_True;
2800 //UNUSED2008-05                              return sal_True;
2801 //UNUSED2008-05                          }
2802 //UNUSED2008-05                      }
2803 //UNUSED2008-05                  }
2804 //UNUSED2008-05              }
2805 //UNUSED2008-05          }
2806 //UNUSED2008-05      }
2807 //UNUSED2008-05      return sal_False;
2808 //UNUSED2008-05  }
2809 
IsMatrix(const ScAddress & aCell,table::CellRangeAddress & aCellAddress,sal_Bool & bIsFirst) const2810 sal_Bool ScXMLExport::IsMatrix (const ScAddress& aCell,
2811                             table::CellRangeAddress& aCellAddress, sal_Bool& bIsFirst) const
2812 {
2813     bIsFirst = sal_False;
2814 
2815     ScRange aMatrixRange;
2816 
2817     if (pDoc && pDoc->GetMatrixFormulaRange(aCell, aMatrixRange))
2818     {
2819         ScUnoConversion::FillApiRange( aCellAddress, aMatrixRange );
2820         if ((aCellAddress.StartColumn == aCell.Col() && aCellAddress.StartRow == aCell.Row()) &&
2821             (aCellAddress.EndColumn > aCell.Col() || aCellAddress.EndRow > aCell.Row()))
2822         {
2823             bIsFirst = sal_True;
2824             return sal_True;
2825         }
2826         else if (aCellAddress.StartColumn != aCell.Col() || aCellAddress.StartRow != aCell.Row() ||
2827             aCellAddress.EndColumn != aCell.Col() || aCellAddress.EndRow != aCell.Row())
2828             return sal_True;
2829         else
2830         {
2831             bIsFirst = sal_True;
2832             return sal_True;
2833         }
2834     }
2835 
2836     return sal_False;
2837 
2838 /*  uno::Reference <sheet::XArrayFormulaRange> xArrayFormulaRange (xCell, uno::UNO_QUERY);
2839     if (xArrayFormulaRange.is())
2840     {
2841         rtl::OUString sArrayFormula(xArrayFormulaRange->getArrayFormula());
2842         if (sArrayFormula.getLength())
2843         {
2844             uno::Reference<sheet::XSheetCellRange> xMatrixSheetCellRange (xCell, uno::UNO_QUERY);
2845             if (xMatrixSheetCellRange.is())
2846             {
2847                 uno::Reference<sheet::XSheetCellCursor> xMatrixSheetCursor(xTable->createCursorByRange(xMatrixSheetCellRange));
2848                 if (xMatrixSheetCursor.is())
2849                 {
2850                     xMatrixSheetCursor->collapseToCurrentArray();
2851                     uno::Reference<sheet::XCellRangeAddressable> xMatrixCellAddress (xMatrixSheetCursor, uno::UNO_QUERY);
2852                     if (xMatrixCellAddress.is())
2853                     {
2854                         aCellAddress = xMatrixCellAddress->getRangeAddress();
2855                         if ((aCellAddress.StartColumn == nCol && aCellAddress.StartRow == nRow) &&
2856                             (aCellAddress.EndColumn > nCol || aCellAddress.EndRow > nRow))
2857                         {
2858                             bIsFirst = sal_True;
2859                             return sal_True;
2860                         }
2861                         else if (aCellAddress.StartColumn != nCol || aCellAddress.StartRow != nRow ||
2862                             aCellAddress.EndColumn != nCol || aCellAddress.EndRow != nRow)
2863                             return sal_True;
2864                         else
2865                         {
2866                             bIsFirst = sal_True;
2867                             return sal_True;
2868                         }
2869                     }
2870                 }
2871             }
2872         }
2873     }
2874     return sal_False;*/
2875 }
2876 
GetCellText(ScMyCell & rMyCell,const ScAddress & aPos) const2877 sal_Bool ScXMLExport::GetCellText (ScMyCell& rMyCell, const ScAddress& aPos) const
2878 {
2879     if (rMyCell.bHasStringValue)
2880         return sal_True;
2881     else
2882     {
2883 /*      if (!rMyCell.bHasXText)
2884         {
2885             rMyCell.xText.set(xCurrentTableCellRange->getCellByPosition(rMyCell.aCellAddress.Column, rMyCell.aCellAddress.Row), uno::UNO_QUERY);
2886             rMyCell.bHasXText = sal_True;
2887         }*/
2888 //      if (rMyCell.xText.is())
2889 //      {
2890             rMyCell.sStringValue = ScCellObj::GetOutputString_Impl(pDoc, aPos);
2891             rMyCell.bHasStringValue = sal_True;
2892             return sal_True;
2893 //      }
2894     }
2895 }
2896 
WriteCell(ScMyCell & aCell,sal_Int32 nEqualCellCount)2897 void ScXMLExport::WriteCell(ScMyCell& aCell, sal_Int32 nEqualCellCount)
2898 {
2899     // nEqualCellCount is the number of additional cells
2900     SetRepeatAttribute(nEqualCellCount, (aCell.nType != table::CellContentType_EMPTY));
2901 
2902     ScAddress aCellPos;
2903     ScUnoConversion::FillScAddress( aCellPos, aCell.aCellAddress );
2904     if (aCell.nStyleIndex != -1)
2905         AddAttribute(sAttrStyleName, *pCellStyles->GetStyleNameByIndex(aCell.nStyleIndex, aCell.bIsAutoStyle));
2906     if (aCell.nValidationIndex > -1)
2907         AddAttribute(XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION_NAME, pValidationsContainer->GetValidationName(aCell.nValidationIndex));
2908     sal_Bool bIsMatrix(aCell.bIsMatrixBase || aCell.bIsMatrixCovered);
2909     sal_Bool bIsFirstMatrixCell(aCell.bIsMatrixBase);
2910     if (bIsFirstMatrixCell)
2911     {
2912         sal_Int32 nColumns(aCell.aMatrixRange.EndColumn - aCell.aMatrixRange.StartColumn + 1);
2913         sal_Int32 nRows(aCell.aMatrixRange.EndRow - aCell.aMatrixRange.StartRow + 1);
2914         rtl::OUStringBuffer sColumns;
2915         rtl::OUStringBuffer sRows;
2916         SvXMLUnitConverter::convertNumber(sColumns, nColumns);
2917         SvXMLUnitConverter::convertNumber(sRows, nRows);
2918         AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_COLUMNS_SPANNED, sColumns.makeStringAndClear());
2919         AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_ROWS_SPANNED, sRows.makeStringAndClear());
2920     }
2921     sal_Bool bIsEmpty(sal_False);
2922     switch (aCell.nType)
2923     {
2924     case table::CellContentType_EMPTY :
2925         {
2926             bIsEmpty = sal_True;
2927         }
2928         break;
2929     case table::CellContentType_VALUE :
2930         {
2931             if (!aCell.bHasDoubleValue)
2932             {
2933                 aCell.fValue = pDoc->GetValue( aCellPos );
2934                 aCell.bHasDoubleValue = sal_True;
2935             }
2936             GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
2937                 aCell.nNumberFormat, aCell.fValue);
2938         }
2939         break;
2940     case table::CellContentType_TEXT :
2941         {
2942             if (GetCellText(aCell, aCellPos))
2943             {
2944                 rtl::OUString sFormula(lcl_GetRawString(pDoc, aCellPos));
2945                 GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
2946                     sFormula, aCell.sStringValue, sal_True, sal_True);
2947             }
2948         }
2949         break;
2950     case table::CellContentType_FORMULA :
2951         {
2952             ScBaseCell* pBaseCell = pDoc ? pDoc->GetCell(aCellPos) : NULL;
2953             if (pBaseCell && pBaseCell->GetCellType() == CELLTYPE_FORMULA)
2954             {
2955                 rtl::OUStringBuffer sFormula;
2956                 ScFormulaCell* pFormulaCell((ScFormulaCell*) pBaseCell);
2957                 if (!bIsMatrix || (bIsMatrix && bIsFirstMatrixCell))
2958                 {
2959                     const formula::FormulaGrammar::Grammar eGrammar = pDoc->GetStorageGrammar();
2960                     sal_uInt16 nNamespacePrefix = (eGrammar == formula::FormulaGrammar::GRAM_ODFF ? XML_NAMESPACE_OF : XML_NAMESPACE_OOOC);
2961                     pFormulaCell->GetFormula(sFormula, eGrammar);//ange scope name support
2962                     rtl::OUString sOUFormula(sFormula.makeStringAndClear());
2963                     if (!bIsMatrix)
2964                     {
2965                         AddAttribute(sAttrFormula, GetNamespaceMap().GetQNameByKey( nNamespacePrefix, sOUFormula, sal_False ));
2966                     }
2967                     else
2968                     {
2969                         AddAttribute(sAttrFormula, GetNamespaceMap().GetQNameByKey( nNamespacePrefix, sOUFormula.copy(1, sOUFormula.getLength() - 2), sal_False ));
2970                     }
2971                 }
2972                 if (pFormulaCell->IsValue())
2973                 {
2974                     sal_Bool bIsStandard;
2975                     rtl::OUString sCurrency;
2976                     GetNumberFormatAttributesExportHelper()->GetCellType(aCell.nNumberFormat, sCurrency, bIsStandard);
2977                     if (bIsStandard)
2978                     {
2979                         if (pDoc)
2980                             GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
2981                                 pFormulaCell->GetStandardFormat(*pDoc->GetFormatTable(), 0),
2982                                 pDoc->GetValue( aCellPos ));
2983                     }
2984                     else
2985                         GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
2986                             aCell.nNumberFormat, pDoc->GetValue( aCellPos ));
2987                 }
2988                 else
2989                 {
2990                     if (GetCellText(aCell, aCellPos))
2991                         if (aCell.sStringValue.getLength())
2992                         {
2993                             AddAttribute(sAttrValueType, XML_STRING);
2994                             AddAttribute(sAttrStringValue, aCell.sStringValue);
2995                         }
2996                 }
2997             }
2998         }
2999         break;
3000         default:
3001         {
3002             // added to avoid warnings
3003         }
3004     }
3005     rtl::OUString* pCellString(&sElemCell);
3006     if (aCell.bIsCovered)
3007     {
3008         pCellString = &sElemCoveredCell;
3009     }
3010     else
3011     {
3012         if (aCell.bIsMergedBase)
3013         {
3014             sal_Int32 nColumns(aCell.aMergeRange.EndColumn - aCell.aMergeRange.StartColumn + 1);
3015             sal_Int32 nRows(aCell.aMergeRange.EndRow - aCell.aMergeRange.StartRow + 1);
3016             rtl::OUStringBuffer sColumns;
3017             rtl::OUStringBuffer sRows;
3018             SvXMLUnitConverter::convertNumber(sColumns, nColumns);
3019             SvXMLUnitConverter::convertNumber(sRows, nRows);
3020             AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_SPANNED, sColumns.makeStringAndClear());
3021             AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_SPANNED, sRows.makeStringAndClear());
3022         }
3023     }
3024     SvXMLElementExport aElemC(*this, *pCellString, sal_True, sal_True);
3025     CheckAttrList();
3026     WriteAreaLink(aCell);
3027     WriteAnnotation(aCell);
3028     WriteDetective(aCell);
3029 
3030     sal_Bool bEditCell = sal_False;
3031 
3032     if (!bIsEmpty)
3033     {
3034         if ((aCell.nType == table::CellContentType_TEXT && IsEditCell(aCell)) ||
3035             (aCell.nType == table::CellContentType_FORMULA && IsMultiLineFormulaCell(aCell)))
3036         {
3037             bEditCell = sal_True;
3038             uno::Reference<text::XText> xText(xCurrentTableCellRange->getCellByPosition(aCell.aCellAddress.Column, aCell.aCellAddress.Row), uno::UNO_QUERY);
3039             if ( xText.is())
3040                 GetTextParagraphExport()->exportText(xText, sal_False, sal_False);
3041         }
3042         else
3043         {
3044             SvXMLElementExport aElemP(*this, sElemP, sal_True, sal_False);
3045             sal_Bool bPrevCharWasSpace(sal_True);
3046             if (GetCellText(aCell, aCellPos))
3047                 GetTextParagraphExport()->exportText(aCell.sStringValue, bPrevCharWasSpace);
3048         }
3049     }
3050     WriteShapes(aCell);
3051     if (!bIsEmpty)
3052         IncrementProgressBar(bEditCell);
3053 }
3054 
ExportShape(const uno::Reference<drawing::XShape> & xShape,awt::Point * pPoint)3055 void ScXMLExport::ExportShape(const uno::Reference < drawing::XShape >& xShape, awt::Point* pPoint)
3056 {
3057     uno::Reference < beans::XPropertySet > xShapeProps ( xShape, uno::UNO_QUERY );
3058 //BM    sal_Bool bMemChart(sal_False);  // das muss man jetzt umbenennen :-)
3059     bool bIsChart( false );
3060     rtl::OUString sPropCLSID (RTL_CONSTASCII_USTRINGPARAM("CLSID"));
3061     rtl::OUString sPropModel (RTL_CONSTASCII_USTRINGPARAM("Model"));
3062     rtl::OUString sPersistName (RTL_CONSTASCII_USTRINGPARAM("PersistName"));
3063     if (xShapeProps.is())
3064     {
3065         sal_Int32 nZOrder = 0;
3066         if (xShapeProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ZOrder"))) >>= nZOrder)
3067         {
3068             rtl::OUStringBuffer sBuffer;
3069             GetMM100UnitConverter().convertNumber(sBuffer, nZOrder);
3070             AddAttribute(XML_NAMESPACE_DRAW, XML_ZINDEX, sBuffer.makeStringAndClear());
3071         }
3072         uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xShapeProps->getPropertySetInfo();
3073         if( xPropSetInfo->hasPropertyByName( sPropCLSID ) )
3074         {
3075             rtl::OUString sCLSID;
3076             if (xShapeProps->getPropertyValue( sPropCLSID ) >>= sCLSID)
3077             {
3078                 if ( sCLSID.equalsIgnoreAsciiCase(GetChartExport()->getChartCLSID()) )
3079                 {
3080                     // we have a chart
3081                     ::rtl::OUString sRanges;
3082                     if ( pDoc )
3083                     {
3084                         ::rtl::OUString aChartName;
3085                         xShapeProps->getPropertyValue( sPersistName ) >>= aChartName;
3086                         ScRange aEmptyRange;
3087                         ScChartListener aSearcher( aChartName, pDoc, aEmptyRange );
3088                         sal_uInt16 nIndex = 0;
3089                         ScChartListenerCollection* pCollection = pDoc->GetChartListenerCollection();
3090                         if ( pCollection && pCollection->Search( &aSearcher, nIndex ) )
3091                         {
3092                             ScChartListener* pListener = static_cast< ScChartListener* >( pCollection->At( nIndex ) );
3093                             if ( pListener )
3094                             {
3095                                 const ScRangeListRef& rRangeList = pListener->GetRangeList();
3096                                 if ( rRangeList.Is() )
3097                                 {
3098                                     ScRangeStringConverter::GetStringFromRangeList( sRanges, rRangeList, pDoc, FormulaGrammar::CONV_OOO );
3099                                     if ( sRanges.getLength() > 0 )
3100                                     {
3101                                         bIsChart = true;
3102                                         SvXMLAttributeList* pAttrList = new SvXMLAttributeList();
3103                                         if ( pAttrList )
3104                                         {
3105                                             pAttrList->AddAttribute(
3106                                                 GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken( XML_NOTIFY_ON_UPDATE_OF_RANGES ) ), sRanges );
3107                                         }
3108                                         GetShapeExport()->exportShape( xShape, SEF_EXPORT_NO_CHART_DATA | SEF_DEFAULT, pPoint, pAttrList );
3109                                     }
3110                                 }
3111                             }
3112                         }
3113                     }
3114 
3115                     if ( sRanges.getLength() == 0 )
3116                     {
3117                         uno::Reference< frame::XModel > xChartModel;
3118                         if( ( xShapeProps->getPropertyValue( sPropModel ) >>= xChartModel ) &&
3119                             xChartModel.is())
3120                         {
3121                             uno::Reference< chart2::XChartDocument > xChartDoc( xChartModel, uno::UNO_QUERY );
3122                             uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartModel, uno::UNO_QUERY );
3123                             if( xChartDoc.is() && xReceiver.is() &&
3124                                 ! xChartDoc->hasInternalDataProvider())
3125                             {
3126                                 // we have a chart that gets its data from Calc
3127                                 bIsChart = true;
3128                                 uno::Sequence< ::rtl::OUString > aRepresentations(
3129                                     xReceiver->getUsedRangeRepresentations());
3130                                 SvXMLAttributeList* pAttrList = 0;
3131                                 if(aRepresentations.getLength())
3132                                 {
3133                                     // add the ranges used by the chart to the shape
3134                                     // element to be able to start listening after
3135                                     // load (when the chart is not yet loaded)
3136                                     uno::Reference< chart2::data::XRangeXMLConversion > xRangeConverter( xChartDoc->getDataProvider(), uno::UNO_QUERY );
3137                                     sRanges = lcl_RangeSequenceToString( aRepresentations, xRangeConverter );
3138                                     pAttrList = new SvXMLAttributeList();
3139                                     pAttrList->AddAttribute(
3140                                         GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken(XML_NOTIFY_ON_UPDATE_OF_RANGES) ), sRanges );
3141                                 }
3142                                 GetShapeExport()->exportShape(xShape, SEF_EXPORT_NO_CHART_DATA | SEF_DEFAULT, pPoint, pAttrList);
3143                             }
3144                         }
3145                     }
3146 
3147 //BM                    rtl::OUString sOUName;
3148 //BM                    xShapeProps->getPropertyValue(sPersistName) >>= sOUName;
3149 //BM                    String sName(sOUName);
3150 //BM                    if (!pChartListener)
3151 //BM                    {
3152 //BM                        String aEmptyString;
3153 //BM                        ScRange aRange;
3154 //BM                        pChartListener = new ScChartListener ( aEmptyString, GetDocument(), aRange );
3155 //BM                    }
3156 //BM                    if(pChartListener)
3157 //BM                    {
3158 //BM                        sal_uInt16 nIndex(0);
3159 //BM                        pChartListener->SetString( sName );
3160 //BM                        if ( GetDocument() && GetDocument()->GetChartListenerCollection()->Search( pChartListener, nIndex ) )
3161 //BM                        {
3162 //BM                            const ScRangeListRef& rRangeListRef(((ScChartListener*)
3163 //BM                                (GetDocument()->GetChartListenerCollection()->
3164 //BM                                At( nIndex )))->GetRangeList());
3165 //BM                            if (rRangeListRef.Is())
3166 //BM                            {
3167 //BM                                bMemChart = sal_True;
3168 //BM                                rtl::OUString sRanges;
3169 //BM                                ScRangeStringConverter::GetStringFromRangeList(sRanges, rRangeListRef, GetDocument());
3170 //BM                                 SvXMLAttributeList* pAttrList = NULL;
3171 //BM                                if (sRanges.getLength())
3172 //BM                                 {
3173 //BM                                     pAttrList = new SvXMLAttributeList();
3174 //BM                                     pAttrList->AddAttribute(
3175 //BM                                         GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken(XML_NOTIFY_ON_UPDATE_OF_RANGES) ), sRanges );
3176 //BM                                 }
3177 //BM                                GetShapeExport()->exportShape(xShape, SEF_EXPORT_NO_CHART_DATA | SEF_DEFAULT, pPoint, pAttrList);
3178 //BM                            }
3179 //BM                        }
3180 //BM                        else
3181 //BM                        {
3182 //BM                            bMemChart = sal_True;
3183 //BM                             SvXMLAttributeList* pAttrList = new SvXMLAttributeList();
3184 //BM                             pAttrList->AddAttribute(
3185 //BM                                 GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken(XML_NOTIFY_ON_UPDATE_OF_RANGES) ), rtl::OUString() );
3186 //BM                            GetShapeExport()->exportShape(xShape, SEF_EXPORT_NO_CHART_DATA | SEF_DEFAULT, pPoint, pAttrList);
3187 //BM                        }
3188 //BM                    }
3189 
3190 /*                  SchMemChart* pMemChart = pDoc->FindChartData(sName);
3191                     if (pMemChart && pMemChart->GetSeriesAddresses().getLength())
3192                     {
3193                         bMemChart = sal_True;
3194                         rtl::OUString sRanges(pMemChart->getXMLStringForChartRange());
3195                         if (sRanges.getLength())
3196                             AddAttribute(XML_NAMESPACE_DRAW, XML_NOTIFY_ON_UPDATE_OF_RANGES, sRanges);
3197                         GetShapeExport()->exportShape(xShape, SEF_EXPORT_NO_CHART_DATA | SEF_DEFAULT, pPoint);
3198                     }*/
3199                 }
3200             }
3201         }
3202     }
3203     if (!bIsChart)
3204         GetShapeExport()->exportShape(xShape, SEF_DEFAULT, pPoint);
3205     IncrementProgressBar(sal_False);
3206 }
3207 
WriteShapes(const ScMyCell & rMyCell)3208 void ScXMLExport::WriteShapes(const ScMyCell& rMyCell)
3209 {
3210     if( rMyCell.bHasShape && !rMyCell.aShapeList.empty() && pDoc )
3211     {
3212         awt::Point aPoint;
3213         Rectangle aRec = pDoc->GetMMRect(static_cast<SCCOL>(rMyCell.aCellAddress.Column), static_cast<SCROW>(rMyCell.aCellAddress.Row),
3214             static_cast<SCCOL>(rMyCell.aCellAddress.Column), static_cast<SCROW>(rMyCell.aCellAddress.Row), static_cast<SCTAB>(rMyCell.aCellAddress.Sheet));
3215         sal_Bool bNegativePage(pDoc->IsNegativePage(rMyCell.aCellAddress.Sheet));
3216         if (bNegativePage)
3217             aPoint.X = aRec.Right();
3218         else
3219             aPoint.X = aRec.Left();
3220         aPoint.Y = aRec.Top();
3221         ScMyShapeList::const_iterator aItr = rMyCell.aShapeList.begin();
3222         ScMyShapeList::const_iterator aEndItr(rMyCell.aShapeList.end());
3223         while (aItr != aEndItr)
3224         {
3225             if (aItr->xShape.is())
3226             {
3227                 if (bNegativePage)
3228                     aPoint.X = 2 * aItr->xShape->getPosition().X + aItr->xShape->getSize().Width - aPoint.X;
3229                 if ( !aItr->xShape->getShapeType().equals(sCaptionShape) )
3230                 {
3231                     awt::Point aEndPoint;
3232                     Rectangle aEndRec(pDoc->GetMMRect(aItr->aEndAddress.Col(), aItr->aEndAddress.Row(),
3233                         aItr->aEndAddress.Col(), aItr->aEndAddress.Row(), aItr->aEndAddress.Tab()));
3234                     rtl::OUString sEndAddress;
3235                     ScRangeStringConverter::GetStringFromAddress(sEndAddress, aItr->aEndAddress, pDoc, FormulaGrammar::CONV_OOO);
3236                     AddAttribute(XML_NAMESPACE_TABLE, XML_END_CELL_ADDRESS, sEndAddress);
3237                     if (bNegativePage)
3238                         aEndPoint.X = -aEndRec.Right();
3239                     else
3240                         aEndPoint.X = aEndRec.Left();
3241                     aEndPoint.Y = aEndRec.Top();
3242                     awt::Point aStartPoint(aItr->xShape->getPosition());
3243                     awt::Size aSize(aItr->xShape->getSize());
3244                     sal_Int32 nEndX;
3245                     if (bNegativePage)
3246                         nEndX = -aStartPoint.X - aEndPoint.X;
3247                     else
3248                         nEndX = aStartPoint.X + aSize.Width - aEndPoint.X;
3249                     sal_Int32 nEndY(aStartPoint.Y + aSize.Height - aEndPoint.Y);
3250                     rtl::OUStringBuffer sBuffer;
3251                     GetMM100UnitConverter().convertMeasure(sBuffer, nEndX);
3252                     AddAttribute(XML_NAMESPACE_TABLE, XML_END_X, sBuffer.makeStringAndClear());
3253                     GetMM100UnitConverter().convertMeasure(sBuffer, nEndY);
3254                     AddAttribute(XML_NAMESPACE_TABLE, XML_END_Y, sBuffer.makeStringAndClear());
3255                 }
3256                 ExportShape(aItr->xShape, &aPoint);
3257                 // if there's an error in ExportShape, the attributes from above must be removed
3258                 CheckAttrList();    // asserts in non pro if we have attributes left
3259                 ClearAttrList();    // clears the attributes
3260             }
3261             ++aItr;
3262         }
3263     }
3264 }
3265 
WriteTableShapes()3266 void ScXMLExport::WriteTableShapes()
3267 {
3268     ScMyTableShapes* pTableShapes(pSharedData->GetTableShapes());
3269     if (pTableShapes && !(*pTableShapes)[nCurrentTable].empty())
3270     {
3271         DBG_ASSERT(pTableShapes->size() > static_cast<size_t>(nCurrentTable), "wrong Table");
3272         SvXMLElementExport aShapesElem(*this, XML_NAMESPACE_TABLE, XML_SHAPES, sal_True, sal_False);
3273         ScMyTableXShapes::iterator aItr((*pTableShapes)[nCurrentTable].begin());
3274         ScMyTableXShapes::iterator aEndItr((*pTableShapes)[nCurrentTable].end());
3275         while (aItr != aEndItr)
3276         {
3277             if (aItr->is())
3278             {
3279                 if (pDoc->IsNegativePage(static_cast<SCTAB>(nCurrentTable)))
3280                 {
3281                     awt::Point aPoint((*aItr)->getPosition());
3282                     awt::Size aSize((*aItr)->getSize());
3283                     aPoint.X += aPoint.X + aSize.Width;
3284                     aPoint.Y = 0;
3285                     ExportShape(*aItr, &aPoint);
3286                 }
3287                 else
3288                     ExportShape(*aItr, NULL);
3289             }
3290             aItr = (*pTableShapes)[nCurrentTable].erase(aItr);
3291         }
3292     }
3293 }
3294 
WriteAreaLink(const ScMyCell & rMyCell)3295 void ScXMLExport::WriteAreaLink( const ScMyCell& rMyCell )
3296 {
3297     if( rMyCell.bHasAreaLink )
3298     {
3299         const ScMyAreaLink& rAreaLink = rMyCell.aAreaLink;
3300         AddAttribute( XML_NAMESPACE_TABLE, XML_NAME, rAreaLink.sSourceStr );
3301         AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
3302         AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, GetRelativeReference(rAreaLink.sURL) );
3303         AddAttribute( XML_NAMESPACE_TABLE, XML_FILTER_NAME, rAreaLink.sFilter );
3304         if( rAreaLink.sFilterOptions.getLength() )
3305             AddAttribute( XML_NAMESPACE_TABLE, XML_FILTER_OPTIONS, rAreaLink.sFilterOptions );
3306         OUStringBuffer sValue;
3307         SvXMLUnitConverter::convertNumber( sValue, rAreaLink.GetColCount() );
3308         AddAttribute( XML_NAMESPACE_TABLE, XML_LAST_COLUMN_SPANNED, sValue.makeStringAndClear() );
3309         SvXMLUnitConverter::convertNumber( sValue, rAreaLink.GetRowCount() );
3310         AddAttribute( XML_NAMESPACE_TABLE, XML_LAST_ROW_SPANNED, sValue.makeStringAndClear() );
3311         if( rAreaLink.nRefresh )
3312         {
3313             SvXMLUnitConverter::convertTime( sValue, (double)rAreaLink.nRefresh / 86400 );
3314             AddAttribute( XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, sValue.makeStringAndClear() );
3315         }
3316         SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_CELL_RANGE_SOURCE, sal_True, sal_True );
3317     }
3318 }
3319 
exportAnnotationMeta(const uno::Reference<drawing::XShape> & xShape)3320 void ScXMLExport::exportAnnotationMeta( const uno::Reference < drawing::XShape >& xShape)
3321 {
3322     if (pCurrentCell && pCurrentCell->xNoteShape.is() && pCurrentCell->xNoteShape.get() == xShape.get() && pCurrentCell->xAnnotation.is())
3323     {
3324         rtl::OUString sAuthor(pCurrentCell->xAnnotation->getAuthor());
3325         if (sAuthor.getLength())
3326         {
3327             SvXMLElementExport aCreatorElem( *this, XML_NAMESPACE_DC,
3328                                                 XML_CREATOR, sal_True,
3329                                                 sal_False );
3330             Characters(sAuthor);
3331         }
3332 
3333         String aDate(pCurrentCell->xAnnotation->getDate());
3334         if (pDoc)
3335         {
3336             SvNumberFormatter* pNumForm = pDoc->GetFormatTable();
3337             double fDate;
3338             sal_uInt32 nfIndex = pNumForm->GetFormatIndex(NF_DATE_SYS_DDMMYYYY, LANGUAGE_SYSTEM);
3339             if (pNumForm->IsNumberFormat(aDate, nfIndex, fDate))
3340             {
3341                 rtl::OUStringBuffer sBuf;
3342                 GetMM100UnitConverter().convertDateTime(sBuf, fDate,sal_True);
3343                 SvXMLElementExport aDateElem( *this, XML_NAMESPACE_DC,
3344                                                 XML_DATE, sal_True,
3345                                                 sal_False );
3346                 Characters(sBuf.makeStringAndClear());
3347             }
3348             else
3349             {
3350                 SvXMLElementExport aDateElem( *this, XML_NAMESPACE_META,
3351                                                 XML_DATE_STRING, sal_True,
3352                                                 sal_False );
3353                 Characters(rtl::OUString(aDate));
3354             }
3355         }
3356         else
3357         {
3358             SvXMLElementExport aDateElem( *this, XML_NAMESPACE_META,
3359                                             XML_DATE_STRING, sal_True,
3360                                             sal_False );
3361             Characters(rtl::OUString(aDate));
3362         }
3363     }
3364 }
3365 
WriteAnnotation(ScMyCell & rMyCell)3366 void ScXMLExport::WriteAnnotation(ScMyCell& rMyCell)
3367 {
3368     if( rMyCell.bHasAnnotation && rMyCell.xAnnotation.is())
3369     {
3370 /*      rtl::OUString sAuthor(rMyCell.xAnnotation->getAuthor());
3371         if (sAuthor.getLength())
3372         {
3373             SvXMLElementExport aCreatorElem( *this, XML_NAMESPACE_DC,
3374                                                 XML_CREATOR, sal_True,
3375                                                 sal_False );
3376             rtl::OUString sAuthor(sAuthor);
3377             Characters(sAuthor);
3378         }
3379 
3380         String aDate(rMyCell.xAnnotation->getDate());
3381         if (pDoc)
3382         {
3383             SvNumberFormatter* pNumForm(pDoc->GetFormatTable());
3384             double fDate;
3385             sal_uInt32 nfIndex = pNumForm->GetFormatIndex(NF_DATE_SYS_DDMMYYYY, LANGUAGE_SYSTEM);
3386             if (pNumForm->IsNumberFormat(aDate, nfIndex, fDate))
3387             {
3388                 rtl::OUStringBuffer sBuf;
3389                 GetMM100UnitConverter().convertDateTime(sBuf, fDate);
3390                 SvXMLElementExport aDateElem( *this, XML_NAMESPACE_DC,
3391                                                 XML_DATE, sal_True,
3392                                                 sal_False );
3393                 Characters(sBuf.makeStringAndClear());
3394             }
3395             else
3396             {
3397                 SvXMLElementExport aDateElem( *this, XML_NAMESPACE_META,
3398                                                 XML_DATE_STRING, sal_True,
3399                                                 sal_False );
3400                 Characters(rtl::OUString(aDate));
3401             }
3402         }
3403         else
3404         {
3405             SvXMLElementExport aDateElem( *this, XML_NAMESPACE_META,
3406                                             XML_DATE_STRING, sal_True,
3407                                             sal_False );
3408             Characters(rtl::OUString(aDate));
3409         }*/
3410 
3411         if (rMyCell.xAnnotation->getIsVisible())
3412             AddAttribute(XML_NAMESPACE_OFFICE, XML_DISPLAY, XML_TRUE);
3413 
3414         pCurrentCell = &rMyCell;
3415 
3416         if(rMyCell.xNoteShape.is())
3417             GetShapeExport()->exportShape(rMyCell.xNoteShape, SEF_DEFAULT|SEF_EXPORT_ANNOTATION, NULL);
3418 
3419         pCurrentCell = NULL;
3420 
3421         rMyCell.xNoteShape.clear();
3422     }
3423 }
3424 
WriteDetective(const ScMyCell & rMyCell)3425 void ScXMLExport::WriteDetective( const ScMyCell& rMyCell )
3426 {
3427     if( rMyCell.bHasDetectiveObj || rMyCell.bHasDetectiveOp )
3428     {
3429         const ScMyDetectiveObjVec& rObjVec = rMyCell.aDetectiveObjVec;
3430         const ScMyDetectiveOpVec& rOpVec = rMyCell.aDetectiveOpVec;
3431         sal_Int32 nObjCount(rObjVec.size());
3432         sal_Int32 nOpCount(rOpVec.size());
3433         if( nObjCount || nOpCount )
3434         {
3435             SvXMLElementExport aDetElem( *this, XML_NAMESPACE_TABLE, XML_DETECTIVE, sal_True, sal_True );
3436             OUString sString;
3437             ScMyDetectiveObjVec::const_iterator aObjItr(rObjVec.begin());
3438             ScMyDetectiveObjVec::const_iterator aEndObjItr(rObjVec.end());
3439             while(aObjItr != aEndObjItr)
3440             {
3441                 if (aObjItr->eObjType != SC_DETOBJ_CIRCLE)
3442                 {
3443                     if( (aObjItr->eObjType == SC_DETOBJ_ARROW) || (aObjItr->eObjType == SC_DETOBJ_TOOTHERTAB))
3444                     {
3445                         ScRangeStringConverter::GetStringFromRange( sString, aObjItr->aSourceRange, pDoc, FormulaGrammar::CONV_OOO );
3446                         AddAttribute( XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, sString );
3447                     }
3448                     ScXMLConverter::GetStringFromDetObjType( sString, aObjItr->eObjType );
3449                     AddAttribute( XML_NAMESPACE_TABLE, XML_DIRECTION, sString );
3450                     if( aObjItr->bHasError )
3451                         AddAttribute( XML_NAMESPACE_TABLE, XML_CONTAINS_ERROR, XML_TRUE );
3452                 }
3453                 else
3454                     AddAttribute( XML_NAMESPACE_TABLE, XML_MARKED_INVALID, XML_TRUE );
3455                 SvXMLElementExport aRangeElem( *this, XML_NAMESPACE_TABLE, XML_HIGHLIGHTED_RANGE, sal_True, sal_True );
3456                 ++aObjItr;
3457             }
3458             OUStringBuffer aBuffer;
3459             ScMyDetectiveOpVec::const_iterator aOpItr(rOpVec.begin());
3460             ScMyDetectiveOpVec::const_iterator aEndOpItr(rOpVec.end());
3461             while(aOpItr != aEndOpItr)
3462             {
3463                 OUString sOpString;
3464                 ScXMLConverter::GetStringFromDetOpType( sOpString, aOpItr->eOpType );
3465                 AddAttribute( XML_NAMESPACE_TABLE, XML_NAME, sOpString );
3466                 SvXMLUnitConverter::convertNumber( aBuffer, aOpItr->nIndex );
3467                 AddAttribute( XML_NAMESPACE_TABLE, XML_INDEX, aBuffer.makeStringAndClear() );
3468                 SvXMLElementExport aRangeElem( *this, XML_NAMESPACE_TABLE, XML_OPERATION, sal_True, sal_True );
3469                 ++aOpItr;
3470             }
3471         }
3472     }
3473 }
3474 
SetRepeatAttribute(sal_Int32 nEqualCellCount,bool bIncProgress)3475 void ScXMLExport::SetRepeatAttribute(sal_Int32 nEqualCellCount, bool bIncProgress)
3476 {
3477     // nEqualCellCount is additional cells, so the attribute value is nEqualCellCount+1
3478     if (nEqualCellCount > 0)
3479     {
3480         sal_Int32 nTemp(nEqualCellCount + 1);
3481         OUString sOUEqualCellCount(OUString::valueOf(nTemp));
3482         AddAttribute(sAttrColumnsRepeated, sOUEqualCellCount);
3483         if (bIncProgress)
3484             IncrementProgressBar(sal_False, nEqualCellCount);
3485     }
3486 }
3487 
IsCellTypeEqual(const ScMyCell & aCell1,const ScMyCell & aCell2) const3488 sal_Bool ScXMLExport::IsCellTypeEqual (const ScMyCell& aCell1, const ScMyCell& aCell2) const
3489 {
3490     return (aCell1.nType == aCell2.nType);
3491 }
3492 
IsEditCell(const com::sun::star::table::CellAddress & aAddress,ScMyCell * pMyCell) const3493 sal_Bool ScXMLExport::IsEditCell(const com::sun::star::table::CellAddress& aAddress, ScMyCell* pMyCell) const
3494 {
3495     ScAddress aCoreAddress(static_cast<SCCOL>(aAddress.Column),
3496                         static_cast<SCROW>(aAddress.Row),
3497                         static_cast<SCTAB>(aAddress.Sheet));
3498     ScBaseCell* pBaseCell = GetDocument() ? GetDocument()->GetCell(aCoreAddress) : NULL;
3499     if (pMyCell)
3500         pMyCell->pBaseCell = pBaseCell;
3501 
3502     if (pBaseCell)
3503         return (pBaseCell->GetCellType() == CELLTYPE_EDIT);
3504     return sal_False;
3505 }
3506 
3507 //UNUSED2008-05  sal_Bool ScXMLExport::IsEditCell(const com::sun::star::uno::Reference <com::sun::star::table::XCell>& xCell) const
3508 //UNUSED2008-05  {
3509 //UNUSED2008-05      uno::Reference<sheet::XCellAddressable> xAddressable (xCell, uno::UNO_QUERY);
3510 //UNUSED2008-05      if ( xAddressable.is() )
3511 //UNUSED2008-05          return IsEditCell(xAddressable->getCellAddress());
3512 //UNUSED2008-05      return sal_False;
3513 //UNUSED2008-05  }
3514 
IsEditCell(ScMyCell & rCell) const3515 sal_Bool ScXMLExport::IsEditCell(ScMyCell& rCell) const
3516 {
3517     if (rCell.bKnowWhetherIsEditCell)
3518         return rCell.bIsEditCell;
3519     else
3520     {
3521         rCell.bIsEditCell = IsEditCell(rCell.aCellAddress, &rCell);
3522         rCell.bKnowWhetherIsEditCell = sal_True;
3523         return rCell.bIsEditCell;
3524     }
3525 }
3526 
IsMultiLineFormulaCell(ScMyCell & rCell) const3527 sal_Bool ScXMLExport::IsMultiLineFormulaCell(ScMyCell& rCell) const
3528 {
3529     if (rCell.pBaseCell)
3530     {
3531         if (rCell.pBaseCell->GetCellType() != CELLTYPE_FORMULA)
3532             return false;
3533 
3534         return static_cast<ScFormulaCell*>(rCell.pBaseCell)->IsMultilineResult();
3535     }
3536 
3537     ScAddress aAddr(static_cast<SCCOL>(rCell.aCellAddress.Column),
3538                     static_cast<SCROW>(rCell.aCellAddress.Row),
3539                     static_cast<SCTAB>(rCell.aCellAddress.Sheet));
3540     ScBaseCell* pBaseCell = pDoc ? pDoc->GetCell(aAddr) : NULL;
3541     if (!pBaseCell)
3542         return false;
3543 
3544     rCell.pBaseCell = pBaseCell;
3545     if (rCell.pBaseCell->GetCellType() != CELLTYPE_FORMULA)
3546         return false;
3547 
3548     return static_cast<ScFormulaCell*>(rCell.pBaseCell)->IsMultilineResult();
3549 }
3550 
3551 //UNUSED2008-05  sal_Bool ScXMLExport::IsAnnotationEqual(const uno::Reference<table::XCell>& /* xCell1 */,
3552 //UNUSED2008-05                                          const uno::Reference<table::XCell>& /* xCell2 */)
3553 //UNUSED2008-05  {
3554 //UNUSED2008-05      // no longer compareable, because the position and size and other attributes can also differ
3555 //UNUSED2008-05
3556 //UNUSED2008-05  /* uno::Reference<sheet::XSheetAnnotationAnchor> xSheetAnnotationAnchor1(xCell1, uno::UNO_QUERY);
3557 //UNUSED2008-05      uno::Reference<sheet::XSheetAnnotationAnchor> xSheetAnnotationAnchor2(xCell2, uno::UNO_QUERY);
3558 //UNUSED2008-05      if (xSheetAnnotationAnchor1.is() && xSheetAnnotationAnchor2.is())
3559 //UNUSED2008-05      {
3560 //UNUSED2008-05          uno::Reference <sheet::XSheetAnnotation> xSheetAnnotation1(xSheetAnnotationAnchor1->getAnnotation());
3561 //UNUSED2008-05          uno::Reference <sheet::XSheetAnnotation> xSheetAnnotation2(xSheetAnnotationAnchor2->getAnnotation());
3562 //UNUSED2008-05          uno::Reference<text::XSimpleText> xSimpleText1(xSheetAnnotation1, uno::UNO_QUERY);
3563 //UNUSED2008-05          uno::Reference<text::XSimpleText> xSimpleText2(xSheetAnnotation2, uno::UNO_QUERY);
3564 //UNUSED2008-05          if (xSheetAnnotation1.is() && xSimpleText1.is() &&
3565 //UNUSED2008-05              xSheetAnnotation2.is() && xSimpleText2.is())
3566 //UNUSED2008-05          {
3567 //UNUSED2008-05              rtl::OUString sText1(xSimpleText1->getString());
3568 //UNUSED2008-05              rtl::OUString sText2(xSimpleText2->getString());
3569 //UNUSED2008-05              sal_Int32 nLength1(sText1.getLength());
3570 //UNUSED2008-05              sal_Int32 nLength2(sText2.getLength());
3571 //UNUSED2008-05              if (nLength1 && nLength2)
3572 //UNUSED2008-05                  if (sText1 == sText2 &&
3573 //UNUSED2008-05                      xSheetAnnotation1->getAuthor() == xSheetAnnotation2->getAuthor() &&
3574 //UNUSED2008-05                      xSheetAnnotation1->getDate() == xSheetAnnotation2->getDate() &&
3575 //UNUSED2008-05                      xSheetAnnotation1->getIsVisible() == xSheetAnnotation2->getIsVisible())
3576 //UNUSED2008-05                      return sal_True;
3577 //UNUSED2008-05                  else
3578 //UNUSED2008-05                      return sal_False;
3579 //UNUSED2008-05              else
3580 //UNUSED2008-05                  if (nLength1 || nLength2)
3581 //UNUSED2008-05                      return sal_False;
3582 //UNUSED2008-05                  else
3583 //UNUSED2008-05                      return sal_True;
3584 //UNUSED2008-05          }
3585 //UNUSED2008-05      }*/
3586 //UNUSED2008-05      return sal_False;
3587 //UNUSED2008-05  }
3588 
IsCellEqual(ScMyCell & aCell1,ScMyCell & aCell2)3589 sal_Bool ScXMLExport::IsCellEqual (ScMyCell& aCell1, ScMyCell& aCell2)
3590 {
3591     ScAddress aCellPos1;
3592     ScUnoConversion::FillScAddress( aCellPos1, aCell1.aCellAddress );
3593     ScAddress aCellPos2;
3594     ScUnoConversion::FillScAddress( aCellPos2, aCell2.aCellAddress );
3595     sal_Bool bIsEqual = sal_False;
3596     if( !aCell1.bIsMergedBase && !aCell2.bIsMergedBase &&
3597         aCell1.bIsCovered == aCell2.bIsCovered &&
3598         !aCell1.bIsMatrixBase && !aCell2.bIsMatrixBase &&
3599         aCell1.bIsMatrixCovered == aCell2.bIsMatrixCovered &&
3600         aCell1.bHasAnnotation == aCell2.bHasAnnotation &&
3601         !aCell1.bHasShape && !aCell2.bHasShape &&
3602         aCell1.bHasAreaLink == aCell2.bHasAreaLink &&
3603         !aCell1.bHasDetectiveObj && !aCell2.bHasDetectiveObj)
3604     {
3605         if( (aCell1.bHasAreaLink &&
3606             (aCell1.aAreaLink.GetColCount() == 1) &&
3607             (aCell2.aAreaLink.GetColCount() == 1) &&
3608             aCell1.aAreaLink.Compare( aCell2.aAreaLink ) ) ||
3609             !aCell1.bHasAreaLink )
3610         {
3611             if (!aCell1.bHasAnnotation || (aCell1.bHasAnnotation && sal_False/*IsAnnotationEqual(aCell1.xCell, aCell2.xCell)*/)) // no longer compareable
3612             {
3613                 if ((((aCell1.nStyleIndex == aCell2.nStyleIndex) && (aCell1.bIsAutoStyle == aCell2.bIsAutoStyle)) ||
3614                      ((aCell1.nStyleIndex == aCell2.nStyleIndex) && (aCell1.nStyleIndex == -1))) &&
3615                     (aCell1.nValidationIndex == aCell2.nValidationIndex) &&
3616                     IsCellTypeEqual(aCell1, aCell2))
3617                 {
3618                     switch ( aCell1.nType )
3619                     {
3620                     case table::CellContentType_EMPTY :
3621                         {
3622                             bIsEqual = sal_True;
3623                         }
3624                         break;
3625                     case table::CellContentType_VALUE :
3626                         {
3627                             if(!aCell1.bHasDoubleValue)
3628                             {
3629                                 aCell1.fValue = pDoc->GetValue( aCellPos1 );
3630                                 aCell1.bHasDoubleValue = sal_True;
3631                             }
3632                             if (!aCell2.bHasDoubleValue)
3633                             {
3634                                 aCell2.fValue = pDoc->GetValue( aCellPos2 );
3635                                 aCell2.bHasDoubleValue = sal_True;
3636                             }
3637                             // #i29101# number format may be different from column default styles,
3638                             // but can lead to different value types, so it must also be compared
3639                             bIsEqual = (aCell1.nNumberFormat == aCell2.nNumberFormat) &&
3640                                        (aCell1.fValue == aCell2.fValue);
3641                         }
3642                         break;
3643                     case table::CellContentType_TEXT :
3644                         {
3645                             if (IsEditCell(aCell1) || IsEditCell(aCell2))
3646                                 bIsEqual = sal_False;
3647                             else
3648                             {
3649                                 if (GetCellText(aCell1, aCellPos1) && GetCellText(aCell2, aCellPos2))
3650                                 {
3651                                     bIsEqual = (aCell1.sStringValue == aCell2.sStringValue) &&
3652                                                (lcl_GetRawString(pDoc, aCellPos1) == lcl_GetRawString(pDoc, aCellPos2));
3653                                 }
3654                                 else
3655                                     bIsEqual = sal_False;
3656                             }
3657                         }
3658                         break;
3659                     case table::CellContentType_FORMULA :
3660                         {
3661                             bIsEqual = sal_False;
3662                         }
3663                         break;
3664                     default :
3665                         {
3666                             bIsEqual = sal_False;
3667                         }
3668                         break;
3669                     }
3670                 }
3671             }
3672         }
3673     }
3674     return bIsEqual;
3675 }
3676 
WriteCalculationSettings(const uno::Reference<sheet::XSpreadsheetDocument> & xSpreadDoc)3677 void ScXMLExport::WriteCalculationSettings(const uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc)
3678 {
3679     uno::Reference<beans::XPropertySet> xPropertySet(xSpreadDoc, uno::UNO_QUERY);
3680     if (xPropertySet.is())
3681     {
3682         sal_Bool bCalcAsShown (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_CALCASSHOWN))) ));
3683         sal_Bool bIgnoreCase (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_IGNORECASE))) ));
3684         sal_Bool bLookUpLabels (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_LOOKUPLABELS))) ));
3685         sal_Bool bMatchWholeCell (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_MATCHWHOLE))) ));
3686         sal_Bool bUseRegularExpressions (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_REGEXENABLED))) ));
3687         sal_Bool bIsIterationEnabled (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITERENABLED))) ));
3688         sal_uInt16 nYear2000 (pDoc ? pDoc->GetDocOptions().GetYear2000() : 0);
3689         sal_Int32 nIterationCount(100);
3690         xPropertySet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITERCOUNT))) >>= nIterationCount;
3691         double fIterationEpsilon = 0;
3692         xPropertySet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITEREPSILON))) >>= fIterationEpsilon;
3693         util::Date aNullDate;
3694         xPropertySet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_NULLDATE))) >>= aNullDate;
3695         if (bCalcAsShown || bIgnoreCase || !bLookUpLabels || !bMatchWholeCell || !bUseRegularExpressions ||
3696             bIsIterationEnabled || nIterationCount != 100 || !::rtl::math::approxEqual(fIterationEpsilon, 0.001) ||
3697             aNullDate.Day != 30 || aNullDate.Month != 12 || aNullDate.Year != 1899 || nYear2000 != 1930)
3698         {
3699             if (bIgnoreCase)
3700                 AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_FALSE);
3701             if (bCalcAsShown)
3702                 AddAttribute(XML_NAMESPACE_TABLE, XML_PRECISION_AS_SHOWN, XML_TRUE);
3703             if (!bMatchWholeCell)
3704                 AddAttribute(XML_NAMESPACE_TABLE, XML_SEARCH_CRITERIA_MUST_APPLY_TO_WHOLE_CELL, XML_FALSE);
3705             if (!bLookUpLabels)
3706                 AddAttribute(XML_NAMESPACE_TABLE, XML_AUTOMATIC_FIND_LABELS, XML_FALSE);
3707             if (!bUseRegularExpressions)
3708                 AddAttribute(XML_NAMESPACE_TABLE, XML_USE_REGULAR_EXPRESSIONS, XML_FALSE);
3709             if (nYear2000 != 1930)
3710             {
3711                 rtl::OUStringBuffer sBuffer;
3712                 GetMM100UnitConverter().convertNumber(sBuffer, nYear2000);
3713                 AddAttribute(XML_NAMESPACE_TABLE, XML_NULL_YEAR, sBuffer.makeStringAndClear());
3714             }
3715             SvXMLElementExport aCalcSettings(*this, XML_NAMESPACE_TABLE, XML_CALCULATION_SETTINGS, sal_True, sal_True);
3716             {
3717                 if (aNullDate.Day != 30 || aNullDate.Month != 12 || aNullDate.Year != 1899)
3718                 {
3719                     rtl::OUStringBuffer sDate;
3720                     GetMM100UnitConverter().convertDateTime(sDate, 0.0, aNullDate);
3721                     AddAttribute(XML_NAMESPACE_TABLE, XML_DATE_VALUE, sDate.makeStringAndClear());
3722                     SvXMLElementExport aElemNullDate(*this, XML_NAMESPACE_TABLE, XML_NULL_DATE, sal_True, sal_True);
3723                 }
3724                 if (bIsIterationEnabled || nIterationCount != 100 || !::rtl::math::approxEqual(fIterationEpsilon, 0.001))
3725                 {
3726                     rtl::OUStringBuffer sBuffer;
3727                     if (bIsIterationEnabled)
3728                         AddAttribute(XML_NAMESPACE_TABLE, XML_STATUS, XML_ENABLE);
3729                     if (nIterationCount != 100)
3730                     {
3731                         GetMM100UnitConverter().convertNumber(sBuffer, nIterationCount);
3732                         AddAttribute(XML_NAMESPACE_TABLE, XML_STEPS, sBuffer.makeStringAndClear());
3733                     }
3734                     if (!::rtl::math::approxEqual(fIterationEpsilon, 0.001))
3735                     {
3736                         GetMM100UnitConverter().convertDouble(sBuffer, fIterationEpsilon);
3737                         AddAttribute(XML_NAMESPACE_TABLE, XML_MAXIMUM_DIFFERENCE, sBuffer.makeStringAndClear());
3738                     }
3739                     SvXMLElementExport aElemIteration(*this, XML_NAMESPACE_TABLE, XML_ITERATION, sal_True, sal_True);
3740                 }
3741             }
3742         }
3743     }
3744 }
3745 
WriteTableSource()3746 void ScXMLExport::WriteTableSource()
3747 {
3748     uno::Reference <sheet::XSheetLinkable> xLinkable (xCurrentTable, uno::UNO_QUERY);
3749     if (xLinkable.is() && GetModel().is())
3750     {
3751         sheet::SheetLinkMode nMode (xLinkable->getLinkMode());
3752         if (nMode != sheet::SheetLinkMode_NONE)
3753         {
3754             rtl::OUString sLink (xLinkable->getLinkUrl());
3755             uno::Reference <beans::XPropertySet> xProps (GetModel(), uno::UNO_QUERY);
3756             if (xProps.is())
3757             {
3758                 uno::Reference <container::XIndexAccess> xIndex(xProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_SHEETLINKS))), uno::UNO_QUERY);
3759                 if (xIndex.is())
3760                 {
3761                     sal_Int32 nCount(xIndex->getCount());
3762                     if (nCount)
3763                     {
3764                         sal_Bool bFound(sal_False);
3765                         uno::Reference <beans::XPropertySet> xLinkProps;
3766                         for (sal_Int32 i = 0; (i < nCount) && !bFound; ++i)
3767                         {
3768                             xLinkProps.set(xIndex->getByIndex(i), uno::UNO_QUERY);
3769                             if (xLinkProps.is())
3770                             {
3771                                 rtl::OUString sNewLink;
3772                                 if (xLinkProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_LINKURL))) >>= sNewLink)
3773                                     bFound = sLink.equals(sNewLink);
3774                             }
3775                         }
3776                         if (bFound && xLinkProps.is())
3777                         {
3778                             rtl::OUString sFilter;
3779                             rtl::OUString sFilterOptions;
3780                             rtl::OUString sTableName (xLinkable->getLinkSheetName());
3781                             sal_Int32 nRefresh(0);
3782                             xLinkProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_FILTER))) >>= sFilter;
3783                             xLinkProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_FILTOPT))) >>= sFilterOptions;
3784                             xLinkProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_REFDELAY))) >>= nRefresh;
3785                             if (sLink.getLength())
3786                             {
3787                                 AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE);
3788                                 AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, GetRelativeReference(sLink));
3789                                 if (sTableName.getLength())
3790                                     AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, sTableName);
3791                                 if (sFilter.getLength())
3792                                     AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_NAME, sFilter);
3793                                 if (sFilterOptions.getLength())
3794                                     AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_OPTIONS, sFilterOptions);
3795                                 if (nMode != sheet::SheetLinkMode_NORMAL)
3796                                     AddAttribute(XML_NAMESPACE_TABLE, XML_MODE, XML_COPY_RESULTS_ONLY);
3797                                 if( nRefresh )
3798                                 {
3799                                     rtl::OUStringBuffer sBuffer;
3800                                     SvXMLUnitConverter::convertTime( sBuffer, (double)nRefresh / 86400 );
3801                                     AddAttribute( XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, sBuffer.makeStringAndClear() );
3802                                 }
3803                                 SvXMLElementExport aSourceElem(*this, XML_NAMESPACE_TABLE, XML_TABLE_SOURCE, sal_True, sal_True);
3804                             }
3805                         }
3806                     }
3807                 }
3808             }
3809         }
3810     }
3811 }
3812 
3813 // core implementation
WriteScenario()3814 void ScXMLExport::WriteScenario()
3815 {
3816     if (pDoc && pDoc->IsScenario(static_cast<SCTAB>(nCurrentTable)))
3817     {
3818         String      sComment;
3819         Color       aColor;
3820         sal_uInt16  nFlags;
3821         pDoc->GetScenarioData(static_cast<SCTAB>(nCurrentTable), sComment, aColor, nFlags);
3822         if (!(nFlags & SC_SCENARIO_SHOWFRAME))
3823             AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_BORDER, XML_FALSE);
3824         rtl::OUStringBuffer aBuffer;
3825         SvXMLUnitConverter::convertColor(aBuffer, aColor);
3826         AddAttribute(XML_NAMESPACE_TABLE, XML_BORDER_COLOR, aBuffer.makeStringAndClear());
3827         if (!(nFlags & SC_SCENARIO_TWOWAY))
3828             AddAttribute(XML_NAMESPACE_TABLE, XML_COPY_BACK, XML_FALSE);
3829         if (!(nFlags & SC_SCENARIO_ATTRIB))
3830             AddAttribute(XML_NAMESPACE_TABLE, XML_COPY_STYLES, XML_FALSE);
3831         if (nFlags & SC_SCENARIO_VALUE)
3832             AddAttribute(XML_NAMESPACE_TABLE, XML_COPY_FORMULAS, XML_FALSE);
3833         if (nFlags & SC_SCENARIO_PROTECT)
3834             AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TRUE);
3835         SvXMLUnitConverter::convertBool(aBuffer, pDoc->IsActiveScenario(static_cast<SCTAB>(nCurrentTable)));
3836         AddAttribute(XML_NAMESPACE_TABLE, XML_IS_ACTIVE, aBuffer.makeStringAndClear());
3837         const ScRangeList* pRangeList = pDoc->GetScenarioRanges(static_cast<SCTAB>(nCurrentTable));
3838         rtl::OUString sRangeListStr;
3839         ScRangeStringConverter::GetStringFromRangeList( sRangeListStr, pRangeList, pDoc, FormulaGrammar::CONV_OOO );
3840         AddAttribute(XML_NAMESPACE_TABLE, XML_SCENARIO_RANGES, sRangeListStr);
3841         if (sComment.Len())
3842             AddAttribute(XML_NAMESPACE_TABLE, XML_COMMENT, rtl::OUString(sComment));
3843         SvXMLElementExport aElem(*this, XML_NAMESPACE_TABLE, XML_SCENARIO, sal_True, sal_True);
3844     }
3845 }
3846 
WriteTheLabelRanges(const uno::Reference<sheet::XSpreadsheetDocument> & xSpreadDoc)3847 void ScXMLExport::WriteTheLabelRanges( const uno::Reference< sheet::XSpreadsheetDocument >& xSpreadDoc )
3848 {
3849     uno::Reference< beans::XPropertySet > xDocProp( xSpreadDoc, uno::UNO_QUERY );
3850     if( !xDocProp.is() ) return;
3851 
3852     sal_Int32 nCount(0);
3853     uno::Reference< container::XIndexAccess > xColRangesIAccess(xDocProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_COLLABELRNG ) ) ), uno::UNO_QUERY);
3854     if( xColRangesIAccess.is() )
3855         nCount += xColRangesIAccess->getCount();
3856 
3857     uno::Reference< container::XIndexAccess > xRowRangesIAccess(xDocProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_ROWLABELRNG ) ) ), uno::UNO_QUERY);
3858     if( xRowRangesIAccess.is() )
3859         nCount += xRowRangesIAccess->getCount();
3860 
3861     if( nCount )
3862     {
3863         SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_LABEL_RANGES, sal_True, sal_True );
3864         WriteLabelRanges( xColRangesIAccess, sal_True );
3865         WriteLabelRanges( xRowRangesIAccess, sal_False );
3866     }
3867 }
3868 
WriteLabelRanges(const uno::Reference<container::XIndexAccess> & xRangesIAccess,sal_Bool bColumn)3869 void ScXMLExport::WriteLabelRanges( const uno::Reference< container::XIndexAccess >& xRangesIAccess, sal_Bool bColumn )
3870 {
3871     if( !xRangesIAccess.is() ) return;
3872 
3873     sal_Int32 nCount(xRangesIAccess->getCount());
3874     for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
3875     {
3876         uno::Reference< sheet::XLabelRange > xRange(xRangesIAccess->getByIndex( nIndex ), uno::UNO_QUERY);
3877         if( xRange.is() )
3878         {
3879             OUString sRangeStr;
3880             table::CellRangeAddress aCellRange( xRange->getLabelArea() );
3881             ScRangeStringConverter::GetStringFromRange( sRangeStr, aCellRange, pDoc, FormulaGrammar::CONV_OOO );
3882             AddAttribute( XML_NAMESPACE_TABLE, XML_LABEL_CELL_RANGE_ADDRESS, sRangeStr );
3883             aCellRange = xRange->getDataArea();
3884             ScRangeStringConverter::GetStringFromRange( sRangeStr, aCellRange, pDoc, FormulaGrammar::CONV_OOO );
3885             AddAttribute( XML_NAMESPACE_TABLE, XML_DATA_CELL_RANGE_ADDRESS, sRangeStr );
3886             AddAttribute( XML_NAMESPACE_TABLE, XML_ORIENTATION, bColumn ? XML_COLUMN : XML_ROW );
3887             SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_LABEL_RANGE, sal_True, sal_True );
3888         }
3889     }
3890 }
3891 
WriteNamedExpressions(const com::sun::star::uno::Reference<com::sun::star::sheet::XSpreadsheetDocument> & xSpreadDoc,sal_Int16 nWhichTable)3892 void ScXMLExport::WriteNamedExpressions(const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheetDocument>& xSpreadDoc, sal_Int16 nWhichTable)
3893 {
3894     uno::Reference <beans::XPropertySet> xPropertySet (xSpreadDoc, uno::UNO_QUERY);
3895     if (xPropertySet.is())
3896     {
3897         uno::Reference <sheet::XNamedRanges2> xNamedRanges(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_NAMEDRANGES))), uno::UNO_QUERY);
3898         CheckAttrList();
3899         if (xNamedRanges.is())
3900         {
3901             uno::Sequence <sheet::RangeScopeName> aRangesNames(xNamedRanges->getElementScopeNames());//modified 20091211, range scope name support
3902             sal_Int32 nNamedRangesCount(aRangesNames.getLength());
3903             if (nNamedRangesCount > 0)
3904             {
3905                 if (pDoc)
3906                 {
3907                     ScRangeName* pNamedRanges(pDoc->GetRangeName());
3908                     SvXMLElementExport aElemNEs(*this, XML_NAMESPACE_TABLE, XML_NAMED_EXPRESSIONS, sal_True, sal_True);
3909                     for (sal_Int32 i = 0; i < nNamedRangesCount; ++i)
3910                     {
3911                         CheckAttrList();
3912                         //range scope name support -start
3913                         rtl::OUString sNamedRange(aRangesNames[i].RangeName);
3914                         rtl::OUString sRangeScope(aRangesNames[i].ScopeName);
3915                         SCTAB nScopeNumber = MAXTABCOUNT;
3916                         String sScopeStr(sRangeScope);
3917                         if(sScopeStr !=EMPTY_STRING)
3918                         {
3919                             pDoc->GetTable(sScopeStr,nScopeNumber);
3920                             if( nWhichTable != nScopeNumber || nScopeNumber ==MAXTABCOUNT)
3921                                 continue;
3922                         }
3923                         else if( nWhichTable !=MAXTABCOUNT)
3924                             continue;
3925                         uno::Reference <sheet::XNamedRange2> xNamedRange(xNamedRanges->getByScopeName(sRangeScope,sNamedRange), uno::UNO_QUERY);
3926                         //range scope name support
3927                         if (xNamedRange.is())
3928                         {
3929                             uno::Reference <container::XNamed> xNamed (xNamedRange, uno::UNO_QUERY);
3930                             uno::Reference <sheet::XCellRangeReferrer> xCellRangeReferrer (xNamedRange, uno::UNO_QUERY);
3931                             if (xNamed.is() && xCellRangeReferrer.is())
3932                             {
3933                                 rtl::OUString sOUName(xNamed->getName());
3934 
3935                                 AddAttribute(sAttrName, sOUName);
3936 
3937                                 OUString sOUBaseCellAddress;
3938                                 ScRangeStringConverter::GetStringFromAddress( sOUBaseCellAddress,
3939                                     xNamedRange->getReferencePosition(), pDoc, FormulaGrammar::CONV_OOO, ' ', sal_False, SCA_ABS_3D );
3940                                 AddAttribute(XML_NAMESPACE_TABLE, XML_BASE_CELL_ADDRESS, sOUBaseCellAddress);
3941 
3942                                 sal_uInt16 nRangeIndex;
3943                                 String sName(sOUName);
3944                                 //range scope name support -start
3945                                 SCTAB nScopeName = MAXTABCOUNT;
3946                                 String sScopeName(sRangeScope);
3947                                 if(sScopeName !=EMPTY_STRING)
3948                                 {
3949                                     pDoc->GetTable(sScopeName,nScopeName);
3950                                 }
3951                                 pNamedRanges->SearchName(sName, nRangeIndex,nScopeName);
3952                                 //range scope name support - end
3953                                 ScRangeData* pNamedRange((*pNamedRanges)[nRangeIndex]); //should get directly and not with ScDocument
3954                                 String sContent;
3955                                 pNamedRange->GetSymbol(sContent, pDoc->GetStorageGrammar());
3956                                 rtl::OUString sOUTempContent(sContent);
3957                                 uno::Reference <table::XCellRange> xCellRange(xCellRangeReferrer->getReferredCells());
3958                                 if(xCellRange.is())
3959                                 {
3960                                     rtl::OUString sOUContent(sOUTempContent.copy(1, sOUTempContent.getLength() - 2));
3961                                     AddAttribute(XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, sOUContent);
3962                                     sal_Int32 nRangeType(xNamedRange->getType());
3963                                     rtl::OUStringBuffer sBufferRangeType;
3964                                     if ((nRangeType & sheet::NamedRangeFlag::COLUMN_HEADER) == sheet::NamedRangeFlag::COLUMN_HEADER)
3965                                         sBufferRangeType.append(GetXMLToken(XML_REPEAT_COLUMN));
3966                                     if ((nRangeType & sheet::NamedRangeFlag::ROW_HEADER) == sheet::NamedRangeFlag::ROW_HEADER)
3967                                     {
3968                                         if (sBufferRangeType.getLength() > 0)
3969                                             sBufferRangeType.appendAscii(" ");
3970                                         sBufferRangeType.append(GetXMLToken(XML_REPEAT_ROW));
3971                                     }
3972                                     if ((nRangeType & sheet::NamedRangeFlag::FILTER_CRITERIA) == sheet::NamedRangeFlag::FILTER_CRITERIA)
3973                                     {
3974                                         if (sBufferRangeType.getLength() > 0)
3975                                             sBufferRangeType.appendAscii(" ");
3976                                         sBufferRangeType.append(GetXMLToken(XML_FILTER));
3977                                     }
3978                                     if ((nRangeType & sheet::NamedRangeFlag::PRINT_AREA) == sheet::NamedRangeFlag::PRINT_AREA)
3979                                     {
3980                                         if (sBufferRangeType.getLength() > 0)
3981                                             sBufferRangeType.appendAscii(" ");
3982                                         sBufferRangeType.append(GetXMLToken(XML_PRINT_RANGE));
3983                                     }
3984                                     rtl::OUString sRangeType = sBufferRangeType.makeStringAndClear();
3985                                     if (sRangeType.getLength())
3986                                         AddAttribute(XML_NAMESPACE_TABLE, XML_RANGE_USABLE_AS, sRangeType);
3987                                     SvXMLElementExport aElemNR(*this, XML_NAMESPACE_TABLE, XML_NAMED_RANGE, sal_True, sal_True);
3988                                 }
3989                                 else
3990                                 {
3991                                     AddAttribute(XML_NAMESPACE_TABLE, XML_EXPRESSION, sOUTempContent);
3992                                     SvXMLElementExport aElemNE(*this, XML_NAMESPACE_TABLE, XML_NAMED_EXPRESSION, sal_True, sal_True);
3993                                 }
3994                             }
3995                         }
3996                     }
3997                 }
3998             }
3999         }
4000     }
4001 }
4002 
WriteExternalRefCaches()4003 void ScXMLExport::WriteExternalRefCaches()
4004 {
4005     if (!pDoc)
4006         return;
4007 
4008     ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
4009     pRefMgr->resetSrcFileData(GetOrigFileName());
4010     sal_uInt16 nCount = pRefMgr->getExternalFileCount();
4011     for (sal_uInt16 nFileId = 0; nFileId < nCount; ++nFileId)
4012     {
4013         const String* pUrl = pRefMgr->getExternalFileName(nFileId);
4014         if (!pUrl)
4015             continue;
4016 
4017         vector<String> aTabNames;
4018         pRefMgr->getAllCachedTableNames(nFileId, aTabNames);
4019         if (aTabNames.empty())
4020             continue;
4021 
4022         for (vector<String>::const_iterator itr = aTabNames.begin(), itrEnd = aTabNames.end();
4023               itr != itrEnd; ++itr)
4024         {
4025             ScExternalRefCache::TableTypeRef pTable = pRefMgr->getCacheTable(nFileId, *itr, false);
4026             if (!pTable.get() || !pTable->isReferenced())
4027                 continue;
4028 
4029             OUStringBuffer aBuf;
4030             aBuf.append(sal_Unicode('\''));
4031             aBuf.append(*pUrl);
4032             aBuf.append(sal_Unicode('\''));
4033             aBuf.append(sal_Unicode('#'));
4034             aBuf.append(*itr);
4035             AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, aBuf.makeStringAndClear());
4036             AddAttribute(XML_NAMESPACE_TABLE, XML_PRINT, GetXMLToken(XML_FALSE));
4037             AddAttribute(XML_NAMESPACE_TABLE, XML_STYLE_NAME, sExternalRefTabStyleName);
4038             SvXMLElementExport aElemTable(*this, XML_NAMESPACE_TABLE, XML_TABLE, sal_True, sal_True);
4039             {
4040                 const ScExternalRefManager::SrcFileData* pExtFileData = pRefMgr->getExternalFileData(nFileId);
4041                 if (pExtFileData)
4042                 {
4043                     String aRelUrl;
4044                     if (pExtFileData->maRelativeName.Len())
4045                         aRelUrl = pExtFileData->maRelativeName;
4046                     else
4047                         aRelUrl = GetRelativeReference(pExtFileData->maRelativeName);
4048                     AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE);
4049                     AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, aRelUrl);
4050                     AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, *itr);
4051                     if (pExtFileData->maFilterName.Len())
4052                         AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_NAME, pExtFileData->maFilterName);
4053                     if (pExtFileData->maFilterOptions.Len())
4054                         AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_OPTIONS, pExtFileData->maFilterOptions);
4055                     AddAttribute(XML_NAMESPACE_TABLE, XML_MODE, XML_COPY_RESULTS_ONLY);
4056                 }
4057                 SvXMLElementExport aElemTableSource(*this, XML_NAMESPACE_TABLE, XML_TABLE_SOURCE, sal_True, sal_True);
4058             }
4059 
4060             // Determine maximum column count of used area, for repeated cells.
4061             SCCOL nMaxColsUsed = 1;     // assume that there is at least one cell somewhere..
4062             vector<SCROW> aRows;
4063             pTable->getAllRows(aRows);
4064             for (vector<SCROW>::const_iterator itrRow = aRows.begin(), itrRowEnd = aRows.end();
4065                   itrRow != itrRowEnd; ++itrRow)
4066             {
4067                 SCROW nRow = *itrRow;
4068                 vector<SCCOL> aCols;
4069                 pTable->getAllCols(nRow, aCols);
4070                 if (!aCols.empty())
4071                 {
4072                     SCCOL nCol = aCols.back();
4073                     if (nMaxColsUsed <= nCol)
4074                         nMaxColsUsed = nCol + 1;
4075                 }
4076             }
4077 
4078             // Column definitions have to be present to make a valid file
4079             {
4080                 if (nMaxColsUsed > 1)
4081                     AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED,
4082                                     OUString::valueOf(static_cast<sal_Int32>(nMaxColsUsed)));
4083                 SvXMLElementExport aElemColumn(*this, XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, sal_True, sal_True);
4084             }
4085 
4086             // Write cache content for this table.
4087             SCROW nLastRow = 0;
4088             bool bFirstRow = true;
4089             for (vector<SCROW>::const_iterator itrRow = aRows.begin(), itrRowEnd = aRows.end();
4090                   itrRow != itrRowEnd; ++itrRow)
4091             {
4092                 SCROW nRow = *itrRow;
4093                 if (bFirstRow)
4094                 {
4095                     if (nRow > 0)
4096                     {
4097                         if (nRow > 1)
4098                         {
4099                             OUStringBuffer aVal;
4100                             aVal.append(nRow);
4101                             AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_REPEATED, aVal.makeStringAndClear());
4102                         }
4103                         SvXMLElementExport aElemRow(*this, XML_NAMESPACE_TABLE, XML_TABLE_ROW, sal_True, sal_True);
4104                         OUStringBuffer aVal;
4105                         aVal.append(static_cast<sal_Int32>(nMaxColsUsed));
4106                         AddAttribute(XML_NAMESPACE_TABLE,  XML_NUMBER_COLUMNS_REPEATED, aVal.makeStringAndClear());
4107                         SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True);
4108                     }
4109                 }
4110                 else
4111                 {
4112                     SCROW nRowGap = nRow - nLastRow;
4113                     if (nRowGap > 1)
4114                     {
4115                         if (nRowGap > 2)
4116                         {
4117                             OUStringBuffer aVal;
4118                             aVal.append(static_cast<sal_Int32>(nRowGap-1));
4119                             AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_REPEATED, aVal.makeStringAndClear());
4120                         }
4121                         SvXMLElementExport aElemRow(*this, XML_NAMESPACE_TABLE, XML_TABLE_ROW, sal_True, sal_True);
4122                         OUStringBuffer aVal;
4123                         aVal.append(static_cast<sal_Int32>(nMaxColsUsed));
4124                         AddAttribute(XML_NAMESPACE_TABLE,  XML_NUMBER_COLUMNS_REPEATED, aVal.makeStringAndClear());
4125                         SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True);
4126                     }
4127                 }
4128                 SvXMLElementExport aElemRow(*this, XML_NAMESPACE_TABLE, XML_TABLE_ROW, sal_True, sal_True);
4129 
4130                 vector<SCCOL> aCols;
4131                 pTable->getAllCols(nRow, aCols);
4132                 SCCOL nLastCol = 0;
4133                 bool bFirstCol = true;
4134                 for (vector<SCCOL>::const_iterator itrCol = aCols.begin(), itrColEnd = aCols.end();
4135                       itrCol != itrColEnd; ++itrCol)
4136                 {
4137                     SCCOL nCol = *itrCol;
4138                     if (bFirstCol)
4139                     {
4140                         if (nCol > 0)
4141                         {
4142                             if (nCol > 1)
4143                             {
4144                                 OUStringBuffer aVal;
4145                                 aVal.append(static_cast<sal_Int32>(nCol));
4146                                 AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal.makeStringAndClear());
4147                             }
4148                             SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True);
4149                         }
4150                     }
4151                     else
4152                     {
4153                         SCCOL nColGap = nCol - nLastCol;
4154                         if (nColGap > 1)
4155                         {
4156                             if (nColGap > 2)
4157                             {
4158                                 OUStringBuffer aVal;
4159                                 aVal.append(static_cast<sal_Int32>(nColGap-1));
4160                                 AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal.makeStringAndClear());
4161                             }
4162                             SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True);
4163                         }
4164                     }
4165 
4166                     // Write out this cell.
4167                     sal_uInt32 nNumFmt = 0;
4168                     ScExternalRefCache::TokenRef pToken = pTable->getCell(nCol, nRow, &nNumFmt);
4169                     OUString aStrVal;
4170                     if (pToken.get())
4171                     {
4172                         sal_Int32 nIndex = GetNumberFormatStyleIndex(nNumFmt);
4173                         if (nIndex >= 0)
4174                         {
4175                             const OUString aStyleName = *pCellStyles->GetStyleNameByIndex(nIndex, true);
4176                             AddAttribute(XML_NAMESPACE_TABLE, XML_STYLE_NAME, aStyleName);
4177                         }
4178 
4179                         switch(pToken->GetType())
4180                         {
4181                             case svDouble:
4182                             {
4183                                 AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_FLOAT);
4184                                 OUStringBuffer aVal;
4185                                 aVal.append(pToken->GetDouble());
4186                                 aStrVal = aVal.makeStringAndClear();
4187                                 AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE, aStrVal);
4188                             }
4189                             break;
4190                             case svString:
4191                             {
4192                                 AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING);
4193                                 aStrVal = pToken->GetString();
4194                             }
4195                             break;
4196                             default:
4197                                 ;
4198                         }
4199                     }
4200                     SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True);
4201                     SvXMLElementExport aElemText(*this, XML_NAMESPACE_TEXT, XML_P, sal_True, sal_False);
4202                     Characters(aStrVal);
4203 
4204                     nLastCol = nCol;
4205                     bFirstCol = false;
4206                 }
4207                 nLastRow = nRow;
4208                 bFirstRow = false;
4209             }
4210         }
4211     }
4212 }
4213 
4214 // core implementation
WriteConsolidation()4215 void ScXMLExport::WriteConsolidation()
4216 {
4217     if (pDoc)
4218     {
4219         const ScConsolidateParam* pCons(pDoc->GetConsolidateDlgData());
4220         if( pCons )
4221         {
4222             OUString sStrData;
4223 
4224             ScXMLConverter::GetStringFromFunction( sStrData, pCons->eFunction );
4225             AddAttribute( XML_NAMESPACE_TABLE, XML_FUNCTION, sStrData );
4226 
4227             sStrData = OUString();
4228             for( sal_Int32 nIndex = 0; nIndex < pCons->nDataAreaCount; ++nIndex )
4229                 ScRangeStringConverter::GetStringFromArea( sStrData, *pCons->ppDataAreas[ nIndex ], pDoc, FormulaGrammar::CONV_OOO, sal_True );
4230             AddAttribute( XML_NAMESPACE_TABLE, XML_SOURCE_CELL_RANGE_ADDRESSES, sStrData );
4231 
4232             ScRangeStringConverter::GetStringFromAddress( sStrData, ScAddress( pCons->nCol, pCons->nRow, pCons->nTab ), pDoc, FormulaGrammar::CONV_OOO );
4233             AddAttribute( XML_NAMESPACE_TABLE, XML_TARGET_CELL_ADDRESS, sStrData );
4234 
4235             if( pCons->bByCol && !pCons->bByRow )
4236                 AddAttribute( XML_NAMESPACE_TABLE, XML_USE_LABEL, XML_COLUMN );
4237             else if( !pCons->bByCol && pCons->bByRow )
4238                 AddAttribute( XML_NAMESPACE_TABLE, XML_USE_LABEL, XML_ROW );
4239             else if( pCons->bByCol && pCons->bByRow )
4240                 AddAttribute( XML_NAMESPACE_TABLE, XML_USE_LABEL, XML_BOTH );
4241 
4242             if( pCons->bReferenceData )
4243                 AddAttribute( XML_NAMESPACE_TABLE, XML_LINK_TO_SOURCE_DATA, XML_TRUE );
4244 
4245             SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_CONSOLIDATION, sal_True, sal_True );
4246         }
4247     }
4248 }
4249 
CreateAutoStylePool()4250 SvXMLAutoStylePoolP* ScXMLExport::CreateAutoStylePool()
4251 {
4252     return new ScXMLAutoStylePoolP(*this);
4253 }
4254 
CreatePageExport()4255 XMLPageExport* ScXMLExport::CreatePageExport()
4256 {
4257     return new XMLTableMasterPageExport( *this );
4258 }
4259 
GetChangeTrackViewSettings(uno::Sequence<beans::PropertyValue> & rProps)4260 void ScXMLExport::GetChangeTrackViewSettings(uno::Sequence<beans::PropertyValue>& rProps)
4261 {
4262     ScChangeViewSettings* pViewSettings(GetDocument() ? GetDocument()->GetChangeViewSettings() : NULL);
4263     if (pViewSettings)
4264     {
4265         sal_Int32 nChangePos(rProps.getLength());
4266         rProps.realloc(nChangePos + 1);
4267         beans::PropertyValue* pProps(rProps.getArray());
4268         if (pProps)
4269         {
4270             uno::Sequence<beans::PropertyValue> aChangeProps(SC_VIEWCHANGES_COUNT);
4271             beans::PropertyValue* pChangeProps(aChangeProps.getArray());
4272             if (pChangeProps)
4273             {
4274                 pChangeProps[SC_SHOW_CHANGES].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChanges"));
4275                 pChangeProps[SC_SHOW_CHANGES].Value <<= pViewSettings->ShowChanges();
4276                 pChangeProps[SC_SHOW_ACCEPTED_CHANGES].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowAcceptedChanges"));
4277                 pChangeProps[SC_SHOW_ACCEPTED_CHANGES].Value <<= pViewSettings->IsShowAccepted();
4278                 pChangeProps[SC_SHOW_REJECTED_CHANGES].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowRejectedChanges"));
4279                 pChangeProps[SC_SHOW_REJECTED_CHANGES].Value <<= pViewSettings->IsShowRejected();
4280                 pChangeProps[SC_SHOW_CHANGES_BY_DATETIME].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByDatetime"));
4281                 pChangeProps[SC_SHOW_CHANGES_BY_DATETIME].Value <<= pViewSettings->HasDate();
4282                 pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_MODE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByDatetimeMode"));
4283                 pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_MODE].Value <<= static_cast<sal_Int16>(pViewSettings->GetTheDateMode());
4284                 util::DateTime aDateTime;
4285                 ScXMLConverter::ConvertCoreToAPIDateTime(pViewSettings->GetTheFirstDateTime(), aDateTime);
4286                 pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByDatetimeFirstDatetime"));
4287                 pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME].Value <<= aDateTime;
4288                 ScXMLConverter::ConvertCoreToAPIDateTime(pViewSettings->GetTheLastDateTime(), aDateTime);
4289                 pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByDatetimeSecondDatetime"));
4290                 pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME].Value <<= aDateTime;
4291                 pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByAuthor"));
4292                 pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR].Value <<= pViewSettings->HasAuthor();
4293                 pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR_NAME].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByAuthorName"));
4294                 pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR_NAME].Value <<= rtl::OUString (pViewSettings->GetTheAuthorToShow());
4295                 pChangeProps[SC_SHOW_CHANGES_BY_COMMENT].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByComment"));
4296                 pChangeProps[SC_SHOW_CHANGES_BY_COMMENT].Value <<= pViewSettings->HasComment();
4297                 pChangeProps[SC_SHOW_CHANGES_BY_COMMENT_TEXT].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByCommentText"));
4298                 pChangeProps[SC_SHOW_CHANGES_BY_COMMENT_TEXT].Value <<= rtl::OUString (pViewSettings->GetTheComment());
4299                 pChangeProps[SC_SHOW_CHANGES_BY_RANGES].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByRanges"));
4300                 pChangeProps[SC_SHOW_CHANGES_BY_RANGES].Value <<= pViewSettings->HasRange();
4301                 rtl::OUString sRangeList;
4302                 ScRangeStringConverter::GetStringFromRangeList(sRangeList, &(pViewSettings->GetTheRangeList()), GetDocument(), FormulaGrammar::CONV_OOO);
4303                 pChangeProps[SC_SHOW_CHANGES_BY_RANGES_LIST].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByRangesList"));
4304                 pChangeProps[SC_SHOW_CHANGES_BY_RANGES_LIST].Value <<= sRangeList;
4305 
4306                 pProps[nChangePos].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TrackedChangesViewSettings"));
4307                 pProps[nChangePos].Value <<= aChangeProps;
4308             }
4309         }
4310     }
4311 }
4312 
GetViewSettings(uno::Sequence<beans::PropertyValue> & rProps)4313 void ScXMLExport::GetViewSettings(uno::Sequence<beans::PropertyValue>& rProps)
4314 {
4315     rProps.realloc(4);
4316     beans::PropertyValue* pProps(rProps.getArray());
4317     if(pProps)
4318     {
4319         if (GetModel().is())
4320         {
4321             ScModelObj* pDocObj(ScModelObj::getImplementation( GetModel() ));
4322             if (pDocObj)
4323             {
4324                 SfxObjectShell* pEmbeddedObj = pDocObj->GetEmbeddedObject();
4325                 if (pEmbeddedObj)
4326                 {
4327                     Rectangle aRect(pEmbeddedObj->GetVisArea());
4328                     sal_uInt16 i(0);
4329                     pProps[i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VisibleAreaTop"));
4330                     pProps[i].Value <<= static_cast<sal_Int32>(aRect.getY());
4331                     pProps[++i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VisibleAreaLeft"));
4332                     pProps[i].Value <<= static_cast<sal_Int32>(aRect.getX());
4333                     pProps[++i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VisibleAreaWidth"));
4334                     pProps[i].Value <<= static_cast<sal_Int32>(aRect.getWidth());
4335                     pProps[++i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VisibleAreaHeight"));
4336                     pProps[i].Value <<= static_cast<sal_Int32>(aRect.getHeight());
4337                 }
4338             }
4339         }
4340     }
4341     GetChangeTrackViewSettings(rProps);
4342 }
4343 
4344 
4345 
4346 
GetConfigurationSettings(uno::Sequence<beans::PropertyValue> & rProps)4347 void ScXMLExport::GetConfigurationSettings(uno::Sequence<beans::PropertyValue>& rProps)
4348 {
4349     if (GetModel().is())
4350     {
4351         uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY);
4352         if (xMultiServiceFactory.is())
4353         {
4354             uno::Reference <beans::XPropertySet> xProperties(xMultiServiceFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.SpreadsheetSettings"))), uno::UNO_QUERY);
4355             if (xProperties.is())
4356                 SvXMLUnitConverter::convertPropertySet(rProps, xProperties);
4357 
4358             sal_Int32 nPropsToAdd = 0;
4359             rtl::OUStringBuffer aTrackedChangesKey;
4360             if (GetDocument() && GetDocument()->GetChangeTrack() && GetDocument()->GetChangeTrack()->IsProtected())
4361             {
4362                 SvXMLUnitConverter::encodeBase64(aTrackedChangesKey, GetDocument()->GetChangeTrack()->GetProtection());
4363                 if (aTrackedChangesKey.getLength())
4364                     ++nPropsToAdd;
4365             }
4366 
4367             bool bVBACompat = false;
4368             uno::Reference <container::XNameAccess> xCodeNameAccess;
4369             DBG_ASSERT( pDoc, "ScXMLExport::GetConfigurationSettings - no ScDocument!" );
4370             if( pDoc && pDoc->IsInVBAMode() )
4371             {
4372                 // VBA compatibility mode
4373                 bVBACompat = true;
4374                 ++nPropsToAdd;
4375                 // code names
4376                 xCodeNameAccess = new XMLCodeNameProvider( pDoc );
4377                 if( xCodeNameAccess->hasElements() )
4378                     ++nPropsToAdd;
4379                 else
4380                     xCodeNameAccess.clear();
4381             }
4382 
4383             if( nPropsToAdd > 0 )
4384             {
4385                 sal_Int32 nCount(rProps.getLength());
4386                 rProps.realloc(nCount + nPropsToAdd);
4387                 if (aTrackedChangesKey.getLength())
4388                 {
4389                     rProps[nCount].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TrackedChangesProtectionKey"));
4390                     rProps[nCount].Value <<= aTrackedChangesKey.makeStringAndClear();
4391                     ++nCount;
4392                 }
4393                 if( bVBACompat )
4394                 {
4395                     rProps[nCount].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VBACompatibilityMode"));
4396                     rProps[nCount].Value <<= bVBACompat;
4397                     ++nCount;
4398                 }
4399                 if( xCodeNameAccess.is() )
4400                 {
4401                     rProps[nCount].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScriptConfiguration"));
4402                     rProps[nCount].Value <<= xCodeNameAccess;
4403                     ++nCount;
4404                 }
4405             }
4406         }
4407     }
4408 }
4409 
CreateShapeExport()4410 XMLShapeExport* ScXMLExport::CreateShapeExport()
4411 {
4412     return new ScXMLShapeExport(*this);
4413 }
4414 
CreateSharedData(const sal_Int32 nTableCount)4415 void ScXMLExport::CreateSharedData(const sal_Int32 nTableCount)
4416 {
4417     pSharedData = new ScMySharedData(nTableCount);
4418 }
4419 
GetNumberFormatAttributesExportHelper()4420 XMLNumberFormatAttributesExportHelper* ScXMLExport::GetNumberFormatAttributesExportHelper()
4421 {
4422     if (!pNumberFormatAttributesExportHelper)
4423         pNumberFormatAttributesExportHelper = new XMLNumberFormatAttributesExportHelper(GetNumberFormatsSupplier(), *this );
4424     return pNumberFormatAttributesExportHelper;
4425 }
4426 
CollectUserDefinedNamespaces(const SfxItemPool * pPool,sal_uInt16 nAttrib)4427 void ScXMLExport::CollectUserDefinedNamespaces(const SfxItemPool* pPool, sal_uInt16 nAttrib)
4428 {
4429     const SfxPoolItem* pItem;
4430     sal_uInt32 nItems(pPool->GetItemCount2( nAttrib ));
4431     for( sal_uInt32 i = 0; i < nItems; ++i )
4432     {
4433         if( 0 != (pItem = pPool->GetItem2( nAttrib, i ) ) )
4434         {
4435             const SvXMLAttrContainerItem *pUnknown((const SvXMLAttrContainerItem *)pItem);
4436             if( (pUnknown->GetAttrCount() > 0) )
4437             {
4438                 sal_uInt16 nIdx(pUnknown->GetFirstNamespaceIndex());
4439                 while( USHRT_MAX != nIdx )
4440                 {
4441                     if( (XML_NAMESPACE_UNKNOWN_FLAG & nIdx) != 0 )
4442                     {
4443                         const OUString& rPrefix = pUnknown->GetPrefix( nIdx );
4444                         // Add namespace declaration for unknown attributes if
4445                         // there aren't existing ones for the prefix used by the
4446                         // attibutes
4447                         _GetNamespaceMap().Add( rPrefix,
4448                                                 pUnknown->GetNamespace( nIdx ),
4449                                                 XML_NAMESPACE_UNKNOWN );
4450                     }
4451                     nIdx = pUnknown->GetNextNamespaceIndex( nIdx );
4452                 }
4453             }
4454         }
4455     }
4456 
4457     // #i66550# needed for 'presentation:event-listener' element for URLs in shapes
4458     _GetNamespaceMap().Add(
4459         GetXMLToken( XML_NP_PRESENTATION ),
4460         GetXMLToken( XML_N_PRESENTATION ),
4461         XML_NAMESPACE_PRESENTATION );
4462 }
4463 
IncrementProgressBar(sal_Bool bEditCell,sal_Int32 nInc)4464 void ScXMLExport::IncrementProgressBar(sal_Bool bEditCell, sal_Int32 nInc)
4465 {
4466     nProgressCount += nInc;
4467     if (bEditCell || nProgressCount > 100)
4468     {
4469         GetProgressBarHelper()->Increment(nProgressCount);
4470         nProgressCount = 0;
4471     }
4472 }
4473 
exportDoc(enum XMLTokenEnum eClass)4474 sal_uInt32 ScXMLExport::exportDoc( enum XMLTokenEnum eClass )
4475 {
4476     if( (getExportFlags() & (EXPORT_FONTDECLS|EXPORT_STYLES|
4477                              EXPORT_MASTERSTYLES|EXPORT_CONTENT)) != 0 )
4478     {
4479         if (GetDocument())
4480         {
4481             CollectUserDefinedNamespaces(GetDocument()->GetPool(), ATTR_USERDEF);
4482             CollectUserDefinedNamespaces(GetDocument()->GetEditPool(), EE_PARA_XMLATTRIBS);
4483             CollectUserDefinedNamespaces(GetDocument()->GetEditPool(), EE_CHAR_XMLATTRIBS);
4484             ScDrawLayer* pDrawLayer = GetDocument()->GetDrawLayer();
4485             if (pDrawLayer)
4486             {
4487                 CollectUserDefinedNamespaces(&pDrawLayer->GetItemPool(), EE_PARA_XMLATTRIBS);
4488                 CollectUserDefinedNamespaces(&pDrawLayer->GetItemPool(), EE_CHAR_XMLATTRIBS);
4489                 CollectUserDefinedNamespaces(&pDrawLayer->GetItemPool(), SDRATTR_XMLATTRIBUTES);
4490             }
4491 
4492             // sheet events use officeooo namespace
4493             if( (getExportFlags() & EXPORT_CONTENT) != 0 &&
4494                 getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST )
4495             {
4496                 bool bAnySheetEvents = false;
4497                 SCTAB nTabCount = pDoc->GetTableCount();
4498                 for (SCTAB nTab=0; nTab<nTabCount; ++nTab)
4499                     if (pDoc->GetSheetEvents(nTab))
4500                         bAnySheetEvents = true;
4501                 if (bAnySheetEvents)
4502                     _GetNamespaceMap().Add(
4503                         GetXMLToken( XML_NP_OFFICE_EXT ),
4504                         GetXMLToken( XML_N_OFFICE_EXT ),
4505                         XML_NAMESPACE_OFFICE_EXT );
4506             }
4507         }
4508     }
4509     return SvXMLExport::exportDoc( eClass );
4510 }
4511 
4512 // XExporter
setSourceDocument(const uno::Reference<lang::XComponent> & xComponent)4513 void SAL_CALL ScXMLExport::setSourceDocument( const uno::Reference<lang::XComponent>& xComponent )
4514                             throw(lang::IllegalArgumentException, uno::RuntimeException)
4515 {
4516     ScUnoGuard aGuard;
4517     SvXMLExport::setSourceDocument( xComponent );
4518 
4519     pDoc = ScXMLConverter::GetScDocument( GetModel() );
4520     DBG_ASSERT( pDoc, "ScXMLExport::setSourceDocument - no ScDocument!" );
4521     if (!pDoc)
4522         throw lang::IllegalArgumentException();
4523 
4524     // create ScChangeTrackingExportHelper after document is known
4525     pChangeTrackingExportHelper = new ScChangeTrackingExportHelper(*this);
4526 
4527     // Set the document's storage grammar corresponding to the ODF version that
4528     // is to be written.
4529     SvtSaveOptions::ODFDefaultVersion meODFDefaultVersion = getDefaultVersion();
4530     switch (meODFDefaultVersion)
4531     {
4532         // ODF 1.0 and 1.1 use GRAM_PODF, everything later or unspecified GRAM_ODFF
4533         case SvtSaveOptions::ODFVER_010:
4534         case SvtSaveOptions::ODFVER_011:
4535             pDoc->SetStorageGrammar( formula::FormulaGrammar::GRAM_PODF);
4536             break;
4537         default:
4538             pDoc->SetStorageGrammar( formula::FormulaGrammar::GRAM_ODFF);
4539     }
4540 }
4541 
4542 // XFilter
filter(const::com::sun::star::uno::Sequence<::com::sun::star::beans::PropertyValue> & aDescriptor)4543 sal_Bool SAL_CALL ScXMLExport::filter( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
4544     throw(::com::sun::star::uno::RuntimeException)
4545 {
4546     ScUnoGuard aGuard;
4547     if (pDoc)
4548         pDoc->DisableIdle(sal_True);
4549     sal_Bool bReturn(SvXMLExport::filter(aDescriptor));
4550     if (pDoc)
4551         pDoc->DisableIdle(sal_False);
4552     return bReturn;
4553 }
4554 
cancel()4555 void SAL_CALL ScXMLExport::cancel()
4556     throw(::com::sun::star::uno::RuntimeException)
4557 {
4558     ScUnoGuard aGuard;
4559     if (pDoc)
4560         pDoc->DisableIdle(sal_False);
4561     SvXMLExport::cancel();
4562 }
4563 
4564 // XInitialization
initialize(const::com::sun::star::uno::Sequence<::com::sun::star::uno::Any> & aArguments)4565 void SAL_CALL ScXMLExport::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
4566     throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
4567 {
4568     ScUnoGuard aGuard;
4569     SvXMLExport::initialize(aArguments);
4570 }
4571 
4572 // XServiceInfo
getImplementationName()4573 ::rtl::OUString SAL_CALL ScXMLExport::getImplementationName(  )
4574     throw(::com::sun::star::uno::RuntimeException)
4575 {
4576     ScUnoGuard aGuard;
4577 
4578     sal_uInt16 nFlags = getExportFlags();
4579     if (nFlags & EXPORT_OASIS)
4580     {
4581         nFlags |= EXPORT_OASIS;
4582         switch( nFlags )
4583         {
4584             case EXPORT_ALL:
4585                 return ScXMLOasisExport_getImplementationName();
4586             case (EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_FONTDECLS):
4587                 return ScXMLOasisExport_Styles_getImplementationName();
4588             case (EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS):
4589                 return ScXMLOasisExport_Content_getImplementationName();
4590             case EXPORT_META:
4591                 return ScXMLOasisExport_Meta_getImplementationName();
4592             case EXPORT_SETTINGS:
4593                 return ScXMLOasisExport_Settings_getImplementationName();
4594             default:
4595                 // generic name for 'unknown' cases
4596                 return ScXMLOasisExport_getImplementationName();
4597         }
4598     }
4599     else
4600     {
4601         switch( nFlags )
4602         {
4603             case EXPORT_ALL:
4604                 return ScXMLOOoExport_getImplementationName();
4605             case (EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_FONTDECLS):
4606                 return ScXMLOOoExport_Styles_getImplementationName();
4607             case (EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS):
4608                 return ScXMLOOoExport_Content_getImplementationName();
4609             case EXPORT_META:
4610                 return ScXMLOOoExport_Meta_getImplementationName();
4611             case EXPORT_SETTINGS:
4612                 return ScXMLOOoExport_Settings_getImplementationName();
4613             default:
4614                 // generic name for 'unknown' cases
4615                 return ScXMLOOoExport_getImplementationName();
4616         }
4617     }
4618     return SvXMLExport::getImplementationName();
4619 }
4620 
supportsService(const::rtl::OUString & ServiceName)4621 sal_Bool SAL_CALL ScXMLExport::supportsService( const ::rtl::OUString& ServiceName )
4622     throw(::com::sun::star::uno::RuntimeException)
4623 {
4624     ScUnoGuard aGuard;
4625     return SvXMLExport::supportsService( ServiceName );
4626 }
4627 
getSupportedServiceNames()4628 ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL ScXMLExport::getSupportedServiceNames(  )
4629     throw(::com::sun::star::uno::RuntimeException)
4630 {
4631     ScUnoGuard aGuard;
4632     return SvXMLExport::getSupportedServiceNames();
4633 }
4634 
4635 // XUnoTunnel
getSomething(const::com::sun::star::uno::Sequence<sal_Int8> & aIdentifier)4636 sal_Int64 SAL_CALL ScXMLExport::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier )
4637     throw(::com::sun::star::uno::RuntimeException)
4638 {
4639     ScUnoGuard aGuard;
4640     return SvXMLExport::getSomething(aIdentifier);
4641 }
4642 
DisposingModel()4643 void ScXMLExport::DisposingModel()
4644 {
4645     SvXMLExport::DisposingModel();
4646     pDoc = NULL;
4647     xCurrentTable = 0;
4648 }
4649 
4650