android: Update app-specific/MIME type icons
[LibreOffice.git] / sw / source / filter / xml / swxml.cxx
blobb679f111a3b6c0eaebf7b1012a9e8068ff3a8819
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 <com/sun/star/embed/XStorage.hpp>
21 #include <com/sun/star/embed/ElementModes.hpp>
22 #include <comphelper/processfactory.hxx>
23 #include <com/sun/star/xml/sax/InputSource.hpp>
24 #include <com/sun/star/xml/sax/Parser.hpp>
25 #include <com/sun/star/xml/sax/SAXParseException.hpp>
26 #include <com/sun/star/text/XTextRange.hpp>
27 #include <com/sun/star/container/XChild.hpp>
28 #include <com/sun/star/document/NamedPropertyValues.hpp>
29 #include <com/sun/star/beans/XPropertySetInfo.hpp>
30 #include <com/sun/star/beans/NamedValue.hpp>
31 #include <com/sun/star/beans/PropertyAttribute.hpp>
32 #include <com/sun/star/packages/zip/ZipIOException.hpp>
33 #include <com/sun/star/packages/WrongPasswordException.hpp>
34 #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
35 #include <com/sun/star/task/XStatusIndicator.hpp>
36 #include <com/sun/star/frame/XModel.hpp>
37 #include <o3tl/any.hxx>
38 #include <vcl/errinf.hxx>
39 #include <sfx2/docfile.hxx>
40 #include <svtools/sfxecode.hxx>
41 #include <svl/stritem.hxx>
42 #include <svx/dialmgr.hxx>
43 #include <svx/strings.hrc>
44 #include <svx/xmlgrhlp.hxx>
45 #include <svx/xmleohlp.hxx>
46 #include <comphelper/fileformat.h>
47 #include <comphelper/genericpropertyset.hxx>
48 #include <comphelper/propertysetinfo.hxx>
49 #include <sal/log.hxx>
50 #include <sfx2/frame.hxx>
51 #include <unotools/ucbstreamhelper.hxx>
52 #include <swerror.h>
53 #include <fltini.hxx>
54 #include <drawdoc.hxx>
55 #include <doc.hxx>
56 #include <docfunc.hxx>
57 #include <IDocumentSettingAccess.hxx>
58 #include <IDocumentDrawModelAccess.hxx>
59 #include <IDocumentMarkAccess.hxx>
60 #include <IDocumentRedlineAccess.hxx>
61 #include <DocumentRedlineManager.hxx>
62 #include <docary.hxx>
63 #include <docsh.hxx>
64 #include <unotextrange.hxx>
65 #include <SwXMLSectionList.hxx>
67 #include <SwStyleNameMapper.hxx>
68 #include <poolfmt.hxx>
69 #include <numrule.hxx>
70 #include <paratr.hxx>
71 #include <fmtrowsplt.hxx>
73 #include <svx/svdpage.hxx>
74 #include <svx/svditer.hxx>
75 #include <svx/svdoole2.hxx>
76 #include <svx/svdograf.hxx>
77 #include <sfx2/docfilt.hxx>
78 #include <sfx2/sfxsids.hrc>
79 #include <istyleaccess.hxx>
81 #include <sfx2/DocumentMetadataAccess.hxx>
82 #include <comphelper/diagnose_ex.hxx>
84 using namespace ::com::sun::star;
85 using namespace ::com::sun::star::uno;
86 using namespace ::com::sun::star::text;
87 using namespace ::com::sun::star::container;
88 using namespace ::com::sun::star::document;
89 using namespace ::com::sun::star::lang;
91 static void lcl_EnsureValidPam( SwPaM& rPam )
93 if( rPam.GetPointContentNode() != nullptr )
95 // set proper point content
96 if( rPam.GetPointContentNode() != rPam.GetPoint()->GetContentNode() )
98 rPam.GetPoint()->nContent.Assign( rPam.GetPointContentNode(), 0 );
100 // else: point was already valid
102 // if mark is invalid, we delete it
103 if( ( rPam.GetMarkContentNode() == nullptr ) ||
104 ( rPam.GetMarkContentNode() != rPam.GetMark()->GetContentNode() ) )
106 rPam.DeleteMark();
109 else
111 // point is not valid, so move it into the first content
112 rPam.DeleteMark();
113 rPam.GetPoint()->Assign(
114 *rPam.GetDoc().GetNodes().GetEndOfContent().StartOfSectionNode() );
115 rPam.GetPoint()->Adjust(SwNodeOffset(+1));
116 rPam.Move( fnMoveForward, GoInContent ); // go into content
120 XMLReader::XMLReader()
124 SwReaderType XMLReader::GetReaderType()
126 return SwReaderType::Storage;
129 namespace
132 /// read a component (file + filter version)
133 ErrCode ReadThroughComponent(
134 uno::Reference<io::XInputStream> const & xInputStream,
135 uno::Reference<XComponent> const & xModelComponent,
136 const OUString& rStreamName,
137 uno::Reference<uno::XComponentContext> const & rxContext,
138 const char* pFilterName,
139 const Sequence<Any>& rFilterArguments,
140 const OUString& rName,
141 bool bMustBeSuccessful,
142 bool bEncrypted )
144 OSL_ENSURE(xInputStream.is(), "input stream missing");
145 OSL_ENSURE(xModelComponent.is(), "document missing");
146 OSL_ENSURE(rxContext.is(), "factory missing");
147 OSL_ENSURE(nullptr != pFilterName,"I need a service name for the component!");
149 // prepare ParserInputSource
150 xml::sax::InputSource aParserInput;
151 aParserInput.sSystemId = rName;
152 aParserInput.aInputStream = xInputStream;
154 // get filter
155 const OUString aFilterName(OUString::createFromAscii(pFilterName));
156 uno::Reference< XInterface > xFilter =
157 rxContext->getServiceManager()->createInstanceWithArgumentsAndContext(aFilterName, rFilterArguments, rxContext);
158 SAL_WARN_IF(!xFilter.is(), "sw.filter", "Can't instantiate filter component: " << aFilterName);
159 if( !xFilter.is() )
160 return ERR_SWG_READ_ERROR;
161 // the underlying SvXMLImport implements XFastParser, XImporter, XFastDocumentHandler
162 uno::Reference< xml::sax::XFastParser > xFastParser(xFilter, UNO_QUERY);
163 uno::Reference< xml::sax::XDocumentHandler > xDocumentHandler;
164 if (!xFastParser)
165 xDocumentHandler.set(xFilter, UNO_QUERY);
166 if (!xDocumentHandler && !xFastParser)
168 SAL_WARN("sd", "service does not implement XFastParser or XDocumentHandler");
169 assert(false);
170 return ERR_SWG_READ_ERROR;
173 // connect model and filter
174 uno::Reference < XImporter > xImporter( xFilter, UNO_QUERY );
175 xImporter->setTargetDocument( xModelComponent );
177 // finally, parse the stream
180 if (xFastParser)
181 xFastParser->parseStream( aParserInput );
182 else
184 uno::Reference< xml::sax::XParser > xParser = xml::sax::Parser::create(rxContext);
185 // connect parser and filter
186 xParser->setDocumentHandler( xDocumentHandler );
187 xParser->parseStream( aParserInput );
190 catch( xml::sax::SAXParseException& r)
192 css::uno::Any ex( cppu::getCaughtException() );
193 // sax parser sends wrapped exceptions,
194 // try to find the original one
195 xml::sax::SAXException aSaxEx = *static_cast<xml::sax::SAXException*>(&r);
196 bool bTryChild = true;
198 while( bTryChild )
200 xml::sax::SAXException aTmp;
201 if ( aSaxEx.WrappedException >>= aTmp )
202 aSaxEx = aTmp;
203 else
204 bTryChild = false;
207 packages::zip::ZipIOException aBrokenPackage;
208 if ( aSaxEx.WrappedException >>= aBrokenPackage )
209 return ERRCODE_IO_BROKENPACKAGE;
211 if( bEncrypted )
212 return ERRCODE_SFX_WRONGPASSWORD;
214 SAL_WARN( "sw", "SAX parse exception caught while importing: " << exceptionToString(ex) );
216 const OUString sErr( OUString::number( r.LineNumber )
217 + ","
218 + OUString::number( r.ColumnNumber ) );
220 if( !rStreamName.isEmpty() )
222 return *new TwoStringErrorInfo(
223 (bMustBeSuccessful ? ERR_FORMAT_FILE_ROWCOL
224 : WARN_FORMAT_FILE_ROWCOL),
225 rStreamName, sErr,
226 DialogMask::ButtonsOk | DialogMask::MessageError );
228 else
230 OSL_ENSURE( bMustBeSuccessful, "Warnings are not supported" );
231 return *new StringErrorInfo( ERR_FORMAT_ROWCOL, sErr,
232 DialogMask::ButtonsOk | DialogMask::MessageError );
235 catch(const xml::sax::SAXException& r)
237 css::uno::Any ex( cppu::getCaughtException() );
238 packages::zip::ZipIOException aBrokenPackage;
239 if ( r.WrappedException >>= aBrokenPackage )
240 return ERRCODE_IO_BROKENPACKAGE;
242 if( bEncrypted )
243 return ERRCODE_SFX_WRONGPASSWORD;
245 SAL_WARN( "sw", "uno exception caught while importing: " << exceptionToString(ex) );
246 return ERR_SWG_READ_ERROR;
248 catch(const packages::zip::ZipIOException&)
250 TOOLS_WARN_EXCEPTION( "sw", "uno exception caught while importing" );
251 return ERRCODE_IO_BROKENPACKAGE;
253 catch(const io::IOException&)
255 TOOLS_WARN_EXCEPTION( "sw", "uno exception caught while importing" );
256 return ERR_SWG_READ_ERROR;
258 catch(const uno::Exception&)
260 TOOLS_WARN_EXCEPTION( "sw", "uno exception caught while importing" );
261 return ERR_SWG_READ_ERROR;
264 // success!
265 return ERRCODE_NONE;
268 // read a component (storage version)
269 ErrCode ReadThroughComponent(
270 uno::Reference<embed::XStorage> const & xStorage,
271 uno::Reference<XComponent> const & xModelComponent,
272 const char* pStreamName,
273 uno::Reference<uno::XComponentContext> const & rxContext,
274 const char* pFilterName,
275 const Sequence<Any>& rFilterArguments,
276 const OUString& rName,
277 bool bMustBeSuccessful)
279 OSL_ENSURE(xStorage.is(), "Need storage!");
280 OSL_ENSURE(nullptr != pStreamName, "Please, please, give me a name!");
282 // open stream (and set parser input)
283 OUString sStreamName = OUString::createFromAscii(pStreamName);
284 bool bContainsStream = false;
287 bContainsStream = xStorage->isStreamElement(sStreamName);
289 catch( container::NoSuchElementException& )
293 if (!bContainsStream )
295 // stream name not found! return immediately with OK signal
296 return ERRCODE_NONE;
299 // set Base URL
300 uno::Reference< beans::XPropertySet > xInfoSet;
301 if( rFilterArguments.hasElements() )
302 rFilterArguments.getConstArray()[0] >>= xInfoSet;
303 OSL_ENSURE( xInfoSet.is(), "missing property set" );
304 if( xInfoSet.is() )
306 xInfoSet->setPropertyValue( "StreamName", Any( sStreamName ) );
311 // get input stream
312 uno::Reference <io::XStream> xStream = xStorage->openStreamElement( sStreamName, embed::ElementModes::READ );
313 uno::Reference <beans::XPropertySet > xProps( xStream, uno::UNO_QUERY );
315 Any aAny = xProps->getPropertyValue("Encrypted");
317 auto b = o3tl::tryAccess<bool>(aAny);
318 bool bEncrypted = b && *b;
320 uno::Reference <io::XInputStream> xInputStream = xStream->getInputStream();
322 // read from the stream
323 return ReadThroughComponent(
324 xInputStream, xModelComponent, sStreamName, rxContext,
325 pFilterName, rFilterArguments,
326 rName, bMustBeSuccessful, bEncrypted );
328 catch ( packages::WrongPasswordException& )
330 return ERRCODE_SFX_WRONGPASSWORD;
332 catch( packages::zip::ZipIOException& )
334 return ERRCODE_IO_BROKENPACKAGE;
336 catch ( uno::Exception& )
338 OSL_FAIL( "Error on import" );
339 // TODO/LATER: error handling
342 return ERR_SWG_READ_ERROR;
347 // #i44177#
348 static void lcl_AdjustOutlineStylesForOOo(SwDoc& _rDoc)
350 // array containing the names of the default outline styles ('Heading 1',
351 // 'Heading 2', ..., 'Heading 10')
352 OUString aDefOutlStyleNames[ MAXLEVEL ];
354 OUString sStyleName;
355 for ( sal_uInt8 i = 0; i < MAXLEVEL; ++i )
357 sStyleName =
358 SwStyleNameMapper::GetProgName( RES_POOLCOLL_HEADLINE1 + i,
359 sStyleName );
360 aDefOutlStyleNames[i] = sStyleName;
364 // array indicating, which outline level already has a style assigned.
365 bool aOutlineLevelAssigned[ MAXLEVEL ];
366 // array of the default outline styles, which are created for the document.
367 SwTextFormatColl* aCreatedDefaultOutlineStyles[ MAXLEVEL ];
370 for ( sal_uInt8 i = 0; i < MAXLEVEL; ++i )
372 aOutlineLevelAssigned[ i ] = false;
373 aCreatedDefaultOutlineStyles[ i ] = nullptr;
377 // determine, which outline level has already a style assigned and
378 // which of the default outline styles is created.
379 const SwTextFormatColls& rColls = *(_rDoc.GetTextFormatColls());
380 for ( size_t n = 1; n < rColls.size(); ++n )
382 SwTextFormatColl* pColl = rColls[ n ];
383 if ( pColl->IsAssignedToListLevelOfOutlineStyle() )
385 aOutlineLevelAssigned[ pColl->GetAssignedOutlineStyleLevel() ] = true;
388 for ( sal_uInt8 i = 0; i < MAXLEVEL; ++i )
390 if ( aCreatedDefaultOutlineStyles[ i ] == nullptr &&
391 pColl->GetName() == aDefOutlStyleNames[i] )
393 aCreatedDefaultOutlineStyles[ i ] = pColl;
394 break;
399 // assign already created default outline style to outline level, which
400 // doesn't have a style assigned to it.
401 const SwNumRule* pOutlineRule = _rDoc.GetOutlineNumRule();
402 for ( sal_uInt8 i = 0; i < MAXLEVEL; ++i )
404 // #i73361#
405 // Do not change assignment of already created default outline style
406 // to a certain outline level.
407 if ( !aOutlineLevelAssigned[ i ] &&
408 aCreatedDefaultOutlineStyles[ i ] != nullptr &&
409 ! aCreatedDefaultOutlineStyles[ i ]->IsAssignedToListLevelOfOutlineStyle() )
411 // apply outline level at created default outline style
412 aCreatedDefaultOutlineStyles[ i ]->AssignToListLevelOfOutlineStyle(i);
414 // apply outline numbering rule, if none is set.
415 const SfxPoolItem& rItem =
416 aCreatedDefaultOutlineStyles[ i ]->GetFormatAttr( RES_PARATR_NUMRULE, false );
417 if ( static_cast<const SwNumRuleItem&>(rItem).GetValue().isEmpty() )
419 SwNumRuleItem aItem( pOutlineRule->GetName() );
420 aCreatedDefaultOutlineStyles[ i ]->SetFormatAttr( aItem );
426 static void lcl_ConvertSdrOle2ObjsToSdrGrafObjs(SwDoc& _rDoc)
428 if ( !(_rDoc.getIDocumentDrawModelAccess().GetDrawModel() &&
429 _rDoc.getIDocumentDrawModelAccess().GetDrawModel()->GetPage( 0 )) )
430 return;
432 const SdrPage& rSdrPage( *(_rDoc.getIDocumentDrawModelAccess().GetDrawModel()->GetPage( 0 )) );
434 // iterate recursive with group objects over all shapes on the draw page
435 SdrObjListIter aIter( &rSdrPage );
436 while( aIter.IsMore() )
438 SdrOle2Obj* pOle2Obj = dynamic_cast< SdrOle2Obj* >( aIter.Next() );
439 if( pOle2Obj )
441 // found an ole2 shape
442 SdrObjList* pObjList = pOle2Obj->getParentSdrObjListFromSdrObject();
444 // get its graphic
445 Graphic aGraphic;
446 pOle2Obj->Connect();
447 const Graphic* pGraphic = pOle2Obj->GetGraphic();
448 if( pGraphic )
449 aGraphic = *pGraphic;
450 pOle2Obj->Disconnect();
452 // create new graphic shape with the ole graphic and shape size
453 rtl::Reference<SdrGrafObj> pGraphicObj = new SdrGrafObj(
454 pOle2Obj->getSdrModelFromSdrObject(),
455 aGraphic,
456 pOle2Obj->GetCurrentBoundRect());
458 // apply layer of ole2 shape at graphic shape
459 pGraphicObj->SetLayer( pOle2Obj->GetLayer() );
461 // replace ole2 shape with the new graphic object and delete the ol2 shape
462 pObjList->ReplaceObject( pGraphicObj.get(), pOle2Obj->GetOrdNum() );
467 ErrCode XMLReader::Read( SwDoc &rDoc, const OUString& rBaseURL, SwPaM &rPaM, const OUString & rName )
469 // needed for relative URLs, but in clipboard copy/paste there may be none
470 // and also there is the SwXMLTextBlocks special case
471 SAL_INFO_IF(rBaseURL.isEmpty(), "sw.filter", "sw::XMLReader: no base URL");
473 // Get service factory
474 uno::Reference< uno::XComponentContext > xContext =
475 comphelper::getProcessComponentContext();
477 uno::Reference<document::XGraphicStorageHandler> xGraphicStorageHandler;
478 rtl::Reference<SvXMLGraphicHelper> xGraphicHelper;
479 uno::Reference< document::XEmbeddedObjectResolver > xObjectResolver;
480 rtl::Reference<SvXMLEmbeddedObjectHelper> xObjectHelper;
482 // get the input stream (storage or stream)
483 uno::Reference<embed::XStorage> xStorage;
484 if( m_pMedium )
485 xStorage = m_pMedium->GetStorage();
486 else
487 xStorage = m_xStorage;
489 if( !xStorage.is() )
490 return ERR_SWG_READ_ERROR;
492 xGraphicHelper = SvXMLGraphicHelper::Create( xStorage,
493 SvXMLGraphicHelperMode::Read );
494 xGraphicStorageHandler = xGraphicHelper.get();
495 SfxObjectShell *pPersist = rDoc.GetPersist();
496 if( pPersist )
498 xObjectHelper = SvXMLEmbeddedObjectHelper::Create(
499 xStorage, *pPersist,
500 SvXMLEmbeddedObjectHelperMode::Read );
501 xObjectResolver = xObjectHelper.get();
504 // Get the docshell, the model, and finally the model's component
505 SwDocShell *pDocSh = rDoc.GetDocShell();
506 OSL_ENSURE( pDocSh, "XMLReader::Read: got no doc shell" );
507 if( !pDocSh )
508 return ERR_SWG_READ_ERROR;
509 uno::Reference< lang::XComponent > xModelComp = pDocSh->GetModel();
510 OSL_ENSURE( xModelComp.is(),
511 "XMLReader::Read: got no model" );
512 if( !xModelComp.is() )
513 return ERR_SWG_READ_ERROR;
515 // create and prepare the XPropertySet that gets passed through
516 // the components, and the XStatusIndicator that shows progress to
517 // the user.
519 // create XPropertySet with three properties for status indicator
520 static comphelper::PropertyMapEntry const aInfoMap[] =
522 { OUString("ProgressRange"), 0,
523 ::cppu::UnoType<sal_Int32>::get(),
524 beans::PropertyAttribute::MAYBEVOID, 0},
525 { OUString("ProgressMax"), 0,
526 ::cppu::UnoType<sal_Int32>::get(),
527 beans::PropertyAttribute::MAYBEVOID, 0},
528 { OUString("ProgressCurrent"), 0,
529 ::cppu::UnoType<sal_Int32>::get(),
530 beans::PropertyAttribute::MAYBEVOID, 0},
531 { OUString("NumberStyles"), 0,
532 cppu::UnoType<container::XNameContainer>::get(),
533 beans::PropertyAttribute::MAYBEVOID, 0},
534 { OUString("RecordChanges"), 0,
535 cppu::UnoType<bool>::get(),
536 beans::PropertyAttribute::MAYBEVOID, 0 },
537 { OUString("ShowChanges"), 0,
538 cppu::UnoType<bool>::get(),
539 beans::PropertyAttribute::MAYBEVOID, 0 },
540 { OUString("RedlineProtectionKey"), 0,
541 cppu::UnoType<Sequence<sal_Int8>>::get(),
542 beans::PropertyAttribute::MAYBEVOID, 0 },
543 { OUString("PrivateData"), 0,
544 cppu::UnoType<XInterface>::get(),
545 beans::PropertyAttribute::MAYBEVOID, 0 },
546 { OUString("BaseURI"), 0,
547 ::cppu::UnoType<OUString>::get(),
548 beans::PropertyAttribute::MAYBEVOID, 0 },
549 { OUString("StreamRelPath"), 0,
550 ::cppu::UnoType<OUString>::get(),
551 beans::PropertyAttribute::MAYBEVOID, 0 },
552 { OUString("StreamName"), 0,
553 ::cppu::UnoType<OUString>::get(),
554 beans::PropertyAttribute::MAYBEVOID, 0 },
555 // properties for insert modes
556 { OUString("StyleInsertModeFamilies"), 0,
557 cppu::UnoType<Sequence<OUString>>::get(),
558 beans::PropertyAttribute::MAYBEVOID, 0 },
559 { OUString("StyleInsertModeOverwrite"), 0,
560 cppu::UnoType<bool>::get(),
561 beans::PropertyAttribute::MAYBEVOID, 0 },
562 { OUString("TextInsertModeRange"), 0,
563 cppu::UnoType<text::XTextRange>::get(),
564 beans::PropertyAttribute::MAYBEVOID, 0},
565 { OUString("AutoTextMode"), 0,
566 cppu::UnoType<bool>::get(),
567 beans::PropertyAttribute::MAYBEVOID, 0 },
568 { OUString("OrganizerMode"), 0,
569 cppu::UnoType<bool>::get(),
570 beans::PropertyAttribute::MAYBEVOID, 0 },
572 // #i28749# - Add property, which indicates, if the
573 // shape position attributes are given in horizontal left-to-right layout.
574 // This is the case for the OpenOffice.org file format.
575 { OUString("ShapePositionInHoriL2R"), 0,
576 cppu::UnoType<bool>::get(),
577 beans::PropertyAttribute::MAYBEVOID, 0 },
579 { OUString("BuildId"), 0,
580 ::cppu::UnoType<OUString>::get(),
581 beans::PropertyAttribute::MAYBEVOID, 0 },
583 // Add property, which indicates, if a text document in OpenOffice.org
584 // file format is read.
585 // Note: Text documents read via the binary filter are also finally
586 // read using the OpenOffice.org file format. Thus, e.g. for text
587 // documents in StarOffice 5.2 binary file format this property
588 // will be true.
589 { OUString("TextDocInOOoFileFormat"), 0,
590 cppu::UnoType<bool>::get(),
591 beans::PropertyAttribute::MAYBEVOID, 0 },
592 { OUString("SourceStorage"), 0, cppu::UnoType<embed::XStorage>::get(),
593 css::beans::PropertyAttribute::MAYBEVOID, 0 },
595 uno::Reference< beans::XPropertySet > xInfoSet(
596 comphelper::GenericPropertySet_CreateInstance(
597 new comphelper::PropertySetInfo( aInfoMap ) ) );
599 // get BuildId from parent container if available
600 uno::Reference< container::XChild > xChild( xModelComp, uno::UNO_QUERY );
601 if( xChild.is() )
603 uno::Reference< beans::XPropertySet > xParentSet( xChild->getParent(), uno::UNO_QUERY );
604 if( xParentSet.is() )
606 uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xParentSet->getPropertySetInfo() );
607 static const OUStringLiteral sPropName(u"BuildId" );
608 if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(sPropName) )
610 xInfoSet->setPropertyValue( sPropName, xParentSet->getPropertyValue(sPropName) );
615 // try to get an XStatusIndicator from the Medium
616 uno::Reference<task::XStatusIndicator> xStatusIndicator;
618 if (pDocSh->GetMedium())
620 SfxItemSet* pSet = pDocSh->GetMedium()->GetItemSet();
621 if (pSet)
623 const SfxUnoAnyItem* pItem =
624 pSet->GetItem(SID_PROGRESS_STATUSBAR_CONTROL);
625 if (pItem)
627 pItem->GetValue() >>= xStatusIndicator;
632 // set progress range and start status indicator
633 sal_Int32 nProgressRange(1000000);
634 if (xStatusIndicator.is())
636 xStatusIndicator->start(SvxResId(RID_SVXSTR_DOC_LOAD), nProgressRange);
638 uno::Any aProgRange;
639 aProgRange <<= nProgressRange;
640 xInfoSet->setPropertyValue("ProgressRange", aProgRange);
642 Reference< container::XNameAccess > xLateInitSettings( document::NamedPropertyValues::create(xContext), UNO_QUERY_THROW );
643 beans::NamedValue aLateInitSettings( "LateInitSettings", Any( xLateInitSettings ) );
645 xInfoSet->setPropertyValue( "SourceStorage", Any( xStorage ) );
647 // prepare filter arguments, WARNING: the order is important!
648 Sequence<Any> aFilterArgs{ Any(xInfoSet),
649 Any(xStatusIndicator),
650 Any(xGraphicStorageHandler),
651 Any(xObjectResolver),
652 Any(aLateInitSettings) };
654 Sequence<Any> aEmptyArgs{ Any(xInfoSet),
655 Any(xStatusIndicator) };
657 // prepare for special modes
658 if( m_aOption.IsFormatsOnly() )
660 sal_Int32 nCount =
661 (m_aOption.IsFrameFormats() ? 1 : 0) +
662 (m_aOption.IsPageDescs() ? 1 : 0) +
663 (m_aOption.IsTextFormats() ? 2 : 0) +
664 (m_aOption.IsNumRules() ? 1 : 0);
666 Sequence< OUString> aFamiliesSeq( nCount );
667 OUString *pSeq = aFamiliesSeq.getArray();
668 if( m_aOption.IsFrameFormats() )
669 // SfxStyleFamily::Frame;
670 *pSeq++ = "FrameStyles";
671 if( m_aOption.IsPageDescs() )
672 // SfxStyleFamily::Page;
673 *pSeq++ = "PageStyles";
674 if( m_aOption.IsTextFormats() )
676 // (SfxStyleFamily::Char|SfxStyleFamily::Para);
677 *pSeq++ = "CharacterStyles";
678 *pSeq++ = "ParagraphStyles";
680 if( m_aOption.IsNumRules() )
681 // SfxStyleFamily::Pseudo;
682 *pSeq++ = "NumberingStyles";
684 xInfoSet->setPropertyValue( "StyleInsertModeFamilies",
685 Any(aFamiliesSeq) );
687 xInfoSet->setPropertyValue( "StyleInsertModeOverwrite", Any(!m_aOption.IsMerge()) );
689 else if( m_bInsertMode )
691 const rtl::Reference<SwXTextRange> xInsertTextRange =
692 SwXTextRange::CreateXTextRange(rDoc, *rPaM.GetPoint(), nullptr);
693 xInfoSet->setPropertyValue( "TextInsertModeRange",
694 Any(uno::Reference<text::XTextRange>(xInsertTextRange)) );
696 else
698 rPaM.GetBound().nContent.Assign(nullptr, 0);
699 rPaM.GetBound(false).nContent.Assign(nullptr, 0);
702 if( IsBlockMode() )
704 xInfoSet->setPropertyValue( "AutoTextMode", Any(true) );
706 if( IsOrganizerMode() )
708 xInfoSet->setPropertyValue( "OrganizerMode", Any(true) );
711 // Set base URI
712 // there is ambiguity which medium should be used here
713 // for now the own medium has a preference
714 SfxMedium* pMedDescrMedium = m_pMedium ? m_pMedium : pDocSh->GetMedium();
715 OSL_ENSURE( pMedDescrMedium, "There is no medium to get MediaDescriptor from!" );
717 xInfoSet->setPropertyValue( "BaseURI", Any( rBaseURL ) );
719 // TODO/LATER: separate links from usual embedded objects
720 OUString StreamPath;
721 if( SfxObjectCreateMode::EMBEDDED == rDoc.GetDocShell()->GetCreateMode() )
723 if ( pMedDescrMedium && pMedDescrMedium->GetItemSet() )
725 const SfxStringItem* pDocHierarchItem =
726 pMedDescrMedium->GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME);
727 if ( pDocHierarchItem )
728 StreamPath = pDocHierarchItem->GetValue();
730 else
732 StreamPath = "dummyObjectName";
735 if( !StreamPath.isEmpty() )
737 xInfoSet->setPropertyValue( "StreamRelPath", Any( StreamPath ) );
741 rtl::Reference<SwDoc> aHoldRef(&rDoc); // prevent deletion
742 ErrCode nRet = ERRCODE_NONE;
744 // save redline mode into import info property set
745 static const OUStringLiteral sShowChanges(u"ShowChanges");
746 static const OUStringLiteral sRecordChanges(u"RecordChanges");
747 static const OUStringLiteral sRedlineProtectionKey(u"RedlineProtectionKey");
748 xInfoSet->setPropertyValue( sShowChanges,
749 Any(IDocumentRedlineAccess::IsShowChanges(rDoc.getIDocumentRedlineAccess().GetRedlineFlags())) );
750 xInfoSet->setPropertyValue( sRecordChanges,
751 Any(IDocumentRedlineAccess::IsRedlineOn(rDoc.getIDocumentRedlineAccess().GetRedlineFlags())) );
752 xInfoSet->setPropertyValue( sRedlineProtectionKey,
753 Any(rDoc.getIDocumentRedlineAccess().GetRedlinePassword()) );
755 // force redline mode to "none"
756 rDoc.getIDocumentRedlineAccess().SetRedlineFlags_intern( RedlineFlags::NONE );
758 const bool bOASIS = ( SotStorage::GetVersion( xStorage ) > SOFFICE_FILEFORMAT_60 );
759 // #i28749# - set property <ShapePositionInHoriL2R>
761 const bool bShapePositionInHoriL2R = !bOASIS;
762 xInfoSet->setPropertyValue(
763 "ShapePositionInHoriL2R",
764 Any( bShapePositionInHoriL2R ) );
767 const bool bTextDocInOOoFileFormat = !bOASIS;
768 xInfoSet->setPropertyValue(
769 "TextDocInOOoFileFormat",
770 Any( bTextDocInOOoFileFormat ) );
773 ErrCode nWarnRDF = ERRCODE_NONE;
774 if ( !(IsOrganizerMode() || IsBlockMode() || m_aOption.IsFormatsOnly() ||
775 m_bInsertMode) )
777 // RDF metadata - must be read before styles/content
778 // N.B.: embedded documents have their own manifest.rdf!
781 const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(xModelComp,
782 uno::UNO_QUERY_THROW);
783 const uno::Reference<frame::XModel> xModel(xModelComp,
784 uno::UNO_QUERY_THROW);
785 const uno::Reference<rdf::XURI> xBaseURI( ::sfx2::createBaseURI(
786 xContext, xModel, rBaseURL, StreamPath) );
787 const uno::Reference<task::XInteractionHandler> xHandler(
788 pDocSh->GetMedium()->GetInteractionHandler() );
789 xDMA->loadMetadataFromStorage(xStorage, xBaseURI, xHandler);
791 catch (const lang::WrappedTargetException & e)
793 ucb::InteractiveAugmentedIOException iaioe;
794 if (e.TargetException >>= iaioe)
796 // import error that was not ignored by InteractionHandler!
797 nWarnRDF = ERR_SWG_READ_ERROR;
799 else
801 nWarnRDF = WARN_SWG_FEATURES_LOST; // uhh... something wrong?
804 catch (uno::Exception &)
806 nWarnRDF = WARN_SWG_FEATURES_LOST; // uhh... something went wrong?
810 // read storage streams
812 // #i103539#: always read meta.xml for generator
813 ErrCode const nWarn = ReadThroughComponent(
814 xStorage, xModelComp, "meta.xml", xContext,
815 (bOASIS ? "com.sun.star.comp.Writer.XMLOasisMetaImporter"
816 : "com.sun.star.comp.Writer.XMLMetaImporter"),
817 aEmptyArgs, rName, false );
819 ErrCode nWarn2 = ERRCODE_NONE;
820 if( !(IsOrganizerMode() || IsBlockMode() || m_aOption.IsFormatsOnly() ||
821 m_bInsertMode) )
823 nWarn2 = ReadThroughComponent(
824 xStorage, xModelComp, "settings.xml", xContext,
825 (bOASIS ? "com.sun.star.comp.Writer.XMLOasisSettingsImporter"
826 : "com.sun.star.comp.Writer.XMLSettingsImporter"),
827 aFilterArgs, rName, false );
830 nRet = ReadThroughComponent(
831 xStorage, xModelComp, "styles.xml", xContext,
832 (bOASIS ? "com.sun.star.comp.Writer.XMLOasisStylesImporter"
833 : "com.sun.star.comp.Writer.XMLStylesImporter"),
834 aFilterArgs, rName, true );
836 if( !nRet && !(IsOrganizerMode() || m_aOption.IsFormatsOnly()) )
837 nRet = ReadThroughComponent(
838 xStorage, xModelComp, "content.xml", xContext,
839 (bOASIS ? "com.sun.star.comp.Writer.XMLOasisContentImporter"
840 : "com.sun.star.comp.Writer.XMLContentImporter"),
841 aFilterArgs, rName, true );
843 if( !IsOrganizerMode() && !IsBlockMode() && !m_bInsertMode &&
844 !m_aOption.IsFormatsOnly() &&
845 // sw_redlinehide: disable layout cache for now
846 *o3tl::doAccess<bool>(xInfoSet->getPropertyValue(sShowChanges)) &&
847 // sw_fieldmarkhide: also disable if there is a fieldmark
848 rDoc.getIDocumentMarkAccess()->getFieldmarksBegin()
849 == rDoc.getIDocumentMarkAccess()->getFieldmarksEnd())
853 uno::Reference < io::XStream > xStm = xStorage->openStreamElement( "layout-cache", embed::ElementModes::READ );
854 std::unique_ptr<SvStream> pStrm2 = utl::UcbStreamHelper::CreateStream( xStm );
855 if( !pStrm2->GetError() )
856 rDoc.ReadLayoutCache( *pStrm2 );
858 catch (const uno::Exception&)
863 // Notify math objects
864 if( m_bInsertMode )
865 rDoc.PrtOLENotify( false );
866 else if ( rDoc.IsOLEPrtNotifyPending() )
867 rDoc.PrtOLENotify( true );
869 nRet = nRet ? nRet : (nWarn ? nWarn : (nWarn2 ? nWarn2 : nWarnRDF ) );
871 ::svx::DropUnusedNamedItems(xModelComp);
873 m_aOption.ResetAllFormatsOnly();
875 // redline password
876 Any aAny = xInfoSet->getPropertyValue( sRedlineProtectionKey );
877 Sequence<sal_Int8> aKey;
878 aAny >>= aKey;
879 rDoc.getIDocumentRedlineAccess().SetRedlinePassword( aKey );
881 // restore redline mode from import info property set
882 RedlineFlags nRedlineFlags = RedlineFlags::ShowInsert;
883 aAny = xInfoSet->getPropertyValue( sShowChanges );
884 if ( *o3tl::doAccess<bool>(aAny) )
885 nRedlineFlags |= RedlineFlags::ShowDelete;
886 aAny = xInfoSet->getPropertyValue( sRecordChanges );
887 if ( *o3tl::doAccess<bool>(aAny) || aKey.hasElements() )
888 nRedlineFlags |= RedlineFlags::On;
890 // ... restore redline mode
891 // (First set bogus mode to make sure the mode in getIDocumentRedlineAccess().SetRedlineFlags()
892 // is different from its previous mode.)
893 rDoc.getIDocumentRedlineAccess().SetRedlineFlags_intern( ~nRedlineFlags );
894 // must set flags to show delete so that CompressRedlines works
895 rDoc.getIDocumentRedlineAccess().SetRedlineFlags(nRedlineFlags|RedlineFlags::ShowDelete);
896 // tdf#83260 ensure that the first call of CompressRedlines after loading
897 // the document is a no-op by calling it now
898 rDoc.getIDocumentRedlineAccess().CompressRedlines();
899 // can't set it on the layout or view shell because it doesn't exist yet
900 rDoc.GetDocumentRedlineManager().SetHideRedlines(!(nRedlineFlags & RedlineFlags::ShowDelete));
902 lcl_EnsureValidPam( rPaM ); // move Pam into valid content
904 if( xGraphicHelper )
905 xGraphicHelper->dispose();
906 xGraphicHelper.clear();
907 xGraphicStorageHandler = nullptr;
908 if( xObjectHelper )
909 xObjectHelper->dispose();
910 xObjectHelper.clear();
911 xObjectResolver = nullptr;
912 aHoldRef.clear();
914 if ( !bOASIS )
916 // #i44177# - assure that for documents in OpenOffice.org
917 // file format the relation between outline numbering rule and styles is
918 // filled-up accordingly.
919 // Note: The OpenOffice.org file format, which has no content that applies
920 // a certain style, which is related to the outline numbering rule,
921 // has lost the information, that this certain style is related to
922 // the outline numbering rule.
923 // #i70748# - only for templates
924 if ( m_pMedium && m_pMedium->GetFilter() &&
925 m_pMedium->GetFilter()->IsOwnTemplateFormat() )
927 lcl_AdjustOutlineStylesForOOo( rDoc );
929 // Fix #i58251#: Unfortunately is the static default different to SO7 behaviour,
930 // so we have to set a dynamic default after importing SO7
931 rDoc.SetDefault(SwFormatRowSplit(false));
934 rDoc.PropagateOutlineRule();
936 // #i62875#
937 if ( rDoc.getIDocumentSettingAccess().get(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE) && !docfunc::ExistsDrawObjs( rDoc ) )
939 rDoc.getIDocumentSettingAccess().set(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE, false);
942 // Convert all instances of <SdrOle2Obj> into <SdrGrafObj>, because the
943 // Writer doesn't support such objects.
944 lcl_ConvertSdrOle2ObjsToSdrGrafObjs( rDoc );
946 // set BuildId on XModel for later OLE object loading
947 if( xInfoSet.is() )
949 uno::Reference< beans::XPropertySet > xModelSet( xModelComp, uno::UNO_QUERY );
950 if( xModelSet.is() )
952 uno::Reference< beans::XPropertySetInfo > xModelSetInfo( xModelSet->getPropertySetInfo() );
953 static const OUStringLiteral sName(u"BuildId" );
954 if( xModelSetInfo.is() && xModelSetInfo->hasPropertyByName(sName) )
956 xModelSet->setPropertyValue( sName, xInfoSet->getPropertyValue(sName) );
961 // tdf#115815 restore annotation ranges stored in temporary bookmarks
962 rDoc.getIDocumentMarkAccess()->restoreAnnotationMarks();
964 if (xStatusIndicator.is())
966 xStatusIndicator->end();
969 rDoc.GetIStyleAccess().clearCaches(); // Clear Automatic-Style-Caches(shared_pointer!)
970 return nRet;
973 // read the sections of the document, which is equal to the medium.
974 // returns the count of it
975 size_t XMLReader::GetSectionList( SfxMedium& rMedium,
976 std::vector<OUString>& rStrings) const
978 uno::Reference< uno::XComponentContext > xContext =
979 comphelper::getProcessComponentContext();
980 uno::Reference < embed::XStorage > xStg2;
981 if( ( xStg2 = rMedium.GetStorage() ).is() )
985 xml::sax::InputSource aParserInput;
986 static const OUStringLiteral sDocName( u"content.xml" );
987 aParserInput.sSystemId = sDocName;
989 uno::Reference < io::XStream > xStm = xStg2->openStreamElement( sDocName, embed::ElementModes::READ );
990 aParserInput.aInputStream = xStm->getInputStream();
992 // get filter
993 rtl::Reference< SwXMLSectionList > xImport = new SwXMLSectionList( xContext, rStrings );
995 // parse
996 xImport->parseStream( aParserInput );
998 catch( xml::sax::SAXParseException& )
1000 TOOLS_WARN_EXCEPTION("sw", "");
1001 // re throw ?
1003 catch( xml::sax::SAXException& )
1005 TOOLS_WARN_EXCEPTION("sw", "");
1006 // re throw ?
1008 catch( io::IOException& )
1010 TOOLS_WARN_EXCEPTION("sw", "");
1011 // re throw ?
1013 catch( packages::WrongPasswordException& )
1015 // re throw ?
1018 return rStrings.size();
1021 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */