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 .
21 #include <rsc/rscsfx.hxx>
22 #include <com/sun/star/embed/XStorage.hpp>
23 #include <com/sun/star/embed/ElementModes.hpp>
24 #include <comphelper/processfactory.hxx>
25 #include <comphelper/componentcontext.hxx>
26 #include <com/sun/star/xml/sax/InputSource.hpp>
27 #include <com/sun/star/xml/sax/Parser.hpp>
28 #include <com/sun/star/io/XActiveDataControl.hpp>
29 #include <com/sun/star/text/XTextRange.hpp>
30 #include <com/sun/star/container/XChild.hpp>
31 #include <com/sun/star/document/NamedPropertyValues.hpp>
32 #include <com/sun/star/beans/XPropertySetInfo.hpp>
33 #include <com/sun/star/beans/PropertyValue.hpp>
34 #include <com/sun/star/beans/NamedValue.hpp>
35 #include <com/sun/star/beans/PropertyAttribute.hpp>
36 #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
37 #include <com/sun/star/io/XActiveDataSource.hpp>
38 #include <com/sun/star/packages/zip/ZipIOException.hpp>
39 #include <com/sun/star/packages/WrongPasswordException.hpp>
40 #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
41 #include <sfx2/docfile.hxx>
42 #include <svtools/sfxecode.hxx>
43 #include <svl/stritem.hxx>
44 #include <unotools/streamwrap.hxx>
45 #include <svx/xmlgrhlp.hxx>
46 #include <svx/xmleohlp.hxx>
47 #include <comphelper/genericpropertyset.hxx>
48 #include <rtl/logfile.hxx>
49 #include <rtl/strbuf.hxx>
50 #include <sfx2/frame.hxx>
51 #include <unotools/ucbstreamhelper.hxx>
57 #include <unotextrange.hxx>
58 #include <swmodule.hxx>
59 #include <SwXMLSectionList.hxx>
61 #include <statstr.hrc>
64 #include <SwStyleNameMapper.hxx>
65 #include <poolfmt.hxx>
66 #include <numrule.hxx>
69 #include <svx/svdmodel.hxx>
70 #include <svx/svdpage.hxx>
71 #include <svx/svditer.hxx>
72 #include <svx/svdoole2.hxx>
73 #include <svx/svdograf.hxx>
74 #include <sfx2/docfilt.hxx> // #i70748#
75 #include <istyleaccess.hxx>
77 #include <sfx2/DocumentMetadataAccess.hxx>
80 using namespace ::com::sun::star
;
81 using namespace ::com::sun::star::uno
;
82 using namespace ::com::sun::star::text
;
83 using namespace ::com::sun::star::container
;
84 using namespace ::com::sun::star::document
;
85 using namespace ::com::sun::star::lang
;
88 static void lcl_EnsureValidPam( SwPaM
& rPam
)
90 if( rPam
.GetCntntNode() != NULL
)
92 // set proper point content
93 if( rPam
.GetCntntNode() != rPam
.GetPoint()->nContent
.GetIdxReg() )
95 rPam
.GetPoint()->nContent
.Assign( rPam
.GetCntntNode(), 0 );
97 // else: point was already valid
99 // if mark is invalid, we delete it
100 if( ( rPam
.GetCntntNode( sal_False
) == NULL
) ||
101 ( rPam
.GetCntntNode( sal_False
) != rPam
.GetMark()->nContent
.GetIdxReg() ) )
108 // point is not valid, so move it into the first content
110 rPam
.GetPoint()->nNode
=
111 *rPam
.GetDoc()->GetNodes().GetEndOfContent().StartOfSectionNode();
112 ++ rPam
.GetPoint()->nNode
;
113 rPam
.Move( fnMoveForward
, fnGoCntnt
); // go into content
117 XMLReader::XMLReader()
121 int XMLReader::GetReaderType()
123 return SW_STORAGE_READER
;
126 /// read a component (file + filter version)
127 sal_Int32
ReadThroughComponent(
128 uno::Reference
<io::XInputStream
> xInputStream
,
129 uno::Reference
<XComponent
> xModelComponent
,
130 const String
& rStreamName
,
131 uno::Reference
<uno::XComponentContext
> & rxContext
,
132 const sal_Char
* pFilterName
,
133 const Sequence
<Any
>& rFilterArguments
,
134 const OUString
& rName
,
135 bool bMustBeSuccessfull
,
138 OSL_ENSURE(xInputStream
.is(), "input stream missing");
139 OSL_ENSURE(xModelComponent
.is(), "document missing");
140 OSL_ENSURE(rxContext
.is(), "factory missing");
141 OSL_ENSURE(NULL
!= pFilterName
,"I need a service name for the component!");
143 RTL_LOGFILE_CONTEXT_AUTHOR( aLog
, "sw", "mb93740", "ReadThroughComponent" );
145 // prepare ParserInputSrouce
146 xml::sax::InputSource aParserInput
;
147 aParserInput
.sSystemId
= rName
;
148 aParserInput
.aInputStream
= xInputStream
;
151 uno::Reference
< xml::sax::XParser
> xParser
= xml::sax::Parser::create(rxContext
);
152 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "parser created" );
155 OUString
aFilterName(OUString::createFromAscii(pFilterName
));
156 uno::Reference
< xml::sax::XDocumentHandler
> xFilter(
157 rxContext
->getServiceManager()->createInstanceWithArgumentsAndContext(aFilterName
, rFilterArguments
, rxContext
),
159 SAL_WARN_IF(!xFilter
.is(), "sw", "Can't instantiate filter component: " << aFilterName
);
161 return ERR_SWG_READ_ERROR
;
162 RTL_LOGFILE_CONTEXT_TRACE1( aLog
, "%s created", pFilterName
);
164 // connect parser and filter
165 xParser
->setDocumentHandler( xFilter
);
167 // connect model and filter
168 uno::Reference
< XImporter
> xImporter( xFilter
, UNO_QUERY
);
169 xImporter
->setTargetDocument( xModelComponent
);
173 // if we do profiling, we want to know the stream
174 OString
aString(OUStringToOString(rStreamName
,
175 RTL_TEXTENCODING_ASCII_US
));
176 RTL_LOGFILE_TRACE_AUTHOR1( "sw", "mb93740",
177 "ReadThroughComponent : parsing \"%s\"", aString
.getStr() );
180 // finally, parser the stream
183 xParser
->parseStream( aParserInput
);
185 catch( xml::sax::SAXParseException
& r
)
187 // sax parser sends wrapped exceptions,
188 // try to find the original one
189 xml::sax::SAXException aSaxEx
= *(xml::sax::SAXException
*)(&r
);
190 bool bTryChild
= true;
194 xml::sax::SAXException aTmp
;
195 if ( aSaxEx
.WrappedException
>>= aTmp
)
201 packages::zip::ZipIOException aBrokenPackage
;
202 if ( aSaxEx
.WrappedException
>>= aBrokenPackage
)
203 return ERRCODE_IO_BROKENPACKAGE
;
206 return ERRCODE_SFX_WRONGPASSWORD
;
208 #if OSL_DEBUG_LEVEL > 0
209 OStringBuffer
aError(RTL_CONSTASCII_STRINGPARAM(
210 "SAX parse exception caught while importing:\n"));
211 aError
.append(OUStringToOString(r
.Message
,
212 RTL_TEXTENCODING_ASCII_US
));
213 OSL_FAIL(aError
.getStr());
216 String
sErr( OUString::number( r
.LineNumber
));
218 sErr
+= OUString::number( r
.ColumnNumber
);
220 if( rStreamName
.Len() )
222 return *new TwoStringErrorInfo(
223 (bMustBeSuccessfull
? ERR_FORMAT_FILE_ROWCOL
224 : WARN_FORMAT_FILE_ROWCOL
),
226 ERRCODE_BUTTON_OK
| ERRCODE_MSG_ERROR
);
230 OSL_ENSURE( bMustBeSuccessfull
, "Warnings are not supported" );
231 return *new StringErrorInfo( ERR_FORMAT_ROWCOL
, sErr
,
232 ERRCODE_BUTTON_OK
| ERRCODE_MSG_ERROR
);
235 catch(const xml::sax::SAXException
& r
)
237 packages::zip::ZipIOException aBrokenPackage
;
238 if ( r
.WrappedException
>>= aBrokenPackage
)
239 return ERRCODE_IO_BROKENPACKAGE
;
242 return ERRCODE_SFX_WRONGPASSWORD
;
244 #if OSL_DEBUG_LEVEL > 0
245 OStringBuffer
aError(RTL_CONSTASCII_STRINGPARAM(
246 "SAX exception caught while importing:\n"));
247 aError
.append(OUStringToOString(r
.Message
,
248 RTL_TEXTENCODING_ASCII_US
));
249 OSL_FAIL(aError
.getStr());
252 return ERR_SWG_READ_ERROR
;
254 catch(const packages::zip::ZipIOException
& r
)
257 #if OSL_DEBUG_LEVEL > 0
258 OStringBuffer
aError(RTL_CONSTASCII_STRINGPARAM(
259 "Zip exception caught while importing:\n"));
260 aError
.append(OUStringToOString(r
.Message
,
261 RTL_TEXTENCODING_ASCII_US
));
262 OSL_FAIL(aError
.getStr());
264 return ERRCODE_IO_BROKENPACKAGE
;
266 catch(const io::IOException
& r
)
269 #if OSL_DEBUG_LEVEL > 0
270 OStringBuffer
aError(RTL_CONSTASCII_STRINGPARAM(
271 "IO exception caught while importing:\n"));
272 aError
.append(OUStringToOString(r
.Message
,
273 RTL_TEXTENCODING_ASCII_US
));
274 OSL_FAIL(aError
.getStr());
276 return ERR_SWG_READ_ERROR
;
278 catch(const uno::Exception
& r
)
281 #if OSL_DEBUG_LEVEL > 0
282 OStringBuffer
aError(RTL_CONSTASCII_STRINGPARAM(
283 "uno exception caught while importing:\n"));
284 aError
.append(OUStringToOString(r
.Message
,
285 RTL_TEXTENCODING_ASCII_US
));
286 OSL_FAIL(aError
.getStr());
288 return ERR_SWG_READ_ERROR
;
295 /// read a component (storage version)
296 sal_Int32
ReadThroughComponent(
297 uno::Reference
<embed::XStorage
> xStorage
,
298 uno::Reference
<XComponent
> xModelComponent
,
299 const sal_Char
* pStreamName
,
300 const sal_Char
* pCompatibilityStreamName
,
301 uno::Reference
<uno::XComponentContext
> & rxContext
,
302 const sal_Char
* pFilterName
,
303 const Sequence
<Any
>& rFilterArguments
,
304 const OUString
& rName
,
305 bool bMustBeSuccessfull
)
307 OSL_ENSURE(xStorage
.is(), "Need storage!");
308 OSL_ENSURE(NULL
!= pStreamName
, "Please, please, give me a name!");
310 // open stream (and set parser input)
311 OUString sStreamName
= OUString::createFromAscii(pStreamName
);
312 sal_Bool bContainsStream
= sal_False
;
315 bContainsStream
= xStorage
->isStreamElement(sStreamName
);
317 catch( container::NoSuchElementException
& )
321 if (!bContainsStream
)
323 // stream name not found! Then try the compatibility name.
324 // if no stream can be opened, return immediately with OK signal
326 // do we even have an alternative name?
327 if ( NULL
== pCompatibilityStreamName
)
330 // if so, does the stream exist?
331 sStreamName
= OUString::createFromAscii(pCompatibilityStreamName
);
334 bContainsStream
= xStorage
->isStreamElement(sStreamName
);
336 catch( container::NoSuchElementException
& )
340 if (! bContainsStream
)
345 uno::Reference
< beans::XPropertySet
> xInfoSet
;
346 if( rFilterArguments
.getLength() > 0 )
347 rFilterArguments
.getConstArray()[0] >>= xInfoSet
;
348 OSL_ENSURE( xInfoSet
.is(), "missing property set" );
351 OUString
sPropName("StreamName");
352 xInfoSet
->setPropertyValue( sPropName
, makeAny( sStreamName
) );
358 uno::Reference
<io::XStream
> xStream
= xStorage
->openStreamElement( sStreamName
, embed::ElementModes::READ
);
359 uno::Reference
<beans::XPropertySet
> xProps( xStream
, uno::UNO_QUERY
);
361 Any aAny
= xProps
->getPropertyValue(
362 OUString("Encrypted") );
364 bool bEncrypted
= aAny
.getValueType() == ::getBooleanCppuType() &&
365 *(sal_Bool
*)aAny
.getValue();
367 uno::Reference
<io::XInputStream
> xInputStream
= xStream
->getInputStream();
369 // read from the stream
370 return ReadThroughComponent(
371 xInputStream
, xModelComponent
, sStreamName
, rxContext
,
372 pFilterName
, rFilterArguments
,
373 rName
, bMustBeSuccessfull
, bEncrypted
);
375 catch ( packages::WrongPasswordException
& )
377 return ERRCODE_SFX_WRONGPASSWORD
;
379 catch( packages::zip::ZipIOException
& )
381 return ERRCODE_IO_BROKENPACKAGE
;
383 catch ( uno::Exception
& )
385 OSL_FAIL( "Error on import!\n" );
386 // TODO/LATER: error handling
389 return ERR_SWG_READ_ERROR
;
393 static void lcl_AdjustOutlineStylesForOOo( SwDoc
& _rDoc
)
395 // array containing the names of the default outline styles ('Heading 1',
396 // 'Heading 2', ..., 'Heading 10')
397 String aDefOutlStyleNames
[ MAXLEVEL
];
400 for ( sal_uInt8 i
= 0; i
< MAXLEVEL
; ++i
)
403 SwStyleNameMapper::GetProgName( static_cast< sal_uInt16
>(RES_POOLCOLL_HEADLINE1
+ i
),
405 aDefOutlStyleNames
[i
] = sStyleName
;
409 // array indicating, which outline level already has a style assigned.
410 bool aOutlineLevelAssigned
[ MAXLEVEL
];
411 // array of the default outline styles, which are created for the document.
412 SwTxtFmtColl
* aCreatedDefaultOutlineStyles
[ MAXLEVEL
];
415 for ( sal_uInt8 i
= 0; i
< MAXLEVEL
; ++i
)
417 aOutlineLevelAssigned
[ i
] = false;
418 aCreatedDefaultOutlineStyles
[ i
] = 0L;
422 // determine, which outline level has already a style assigned and
423 // which of the default outline styles is created.
424 const SwTxtFmtColls
& rColls
= *(_rDoc
.GetTxtFmtColls());
425 for ( sal_uInt16 n
= 1; n
< rColls
.size(); ++n
)
427 SwTxtFmtColl
* pColl
= rColls
[ n
];
428 if ( pColl
->IsAssignedToListLevelOfOutlineStyle() )
430 aOutlineLevelAssigned
[ pColl
->GetAssignedOutlineStyleLevel() ] = true;//<-end,zhaojianwei
433 for ( sal_uInt8 i
= 0; i
< MAXLEVEL
; ++i
)
435 if ( aCreatedDefaultOutlineStyles
[ i
] == 0L &&
436 pColl
->GetName() == aDefOutlStyleNames
[i
] )
438 aCreatedDefaultOutlineStyles
[ i
] = pColl
;
444 // assign already created default outline style to outline level, which
445 // doesn't have a style assigned to it.
446 const SwNumRule
* pOutlineRule
= _rDoc
.GetOutlineNumRule();
447 for ( sal_uInt8 i
= 0; i
< MAXLEVEL
; ++i
)
450 // Do not change assignment of already created default outline style
451 // to a certain outline level.
452 if ( !aOutlineLevelAssigned
[ i
] &&
453 aCreatedDefaultOutlineStyles
[ i
] != 0 &&
454 ! aCreatedDefaultOutlineStyles
[ i
]->IsAssignedToListLevelOfOutlineStyle() )
456 // apply outline level at created default outline style
457 aCreatedDefaultOutlineStyles
[ i
]->AssignToListLevelOfOutlineStyle(i
);//#outline level added by zhaojianwei
459 // apply outline numbering rule, if none is set.
460 const SfxPoolItem
& rItem
=
461 aCreatedDefaultOutlineStyles
[ i
]->GetFmtAttr( RES_PARATR_NUMRULE
, sal_False
);
462 if ( static_cast<const SwNumRuleItem
&>(rItem
).GetValue().isEmpty() )
464 SwNumRuleItem
aItem( pOutlineRule
->GetName() );
465 aCreatedDefaultOutlineStyles
[ i
]->SetFmtAttr( aItem
);
472 static void lcl_ConvertSdrOle2ObjsToSdrGrafObjs( SwDoc
& _rDoc
)
474 if ( _rDoc
.GetDrawModel() &&
475 _rDoc
.GetDrawModel()->GetPage( 0 ) )
477 const SdrPage
& rSdrPage( *(_rDoc
.GetDrawModel()->GetPage( 0 )) );
479 // iterate recursive with group objects over all shapes on the draw page
480 SdrObjListIter
aIter( rSdrPage
);
481 while( aIter
.IsMore() )
483 SdrOle2Obj
* pOle2Obj
= dynamic_cast< SdrOle2Obj
* >( aIter
.Next() );
486 // found an ole2 shape
487 SdrObjList
* pObjList
= pOle2Obj
->GetObjList();
492 const Graphic
* pGraphic
= pOle2Obj
->GetGraphic();
494 aGraphic
= *pGraphic
;
495 pOle2Obj
->Disconnect();
497 // create new graphic shape with the ole graphic and shape size
498 SdrGrafObj
* pGraphicObj
= new SdrGrafObj( aGraphic
, pOle2Obj
->GetCurrentBoundRect() );
499 // apply layer of ole2 shape at graphic shape
500 pGraphicObj
->SetLayer( pOle2Obj
->GetLayer() );
502 // replace ole2 shape with the new graphic object and delete the ol2 shape
503 SdrObject
* pReplaced
= pObjList
->ReplaceObject( pGraphicObj
, pOle2Obj
->GetOrdNum() );
504 SdrObject::Free( pReplaced
);
511 sal_uLong
XMLReader::Read( SwDoc
&rDoc
, const String
& rBaseURL
, SwPaM
&rPaM
, const String
& rName
)
513 // Get service factory
514 uno::Reference
< uno::XComponentContext
> xContext
=
515 comphelper::getProcessComponentContext();
517 uno::Reference
< io::XActiveDataSource
> xSource
;
518 uno::Reference
< XInterface
> xPipe
;
519 uno::Reference
< document::XGraphicObjectResolver
> xGraphicResolver
;
520 SvXMLGraphicHelper
*pGraphicHelper
= 0;
521 uno::Reference
< document::XEmbeddedObjectResolver
> xObjectResolver
;
522 SvXMLEmbeddedObjectHelper
*pObjectHelper
= 0;
524 // get the input stream (storage or stream)
525 uno::Reference
<io::XInputStream
> xInputStream
;
526 uno::Reference
<embed::XStorage
> xStorage
;
528 xStorage
= pMedium
->GetStorage();
533 return ERR_SWG_READ_ERROR
;
535 pGraphicHelper
= SvXMLGraphicHelper::Create( xStorage
,
536 GRAPHICHELPER_MODE_READ
,
538 xGraphicResolver
= pGraphicHelper
;
539 SfxObjectShell
*pPersist
= rDoc
.GetPersist();
542 pObjectHelper
= SvXMLEmbeddedObjectHelper::Create(
544 EMBEDDEDOBJECTHELPER_MODE_READ
,
546 xObjectResolver
= pObjectHelper
;
549 // Get the docshell, the model, and finally the model's component
550 SwDocShell
*pDocSh
= rDoc
.GetDocShell();
551 OSL_ENSURE( pDocSh
, "XMLReader::Read: got no doc shell" );
553 return ERR_SWG_READ_ERROR
;
554 uno::Reference
< lang::XComponent
> xModelComp( pDocSh
->GetModel(), UNO_QUERY
);
555 OSL_ENSURE( xModelComp
.is(),
556 "XMLReader::Read: got no model" );
557 if( !xModelComp
.is() )
558 return ERR_SWG_READ_ERROR
;
561 // create and prepare the XPropertySet that gets passed through
562 // the components, and the XStatusIndicator that shows progress to
565 // create XPropertySet with three properties for status indicator
566 comphelper::PropertyMapEntry aInfoMap
[] =
568 { "ProgressRange", sizeof("ProgressRange")-1, 0,
569 &::getCppuType((sal_Int32
*)0),
570 beans::PropertyAttribute::MAYBEVOID
, 0},
571 { "ProgressMax", sizeof("ProgressMax")-1, 0,
572 &::getCppuType((sal_Int32
*)0),
573 beans::PropertyAttribute::MAYBEVOID
, 0},
574 { "ProgressCurrent", sizeof("ProgressCurrent")-1, 0,
575 &::getCppuType((sal_Int32
*)0),
576 beans::PropertyAttribute::MAYBEVOID
, 0},
577 { "NumberStyles", sizeof("NumberStyles")-1, 0,
578 &::getCppuType( (uno::Reference
<container::XNameContainer
> *) 0),
579 beans::PropertyAttribute::MAYBEVOID
, 0},
580 { "RecordChanges", sizeof("RecordChanges")-1, 0,
581 &::getBooleanCppuType(),
582 beans::PropertyAttribute::MAYBEVOID
, 0 },
583 { "ShowChanges", sizeof("ShowChanges")-1, 0,
584 &::getBooleanCppuType(),
585 beans::PropertyAttribute::MAYBEVOID
, 0 },
586 { "RedlineProtectionKey", sizeof("RedlineProtectionKey")-1, 0,
587 #if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))
588 new uno::Type(::getCppuType((Sequence
<sal_Int8
>*)0)),
590 &::getCppuType((Sequence
<sal_Int8
>*)0),
592 beans::PropertyAttribute::MAYBEVOID
, 0 },
593 { "PrivateData", sizeof("PrivateData")-1, 0,
594 &::getCppuType( (uno::Reference
<XInterface
> *)0 ),
595 beans::PropertyAttribute::MAYBEVOID
, 0 },
596 { "BaseURI", sizeof("BaseURI")-1, 0,
597 &::getCppuType( (OUString
*)0 ),
598 beans::PropertyAttribute::MAYBEVOID
, 0 },
599 { "StreamRelPath", sizeof("StreamRelPath")-1, 0,
600 &::getCppuType( (OUString
*)0 ),
601 beans::PropertyAttribute::MAYBEVOID
, 0 },
602 { "StreamName", sizeof("StreamName")-1, 0,
603 &::getCppuType( (OUString
*)0 ),
604 beans::PropertyAttribute::MAYBEVOID
, 0 },
605 // properties for insert modes
606 { "StyleInsertModeFamilies", sizeof("StyleInsertModeFamilies")-1, 0,
607 &::getCppuType((Sequence
<OUString
>*)0),
608 beans::PropertyAttribute::MAYBEVOID
, 0 },
609 { "StyleInsertModeOverwrite", sizeof("StyleInsertModeOverwrite")-1, 0,
610 &::getBooleanCppuType(),
611 beans::PropertyAttribute::MAYBEVOID
, 0 },
612 { "TextInsertModeRange", sizeof("TextInsertModeRange")-1, 0,
613 &::getCppuType( (uno::Reference
<text::XTextRange
> *) 0),
614 beans::PropertyAttribute::MAYBEVOID
, 0},
615 { "AutoTextMode", sizeof("AutoTextMode")-1, 0,
616 &::getBooleanCppuType(),
617 beans::PropertyAttribute::MAYBEVOID
, 0 },
618 { "OrganizerMode", sizeof("OrganizerMode")-1, 0,
619 &::getBooleanCppuType(),
620 beans::PropertyAttribute::MAYBEVOID
, 0 },
622 // #i28749# - Add property, which indicates, if the
623 // shape position attributes are given in horizontal left-to-right layout.
624 // This is the case for the OpenOffice.org file format.
625 { "ShapePositionInHoriL2R", sizeof("ShapePositionInHoriL2R")-1, 0,
626 &::getBooleanCppuType(),
627 beans::PropertyAttribute::MAYBEVOID
, 0 },
629 { "BuildId", sizeof("BuildId")-1, 0,
630 &::getCppuType( (OUString
*)0 ),
631 beans::PropertyAttribute::MAYBEVOID
, 0 },
633 // Add property, which indicates, if a text document in OpenOffice.org
634 // file format is read.
635 // Note: Text documents read via the binary filter are also finally
636 // read using the OpenOffice.org file format. Thus, e.g. for text
637 // documents in StarOffice 5.2 binary file format this property
639 { "TextDocInOOoFileFormat", sizeof("TextDocInOOoFileFormat")-1, 0,
640 &::getBooleanCppuType(),
641 beans::PropertyAttribute::MAYBEVOID
, 0 },
642 { "SourceStorage", sizeof("SourceStorage")-1, 0, &embed::XStorage::static_type(),
643 ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
, 0 },
644 { NULL
, 0, 0, NULL
, 0, 0 }
646 uno::Reference
< beans::XPropertySet
> xInfoSet(
647 comphelper::GenericPropertySet_CreateInstance(
648 new comphelper::PropertySetInfo( aInfoMap
) ) );
650 // ---- get BuildId from parent container if available
652 uno::Reference
< container::XChild
> xChild( xModelComp
, uno::UNO_QUERY
);
655 uno::Reference
< beans::XPropertySet
> xParentSet( xChild
->getParent(), uno::UNO_QUERY
);
656 if( xParentSet
.is() )
658 uno::Reference
< beans::XPropertySetInfo
> xPropSetInfo( xParentSet
->getPropertySetInfo() );
659 OUString
sPropName("BuildId" );
660 if( xPropSetInfo
.is() && xPropSetInfo
->hasPropertyByName(sPropName
) )
662 xInfoSet
->setPropertyValue( sPropName
, xParentSet
->getPropertyValue(sPropName
) );
667 // try to get an XStatusIndicator from the Medium
668 uno::Reference
<task::XStatusIndicator
> xStatusIndicator
;
670 if (pDocSh
->GetMedium())
672 SfxItemSet
* pSet
= pDocSh
->GetMedium()->GetItemSet();
675 const SfxUnoAnyItem
* pItem
= static_cast<const SfxUnoAnyItem
*>(
676 pSet
->GetItem(SID_PROGRESS_STATUSBAR_CONTROL
) );
679 pItem
->GetValue() >>= xStatusIndicator
;
685 // set progress range and start status indicator
686 sal_Int32
nProgressRange(1000000);
687 if (xStatusIndicator
.is())
689 xStatusIndicator
->start(SW_RESSTR(STR_STATSTR_SWGREAD
), nProgressRange
);
692 aProgRange
<<= nProgressRange
;
693 OUString
sProgressRange("ProgressRange");
694 xInfoSet
->setPropertyValue(sProgressRange
, aProgRange
);
696 Reference
< container::XNameAccess
> xLateInitSettings( document::NamedPropertyValues::create(xContext
), UNO_QUERY_THROW
);
697 beans::NamedValue
aLateInitSettings(
698 OUString( "LateInitSettings" ),
699 makeAny( xLateInitSettings
)
702 xInfoSet
->setPropertyValue( "SourceStorage", Any( xStorage
) );
704 // prepare filter arguments, WARNING: the order is important!
705 Sequence
<Any
> aFilterArgs( 5 );
706 Any
*pArgs
= aFilterArgs
.getArray();
707 *pArgs
++ <<= xInfoSet
;
708 *pArgs
++ <<= xStatusIndicator
;
709 *pArgs
++ <<= xGraphicResolver
;
710 *pArgs
++ <<= xObjectResolver
;
711 *pArgs
++ <<= aLateInitSettings
;
713 Sequence
<Any
> aEmptyArgs( 3 );
714 pArgs
= aEmptyArgs
.getArray();
715 *pArgs
++ <<= xInfoSet
;
716 *pArgs
++ <<= xStatusIndicator
;
718 // prepare for special modes
719 if( aOpt
.IsFmtsOnly() )
722 (aOpt
.IsFrmFmts() ? 1 : 0) +
723 (aOpt
.IsPageDescs() ? 1 : 0) +
724 (aOpt
.IsTxtFmts() ? 2 : 0) +
725 (aOpt
.IsNumRules() ? 1 : 0);
727 Sequence
< OUString
> aFamiliesSeq( nCount
);
728 OUString
*pSeq
= aFamiliesSeq
.getArray();
729 if( aOpt
.IsFrmFmts() )
730 // SFX_STYLE_FAMILY_FRAME;
731 *pSeq
++ = OUString("FrameStyles");
732 if( aOpt
.IsPageDescs() )
733 // SFX_STYLE_FAMILY_PAGE;
734 *pSeq
++ = OUString("PageStyles");
735 if( aOpt
.IsTxtFmts() )
737 // (SFX_STYLE_FAMILY_CHAR|SFX_STYLE_FAMILY_PARA);
738 *pSeq
++ = OUString("CharacterStyles");
739 *pSeq
++ = OUString("ParagraphStyles");
741 if( aOpt
.IsNumRules() )
742 // SFX_STYLE_FAMILY_PSEUDO;
743 *pSeq
++ = OUString("NumberingStyles");
745 OUString
sStyleInsertModeFamilies("StyleInsertModeFamilies");
746 xInfoSet
->setPropertyValue( sStyleInsertModeFamilies
,
747 makeAny(aFamiliesSeq
) );
749 OUString
sStyleInsertModeOverwrite("StyleInsertModeOverwrite");
750 sal_Bool bTmp
= !aOpt
.IsMerge();
752 aAny
.setValue( &bTmp
, ::getBooleanCppuType() );
753 xInfoSet
->setPropertyValue( sStyleInsertModeOverwrite
, aAny
);
755 else if( bInsertMode
)
757 const uno::Reference
<text::XTextRange
> xInsertTextRange
=
758 SwXTextRange::CreateXTextRange(rDoc
, *rPaM
.GetPoint(), 0);
759 OUString
sTextInsertModeRange("TextInsertModeRange");
760 xInfoSet
->setPropertyValue( sTextInsertModeRange
,
761 makeAny(xInsertTextRange
) );
765 rPaM
.GetBound(true).nContent
.Assign(0, 0);
766 rPaM
.GetBound(false).nContent
.Assign(0, 0);
771 OUString
sAutoTextMode("AutoTextMode");
772 sal_Bool bTmp
= sal_True
;
774 aAny
.setValue( &bTmp
, ::getBooleanCppuType() );
775 xInfoSet
->setPropertyValue( sAutoTextMode
, aAny
);
777 if( IsOrganizerMode() )
779 OUString
sOrganizerMode("OrganizerMode");
780 sal_Bool bTmp
= sal_True
;
782 aAny
.setValue( &bTmp
, ::getBooleanCppuType() );
783 xInfoSet
->setPropertyValue( sOrganizerMode
, aAny
);
787 // there is ambiguity which medium should be used here
788 // for now the own medium has a preference
789 SfxMedium
* pMedDescrMedium
= pMedium
? pMedium
: pDocSh
->GetMedium();
790 OSL_ENSURE( pMedDescrMedium
, "There is no medium to get MediaDescriptor from!\n" );
792 OUString
aBaseURL( rBaseURL
);
793 OUString
sPropName("BaseURI");
794 xInfoSet
->setPropertyValue( sPropName
, makeAny( aBaseURL
) );
796 // TODO/LATER: separate links from usual embedded objects
798 if( SFX_CREATE_MODE_EMBEDDED
== rDoc
.GetDocShell()->GetCreateMode() )
800 if ( pMedDescrMedium
&& pMedDescrMedium
->GetItemSet() )
802 const SfxStringItem
* pDocHierarchItem
= static_cast<const SfxStringItem
*>(
803 pMedDescrMedium
->GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME
) );
804 if ( pDocHierarchItem
)
805 StreamPath
= pDocHierarchItem
->GetValue();
809 StreamPath
= OUString("dummyObjectName");
812 if( !StreamPath
.isEmpty() )
814 sPropName
= OUString("StreamRelPath");
815 xInfoSet
->setPropertyValue( sPropName
, makeAny( StreamPath
) );
819 rDoc
.acquire(); // prevent deletion
822 // save redline mode into import info property set
825 OUString
sShowChanges("ShowChanges");
826 bTmp
= IDocumentRedlineAccess::IsShowChanges( rDoc
.GetRedlineMode() );
827 aAny
.setValue( &bTmp
, ::getBooleanCppuType() );
828 xInfoSet
->setPropertyValue( sShowChanges
, aAny
);
829 OUString
sRecordChanges("RecordChanges");
830 bTmp
= IDocumentRedlineAccess::IsRedlineOn(rDoc
.GetRedlineMode());
831 aAny
.setValue( &bTmp
, ::getBooleanCppuType() );
832 xInfoSet
->setPropertyValue( sRecordChanges
, aAny
);
833 OUString
sRedlineProtectionKey("RedlineProtectionKey");
834 aAny
<<= rDoc
.GetRedlinePassword();
835 xInfoSet
->setPropertyValue( sRedlineProtectionKey
, aAny
);
838 // force redline mode to "none"
839 rDoc
.SetRedlineMode_intern( nsRedlineMode_t::REDLINE_NONE
);
841 const sal_Bool bOASIS
= ( SotStorage::GetVersion( xStorage
) > SOFFICE_FILEFORMAT_60
);
842 // #i28749# - set property <ShapePositionInHoriL2R>
844 const sal_Bool bShapePositionInHoriL2R
= !bOASIS
;
845 xInfoSet
->setPropertyValue(
846 OUString("ShapePositionInHoriL2R"),
847 makeAny( bShapePositionInHoriL2R
) );
850 const sal_Bool bTextDocInOOoFileFormat
= !bOASIS
;
851 xInfoSet
->setPropertyValue(
852 OUString("TextDocInOOoFileFormat"),
853 makeAny( bTextDocInOOoFileFormat
) );
856 sal_uInt32 nWarnRDF
= 0;
857 if ( !(IsOrganizerMode() || IsBlockMode() || aOpt
.IsFmtsOnly() ||
860 // RDF metadata - must be read before styles/content
861 // N.B.: embedded documents have their own manifest.rdf!
864 const uno::Reference
<rdf::XDocumentMetadataAccess
> xDMA(xModelComp
,
865 uno::UNO_QUERY_THROW
);
866 const uno::Reference
<rdf::XURI
> xBaseURI( ::sfx2::createBaseURI(
867 xContext
, xStorage
, aBaseURL
, StreamPath
) );
868 const uno::Reference
<task::XInteractionHandler
> xHandler(
869 pDocSh
->GetMedium()->GetInteractionHandler() );
870 xDMA
->loadMetadataFromStorage(xStorage
, xBaseURI
, xHandler
);
872 catch (const lang::WrappedTargetException
& e
)
874 ucb::InteractiveAugmentedIOException iaioe
;
875 if (e
.TargetException
>>= iaioe
)
877 // import error that was not ignored by InteractionHandler!
878 nWarnRDF
= ERR_SWG_READ_ERROR
;
882 nWarnRDF
= WARN_SWG_FEATURES_LOST
; // uhh... something wrong?
885 catch (uno::Exception
&)
887 nWarnRDF
= WARN_SWG_FEATURES_LOST
; // uhh... something went wrong?
891 // read storage streams
893 // #i103539#: always read meta.xml for generator
894 sal_uInt32
const nWarn
= ReadThroughComponent(
895 xStorage
, xModelComp
, "meta.xml", "Meta.xml", xContext
,
896 (bOASIS
? "com.sun.star.comp.Writer.XMLOasisMetaImporter"
897 : "com.sun.star.comp.Writer.XMLMetaImporter"),
898 aEmptyArgs
, rName
, false );
900 sal_uInt32 nWarn2
= 0;
901 if( !(IsOrganizerMode() || IsBlockMode() || aOpt
.IsFmtsOnly() ||
904 nWarn2
= ReadThroughComponent(
905 xStorage
, xModelComp
, "settings.xml", NULL
, xContext
,
906 (bOASIS
? "com.sun.star.comp.Writer.XMLOasisSettingsImporter"
907 : "com.sun.star.comp.Writer.XMLSettingsImporter"),
908 aFilterArgs
, rName
, false );
911 nRet
= ReadThroughComponent(
912 xStorage
, xModelComp
, "styles.xml", NULL
, xContext
,
913 (bOASIS
? "com.sun.star.comp.Writer.XMLOasisStylesImporter"
914 : "com.sun.star.comp.Writer.XMLStylesImporter"),
915 aFilterArgs
, rName
, true );
917 if( !nRet
&& !(IsOrganizerMode() || aOpt
.IsFmtsOnly()) )
918 nRet
= ReadThroughComponent(
919 xStorage
, xModelComp
, "content.xml", "Content.xml", xContext
,
920 (bOASIS
? "com.sun.star.comp.Writer.XMLOasisContentImporter"
921 : "com.sun.star.comp.Writer.XMLContentImporter"),
922 aFilterArgs
, rName
, true );
924 if( !(IsOrganizerMode() || IsBlockMode() || bInsertMode
||
925 aOpt
.IsFmtsOnly() ) )
927 OUString
sStreamName("layout-cache");
930 uno::Reference
< io::XStream
> xStm
= xStorage
->openStreamElement( sStreamName
, embed::ElementModes::READ
);
931 SvStream
* pStrm2
= utl::UcbStreamHelper::CreateStream( xStm
);
932 if( !pStrm2
->GetError() )
933 rDoc
.ReadLayoutCache( *pStrm2
);
936 catch ( uno::Exception
& )
941 // Notify math objects
943 rDoc
.PrtOLENotify( sal_False
);
944 else if ( rDoc
.IsOLEPrtNotifyPending() )
945 rDoc
.PrtOLENotify( sal_True
);
947 nRet
= nRet
? nRet
: (nWarn
? nWarn
: (nWarn2
? nWarn2
: nWarnRDF
) );
949 aOpt
.ResetAllFmtsOnly();
952 aAny
= xInfoSet
->getPropertyValue( sRedlineProtectionKey
);
953 Sequence
<sal_Int8
> aKey
;
955 rDoc
.SetRedlinePassword( aKey
);
957 // restore redline mode from import info property set
958 sal_Int16 nRedlineMode
= nsRedlineMode_t::REDLINE_SHOW_INSERT
;
959 aAny
= xInfoSet
->getPropertyValue( sShowChanges
);
960 if ( *(sal_Bool
*)aAny
.getValue() )
961 nRedlineMode
|= nsRedlineMode_t::REDLINE_SHOW_DELETE
;
962 aAny
= xInfoSet
->getPropertyValue( sRecordChanges
);
963 if ( *(sal_Bool
*)aAny
.getValue() || (aKey
.getLength() > 0) )
964 nRedlineMode
|= nsRedlineMode_t::REDLINE_ON
;
966 nRedlineMode
|= nsRedlineMode_t::REDLINE_NONE
;
968 // ... restore redline mode
969 // (First set bogus mode to make sure the mode in SetRedlineMode()
970 // is different from it's previous mode.)
971 rDoc
.SetRedlineMode_intern((RedlineMode_t
)( ~nRedlineMode
));
972 rDoc
.SetRedlineMode( (RedlineMode_t
)( nRedlineMode
));
974 lcl_EnsureValidPam( rPaM
); // move Pam into valid content
977 SvXMLGraphicHelper::Destroy( pGraphicHelper
);
978 xGraphicResolver
= 0;
980 SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper
);
986 // #i44177# - assure that for documents in OpenOffice.org
987 // file format the relation between outline numbering rule and styles is
988 // filled-up accordingly.
989 // Note: The OpenOffice.org file format, which has no content that applys
990 // a certain style, which is related to the outline numbering rule,
991 // has lost the information, that this certain style is related to
992 // the outline numbering rule.
993 // #i70748# - only for templates
994 if ( pMedium
&& pMedium
->GetFilter() &&
995 pMedium
->GetFilter()->IsOwnTemplateFormat() )
997 lcl_AdjustOutlineStylesForOOo( rDoc
);
999 // Fix #i58251#: Unfortunately is the static default different to SO7 behaviour,
1000 // so we have to set a dynamic default after importing SO7
1001 rDoc
.SetDefault( SfxBoolItem( RES_ROW_SPLIT
, sal_False
) );
1004 rDoc
.PropagateOutlineRule();
1007 if ( rDoc
.get(IDocumentSettingAccess::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE
) && !docfunc::ExistsDrawObjs( rDoc
) )
1009 rDoc
.set(IDocumentSettingAccess::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE
, false);
1012 // Convert all instances of <SdrOle2Obj> into <SdrGrafObj>, because the
1013 // Writer doesn't support such objects.
1014 lcl_ConvertSdrOle2ObjsToSdrGrafObjs( rDoc
);
1016 // set BuildId on XModel for later OLE object loading
1019 uno::Reference
< beans::XPropertySet
> xModelSet( xModelComp
, uno::UNO_QUERY
);
1020 if( xModelSet
.is() )
1022 uno::Reference
< beans::XPropertySetInfo
> xModelSetInfo( xModelSet
->getPropertySetInfo() );
1023 OUString
sName("BuildId" );
1024 if( xModelSetInfo
.is() && xModelSetInfo
->hasPropertyByName(sName
) )
1026 xModelSet
->setPropertyValue( sName
, xInfoSet
->getPropertyValue(sName
) );
1031 if (xStatusIndicator
.is())
1033 xStatusIndicator
->end();
1036 rDoc
.GetIStyleAccess().clearCaches(); // Clear Automatic-Style-Caches(shared_pointer!)
1040 // read the sections of the document, which is equal to the medium.
1041 // returns the count of it
1042 size_t XMLReader::GetSectionList( SfxMedium
& rMedium
,
1043 std::vector
<String
*>& rStrings
) const
1045 uno::Reference
< uno::XComponentContext
> xContext
=
1046 comphelper::getProcessComponentContext();
1047 uno::Reference
< embed::XStorage
> xStg2
;
1048 if( ( xStg2
= rMedium
.GetStorage() ).is() )
1053 xml::sax::InputSource aParserInput
;
1054 OUString
sDocName( "content.xml" );
1055 aParserInput
.sSystemId
= sDocName
;
1057 uno::Reference
< io::XStream
> xStm
= xStg2
->openStreamElement( sDocName
, embed::ElementModes::READ
);
1058 aParserInput
.aInputStream
= xStm
->getInputStream();
1061 uno::Reference
< xml::sax::XDocumentHandler
> xFilter
= new SwXMLSectionList( xContext
, rStrings
);
1063 // connect parser and filter
1064 uno::Reference
< xml::sax::XParser
> xParser
= xml::sax::Parser::create(xContext
);
1065 xParser
->setDocumentHandler( xFilter
);
1068 xParser
->parseStream( aParserInput
);
1070 catch( xml::sax::SAXParseException
& )
1074 catch( xml::sax::SAXException
& )
1078 catch( io::IOException
& )
1082 catch( packages::WrongPasswordException
& )
1087 return rStrings
.size();
1090 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */