bump product version to 5.0.4.1
[LibreOffice.git] / sd / source / filter / xml / sdxmlwrp.cxx
blobb7c627a30b8a9fa5b0f76cad4f28d7be6aec6b95
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <rtl/strbuf.hxx>
21 #include <com/sun/star/container/XChild.hpp>
22 #include <com/sun/star/beans/XPropertySetInfo.hpp>
23 #include <com/sun/star/embed/ElementModes.hpp>
24 #include <com/sun/star/xml/sax/SAXParseException.hpp>
25 #include <comphelper/processfactory.hxx>
26 #include <sfx2/docfile.hxx>
27 #include <sfx2/docfilt.hxx>
28 #include "drawdoc.hxx"
29 #include "Outliner.hxx"
30 #include <unotools/streamwrap.hxx>
31 #include <svx/xmlgrhlp.hxx>
33 #include "../../ui/inc/DrawDocShell.hxx"
35 #include "sdxmlwrp.hxx"
36 #include "strmname.h"
37 #include <svx/xmleohlp.hxx>
38 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
39 #include <com/sun/star/document/XFilter.hpp>
40 #include <com/sun/star/document/XImporter.hpp>
41 #include <com/sun/star/document/XExporter.hpp>
42 #include <com/sun/star/lang/XServiceInfo.hpp>
43 #include <com/sun/star/document/XGraphicObjectResolver.hpp>
44 #include <com/sun/star/beans/PropertyAttribute.hpp>
45 #include <com/sun/star/container/XNameAccess.hpp>
46 #include <com/sun/star/packages/zip/ZipIOException.hpp>
48 #include <com/sun/star/xml/sax/XErrorHandler.hpp>
49 #include <com/sun/star/xml/sax/XEntityResolver.hpp>
50 #include <com/sun/star/xml/sax/InputSource.hpp>
51 #include <com/sun/star/xml/sax/XDTDHandler.hpp>
52 #include <com/sun/star/xml/sax/Parser.hpp>
53 #include <com/sun/star/xml/sax/Writer.hpp>
54 #include <com/sun/star/io/XActiveDataSource.hpp>
55 #include <com/sun/star/io/XActiveDataControl.hpp>
56 #include <comphelper/genericpropertyset.hxx>
57 #include <comphelper/propertysetinfo.hxx>
58 #include <editeng/eeitem.hxx>
59 #include <unotools/saveopt.hxx>
61 // include necessary for XML progress bar at load time
62 #include <svl/itemset.hxx>
63 #include <svl/stritem.hxx>
64 #include <svtools/sfxecode.hxx>
66 #include "sderror.hxx"
67 #include "sdresid.hxx"
68 #include "sdtransform.hxx"
69 #include "glob.hrc"
71 #include <sfx2/frame.hxx>
73 using namespace com::sun::star;
74 using namespace com::sun::star::uno;
75 using namespace com::sun::star::lang;
76 using namespace com::sun::star::document;
77 using namespace comphelper;
79 #define SD_XML_READERROR 1234
81 char const sXML_metaStreamName[] = "meta.xml";
82 char const sXML_styleStreamName[] = "styles.xml";
83 char const sXML_contentStreamName[] = "content.xml";
84 char const sXML_settingsStreamName[] = "settings.xml";
86 char const sXML_export_impress_oasis_service[] = "com.sun.star.comp.Impress.XMLOasisExporter";
87 char const sXML_export_impress_meta_oasis_service[] = "com.sun.star.comp.Impress.XMLOasisMetaExporter";
88 char const sXML_export_impress_styles_oasis_service[] = "com.sun.star.comp.Impress.XMLOasisStylesExporter";
89 char const sXML_export_impress_content_oasis_service[] = "com.sun.star.comp.Impress.XMLOasisContentExporter";
90 char const sXML_export_impress_settings_oasis_service[] = "com.sun.star.comp.Impress.XMLOasisSettingsExporter";
92 char const sXML_export_draw_oasis_service[] = "com.sun.star.comp.Draw.XMLOasisExporter";
93 char const sXML_export_draw_meta_oasis_service[] = "com.sun.star.comp.Draw.XMLOasisMetaExporter";
94 char const sXML_export_draw_styles_oasis_service[] = "com.sun.star.comp.Draw.XMLOasisStylesExporter";
95 char const sXML_export_draw_content_oasis_service[] = "com.sun.star.comp.Draw.XMLOasisContentExporter";
96 char const sXML_export_draw_settings_oasis_service[] = "com.sun.star.comp.Draw.XMLOasisSettingsExporter";
98 char const sXML_import_impress_oasis_service[] = "com.sun.star.comp.Impress.XMLOasisImporter";
99 char const sXML_import_impress_meta_oasis_service[] = "com.sun.star.comp.Impress.XMLOasisMetaImporter";
100 char const sXML_import_impress_styles_oasis_service[] = "com.sun.star.comp.Impress.XMLOasisStylesImporter";
101 char const sXML_import_impress_content_oasis_service[] = "com.sun.star.comp.Impress.XMLOasisContentImporter";
102 char const sXML_import_impress_settings_oasis_service[] = "com.sun.star.comp.Impress.XMLOasisSettingsImporter";
104 char const sXML_import_draw_oasis_service[] = "com.sun.star.comp.Draw.XMLOasisImporter";
105 char const sXML_import_draw_meta_oasis_service[] = "com.sun.star.comp.Draw.XMLOasisMetaImporter";
106 char const sXML_import_draw_styles_oasis_service[] = "com.sun.star.comp.Draw.XMLOasisStylesImporter";
107 char const sXML_import_draw_content_oasis_service[] = "com.sun.star.comp.Draw.XMLOasisContentImporter";
108 char const sXML_import_draw_settings_oasis_service[] = "com.sun.star.comp.Draw.XMLOasisSettingsImporter";
110 // OOo
111 char const sXML_export_impress_ooo_service[] = "com.sun.star.comp.Impress.XMLExporter";
112 char const sXML_export_impress_meta_ooo_service[] = "com.sun.star.comp.Impress.XMLMetaExporter";
113 char const sXML_export_impress_styles_ooo_service[] = "com.sun.star.comp.Impress.XMLStylesExporter";
114 char const sXML_export_impress_content_ooo_service[] = "com.sun.star.comp.Impress.XMLContentExporter";
115 char const sXML_export_impress_settings_ooo_service[] = "com.sun.star.comp.Impress.XMLSettingsExporter";
117 char const sXML_export_draw_ooo_service[] = "com.sun.star.comp.Draw.XMLExporter";
118 char const sXML_export_draw_meta_ooo_service[] = "com.sun.star.comp.Draw.XMLMetaExporter";
119 char const sXML_export_draw_styles_ooo_service[] = "com.sun.star.comp.Draw.XMLStylesExporter";
120 char const sXML_export_draw_content_ooo_service[] = "com.sun.star.comp.Draw.XMLContentExporter";
121 char const sXML_export_draw_settings_ooo_service[] = "com.sun.star.comp.Draw.XMLSettingsExporter";
123 char const sXML_import_impress_ooo_service[] = "com.sun.star.comp.Impress.XMLImporter";
124 char const sXML_import_impress_meta_ooo_service[] = "com.sun.star.comp.Impress.XMLMetaImporter";
125 char const sXML_import_impress_styles_ooo_service[] = "com.sun.star.comp.Impress.XMLStylesImporter";
126 char const sXML_import_impress_content_ooo_service[] = "com.sun.star.comp.Impress.XMLContentImporter";
127 char const sXML_import_impress_settings_ooo_service[] = "com.sun.star.comp.Impress.XMLSettingsImporter";
129 char const sXML_import_draw_ooo_service[] = "com.sun.star.comp.Draw.XMLImporter";
130 char const sXML_import_draw_meta_ooo_service[] = "com.sun.star.comp.Draw.XMLMetaImporter";
131 char const sXML_import_draw_styles_ooo_service[] = "com.sun.star.comp.Draw.XMLStylesImporter";
132 char const sXML_import_draw_content_ooo_service[] = "com.sun.star.comp.Draw.XMLContentImporter";
133 char const sXML_import_draw_settings_ooo_service[] = "com.sun.star.comp.Draw.XMLSettingsImporter";
135 struct XML_SERVICEMAP
137 const sal_Char* mpService;
138 const sal_Char* mpStream;
141 struct XML_SERVICES
143 const sal_Char* mpAll;
144 const sal_Char* mpMeta;
145 const sal_Char* mpStyles;
146 const sal_Char* mpContent;
147 const sal_Char* mpSettings;
150 XML_SERVICES* getServices( bool bImport, bool bDraw, sal_uLong nStoreVer )
152 static XML_SERVICES gServices[] =
154 { sXML_export_impress_oasis_service, sXML_export_impress_meta_oasis_service, sXML_export_impress_styles_oasis_service, sXML_export_impress_content_oasis_service, sXML_export_impress_settings_oasis_service },
155 { sXML_export_draw_oasis_service, sXML_export_draw_meta_oasis_service, sXML_export_draw_styles_oasis_service, sXML_export_draw_content_oasis_service, sXML_export_draw_settings_oasis_service },
156 { sXML_import_impress_oasis_service, sXML_import_impress_meta_oasis_service, sXML_import_impress_styles_oasis_service, sXML_import_impress_content_oasis_service, sXML_import_impress_settings_oasis_service },
157 { sXML_import_draw_oasis_service, sXML_import_draw_meta_oasis_service, sXML_import_draw_styles_oasis_service, sXML_import_draw_content_oasis_service, sXML_import_draw_settings_oasis_service },
159 { sXML_export_impress_ooo_service, sXML_export_impress_meta_ooo_service, sXML_export_impress_styles_ooo_service, sXML_export_impress_content_ooo_service, sXML_export_impress_settings_ooo_service },
160 { sXML_export_draw_ooo_service, sXML_export_draw_meta_ooo_service, sXML_export_draw_styles_ooo_service, sXML_export_draw_content_ooo_service, sXML_export_draw_settings_ooo_service },
161 { sXML_import_impress_ooo_service, sXML_import_impress_meta_ooo_service, sXML_import_impress_styles_ooo_service, sXML_import_impress_content_ooo_service, sXML_import_impress_settings_ooo_service },
162 { sXML_import_draw_ooo_service, sXML_import_draw_meta_ooo_service, sXML_import_draw_styles_ooo_service, sXML_import_draw_content_ooo_service, sXML_import_draw_settings_ooo_service },
165 return &gServices[ (bImport ? 2 : 0) + ((nStoreVer == SOFFICE_FILEFORMAT_60) ? 4 : 0) + (bDraw ? 1 : 0 ) ];
168 // - SdXMLWrapper -
170 SdXMLFilter::SdXMLFilter( SfxMedium& rMedium, ::sd::DrawDocShell& rDocShell, bool bShowProgress, SdXMLFilterMode eFilterMode, sal_uLong nStoreVer ) :
171 SdFilter( rMedium, rDocShell, bShowProgress ), meFilterMode( eFilterMode ), mnStoreVer( nStoreVer )
175 SdXMLFilter::~SdXMLFilter()
179 namespace
182 sal_Int32 ReadThroughComponent(
183 Reference<io::XInputStream> xInputStream,
184 Reference<XComponent> xModelComponent,
185 const OUString& rStreamName,
186 Reference<uno::XComponentContext> & rxContext,
187 const sal_Char* pFilterName,
188 const Sequence<Any>& rFilterArguments,
189 const OUString& rName,
190 bool bMustBeSuccessfull,
191 bool bEncrypted )
193 DBG_ASSERT(xInputStream.is(), "input stream missing");
194 DBG_ASSERT(xModelComponent.is(), "document missing");
195 DBG_ASSERT(rxContext.is(), "factory missing");
196 DBG_ASSERT(NULL != pFilterName,"I need a service name for the component!");
198 SAL_INFO( "sd.filter", "ReadThroughComponent" );
200 // prepare ParserInputSrouce
201 xml::sax::InputSource aParserInput;
202 aParserInput.sSystemId = rName;
203 aParserInput.aInputStream = xInputStream;
205 // get parser
206 Reference< xml::sax::XParser > xParser = xml::sax::Parser::create(rxContext);
207 SAL_INFO( "sd.filter", "parser created" );
209 // get filter
210 OUString aFilterName(OUString::createFromAscii(pFilterName));
211 Reference< xml::sax::XDocumentHandler > xFilter(
212 rxContext->getServiceManager()->createInstanceWithArgumentsAndContext(aFilterName, rFilterArguments, rxContext),
213 UNO_QUERY );
214 SAL_WARN_IF(!xFilter.is(), "sd.filter", "Can't instantiate filter component: " << aFilterName);
215 if( !xFilter.is() )
216 return SD_XML_READERROR;
217 SAL_INFO( "sd.filter", "" << pFilterName << " created" );
219 // connect parser and filter
220 xParser->setDocumentHandler( xFilter );
222 // connect model and filter
223 Reference < XImporter > xImporter( xFilter, UNO_QUERY );
224 xImporter->setTargetDocument( xModelComponent );
225 // finally, parser the stream
226 SAL_INFO( "sd.filter", "parsing stream" );
229 xParser->parseStream( aParserInput );
231 catch (const xml::sax::SAXParseException& r)
233 // sax parser sends wrapped exceptions,
234 // try to find the original one
235 xml::sax::SAXException aSaxEx = *(xml::sax::SAXException*)(&r);
236 bool bTryChild = true;
238 while( bTryChild )
240 xml::sax::SAXException aTmp;
241 if ( aSaxEx.WrappedException >>= aTmp )
242 aSaxEx = aTmp;
243 else
244 bTryChild = false;
247 packages::zip::ZipIOException aBrokenPackage;
248 if ( aSaxEx.WrappedException >>= aBrokenPackage )
249 return ERRCODE_IO_BROKENPACKAGE;
251 if( bEncrypted )
252 return ERRCODE_SFX_WRONGPASSWORD;
254 #if OSL_DEBUG_LEVEL > 1
255 SAL_WARN( "sd.filter", "SAX parse exception caught while importing:" << r.Message);
256 #endif
258 OUString sErr( OUString::number( r.LineNumber ));
259 sErr += ",";
260 sErr += OUString::number( r.ColumnNumber );
262 if (!rStreamName.isEmpty())
264 return *new TwoStringErrorInfo(
265 (bMustBeSuccessfull ? ERR_FORMAT_FILE_ROWCOL
266 : WARN_FORMAT_FILE_ROWCOL),
267 rStreamName, sErr,
268 ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR );
270 else
272 DBG_ASSERT( bMustBeSuccessfull, "Warnings are not supported" );
273 return *new StringErrorInfo( ERR_FORMAT_ROWCOL, sErr,
274 ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR );
277 catch (const xml::sax::SAXException& r)
279 packages::zip::ZipIOException aBrokenPackage;
280 if ( r.WrappedException >>= aBrokenPackage )
281 return ERRCODE_IO_BROKENPACKAGE;
283 if( bEncrypted )
284 return ERRCODE_SFX_WRONGPASSWORD;
286 #if OSL_DEBUG_LEVEL > 1
287 SAL_WARN( "sd.filter", "SAX exception caught while importing:" << r.Message);
288 #endif
289 return SD_XML_READERROR;
291 catch (const packages::zip::ZipIOException& r)
293 #if OSL_DEBUG_LEVEL > 1
294 SAL_WARN( "sd.filter", "Zip exception caught while importing:" << r.Message);
295 #else
296 (void)r;
297 #endif
298 return ERRCODE_IO_BROKENPACKAGE;
300 catch (const io::IOException& r)
302 #if OSL_DEBUG_LEVEL > 1
303 SAL_WARN( "sd.filter", "IO exception caught while importing:" << r.Message);
304 #else
305 (void)r;
306 #endif
307 return SD_XML_READERROR;
309 catch (const uno::Exception& r)
311 #if OSL_DEBUG_LEVEL > 1
312 SAL_WARN( "sd.filter", "uno exception caught while importing:" << r.Message);
313 #else
314 (void)r;
315 #endif
316 return SD_XML_READERROR;
319 // success!
320 return 0;
323 sal_Int32 ReadThroughComponent(
324 const uno::Reference < embed::XStorage >& xStorage,
325 Reference<XComponent> xModelComponent,
326 const sal_Char* pStreamName,
327 const sal_Char* pCompatibilityStreamName,
328 Reference<uno::XComponentContext> & rxContext,
329 const sal_Char* pFilterName,
330 const Sequence<Any>& rFilterArguments,
331 const OUString& rName,
332 bool bMustBeSuccessfull )
334 DBG_ASSERT(xStorage.is(), "Need storage!");
335 DBG_ASSERT(NULL != pStreamName, "Please, please, give me a name!");
337 // open stream (and set parser input)
338 OUString sStreamName = OUString::createFromAscii(pStreamName);
339 bool bContainsStream = false;
342 bContainsStream = xStorage->isStreamElement(sStreamName);
344 catch (const container::NoSuchElementException&)
348 if (!bContainsStream )
350 // stream name not found! Then try the compatibility name.
351 // if no stream can be opened, return immediately with OK signal
353 // do we even have an alternative name?
354 if ( NULL == pCompatibilityStreamName )
355 return 0;
357 // if so, does the stream exist?
358 sStreamName = OUString::createFromAscii(pCompatibilityStreamName);
361 bContainsStream = xStorage->isStreamElement(sStreamName);
363 catch (const container::NoSuchElementException&)
367 if (! bContainsStream )
368 return 0;
371 // set Base URL
372 uno::Reference< beans::XPropertySet > xInfoSet;
373 if( rFilterArguments.getLength() > 0 )
374 rFilterArguments.getConstArray()[0] >>= xInfoSet;
375 DBG_ASSERT( xInfoSet.is(), "missing property set" );
376 if( xInfoSet.is() )
378 OUString sPropName( "StreamName" );
379 xInfoSet->setPropertyValue( sPropName, makeAny( sStreamName ) );
384 // get input stream
385 Reference <io::XStream> xStream =
386 xStorage->openStreamElement( sStreamName, embed::ElementModes::READ );
387 Reference <beans::XPropertySet > xProps( xStream, uno::UNO_QUERY );
388 if ( !xStream.is() || ! xProps.is() )
389 return SD_XML_READERROR;
391 Any aAny = xProps->getPropertyValue( "Encrypted" );
393 bool bEncrypted = aAny.getValueType() == cppu::UnoType<bool>::get() &&
394 *static_cast<sal_Bool const *>(aAny.getValue());
396 Reference <io::XInputStream> xInputStream = xStream->getInputStream();
398 // read from the stream
399 return ReadThroughComponent(
400 xInputStream, xModelComponent, sStreamName, rxContext,
401 pFilterName, rFilterArguments,
402 rName, bMustBeSuccessfull, bEncrypted );
404 catch (const packages::WrongPasswordException&)
406 return ERRCODE_SFX_WRONGPASSWORD;
408 catch (const packages::zip::ZipIOException&)
410 return ERRCODE_IO_BROKENPACKAGE;
412 catch (const uno::Exception&)
415 return SD_XML_READERROR;
420 //PRESOBJ_OUTLINEs in master pages are the preview of the outline styles
421 //numbering format. Since fdo#78151 toggling bullets on and off changes
422 //the style they are a preview of, previously toggling bullets on and off
423 //would only affect the preview paragraph itself without an effect on the
424 //style. i.e. previews of numbering which don't match the real numbering
425 //they are supposed to be a preview of.
427 //But there exist documents which were saved previous to that modification
428 //so here we detect such cases and fix them up to ensure the previews
429 //numbering level matches that of the outline level it previews
430 void fixupOutlinePlaceholderNumberingDepths(SdDrawDocument* pDoc)
432 for (sal_uInt16 i = 0; i < pDoc->GetMasterSdPageCount(PK_STANDARD); ++i)
434 SdPage *pMasterPage = pDoc->GetMasterSdPage(i, PK_STANDARD);
435 SdrObject* pMasterOutline = pMasterPage->GetPresObj(PRESOBJ_OUTLINE);
436 if (!pMasterOutline)
437 continue;
438 OutlinerParaObject* pOutlParaObj = pMasterOutline->GetOutlinerParaObject();
439 if (!pOutlParaObj)
440 continue;
441 ::sd::Outliner* pOutliner = pDoc->GetInternalOutliner();
442 pOutliner->Clear();
443 pOutliner->SetText(*pOutlParaObj);
444 bool bInconsistent = false;
445 const sal_Int32 nParaCount = pOutliner->GetParagraphCount();
446 for (sal_Int32 j = 0; j < nParaCount; ++j)
448 //Make sure the depth of the paragraph matches that of the outline style it previews
449 const sal_Int16 nExpectedDepth = j;
450 if (nExpectedDepth != pOutliner->GetDepth(j))
452 Paragraph* p = pOutliner->GetParagraph(j);
453 pOutliner->SetDepth(p, nExpectedDepth);
454 bInconsistent = true;
457 //If the preview has hard-coded bullets/numbering then they must
458 //be stripped to reveal the true underlying styles attributes
459 SfxItemSet aAttrs(pOutliner->GetParaAttribs(j));
460 if (aAttrs.GetItemState(EE_PARA_NUMBULLET) == SfxItemState::SET)
462 aAttrs.ClearItem(EE_PARA_NUMBULLET);
463 pOutliner->SetParaAttribs(j, aAttrs);
464 bInconsistent = true;
468 if (bInconsistent)
470 SAL_WARN("sd.filter", "Fixing inconsistent outline numbering placeholder preview");
471 pMasterOutline->SetOutlinerParaObject(pOutliner->CreateParaObject(0, nParaCount));
473 pOutliner->Clear();
477 bool SdXMLFilter::Import( ErrCode& nError )
479 sal_uInt32 nRet = 0;
481 // Get service factory
482 Reference< uno::XComponentContext > rxContext =
483 comphelper::getProcessComponentContext();
485 SdDrawDocument* pDoc = mrDocShell.GetDoc();
486 pDoc->EnableUndo(false);
487 pDoc->NewOrLoadCompleted( NEW_DOC );
488 pDoc->CreateFirstPages();
489 pDoc->StopWorkStartupDelay();
491 mxModel->lockControllers();
493 /** property map for import info set */
494 PropertyMapEntry const aImportInfoMap[] =
496 // necessary properties for XML progress bar at load time
497 { OUString("ProgressRange"), 0, ::cppu::UnoType<sal_Int32>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
498 { OUString("ProgressMax"), 0, ::cppu::UnoType<sal_Int32>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
499 { OUString("ProgressCurrent"), 0, ::cppu::UnoType<sal_Int32>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
500 { OUString("Preview"), 0, ::cppu::UnoType<sal_Bool>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
501 { OUString("PageLayouts"), 0, cppu::UnoType<container::XNameAccess>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
502 { OUString("PrivateData"), 0,
503 cppu::UnoType<XInterface>::get(),
504 ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
505 { OUString("BaseURI"), 0,
506 ::cppu::UnoType<OUString>::get(),
507 ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
508 { OUString("StreamRelPath"), 0,
509 ::cppu::UnoType<OUString>::get(),
510 ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
511 { OUString("StreamName"), 0,
512 ::cppu::UnoType<OUString>::get(),
513 ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
514 { OUString("BuildId"), 0,
515 ::cppu::UnoType<OUString>::get(),
516 ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
517 { OUString("OrganizerMode"), 0,
518 cppu::UnoType<bool>::get(),
519 ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
520 { OUString("SourceStorage"), 0, cppu::UnoType<embed::XStorage>::get(),
521 ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
522 { OUString(), 0, css::uno::Type(), 0, 0 }
525 uno::Reference< beans::XPropertySet > xInfoSet( GenericPropertySet_CreateInstance( new PropertySetInfo( aImportInfoMap ) ) );
526 xInfoSet->setPropertyValue( "Preview" , uno::makeAny( mrDocShell.GetDoc()->IsStarDrawPreviewMode() ) );
528 // ---- get BuildId from parent container if available
530 uno::Reference< container::XChild > xChild( mxModel, uno::UNO_QUERY );
531 if( xChild.is() )
533 uno::Reference< beans::XPropertySet > xParentSet( xChild->getParent(), uno::UNO_QUERY );
534 if( xParentSet.is() )
536 uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xParentSet->getPropertySetInfo() );
537 OUString sPropName( "BuildId" );
538 if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(sPropName) )
540 xInfoSet->setPropertyValue( sPropName, xParentSet->getPropertyValue(sPropName) );
545 Reference< io::XActiveDataSource > xSource;
546 Reference< XInterface > xPipe;
547 Reference< document::XGraphicObjectResolver > xGraphicResolver;
548 SvXMLGraphicHelper *pGraphicHelper = 0;
549 Reference< document::XEmbeddedObjectResolver > xObjectResolver;
550 SvXMLEmbeddedObjectHelper *pObjectHelper = 0;
552 Reference< lang::XComponent > xModelComp( mxModel, uno::UNO_QUERY );
554 // try to get an XStatusIndicator from the Medium
555 if( mbShowProgress )
557 SfxItemSet* pSet = mrMedium.GetItemSet();
558 if(pSet)
560 const SfxUnoAnyItem* pItem = static_cast<const SfxUnoAnyItem*>(
561 pSet->GetItem(SID_PROGRESS_STATUSBAR_CONTROL) );
562 if (pItem)
564 pItem->GetValue() >>= mxStatusIndicator;
568 if(mxStatusIndicator.is())
570 sal_Int32 nProgressRange(1000000);
571 sal_Int32 nProgressCurrent(0);
572 OUString aMsg(SD_RESSTR(STR_LOAD_DOC));
573 mxStatusIndicator->start(aMsg, nProgressRange);
575 // set ProgressRange
576 uno::Any aProgRange;
577 aProgRange <<= nProgressRange;
578 xInfoSet->setPropertyValue( "ProgressRange" , aProgRange);
580 // set ProgressCurrent
581 uno::Any aProgCurrent;
582 aProgCurrent <<= nProgressCurrent;
583 xInfoSet->setPropertyValue( "ProgressCurrent" , aProgCurrent);
587 // get the input stream (storage or stream)
589 tools::SvRef<SotStorageStream> xDocStream;
590 Reference<io::XInputStream> xInputStream;
591 uno::Reference < embed::XStorage > xStorage = mrMedium.GetStorage();
593 OUString sSourceStorage( "SourceStorage");
594 xInfoSet->setPropertyValue( sSourceStorage, Any( xStorage ) );
596 if( !xStorage.is() )
597 nRet = SD_XML_READERROR;
599 if( 0 == nRet )
601 pGraphicHelper = SvXMLGraphicHelper::Create( xStorage,
602 GRAPHICHELPER_MODE_READ,
603 false );
604 xGraphicResolver = pGraphicHelper;
605 pObjectHelper = SvXMLEmbeddedObjectHelper::Create(
606 xStorage, *pDoc->GetPersist(),
607 EMBEDDEDOBJECTHELPER_MODE_READ,
608 false );
609 xObjectResolver = pObjectHelper;
612 // Set base URI
613 xInfoSet->setPropertyValue( "BaseURI" , makeAny( mrMedium.GetBaseURL() ) );
615 if( 0 == nRet && SfxObjectCreateMode::EMBEDDED == mrDocShell.GetCreateMode() )
617 OUString aName;
618 if ( mrMedium.GetItemSet() )
620 const SfxStringItem* pDocHierarchItem = static_cast<const SfxStringItem*>(
621 mrMedium.GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) );
622 if ( pDocHierarchItem )
623 aName = pDocHierarchItem->GetValue();
625 else
626 aName = "dummyObjectName" ;
628 if( !aName.isEmpty() )
629 xInfoSet->setPropertyValue( "StreamRelPath", Any( aName ) );
632 if (SDXMLMODE_Organizer == meFilterMode)
633 xInfoSet->setPropertyValue("OrganizerMode", uno::makeAny(sal_True));
635 if( 0 == nRet )
638 // prepare filter arguments
639 Sequence<Any> aFilterArgs( 4 );
640 Any *pArgs = aFilterArgs.getArray();
641 *pArgs++ <<= xInfoSet;
642 *pArgs++ <<= xGraphicResolver;
643 *pArgs++ <<= xObjectResolver;
644 *pArgs++ <<= mxStatusIndicator;
646 Sequence<Any> aEmptyArgs( 2 );
647 pArgs = aEmptyArgs.getArray();
648 *pArgs++ <<= xInfoSet;
649 *pArgs++ <<= mxStatusIndicator;
651 const OUString aName( mrMedium.GetName() );
653 XML_SERVICES* pServices = getServices( true, IsDraw(), mnStoreVer );
655 sal_uInt32 nWarn = 0;
656 sal_uInt32 nWarn2 = 0;
657 // read storage streams
658 // #i103539#: always read meta.xml for generator
659 nWarn = ReadThroughComponent(
660 xStorage, xModelComp, "meta.xml", "Meta.xml", rxContext,
661 pServices->mpMeta,
662 aEmptyArgs, aName, false );
664 if( meFilterMode != SDXMLMODE_Organizer )
666 nWarn2 = ReadThroughComponent(
667 xStorage, xModelComp, "settings.xml", NULL, rxContext,
668 pServices->mpSettings,
669 aFilterArgs, aName, false );
672 nRet = ReadThroughComponent(
673 xStorage, xModelComp, "styles.xml", NULL, rxContext,
674 pServices->mpStyles,
675 aFilterArgs, aName, true );
677 if( !nRet && (meFilterMode != SDXMLMODE_Organizer) )
678 nRet = ReadThroughComponent(
679 xStorage, xModelComp, "content.xml", "Content.xml", rxContext,
680 pServices->mpContent,
681 aFilterArgs, aName, true );
683 if( !nRet )
685 if( nWarn )
686 nRet = nWarn;
687 else if( nWarn2 )
688 nRet = nWarn2;
692 if( pGraphicHelper )
693 SvXMLGraphicHelper::Destroy( pGraphicHelper );
694 xGraphicResolver = 0;
695 if( pObjectHelper )
696 SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper );
697 xObjectResolver = 0;
699 if( mxStatusIndicator.is() )
700 mxStatusIndicator->end();
702 if( mxModel.is() )
703 mxModel->unlockControllers();
705 if( nRet == 0 )
706 pDoc->UpdateAllLinks();
708 switch( nRet )
710 case 0: break;
711 case SD_XML_READERROR: break;
712 case ERRCODE_IO_BROKENPACKAGE:
713 if( xStorage.is() )
715 nError = ERRCODE_IO_BROKENPACKAGE;
716 break;
718 // fall through intended
719 default:
721 // TODO/LATER: this is completely wrong! Filter code should never call ErrorHandler directly!
722 ErrorHandler::HandleError( nRet );
723 if( IsWarning( nRet ) )
724 nRet = 0;
728 // clear unused named items from item pool
730 uno::Reference< lang::XMultiServiceFactory> xModelFactory( mxModel, uno::UNO_QUERY );
731 if( xModelFactory.is() )
735 const OUString aName("~clear~" );
736 uno::Reference< container::XNameContainer > xGradient( xModelFactory->createInstance( "com.sun.star.drawing.GradientTable" ), uno::UNO_QUERY );
737 if( xGradient.is() )
738 xGradient->removeByName( aName );
740 uno::Reference< container::XNameContainer > xHatch( xModelFactory->createInstance( "com.sun.star.drawing.HatchTable" ), uno::UNO_QUERY );
741 if( xHatch.is() )
742 xHatch->removeByName( aName );
744 uno::Reference< container::XNameContainer > xBitmap( xModelFactory->createInstance( "com.sun.star.drawing.BitmapTable" ), uno::UNO_QUERY );
745 if( xBitmap.is() )
746 xBitmap->removeByName( aName );
748 uno::Reference< container::XNameContainer > xTransGradient( xModelFactory->createInstance( "com.sun.star.drawing.TransparencyGradientTable" ), uno::UNO_QUERY );
749 if( xTransGradient.is() )
750 xTransGradient->removeByName( aName );
752 uno::Reference< container::XNameContainer > xMarker( xModelFactory->createInstance( "com.sun.star.drawing.MarkerTable" ), uno::UNO_QUERY );
753 if( xMarker.is() )
754 xMarker->removeByName( aName );
756 uno::Reference< container::XNameContainer > xDashes( xModelFactory->createInstance( "com.sun.star.drawing.DashTable" ), uno::UNO_QUERY );
757 if( xDashes.is() )
758 xDashes->removeByName( aName );
760 catch (const Exception&)
762 SAL_WARN( "sd.filter","sd::SdXMLFilter::Import(), exception during clearing of unused named items");
766 // set BuildId on XModel for later OLE object loading
767 if( xInfoSet.is() )
769 uno::Reference< beans::XPropertySet > xModelSet( mxModel, uno::UNO_QUERY );
770 if( xModelSet.is() )
772 uno::Reference< beans::XPropertySetInfo > xModelSetInfo( xModelSet->getPropertySetInfo() );
773 const OUString sPropName( "BuildId" );
775 OUString sBuildId;
776 xInfoSet->getPropertyValue(sPropName) >>= sBuildId;
778 if( xModelSetInfo.is() && xModelSetInfo->hasPropertyByName(sPropName) )
780 xModelSet->setPropertyValue( sPropName, Any( sBuildId ) );
783 bool bTransform = false;
785 if( nRet == 0 )
787 if( !sBuildId.isEmpty() )
789 sal_Int32 nIndex = sBuildId.indexOf('$');
790 if( nIndex != -1 )
792 sal_Int32 nUPD = sBuildId.copy( 0, nIndex ).toInt32();
794 if( nUPD == 300 )
796 sal_Int32 nBuildId = sBuildId.copy( nIndex+1 ).toInt32();
797 if( (nBuildId > 0) && (nBuildId < 9316) )
798 bTransform = true; // treat OOo 3.0 beta1 as OOo 2.x
800 else if( (nUPD == 680) || ( nUPD >= 640 && nUPD <= 645 ) )
801 bTransform = true;
804 else
806 // check for binary formats
807 const SfxFilter * pFilter = mrMedium.GetFilter();
808 if( pFilter )
810 OUString typeName(pFilter->GetRealTypeName());
811 if( typeName.startsWith( "impress_StarImpress" ) ||
812 typeName.startsWith( "draw_StarDraw" ) )
814 bTransform = true;
820 if( bTransform )
821 TransformOOo2xDocument( pDoc );
825 fixupOutlinePlaceholderNumberingDepths(pDoc);
827 pDoc->EnableUndo(true);
828 mrDocShell.ClearUndoBuffer();
829 return nRet == 0;
832 bool SdXMLFilter::Export()
834 SvXMLEmbeddedObjectHelper* pObjectHelper = NULL;
835 SvXMLGraphicHelper* pGraphicHelper = NULL;
836 bool bDocRet = false;
838 if( !mxModel.is() )
840 SAL_WARN( "sd.filter","Got NO Model in XMLExport");
841 return false;
844 bool bLocked = mxModel->hasControllersLocked();
848 mxModel->lockControllers();
850 uno::Reference< lang::XServiceInfo > xServiceInfo( mxModel, uno::UNO_QUERY );
852 if( !xServiceInfo.is() || !xServiceInfo->supportsService( "com.sun.star.drawing.GenericDrawingDocument" ) )
854 SAL_WARN( "sd.filter", "Model is no DrawingDocument in XMLExport" );
855 return false;
858 uno::Reference<uno::XComponentContext> xContext( ::comphelper::getProcessComponentContext() );
860 uno::Reference< xml::sax::XWriter > xWriter = xml::sax::Writer::create( xContext );
862 /** property map for export info set */
863 PropertyMapEntry const aExportInfoMap[] =
865 { OUString("ProgressRange"), 0, ::cppu::UnoType<sal_Int32>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
866 { OUString("ProgressMax"), 0, ::cppu::UnoType<sal_Int32>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
867 { OUString("ProgressCurrent"), 0, ::cppu::UnoType<sal_Int32>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
868 { OUString("UsePrettyPrinting"),0, cppu::UnoType<bool>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
870 { OUString("PageLayoutNames"), 0, ::cppu::UnoType<OUString>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
871 { OUString("BaseURI"), 0,
872 ::cppu::UnoType<OUString>::get(),
873 ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
874 { OUString("StreamRelPath"), 0,
875 ::cppu::UnoType<OUString>::get(),
876 ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
877 { OUString("StreamName"), 0,
878 ::cppu::UnoType<OUString>::get(),
879 ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
880 { OUString("StyleNames"), 0,
881 cppu::UnoType<Sequence<OUString>>::get(),
882 ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
883 { OUString("StyleFamilies"), 0,
884 cppu::UnoType<Sequence<sal_Int32>>::get(),
885 ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
886 { OUString("TargetStorage"), 0, cppu::UnoType<embed::XStorage>::get(),
887 ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
888 { OUString(), 0, css::uno::Type(), 0, 0 }
891 uno::Reference< beans::XPropertySet > xInfoSet( GenericPropertySet_CreateInstance( new PropertySetInfo( aExportInfoMap ) ) );
893 SvtSaveOptions aSaveOpt;
894 OUString sUsePrettyPrinting("UsePrettyPrinting");
895 bool bUsePrettyPrinting( aSaveOpt.IsPrettyPrinting() );
896 xInfoSet->setPropertyValue( sUsePrettyPrinting, makeAny( bUsePrettyPrinting ) );
898 const uno::Reference < embed::XStorage >& xStorage = mrMedium.GetOutputStorage();
900 // Set base URI
901 OUString sPropName( "BaseURI" );
902 xInfoSet->setPropertyValue( sPropName, makeAny( mrMedium.GetBaseURL( true ) ) );
904 OUString sTargetStorage( "TargetStorage" );
905 xInfoSet->setPropertyValue( sTargetStorage, Any( xStorage ) );
907 if( SfxObjectCreateMode::EMBEDDED == mrDocShell.GetCreateMode() )
909 OUString aName;
910 if ( mrMedium.GetItemSet() )
912 const SfxStringItem* pDocHierarchItem = static_cast<const SfxStringItem*>(
913 mrMedium.GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) );
914 if ( pDocHierarchItem )
915 aName = pDocHierarchItem->GetValue();
918 if( !aName.isEmpty() )
920 sPropName = "StreamRelPath";
921 xInfoSet->setPropertyValue( sPropName, makeAny( aName ) );
925 // initialize descriptor
926 uno::Sequence< beans::PropertyValue > aDescriptor( 1 );
927 beans::PropertyValue* pProps = aDescriptor.getArray();
929 pProps[0].Name = "FileName";
930 pProps[0].Value <<= OUString( mrMedium.GetName() );
933 uno::Reference< document::XEmbeddedObjectResolver > xObjectResolver;
934 uno::Reference< document::XGraphicObjectResolver > xGrfResolver;
936 // create helper for graphic and ole export if we have a storage
937 if( xStorage.is() )
939 pObjectHelper = SvXMLEmbeddedObjectHelper::Create( xStorage, *mrDocShell.GetDoc()->GetPersist(), EMBEDDEDOBJECTHELPER_MODE_WRITE, false );
940 xObjectResolver = pObjectHelper;
942 pGraphicHelper = SvXMLGraphicHelper::Create( xStorage, GRAPHICHELPER_MODE_WRITE, false );
943 xGrfResolver = pGraphicHelper;
946 if(mbShowProgress)
948 CreateStatusIndicator();
949 if(mxStatusIndicator.is())
951 sal_Int32 nProgressRange(1000000);
952 sal_Int32 nProgressCurrent(0);
953 OUString aMsg(SD_RESSTR(STR_SAVE_DOC));
954 mxStatusIndicator->start(aMsg, nProgressRange);
956 // set ProgressRange
957 uno::Any aProgRange;
958 aProgRange <<= nProgressRange;
959 xInfoSet->setPropertyValue( "ProgressRange" , aProgRange);
961 // set ProgressCurrent
962 uno::Any aProgCurrent;
963 aProgCurrent <<= nProgressCurrent;
964 xInfoSet->setPropertyValue( "ProgressCurrent" , aProgCurrent);
968 uno::Reference< lang::XComponent > xComponent( mxModel, uno::UNO_QUERY );
970 XML_SERVICES* pServiceNames = getServices( false, IsDraw(), mnStoreVer );
972 XML_SERVICEMAP aServices[5]; sal_uInt16 i = 0;
973 aServices[i ].mpService = pServiceNames->mpStyles;
974 aServices[i++].mpStream = sXML_styleStreamName;
976 aServices[i ].mpService = pServiceNames->mpContent;
977 aServices[i++].mpStream = sXML_contentStreamName;
979 aServices[i ].mpService = pServiceNames->mpSettings;
980 aServices[i++].mpStream = sXML_settingsStreamName;
982 if( mrDocShell.GetCreateMode() != SfxObjectCreateMode::EMBEDDED )
984 aServices[i ].mpService = pServiceNames->mpMeta;
985 aServices[i++].mpStream = sXML_metaStreamName;
988 aServices[i].mpService = NULL;
989 aServices[i].mpStream = NULL;
991 XML_SERVICEMAP* pServices = aServices;
993 // doc export
996 SAL_INFO( "sd.filter", "exporting substream " << pServices->mpStream );
998 uno::Reference<io::XOutputStream> xDocOut;
999 if( xStorage.is() )
1001 const OUString sDocName( OUString::createFromAscii( pServices->mpStream ) );
1002 uno::Reference<io::XStream> xStream =
1003 xStorage->openStreamElement( sDocName,
1004 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
1006 DBG_ASSERT(xStream.is(), "Can't create output stream in package!");
1007 if( !xStream.is() )
1008 return false;
1010 xDocOut = xStream->getOutputStream();
1011 Reference <beans::XPropertySet > xProps( xStream, uno::UNO_QUERY );
1012 if( !xDocOut.is() || !xProps.is() )
1013 return false;
1015 uno::Any aAny;
1016 aAny <<= OUString( "text/xml");
1017 xProps->setPropertyValue( "MediaType" , aAny);
1019 // encrypt all streams
1020 xProps->setPropertyValue( "UseCommonStoragePasswordEncryption",
1021 uno::makeAny( true ) );
1023 const OUString sStreamName( "StreamName");
1024 xInfoSet->setPropertyValue( sStreamName, Any( sDocName ) );
1027 uno::Reference< io::XActiveDataSource > xDocSrc( xWriter, uno::UNO_QUERY );
1028 xDocSrc->setOutputStream( xDocOut );
1030 uno::Sequence< uno::Any > aArgs( 2 + ( mxStatusIndicator.is() ? 1 : 0 ) + ( xGrfResolver.is() ? 1 : 0 ) + ( xObjectResolver.is() ? 1 : 0 ) );
1031 uno::Any* pArgs = aArgs.getArray();
1032 *pArgs++ <<= xInfoSet;
1033 if( xGrfResolver.is() ) *pArgs++ <<= xGrfResolver;
1034 if( xObjectResolver.is() ) *pArgs++ <<= xObjectResolver;
1035 if( mxStatusIndicator.is() ) *pArgs++ <<= mxStatusIndicator;
1037 *pArgs <<= xWriter;
1039 uno::Reference< document::XFilter > xFilter( xContext->getServiceManager()->createInstanceWithArgumentsAndContext( OUString::createFromAscii( pServices->mpService ), aArgs, xContext ), uno::UNO_QUERY );
1040 if( xFilter.is() )
1042 uno::Reference< document::XExporter > xExporter( xFilter, uno::UNO_QUERY );
1043 if( xExporter.is() )
1045 xExporter->setSourceDocument( xComponent );
1046 // outputstream will be closed by SAX parser
1047 bDocRet = xFilter->filter( aDescriptor );
1051 pServices++;
1053 while( bDocRet && pServices->mpService );
1055 if(mbShowProgress)
1057 if(mxStatusIndicator.is())
1058 mxStatusIndicator->end();
1062 catch (const uno::Exception &e)
1064 #if OSL_DEBUG_LEVEL > 1
1065 SAL_WARN( "sd.filter", "uno Exception caught while exporting:" << e.Message);
1066 #else
1067 (void)e;
1068 #endif
1069 bDocRet = false;
1071 if ( !bLocked )
1072 mxModel->unlockControllers();
1074 if( pGraphicHelper )
1075 SvXMLGraphicHelper::Destroy( pGraphicHelper );
1077 if( pObjectHelper )
1078 SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper );
1080 return bDocRet;
1083 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */