1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: swxml.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
37 #define _SVSTDARR_STRINGS
38 #include <rsc/rscsfx.hxx>
39 #include <tools/urlobj.hxx>
40 #include <com/sun/star/embed/XStorage.hpp>
41 #include <com/sun/star/embed/ElementModes.hpp>
42 #include <comphelper/processfactory.hxx>
43 #include <comphelper/componentcontext.hxx>
44 #include <com/sun/star/xml/sax/InputSource.hpp>
45 #include <com/sun/star/xml/sax/XParser.hpp>
46 #include <com/sun/star/io/XActiveDataControl.hpp>
47 #include <com/sun/star/text/XTextRange.hpp>
48 #include <com/sun/star/container/XChild.hpp>
49 #include <com/sun/star/beans/XPropertySetInfo.hpp>
50 #include <com/sun/star/beans/PropertyValue.hpp>
51 #include <com/sun/star/beans/NamedValue.hpp>
52 #include <com/sun/star/beans/PropertyAttribute.hpp>
53 #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
54 #include <com/sun/star/io/XActiveDataSource.hpp>
55 #include <com/sun/star/packages/zip/ZipIOException.hpp>
56 #include <com/sun/star/packages/WrongPasswordException.hpp>
57 #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
58 #include <svtools/svstdarr.hxx>
59 #include <sfx2/docfile.hxx>
60 #include <svtools/sfxecode.hxx>
61 #include <svtools/stritem.hxx>
62 #include <unotools/streamwrap.hxx>
63 #include <svx/xmlgrhlp.hxx>
64 #include <svx/xmleohlp.hxx>
65 #include <comphelper/genericpropertyset.hxx>
66 #include <rtl/logfile.hxx>
68 #include <sfx2/frame.hxx>
69 #include <unotools/ucbstreamhelper.hxx>
76 #include <swmodule.hxx>
77 #include <SwXMLSectionList.hxx>
79 #include <statstr.hrc>
81 // --> OD 2005-09-06 #i44177#
82 #include <SwStyleNameMapper.hxx>
83 #include <poolfmt.hxx>
84 #include <numrule.hxx>
88 // --> OD 2006-02-22 #b6382898#
89 #include <svx/svdmodel.hxx>
90 #include <svx/svdpage.hxx>
91 #include <svx/svditer.hxx>
92 #include <svx/svdoole2.hxx>
93 #include <svx/svdograf.hxx>
96 // --> OD 2008-12-17 #i70748#
97 #include <sfx2/docfilt.hxx>
100 #include <istyleaccess.hxx>
101 #define LOGFILE_AUTHOR "mb93740"
103 #include <sfx2/DocumentMetadataAccess.hxx>
106 using namespace ::com::sun::star
;
107 using namespace ::com::sun::star::uno
;
108 using namespace ::com::sun::star::text
;
109 using namespace ::com::sun::star::container
;
110 using namespace ::com::sun::star::document
;
111 using namespace ::com::sun::star::lang
;
112 using ::rtl::OUString
;
115 void lcl_EnsureValidPam( SwPaM
& rPam
)
117 if( rPam
.GetCntntNode() != NULL
)
119 // set proper point content
120 if( rPam
.GetCntntNode() != rPam
.GetPoint()->nContent
.GetIdxReg() )
122 rPam
.GetPoint()->nContent
.Assign( rPam
.GetCntntNode(), 0 );
124 // else: point was already valid
126 // if mark is invalid, we delete it
127 if( ( rPam
.GetCntntNode( FALSE
) == NULL
) ||
128 ( rPam
.GetCntntNode( FALSE
) != rPam
.GetMark()->nContent
.GetIdxReg() ) )
135 // point is not valid, so move it into the first content
137 rPam
.GetPoint()->nNode
=
138 *rPam
.GetDoc()->GetNodes().GetEndOfContent().StartOfSectionNode();
139 ++ rPam
.GetPoint()->nNode
;
140 rPam
.Move( fnMoveForward
, fnGoCntnt
); // go into content
144 XMLReader::XMLReader()
148 int XMLReader::GetReaderType()
150 return SW_STORAGE_READER
;
153 /// read a component (file + filter version)
154 sal_Int32
ReadThroughComponent(
155 uno::Reference
<io::XInputStream
> xInputStream
,
156 uno::Reference
<XComponent
> xModelComponent
,
157 const String
& rStreamName
,
158 uno::Reference
<lang::XMultiServiceFactory
> & rFactory
,
159 const sal_Char
* pFilterName
,
160 const Sequence
<Any
>& rFilterArguments
,
161 const OUString
& rName
,
162 sal_Bool bMustBeSuccessfull
,
163 sal_Bool bEncrypted
)
165 DBG_ASSERT(xInputStream
.is(), "input stream missing");
166 DBG_ASSERT(xModelComponent
.is(), "document missing");
167 DBG_ASSERT(rFactory
.is(), "factory missing");
168 DBG_ASSERT(NULL
!= pFilterName
,"I need a service name for the component!");
170 RTL_LOGFILE_CONTEXT_AUTHOR( aLog
, "sw", LOGFILE_AUTHOR
, "ReadThroughComponent" );
172 // prepare ParserInputSrouce
173 xml::sax::InputSource aParserInput
;
174 aParserInput
.sSystemId
= rName
;
175 aParserInput
.aInputStream
= xInputStream
;
178 uno::Reference
< xml::sax::XParser
> xParser(
179 rFactory
->createInstance(
180 OUString::createFromAscii("com.sun.star.xml.sax.Parser") ),
182 DBG_ASSERT( xParser
.is(), "Can't create parser" );
184 return ERR_SWG_READ_ERROR
;
185 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "parser created" );
188 uno::Reference
< xml::sax::XDocumentHandler
> xFilter(
189 rFactory
->createInstanceWithArguments(
190 OUString::createFromAscii(pFilterName
), rFilterArguments
),
192 DBG_ASSERT( xFilter
.is(), "Can't instantiate filter component." );
194 return ERR_SWG_READ_ERROR
;
195 RTL_LOGFILE_CONTEXT_TRACE1( aLog
, "%s created", pFilterName
);
197 // connect parser and filter
198 xParser
->setDocumentHandler( xFilter
);
200 // connect model and filter
201 uno::Reference
< XImporter
> xImporter( xFilter
, UNO_QUERY
);
202 xImporter
->setTargetDocument( xModelComponent
);
206 // if we do profiling, we want to know the stream
207 ByteString
aString( (String
)rStreamName
, RTL_TEXTENCODING_ASCII_US
);
208 RTL_LOGFILE_TRACE_AUTHOR1( "sw", LOGFILE_AUTHOR
,
209 "ReadThroughComponent : parsing \"%s\"", aString
.GetBuffer() );
212 // finally, parser the stream
215 xParser
->parseStream( aParserInput
);
217 catch( xml::sax::SAXParseException
& r
)
219 // sax parser sends wrapped exceptions,
220 // try to find the original one
221 xml::sax::SAXException aSaxEx
= *(xml::sax::SAXException
*)(&r
);
222 sal_Bool bTryChild
= sal_True
;
226 xml::sax::SAXException aTmp
;
227 if ( aSaxEx
.WrappedException
>>= aTmp
)
230 bTryChild
= sal_False
;
233 packages::zip::ZipIOException aBrokenPackage
;
234 if ( aSaxEx
.WrappedException
>>= aBrokenPackage
)
235 return ERRCODE_IO_BROKENPACKAGE
;
238 return ERRCODE_SFX_WRONGPASSWORD
;
240 #if OSL_DEBUG_LEVEL > 1
241 ByteString
aError( "SAX parse exception catched while importing:\n" );
242 aError
+= ByteString( String( r
.Message
), RTL_TEXTENCODING_ASCII_US
);
243 DBG_ERROR( aError
.GetBuffer() );
246 String
sErr( String::CreateFromInt32( r
.LineNumber
));
248 sErr
+= String::CreateFromInt32( r
.ColumnNumber
);
250 if( rStreamName
.Len() )
252 return *new TwoStringErrorInfo(
253 (bMustBeSuccessfull
? ERR_FORMAT_FILE_ROWCOL
254 : WARN_FORMAT_FILE_ROWCOL
),
256 ERRCODE_BUTTON_OK
| ERRCODE_MSG_ERROR
);
260 ASSERT( bMustBeSuccessfull
, "Warnings are not supported" );
261 return *new StringErrorInfo( ERR_FORMAT_ROWCOL
, sErr
,
262 ERRCODE_BUTTON_OK
| ERRCODE_MSG_ERROR
);
265 catch( xml::sax::SAXException
& r
)
267 packages::zip::ZipIOException aBrokenPackage
;
268 if ( r
.WrappedException
>>= aBrokenPackage
)
269 return ERRCODE_IO_BROKENPACKAGE
;
272 return ERRCODE_SFX_WRONGPASSWORD
;
274 #if OSL_DEBUG_LEVEL > 1
275 ByteString
aError( "SAX exception catched while importing:\n" );
276 aError
+= ByteString( String( r
.Message
), RTL_TEXTENCODING_ASCII_US
);
277 DBG_ERROR( aError
.GetBuffer() );
280 return ERR_SWG_READ_ERROR
;
282 catch( packages::zip::ZipIOException
& r
)
285 #if OSL_DEBUG_LEVEL > 1
286 ByteString
aError( "Zip exception catched while importing:\n" );
287 aError
+= ByteString( String( r
.Message
), RTL_TEXTENCODING_ASCII_US
);
288 DBG_ERROR( aError
.GetBuffer() );
290 return ERRCODE_IO_BROKENPACKAGE
;
292 catch( io::IOException
& r
)
295 #if OSL_DEBUG_LEVEL > 1
296 ByteString
aError( "IO exception catched while importing:\n" );
297 aError
+= ByteString( String( r
.Message
), RTL_TEXTENCODING_ASCII_US
);
298 DBG_ERROR( aError
.GetBuffer() );
300 return ERR_SWG_READ_ERROR
;
302 catch( uno::Exception
& r
)
305 #if OSL_DEBUG_LEVEL > 1
306 ByteString
aError( "uno exception catched while importing:\n" );
307 aError
+= ByteString( String( r
.Message
), RTL_TEXTENCODING_ASCII_US
);
308 DBG_ERROR( aError
.GetBuffer() );
310 return ERR_SWG_READ_ERROR
;
317 /// read a component (storage version)
318 sal_Int32
ReadThroughComponent(
319 uno::Reference
<embed::XStorage
> xStorage
,
320 uno::Reference
<XComponent
> xModelComponent
,
321 const sal_Char
* pStreamName
,
322 const sal_Char
* pCompatibilityStreamName
,
323 uno::Reference
<lang::XMultiServiceFactory
> & rFactory
,
324 const sal_Char
* pFilterName
,
325 const Sequence
<Any
>& rFilterArguments
,
326 const OUString
& rName
,
327 sal_Bool bMustBeSuccessfull
)
329 DBG_ASSERT(xStorage
.is(), "Need storage!");
330 DBG_ASSERT(NULL
!= pStreamName
, "Please, please, give me a name!");
332 // open stream (and set parser input)
333 OUString sStreamName
= OUString::createFromAscii(pStreamName
);
334 sal_Bool bContainsStream
= sal_False
;
337 bContainsStream
= xStorage
->isStreamElement(sStreamName
);
339 catch( container::NoSuchElementException
& )
343 if (!bContainsStream
)
345 // stream name not found! Then try the compatibility name.
346 // if no stream can be opened, return immediatly with OK signal
348 // do we even have an alternative name?
349 if ( NULL
== pCompatibilityStreamName
)
352 // if so, does the stream exist?
353 sStreamName
= OUString::createFromAscii(pCompatibilityStreamName
);
356 bContainsStream
= xStorage
->isStreamElement(sStreamName
);
358 catch( container::NoSuchElementException
& )
362 if (! bContainsStream
)
367 uno::Reference
< beans::XPropertySet
> xInfoSet
;
368 if( rFilterArguments
.getLength() > 0 )
369 rFilterArguments
.getConstArray()[0] >>= xInfoSet
;
370 DBG_ASSERT( xInfoSet
.is(), "missing property set" );
373 OUString
sPropName( RTL_CONSTASCII_USTRINGPARAM("StreamName") );
374 xInfoSet
->setPropertyValue( sPropName
, makeAny( sStreamName
) );
380 uno::Reference
<io::XStream
> xStream
= xStorage
->openStreamElement( sStreamName
, embed::ElementModes::READ
);
381 uno::Reference
<beans::XPropertySet
> xProps( xStream
, uno::UNO_QUERY
);
383 Any aAny
= xProps
->getPropertyValue(
384 OUString( RTL_CONSTASCII_USTRINGPARAM("Encrypted") ) );
386 sal_Bool bEncrypted
= aAny
.getValueType() == ::getBooleanCppuType() &&
387 *(sal_Bool
*)aAny
.getValue();
389 uno::Reference
<io::XInputStream
> xInputStream
= xStream
->getInputStream();
391 // read from the stream
392 return ReadThroughComponent(
393 xInputStream
, xModelComponent
, sStreamName
, rFactory
,
394 pFilterName
, rFilterArguments
,
395 rName
, bMustBeSuccessfull
, bEncrypted
);
397 catch ( packages::WrongPasswordException
& )
399 return ERRCODE_SFX_WRONGPASSWORD
;
401 catch( packages::zip::ZipIOException
& )
403 return ERRCODE_IO_BROKENPACKAGE
;
405 catch ( uno::Exception
& )
407 OSL_ENSURE( sal_False
, "Error on import!\n" );
408 // TODO/LATER: error handling
411 return ERR_SWG_READ_ERROR
;
414 // --> OD 2005-09-06 #i44177#
415 void lcl_AdjustOutlineStylesForOOo( SwDoc
& _rDoc
)
417 // array containing the names of the default outline styles ('Heading 1',
418 // 'Heading 2', ..., 'Heading 10')
419 String aDefOutlStyleNames
[ MAXLEVEL
];
422 for ( BYTE i
= 0; i
< MAXLEVEL
; ++i
)
425 SwStyleNameMapper::GetProgName( static_cast< sal_uInt16
>(RES_POOLCOLL_HEADLINE1
+ i
),
427 aDefOutlStyleNames
[i
] = sStyleName
;
431 // array indicating, which outline level already has a style assigned.
432 bool aOutlineLevelAssigned
[ MAXLEVEL
];
433 // array of the default outline styles, which are created for the document.
434 SwTxtFmtColl
* aCreatedDefaultOutlineStyles
[ MAXLEVEL
];
437 for ( BYTE i
= 0; i
< MAXLEVEL
; ++i
)
439 aOutlineLevelAssigned
[ i
] = false;
440 aCreatedDefaultOutlineStyles
[ i
] = 0L;
444 // determine, which outline level has already a style assigned and
445 // which of the default outline styles is created.
446 const SwTxtFmtColls
& rColls
= *(_rDoc
.GetTxtFmtColls());
447 for ( USHORT n
= 1; n
< rColls
.Count(); ++n
)
449 SwTxtFmtColl
* pColl
= rColls
[ n
];
450 //if ( pColl->GetOutlineLevel() != NO_NUMBERING ) //#outline level zhaojianwei
451 if ( pColl
->IsAssignedToListLevelOfOutlineStyle() )
453 // aOutlineLevelAssigned[ pColl->GetOutlineLevel() ] = true;
454 aOutlineLevelAssigned
[ pColl
->GetAssignedOutlineStyleLevel() ] = true;//<-end,zhaojianwei
457 for ( BYTE i
= 0; i
< MAXLEVEL
; ++i
)
459 if ( aCreatedDefaultOutlineStyles
[ i
] == 0L &&
460 pColl
->GetName() == aDefOutlStyleNames
[i
] )
462 aCreatedDefaultOutlineStyles
[ i
] = pColl
;
468 // assign already created default outline style to outline level, which
469 // doesn't have a style assigned to it.
470 const SwNumRule
* pOutlineRule
= _rDoc
.GetOutlineNumRule();
471 for ( BYTE i
= 0; i
< MAXLEVEL
; ++i
)
473 // --> OD 2007-01-11 #i73361#
474 // Do not change assignment of already created default outline style
475 // to a certain outline level.
476 // if ( aCreatedDefaultOutlineStyles[ i ] != 0 && !aOutlineLevelAssigned[ i ] )
477 if ( !aOutlineLevelAssigned
[ i
] &&
478 aCreatedDefaultOutlineStyles
[ i
] != 0 &&
479 ! aCreatedDefaultOutlineStyles
[ i
]->IsAssignedToListLevelOfOutlineStyle() )
482 // apply outline level at created default outline style
483 //aCreatedDefaultOutlineStyles[ i ]->SetOutlineLevel( i );
484 aCreatedDefaultOutlineStyles
[ i
]->AssignToListLevelOfOutlineStyle(i
);//#outline level added by zhaojianwei
486 // apply outline numbering rule, if none is set.
487 const SfxPoolItem
& rItem
=
488 aCreatedDefaultOutlineStyles
[ i
]->GetFmtAttr( RES_PARATR_NUMRULE
, FALSE
);
489 if ( static_cast<const SwNumRuleItem
&>(rItem
).GetValue().Len() == 0 )
491 SwNumRuleItem
aItem( pOutlineRule
->GetName() );
492 aCreatedDefaultOutlineStyles
[ i
]->SetFmtAttr( aItem
);
500 // --> OD 2006-02-22 #b6382898#
501 void lcl_ConvertSdrOle2ObjsToSdrGrafObjs( SwDoc
& _rDoc
)
503 if ( _rDoc
.GetDrawModel() &&
504 _rDoc
.GetDrawModel()->GetPage( 0 ) )
506 const SdrPage
& rSdrPage( *(_rDoc
.GetDrawModel()->GetPage( 0 )) );
508 // iterate recursive with group objects over all shapes on the draw page
509 SdrObjListIter
aIter( rSdrPage
);
510 while( aIter
.IsMore() )
512 SdrOle2Obj
* pOle2Obj
= dynamic_cast< SdrOle2Obj
* >( aIter
.Next() );
515 // found an ole2 shape
516 SdrObjList
* pObjList
= pOle2Obj
->GetObjList();
521 Graphic
* pGraphic
= pOle2Obj
->GetGraphic();
523 aGraphic
= *pGraphic
;
524 pOle2Obj
->Disconnect();
526 // create new graphic shape with the ole graphic and shape size
527 SdrGrafObj
* pGraphicObj
= new SdrGrafObj( aGraphic
, pOle2Obj
->GetCurrentBoundRect() );
528 // apply layer of ole2 shape at graphic shape
529 pGraphicObj
->SetLayer( pOle2Obj
->GetLayer() );
531 // replace ole2 shape with the new graphic object and delete the ol2 shape
532 SdrObject
* pReplaced
= pObjList
->ReplaceObject( pGraphicObj
, pOle2Obj
->GetOrdNum() );
533 SdrObject::Free( pReplaced
);
541 ULONG
XMLReader::Read( SwDoc
&rDoc
, const String
& rBaseURL
, SwPaM
&rPaM
, const String
& rName
)
543 // Get service factory
544 uno::Reference
< lang::XMultiServiceFactory
> xServiceFactory
=
545 comphelper::getProcessServiceFactory();
546 ASSERT( xServiceFactory
.is(),
547 "XMLReader::Read: got no service manager" );
548 if( !xServiceFactory
.is() )
549 return ERR_SWG_READ_ERROR
;
551 uno::Reference
< io::XActiveDataSource
> xSource
;
552 uno::Reference
< XInterface
> xPipe
;
553 uno::Reference
< document::XGraphicObjectResolver
> xGraphicResolver
;
554 SvXMLGraphicHelper
*pGraphicHelper
= 0;
555 uno::Reference
< document::XEmbeddedObjectResolver
> xObjectResolver
;
556 SvXMLEmbeddedObjectHelper
*pObjectHelper
= 0;
558 // get the input stream (storage or stream)
559 uno::Reference
<io::XInputStream
> xInputStream
;
560 uno::Reference
<embed::XStorage
> xStorage
;
562 xStorage
= pMedium
->GetStorage();
567 return ERR_SWG_READ_ERROR
;
569 pGraphicHelper
= SvXMLGraphicHelper::Create( xStorage
,
570 GRAPHICHELPER_MODE_READ
,
572 xGraphicResolver
= pGraphicHelper
;
573 SfxObjectShell
*pPersist
= rDoc
.GetPersist();
576 pObjectHelper
= SvXMLEmbeddedObjectHelper::Create(
578 EMBEDDEDOBJECTHELPER_MODE_READ
,
580 xObjectResolver
= pObjectHelper
;
583 // Get the docshell, the model, and finally the model's component
584 SwDocShell
*pDocSh
= rDoc
.GetDocShell();
585 ASSERT( pDocSh
, "XMLReader::Read: got no doc shell" );
587 return ERR_SWG_READ_ERROR
;
588 uno::Reference
< lang::XComponent
> xModelComp( pDocSh
->GetModel(), UNO_QUERY
);
589 ASSERT( xModelComp
.is(),
590 "XMLReader::Read: got no model" );
591 if( !xModelComp
.is() )
592 return ERR_SWG_READ_ERROR
;
595 // create and prepare the XPropertySet that gets passed through
596 // the components, and the XStatusIndicator that shows progress to
599 // create XPropertySet with three properties for status indicator
600 comphelper::PropertyMapEntry aInfoMap
[] =
602 { "ProgressRange", sizeof("ProgressRange")-1, 0,
603 &::getCppuType((sal_Int32
*)0),
604 beans::PropertyAttribute::MAYBEVOID
, 0},
605 { "ProgressMax", sizeof("ProgressMax")-1, 0,
606 &::getCppuType((sal_Int32
*)0),
607 beans::PropertyAttribute::MAYBEVOID
, 0},
608 { "ProgressCurrent", sizeof("ProgressCurrent")-1, 0,
609 &::getCppuType((sal_Int32
*)0),
610 beans::PropertyAttribute::MAYBEVOID
, 0},
611 { "NumberStyles", sizeof("NumberStyles")-1, 0,
612 &::getCppuType( (uno::Reference
<container::XNameContainer
> *) 0),
613 beans::PropertyAttribute::MAYBEVOID
, 0},
614 { "RecordChanges", sizeof("RecordChanges")-1, 0,
615 &::getBooleanCppuType(),
616 beans::PropertyAttribute::MAYBEVOID
, 0 },
617 { "ShowChanges", sizeof("ShowChanges")-1, 0,
618 &::getBooleanCppuType(),
619 beans::PropertyAttribute::MAYBEVOID
, 0 },
620 { "RedlineProtectionKey", sizeof("RedlineProtectionKey")-1, 0,
621 #if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))
622 new uno::Type(::getCppuType((Sequence
<sal_Int8
>*)0)),
624 &::getCppuType((Sequence
<sal_Int8
>*)0),
626 beans::PropertyAttribute::MAYBEVOID
, 0 },
627 { "PrivateData", sizeof("PrivateData")-1, 0,
628 &::getCppuType( (uno::Reference
<XInterface
> *)0 ),
629 beans::PropertyAttribute::MAYBEVOID
, 0 },
630 { "BaseURI", sizeof("BaseURI")-1, 0,
631 &::getCppuType( (OUString
*)0 ),
632 beans::PropertyAttribute::MAYBEVOID
, 0 },
633 { "StreamRelPath", sizeof("StreamRelPath")-1, 0,
634 &::getCppuType( (OUString
*)0 ),
635 beans::PropertyAttribute::MAYBEVOID
, 0 },
636 { "StreamName", sizeof("StreamName")-1, 0,
637 &::getCppuType( (OUString
*)0 ),
638 beans::PropertyAttribute::MAYBEVOID
, 0 },
639 // properties for insert modes
640 { "StyleInsertModeFamilies", sizeof("StyleInsertModeFamilies")-1, 0,
641 &::getCppuType((Sequence
<OUString
>*)0),
642 beans::PropertyAttribute::MAYBEVOID
, 0 },
643 { "StyleInsertModeOverwrite", sizeof("StyleInsertModeOverwrite")-1, 0,
644 &::getBooleanCppuType(),
645 beans::PropertyAttribute::MAYBEVOID
, 0 },
646 { "TextInsertModeRange", sizeof("TextInsertModeRange")-1, 0,
647 &::getCppuType( (uno::Reference
<text::XTextRange
> *) 0),
648 beans::PropertyAttribute::MAYBEVOID
, 0},
649 { "AutoTextMode", sizeof("AutoTextMode")-1, 0,
650 &::getBooleanCppuType(),
651 beans::PropertyAttribute::MAYBEVOID
, 0 },
652 { "OrganizerMode", sizeof("OrganizerMode")-1, 0,
653 &::getBooleanCppuType(),
654 beans::PropertyAttribute::MAYBEVOID
, 0 },
655 // --> OD 2004-08-10 #i28749# - Add property, which indicates, if the
656 // shape position attributes are given in horizontal left-to-right layout.
657 // This is the case for the OpenOffice.org file format.
658 { "ShapePositionInHoriL2R", sizeof("ShapePositionInHoriL2R")-1, 0,
659 &::getBooleanCppuType(),
660 beans::PropertyAttribute::MAYBEVOID
, 0 },
662 { "BuildId", sizeof("BuildId")-1, 0,
663 &::getCppuType( (OUString
*)0 ),
664 beans::PropertyAttribute::MAYBEVOID
, 0 },
665 // --> OD 2007-12-19 #152540#
666 // Add property, which indicates, if a text document in OpenOffice.org
667 // file format is read.
668 // Note: Text documents read via the binary filter are also finally
669 // read using the OpenOffice.org file format. Thus, e.g. for text
670 // documents in StarOffice 5.2 binary file format this property
672 { "TextDocInOOoFileFormat", sizeof("TextDocInOOoFileFormat")-1, 0,
673 &::getBooleanCppuType(),
674 beans::PropertyAttribute::MAYBEVOID
, 0 },
676 { NULL
, 0, 0, NULL
, 0, 0 }
678 uno::Reference
< beans::XPropertySet
> xInfoSet(
679 comphelper::GenericPropertySet_CreateInstance(
680 new comphelper::PropertySetInfo( aInfoMap
) ) );
682 // ---- get BuildId from parent container if available
684 uno::Reference
< container::XChild
> xChild( xModelComp
, uno::UNO_QUERY
);
687 uno::Reference
< beans::XPropertySet
> xParentSet( xChild
->getParent(), uno::UNO_QUERY
);
688 if( xParentSet
.is() )
690 uno::Reference
< beans::XPropertySetInfo
> xPropSetInfo( xParentSet
->getPropertySetInfo() );
691 OUString
sPropName( RTL_CONSTASCII_USTRINGPARAM("BuildId" ) );
692 if( xPropSetInfo
.is() && xPropSetInfo
->hasPropertyByName(sPropName
) )
694 xInfoSet
->setPropertyValue( sPropName
, xParentSet
->getPropertyValue(sPropName
) );
699 // try to get an XStatusIndicator from the Medium
700 uno::Reference
<task::XStatusIndicator
> xStatusIndicator
;
702 if (pDocSh
->GetMedium())
704 SfxItemSet
* pSet
= pDocSh
->GetMedium()->GetItemSet();
707 const SfxUnoAnyItem
* pItem
= static_cast<const SfxUnoAnyItem
*>(
708 pSet
->GetItem(SID_PROGRESS_STATUSBAR_CONTROL
) );
711 pItem
->GetValue() >>= xStatusIndicator
;
717 // set progress range and start status indicator
718 sal_Int32
nProgressRange(1000000);
719 if (xStatusIndicator
.is())
721 xStatusIndicator
->start(SW_RESSTR(STR_STATSTR_SWGREAD
), nProgressRange
);
724 aProgRange
<<= nProgressRange
;
725 OUString
sProgressRange(RTL_CONSTASCII_USTRINGPARAM("ProgressRange"));
726 xInfoSet
->setPropertyValue(sProgressRange
, aProgRange
);
728 ::comphelper::ComponentContext
aContext( xServiceFactory
);
729 Reference
< container::XNameAccess
> xLateInitSettings(
730 aContext
.createComponent( "com.sun.star.document.NamedPropertyValues" ), UNO_QUERY_THROW
);
731 beans::NamedValue
aLateInitSettings(
732 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LateInitSettings" ) ),
733 makeAny( xLateInitSettings
)
736 // prepare filter arguments, WARNING: the order is important!
737 Sequence
<Any
> aFilterArgs( 5 );
738 Any
*pArgs
= aFilterArgs
.getArray();
739 *pArgs
++ <<= xInfoSet
;
740 *pArgs
++ <<= xStatusIndicator
;
741 *pArgs
++ <<= xGraphicResolver
;
742 *pArgs
++ <<= xObjectResolver
;
743 *pArgs
++ <<= aLateInitSettings
;
745 Sequence
<Any
> aEmptyArgs( 3 );
746 pArgs
= aEmptyArgs
.getArray();
747 *pArgs
++ <<= xInfoSet
;
748 *pArgs
++ <<= xStatusIndicator
;
750 // prepare for special modes
751 if( aOpt
.IsFmtsOnly() )
754 (aOpt
.IsFrmFmts() ? 1 : 0) +
755 (aOpt
.IsPageDescs() ? 1 : 0) +
756 (aOpt
.IsTxtFmts() ? 2 : 0) +
757 (aOpt
.IsNumRules() ? 1 : 0);
759 Sequence
< OUString
> aFamiliesSeq( nCount
);
760 OUString
*pSeq
= aFamiliesSeq
.getArray();
761 if( aOpt
.IsFrmFmts() )
762 // SFX_STYLE_FAMILY_FRAME;
763 *pSeq
++ = OUString::createFromAscii("FrameStyles");
764 if( aOpt
.IsPageDescs() )
765 // SFX_STYLE_FAMILY_PAGE;
766 *pSeq
++ = OUString::createFromAscii("PageStyles");
767 if( aOpt
.IsTxtFmts() )
769 // (SFX_STYLE_FAMILY_CHAR|SFX_STYLE_FAMILY_PARA);
770 *pSeq
++ = OUString::createFromAscii("CharacterStyles");
771 *pSeq
++ = OUString::createFromAscii("ParagraphStyles");
773 if( aOpt
.IsNumRules() )
774 // SFX_STYLE_FAMILY_PSEUDO;
775 *pSeq
++ = OUString::createFromAscii("NumberingStyles");
777 OUString
sStyleInsertModeFamilies(
778 RTL_CONSTASCII_USTRINGPARAM("StyleInsertModeFamilies"));
779 xInfoSet
->setPropertyValue( sStyleInsertModeFamilies
,
780 makeAny(aFamiliesSeq
) );
782 OUString
sStyleInsertModeOverwrite(
783 RTL_CONSTASCII_USTRINGPARAM("StyleInsertModeOverwrite"));
784 sal_Bool bTmp
= !aOpt
.IsMerge();
786 aAny
.setValue( &bTmp
, ::getBooleanCppuType() );
787 xInfoSet
->setPropertyValue( sStyleInsertModeOverwrite
, aAny
);
789 else if( bInsertMode
)
791 uno::Reference
<XTextRange
> xInsertTextRange
=
792 SwXTextRange::CreateTextRangeFromPosition( &rDoc
, *rPaM
.GetPoint(),
794 OUString
sTextInsertModeRange(
795 RTL_CONSTASCII_USTRINGPARAM("TextInsertModeRange"));
796 xInfoSet
->setPropertyValue( sTextInsertModeRange
,
797 makeAny(xInsertTextRange
) );
801 rPaM
.GetBound(true).nContent
.Assign(0, 0);
802 rPaM
.GetBound(false).nContent
.Assign(0, 0);
807 OUString
sAutoTextMode(
808 RTL_CONSTASCII_USTRINGPARAM("AutoTextMode"));
809 sal_Bool bTmp
= sal_True
;
811 aAny
.setValue( &bTmp
, ::getBooleanCppuType() );
812 xInfoSet
->setPropertyValue( sAutoTextMode
, aAny
);
814 if( IsOrganizerMode() )
816 OUString
sOrganizerMode(
817 RTL_CONSTASCII_USTRINGPARAM("OrganizerMode"));
818 sal_Bool bTmp
= sal_True
;
820 aAny
.setValue( &bTmp
, ::getBooleanCppuType() );
821 xInfoSet
->setPropertyValue( sOrganizerMode
, aAny
);
825 // there is ambiguity which medium should be used here
826 // for now the own medium has a preference
827 SfxMedium
* pMedDescrMedium
= pMedium
? pMedium
: pDocSh
->GetMedium();
828 OSL_ENSURE( pMedDescrMedium
, "There is no medium to get MediaDescriptor from!\n" );
830 ::rtl::OUString
aBaseURL( rBaseURL
);
831 OUString
sPropName( RTL_CONSTASCII_USTRINGPARAM("BaseURI") );
832 xInfoSet
->setPropertyValue( sPropName
, makeAny( aBaseURL
) );
834 // TODO/LATER: separate links from usual embedded objects
835 ::rtl::OUString StreamPath
;
836 if( SFX_CREATE_MODE_EMBEDDED
== rDoc
.GetDocShell()->GetCreateMode() )
838 if ( pMedDescrMedium
&& pMedDescrMedium
->GetItemSet() )
840 const SfxStringItem
* pDocHierarchItem
= static_cast<const SfxStringItem
*>(
841 pMedDescrMedium
->GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME
) );
842 if ( pDocHierarchItem
)
843 StreamPath
= pDocHierarchItem
->GetValue();
847 StreamPath
= ::rtl::OUString::createFromAscii( "dummyObjectName" );
850 if( StreamPath
.getLength() )
852 sPropName
= OUString(RTL_CONSTASCII_USTRINGPARAM("StreamRelPath"));
853 xInfoSet
->setPropertyValue( sPropName
, makeAny( StreamPath
) );
857 rDoc
.acquire(); // prevent deletion
860 // save redline mode into import info property set
863 OUString
sShowChanges( RTL_CONSTASCII_USTRINGPARAM("ShowChanges") );
864 bTmp
= IDocumentRedlineAccess::IsShowChanges( rDoc
.GetRedlineMode() );
865 aAny
.setValue( &bTmp
, ::getBooleanCppuType() );
866 xInfoSet
->setPropertyValue( sShowChanges
, aAny
);
867 OUString
sRecordChanges( RTL_CONSTASCII_USTRINGPARAM("RecordChanges") );
868 bTmp
= IDocumentRedlineAccess::IsRedlineOn(rDoc
.GetRedlineMode());
869 aAny
.setValue( &bTmp
, ::getBooleanCppuType() );
870 xInfoSet
->setPropertyValue( sRecordChanges
, aAny
);
871 OUString
sRedlineProtectionKey( RTL_CONSTASCII_USTRINGPARAM("RedlineProtectionKey") );
872 aAny
<<= rDoc
.GetRedlinePassword();
873 xInfoSet
->setPropertyValue( sRedlineProtectionKey
, aAny
);
876 // force redline mode to "none"
877 rDoc
.SetRedlineMode_intern( nsRedlineMode_t::REDLINE_NONE
);
879 const sal_Bool bOASIS
= ( SotStorage::GetVersion( xStorage
) > SOFFICE_FILEFORMAT_60
);
880 // --> OD 2004-08-10 #i28749# - set property <ShapePositionInHoriL2R>
882 const sal_Bool bShapePositionInHoriL2R
= !bOASIS
;
883 xInfoSet
->setPropertyValue(
884 OUString(RTL_CONSTASCII_USTRINGPARAM("ShapePositionInHoriL2R")),
885 makeAny( bShapePositionInHoriL2R
) );
888 // --> OD 2007-12-19 #152540#
890 const sal_Bool bTextDocInOOoFileFormat
= !bOASIS
;
891 xInfoSet
->setPropertyValue(
892 OUString(RTL_CONSTASCII_USTRINGPARAM("TextDocInOOoFileFormat")),
893 makeAny( bTextDocInOOoFileFormat
) );
897 sal_uInt32 nWarnRDF
= 0;
898 if ( !(IsOrganizerMode() || IsBlockMode() || aOpt
.IsFmtsOnly() ||
901 // RDF metadata - must be read before styles/content
902 // N.B.: embedded documents have their own manifest.rdf!
905 const uno::Reference
<rdf::XDocumentMetadataAccess
> xDMA(xModelComp
,
906 uno::UNO_QUERY_THROW
);
907 const uno::Reference
<rdf::XURI
> xBaseURI( ::sfx2::createBaseURI(
908 aContext
.getUNOContext(), xStorage
, aBaseURL
, StreamPath
) );
909 const uno::Reference
<task::XInteractionHandler
> xHandler(
910 pDocSh
->GetMedium()->GetInteractionHandler() );
911 xDMA
->loadMetadataFromStorage(xStorage
, xBaseURI
, xHandler
);
913 catch (lang::WrappedTargetException
& e
)
915 ucb::InteractiveAugmentedIOException iaioe
;
916 if (e
.TargetException
>>= iaioe
)
918 // import error that was not ignored by InteractionHandler!
919 nWarnRDF
= ERR_SWG_READ_ERROR
;
923 nWarnRDF
= WARN_SWG_FEATURES_LOST
; // uhh... something wrong?
926 catch (uno::Exception
&)
928 nWarnRDF
= WARN_SWG_FEATURES_LOST
; // uhh... something went wrong?
932 sal_uInt32 nWarn
= 0;
933 sal_uInt32 nWarn2
= 0;
934 // read storage streams
935 if( !(IsOrganizerMode() || IsBlockMode() || aOpt
.IsFmtsOnly() ||
938 nWarn
= ReadThroughComponent(
939 xStorage
, xModelComp
, "meta.xml", "Meta.xml", xServiceFactory
,
940 (bOASIS
? "com.sun.star.comp.Writer.XMLOasisMetaImporter"
941 : "com.sun.star.comp.Writer.XMLMetaImporter"),
942 aEmptyArgs
, rName
, sal_False
);
944 nWarn2
= ReadThroughComponent(
945 xStorage
, xModelComp
, "settings.xml", NULL
, xServiceFactory
,
946 (bOASIS
? "com.sun.star.comp.Writer.XMLOasisSettingsImporter"
947 : "com.sun.star.comp.Writer.XMLSettingsImporter"),
948 aFilterArgs
, rName
, sal_False
);
951 nRet
= ReadThroughComponent(
952 xStorage
, xModelComp
, "styles.xml", NULL
, xServiceFactory
,
953 (bOASIS
? "com.sun.star.comp.Writer.XMLOasisStylesImporter"
954 : "com.sun.star.comp.Writer.XMLStylesImporter"),
955 aFilterArgs
, rName
, sal_True
);
957 if( !nRet
&& !(IsOrganizerMode() || aOpt
.IsFmtsOnly()) )
958 nRet
= ReadThroughComponent(
959 xStorage
, xModelComp
, "content.xml", "Content.xml", xServiceFactory
,
960 (bOASIS
? "com.sun.star.comp.Writer.XMLOasisContentImporter"
961 : "com.sun.star.comp.Writer.XMLContentImporter"),
962 aFilterArgs
, rName
, sal_True
);
964 if( !(IsOrganizerMode() || IsBlockMode() || bInsertMode
||
965 aOpt
.IsFmtsOnly() ) )
967 OUString
sStreamName( RTL_CONSTASCII_USTRINGPARAM("layout-cache") );
970 uno::Reference
< io::XStream
> xStm
= xStorage
->openStreamElement( sStreamName
, embed::ElementModes::READ
);
971 SvStream
* pStrm2
= utl::UcbStreamHelper::CreateStream( xStm
);
972 if( !pStrm2
->GetError() )
973 rDoc
.ReadLayoutCache( *pStrm2
);
976 catch ( uno::Exception
& )
981 // Notify math objects
983 rDoc
.PrtOLENotify( FALSE
);
984 else if ( rDoc
.IsOLEPrtNotifyPending() )
985 rDoc
.PrtOLENotify( TRUE
);
987 nRet
= nRet
? nRet
: (nWarn
? nWarn
: (nWarn2
? nWarn2
: nWarnRDF
) );
989 aOpt
.ResetAllFmtsOnly();
992 aAny
= xInfoSet
->getPropertyValue( sRedlineProtectionKey
);
993 Sequence
<sal_Int8
> aKey
;
995 rDoc
.SetRedlinePassword( aKey
);
997 // restore redline mode from import info property set
998 sal_Int16 nRedlineMode
= nsRedlineMode_t::REDLINE_SHOW_INSERT
;
999 aAny
= xInfoSet
->getPropertyValue( sShowChanges
);
1000 if ( *(sal_Bool
*)aAny
.getValue() )
1001 nRedlineMode
|= nsRedlineMode_t::REDLINE_SHOW_DELETE
;
1002 aAny
= xInfoSet
->getPropertyValue( sRecordChanges
);
1003 if ( *(sal_Bool
*)aAny
.getValue() || (aKey
.getLength() > 0) )
1004 nRedlineMode
|= nsRedlineMode_t::REDLINE_ON
;
1006 nRedlineMode
|= nsRedlineMode_t::REDLINE_NONE
;
1008 // ... restore redline mode
1009 // (First set bogus mode to make sure the mode in SetRedlineMode()
1010 // is different from it's previous mode.)
1011 rDoc
.SetRedlineMode_intern((RedlineMode_t
)( ~nRedlineMode
));
1012 rDoc
.SetRedlineMode( (RedlineMode_t
)( nRedlineMode
));
1014 // #103728# move Pam into valid content
1015 lcl_EnsureValidPam( rPaM
);
1017 if( pGraphicHelper
)
1018 SvXMLGraphicHelper::Destroy( pGraphicHelper
);
1019 xGraphicResolver
= 0;
1021 SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper
);
1022 xObjectResolver
= 0;
1027 // --> OD 2005-09-06 #i44177# - assure that for documents in OpenOffice.org
1028 // file format the relation between outline numbering rule and styles is
1029 // filled-up accordingly.
1030 // Note: The OpenOffice.org file format, which has no content that applys
1031 // a certain style, which is related to the outline numbering rule,
1032 // has lost the information, that this certain style is related to
1033 // the outline numbering rule.
1034 // --> OD 2008-12-17 #i70748# - only for templates
1035 if ( pMedium
&& pMedium
->GetFilter() &&
1036 pMedium
->GetFilter()->IsOwnTemplateFormat() )
1038 lcl_AdjustOutlineStylesForOOo( rDoc
);
1041 // Fix #i58251#: Unfortunately is the static default different to SO7 behaviour,
1042 // so we have to set a dynamic default after importing SO7
1043 rDoc
.SetDefault( SfxBoolItem( RES_ROW_SPLIT
, FALSE
) );
1047 rDoc
.PropagateOutlineRule();
1049 // --> OD 2006-03-14 #i62875#
1050 if ( rDoc
.get(IDocumentSettingAccess::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE
) && !docfunc::ExistsDrawObjs( rDoc
) )
1052 rDoc
.set(IDocumentSettingAccess::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE
, false);
1056 // --> OD 2006-02-22 #b6382898#
1057 // Convert all instances of <SdrOle2Obj> into <SdrGrafObj>, because the
1058 // Writer doesn't support such objects.
1059 lcl_ConvertSdrOle2ObjsToSdrGrafObjs( rDoc
);
1062 // set BuildId on XModel for later OLE object loading
1065 uno::Reference
< beans::XPropertySet
> xModelSet( xModelComp
, uno::UNO_QUERY
);
1066 if( xModelSet
.is() )
1068 uno::Reference
< beans::XPropertySetInfo
> xModelSetInfo( xModelSet
->getPropertySetInfo() );
1069 OUString
sName( RTL_CONSTASCII_USTRINGPARAM("BuildId" ) );
1070 if( xModelSetInfo
.is() && xModelSetInfo
->hasPropertyByName(sName
) )
1072 xModelSet
->setPropertyValue( sName
, xInfoSet
->getPropertyValue(sName
) );
1077 if (xStatusIndicator
.is())
1079 xStatusIndicator
->end();
1082 rDoc
.GetIStyleAccess().clearCaches(); // Clear Automatic-Style-Caches(shared_pointer!)
1086 // read the sections of the document, which is equal to the medium.
1087 // returns the count of it
1088 USHORT
XMLReader::GetSectionList( SfxMedium
& rMedium
,
1089 SvStrings
& rStrings
) const
1091 uno::Reference
< lang::XMultiServiceFactory
> xServiceFactory
=
1092 comphelper::getProcessServiceFactory();
1093 ASSERT( xServiceFactory
.is(),
1094 "XMLReader::Read: got no service manager" );
1095 uno::Reference
< embed::XStorage
> xStg2
;
1096 if( xServiceFactory
.is() && ( xStg2
= rMedium
.GetStorage() ).is() )
1101 xml::sax::InputSource aParserInput
;
1102 OUString
sDocName( RTL_CONSTASCII_USTRINGPARAM( "content.xml" ) );
1103 aParserInput
.sSystemId
= sDocName
;
1105 uno::Reference
< io::XStream
> xStm
= xStg2
->openStreamElement( sDocName
, embed::ElementModes::READ
);
1106 aParserInput
.aInputStream
= xStm
->getInputStream();
1109 uno::Reference
< XInterface
> xXMLParser
= xServiceFactory
->createInstance(
1110 OUString::createFromAscii("com.sun.star.xml.sax.Parser") );
1111 ASSERT( xXMLParser
.is(),
1112 "XMLReader::Read: com.sun.star.xml.sax.Parser service missing" );
1113 if( xXMLParser
.is() )
1117 // uno::Reference< xml::sax::XDocumentHandler > xFilter = new SwXMLSectionList( rStrings );
1118 uno::Reference
< xml::sax::XDocumentHandler
> xFilter
= new SwXMLSectionList( xServiceFactory
, rStrings
);
1120 // connect parser and filter
1121 uno::Reference
< xml::sax::XParser
> xParser( xXMLParser
, UNO_QUERY
);
1122 xParser
->setDocumentHandler( xFilter
);
1125 xParser
->parseStream( aParserInput
);
1128 catch( xml::sax::SAXParseException
& )
1132 catch( xml::sax::SAXException
& )
1136 catch( io::IOException
& )
1140 catch( packages::WrongPasswordException
& )
1145 return rStrings
.Count();