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 <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>
54 #include <drawdoc.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>
64 #include <unotextrange.hxx>
65 #include <SwXMLSectionList.hxx>
67 #include <SwStyleNameMapper.hxx>
68 #include <poolfmt.hxx>
69 #include <numrule.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() ) )
111 // point is not valid, so move it into the first content
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
;
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
,
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
;
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
);
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
;
165 xDocumentHandler
.set(xFilter
, UNO_QUERY
);
166 if (!xDocumentHandler
&& !xFastParser
)
168 SAL_WARN("sd", "service does not implement XFastParser or XDocumentHandler");
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
181 xFastParser
->parseStream( aParserInput
);
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;
200 xml::sax::SAXException aTmp
;
201 if ( aSaxEx
.WrappedException
>>= aTmp
)
207 packages::zip::ZipIOException aBrokenPackage
;
208 if ( aSaxEx
.WrappedException
>>= aBrokenPackage
)
209 return ERRCODE_IO_BROKENPACKAGE
;
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
)
218 + OUString::number( r
.ColumnNumber
) );
220 if( !rStreamName
.isEmpty() )
222 return *new TwoStringErrorInfo(
223 (bMustBeSuccessful
? ERR_FORMAT_FILE_ROWCOL
224 : WARN_FORMAT_FILE_ROWCOL
),
226 DialogMask::ButtonsOk
| DialogMask::MessageError
);
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
;
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
;
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
300 uno::Reference
< beans::XPropertySet
> xInfoSet
;
301 if( rFilterArguments
.hasElements() )
302 rFilterArguments
.getConstArray()[0] >>= xInfoSet
;
303 OSL_ENSURE( xInfoSet
.is(), "missing property set" );
306 xInfoSet
->setPropertyValue( "StreamName", Any( sStreamName
) );
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
;
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
];
355 for ( sal_uInt8 i
= 0; i
< MAXLEVEL
; ++i
)
358 SwStyleNameMapper::GetProgName( RES_POOLCOLL_HEADLINE1
+ i
,
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
;
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
)
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 )) )
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() );
441 // found an ole2 shape
442 SdrObjList
* pObjList
= pOle2Obj
->getParentSdrObjListFromSdrObject();
447 const Graphic
* pGraphic
= pOle2Obj
->GetGraphic();
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(),
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
;
485 xStorage
= m_pMedium
->GetStorage();
487 xStorage
= m_xStorage
;
490 return ERR_SWG_READ_ERROR
;
492 xGraphicHelper
= SvXMLGraphicHelper::Create( xStorage
,
493 SvXMLGraphicHelperMode::Read
);
494 xGraphicStorageHandler
= xGraphicHelper
.get();
495 SfxObjectShell
*pPersist
= rDoc
.GetPersist();
498 xObjectHelper
= SvXMLEmbeddedObjectHelper::Create(
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" );
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
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
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
);
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();
623 const SfxUnoAnyItem
* pItem
=
624 pSet
->GetItem(SID_PROGRESS_STATUSBAR_CONTROL
);
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
);
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() )
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",
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
)) );
698 rPaM
.GetBound().nContent
.Assign(nullptr, 0);
699 rPaM
.GetBound(false).nContent
.Assign(nullptr, 0);
704 xInfoSet
->setPropertyValue( "AutoTextMode", Any(true) );
706 if( IsOrganizerMode() )
708 xInfoSet
->setPropertyValue( "OrganizerMode", Any(true) );
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
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();
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() ||
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
;
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() ||
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
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();
876 Any aAny
= xInfoSet
->getPropertyValue( sRedlineProtectionKey
);
877 Sequence
<sal_Int8
> 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
905 xGraphicHelper
->dispose();
906 xGraphicHelper
.clear();
907 xGraphicStorageHandler
= nullptr;
909 xObjectHelper
->dispose();
910 xObjectHelper
.clear();
911 xObjectResolver
= nullptr;
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();
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
949 uno::Reference
< beans::XPropertySet
> xModelSet( xModelComp
, uno::UNO_QUERY
);
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!)
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();
993 rtl::Reference
< SwXMLSectionList
> xImport
= new SwXMLSectionList( xContext
, rStrings
);
996 xImport
->parseStream( aParserInput
);
998 catch( xml::sax::SAXParseException
& )
1000 TOOLS_WARN_EXCEPTION("sw", "");
1003 catch( xml::sax::SAXException
& )
1005 TOOLS_WARN_EXCEPTION("sw", "");
1008 catch( io::IOException
& )
1010 TOOLS_WARN_EXCEPTION("sw", "");
1013 catch( packages::WrongPasswordException
& )
1018 return rStrings
.size();
1021 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */