1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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"
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"
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";
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
;
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 ) ];
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()
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
,
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
;
206 Reference
< xml::sax::XParser
> xParser
= xml::sax::Parser::create(rxContext
);
207 SAL_INFO( "sd.filter", "parser created" );
210 OUString
aFilterName(OUString::createFromAscii(pFilterName
));
211 Reference
< xml::sax::XDocumentHandler
> xFilter(
212 rxContext
->getServiceManager()->createInstanceWithArgumentsAndContext(aFilterName
, rFilterArguments
, rxContext
),
214 SAL_WARN_IF(!xFilter
.is(), "sd.filter", "Can't instantiate filter component: " << aFilterName
);
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;
240 xml::sax::SAXException aTmp
;
241 if ( aSaxEx
.WrappedException
>>= aTmp
)
247 packages::zip::ZipIOException aBrokenPackage
;
248 if ( aSaxEx
.WrappedException
>>= aBrokenPackage
)
249 return ERRCODE_IO_BROKENPACKAGE
;
252 return ERRCODE_SFX_WRONGPASSWORD
;
254 #if OSL_DEBUG_LEVEL > 1
255 SAL_WARN( "sd.filter", "SAX parse exception caught while importing:" << r
.Message
);
258 OUString
sErr( OUString::number( r
.LineNumber
));
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
),
268 ERRCODE_BUTTON_OK
| ERRCODE_MSG_ERROR
);
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
;
284 return ERRCODE_SFX_WRONGPASSWORD
;
286 #if OSL_DEBUG_LEVEL > 1
287 SAL_WARN( "sd.filter", "SAX exception caught while importing:" << r
.Message
);
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
);
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
);
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
);
316 return SD_XML_READERROR
;
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
)
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
)
372 uno::Reference
< beans::XPropertySet
> xInfoSet
;
373 if( rFilterArguments
.getLength() > 0 )
374 rFilterArguments
.getConstArray()[0] >>= xInfoSet
;
375 DBG_ASSERT( xInfoSet
.is(), "missing property set" );
378 OUString
sPropName( "StreamName" );
379 xInfoSet
->setPropertyValue( sPropName
, makeAny( sStreamName
) );
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
);
438 OutlinerParaObject
* pOutlParaObj
= pMasterOutline
->GetOutlinerParaObject();
441 ::sd::Outliner
* pOutliner
= pDoc
->GetInternalOutliner();
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;
470 SAL_WARN("sd.filter", "Fixing inconsistent outline numbering placeholder preview");
471 pMasterOutline
->SetOutlinerParaObject(pOutliner
->CreateParaObject(0, nParaCount
));
477 bool SdXMLFilter::Import( ErrCode
& nError
)
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
);
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
557 SfxItemSet
* pSet
= mrMedium
.GetItemSet();
560 const SfxUnoAnyItem
* pItem
= static_cast<const SfxUnoAnyItem
*>(
561 pSet
->GetItem(SID_PROGRESS_STATUSBAR_CONTROL
) );
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
);
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
) );
597 nRet
= SD_XML_READERROR
;
601 pGraphicHelper
= SvXMLGraphicHelper::Create( xStorage
,
602 GRAPHICHELPER_MODE_READ
,
604 xGraphicResolver
= pGraphicHelper
;
605 pObjectHelper
= SvXMLEmbeddedObjectHelper::Create(
606 xStorage
, *pDoc
->GetPersist(),
607 EMBEDDEDOBJECTHELPER_MODE_READ
,
609 xObjectResolver
= pObjectHelper
;
613 xInfoSet
->setPropertyValue( "BaseURI" , makeAny( mrMedium
.GetBaseURL() ) );
615 if( 0 == nRet
&& SfxObjectCreateMode::EMBEDDED
== mrDocShell
.GetCreateMode() )
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();
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
));
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
,
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
,
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 );
693 SvXMLGraphicHelper::Destroy( pGraphicHelper
);
694 xGraphicResolver
= 0;
696 SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper
);
699 if( mxStatusIndicator
.is() )
700 mxStatusIndicator
->end();
703 mxModel
->unlockControllers();
706 pDoc
->UpdateAllLinks();
711 case SD_XML_READERROR
: break;
712 case ERRCODE_IO_BROKENPACKAGE
:
715 nError
= ERRCODE_IO_BROKENPACKAGE
;
718 // fall through intended
721 // TODO/LATER: this is completely wrong! Filter code should never call ErrorHandler directly!
722 ErrorHandler::HandleError( nRet
);
723 if( IsWarning( nRet
) )
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
);
738 xGradient
->removeByName( aName
);
740 uno::Reference
< container::XNameContainer
> xHatch( xModelFactory
->createInstance( "com.sun.star.drawing.HatchTable" ), uno::UNO_QUERY
);
742 xHatch
->removeByName( aName
);
744 uno::Reference
< container::XNameContainer
> xBitmap( xModelFactory
->createInstance( "com.sun.star.drawing.BitmapTable" ), uno::UNO_QUERY
);
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
);
754 xMarker
->removeByName( aName
);
756 uno::Reference
< container::XNameContainer
> xDashes( xModelFactory
->createInstance( "com.sun.star.drawing.DashTable" ), uno::UNO_QUERY
);
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
769 uno::Reference
< beans::XPropertySet
> xModelSet( mxModel
, uno::UNO_QUERY
);
772 uno::Reference
< beans::XPropertySetInfo
> xModelSetInfo( xModelSet
->getPropertySetInfo() );
773 const OUString
sPropName( "BuildId" );
776 xInfoSet
->getPropertyValue(sPropName
) >>= sBuildId
;
778 if( xModelSetInfo
.is() && xModelSetInfo
->hasPropertyByName(sPropName
) )
780 xModelSet
->setPropertyValue( sPropName
, Any( sBuildId
) );
783 bool bTransform
= false;
787 if( !sBuildId
.isEmpty() )
789 sal_Int32 nIndex
= sBuildId
.indexOf('$');
792 sal_Int32 nUPD
= sBuildId
.copy( 0, nIndex
).toInt32();
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 ) )
806 // check for binary formats
807 const SfxFilter
* pFilter
= mrMedium
.GetFilter();
810 OUString
typeName(pFilter
->GetRealTypeName());
811 if( typeName
.startsWith( "impress_StarImpress" ) ||
812 typeName
.startsWith( "draw_StarDraw" ) )
821 TransformOOo2xDocument( pDoc
);
825 fixupOutlinePlaceholderNumberingDepths(pDoc
);
827 pDoc
->EnableUndo(true);
828 mrDocShell
.ClearUndoBuffer();
832 bool SdXMLFilter::Export()
834 SvXMLEmbeddedObjectHelper
* pObjectHelper
= NULL
;
835 SvXMLGraphicHelper
* pGraphicHelper
= NULL
;
836 bool bDocRet
= false;
840 SAL_WARN( "sd.filter","Got NO Model in XMLExport");
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" );
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();
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() )
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
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
;
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
);
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
;
996 SAL_INFO( "sd.filter", "exporting substream " << pServices
->mpStream
);
998 uno::Reference
<io::XOutputStream
> xDocOut
;
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!");
1010 xDocOut
= xStream
->getOutputStream();
1011 Reference
<beans::XPropertySet
> xProps( xStream
, uno::UNO_QUERY
);
1012 if( !xDocOut
.is() || !xProps
.is() )
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
;
1039 uno::Reference
< document::XFilter
> xFilter( xContext
->getServiceManager()->createInstanceWithArgumentsAndContext( OUString::createFromAscii( pServices
->mpService
), aArgs
, xContext
), uno::UNO_QUERY
);
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
);
1053 while( bDocRet
&& pServices
->mpService
);
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
);
1072 mxModel
->unlockControllers();
1074 if( pGraphicHelper
)
1075 SvXMLGraphicHelper::Destroy( pGraphicHelper
);
1078 SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper
);
1083 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */