update credits
[LibreOffice.git] / sw / source / filter / xml / swxml.cxx
blobc01fd8acc5bc0841bcd613a254df7ffae75b804f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
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>
52 #include <swerror.h>
53 #include <fltini.hxx>
54 #include <doc.hxx>
55 #include <docary.hxx>
56 #include <docsh.hxx>
57 #include <unotextrange.hxx>
58 #include <swmodule.hxx>
59 #include <SwXMLSectionList.hxx>
61 #include <statstr.hrc>
63 // #i44177#
64 #include <SwStyleNameMapper.hxx>
65 #include <poolfmt.hxx>
66 #include <numrule.hxx>
67 #include <paratr.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() ) )
103 rPam.DeleteMark();
106 else
108 // point is not valid, so move it into the first content
109 rPam.DeleteMark();
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,
136 bool bEncrypted )
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;
150 // get parser
151 uno::Reference< xml::sax::XParser > xParser = xml::sax::Parser::create(rxContext);
152 RTL_LOGFILE_CONTEXT_TRACE( aLog, "parser created" );
154 // get filter
155 OUString aFilterName(OUString::createFromAscii(pFilterName));
156 uno::Reference< xml::sax::XDocumentHandler > xFilter(
157 rxContext->getServiceManager()->createInstanceWithArgumentsAndContext(aFilterName, rFilterArguments, rxContext),
158 UNO_QUERY);
159 SAL_WARN_IF(!xFilter.is(), "sw", "Can't instantiate filter component: " << aFilterName);
160 if( !xFilter.is() )
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 );
172 #ifdef TIMELOG
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() );
178 #endif
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;
192 while( bTryChild )
194 xml::sax::SAXException aTmp;
195 if ( aSaxEx.WrappedException >>= aTmp )
196 aSaxEx = aTmp;
197 else
198 bTryChild = false;
201 packages::zip::ZipIOException aBrokenPackage;
202 if ( aSaxEx.WrappedException >>= aBrokenPackage )
203 return ERRCODE_IO_BROKENPACKAGE;
205 if( bEncrypted )
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());
214 #endif
216 String sErr( OUString::number( r.LineNumber ));
217 sErr += ',';
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),
225 rStreamName, sErr,
226 ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR );
228 else
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;
241 if( bEncrypted )
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());
250 #endif
252 return ERR_SWG_READ_ERROR;
254 catch(const packages::zip::ZipIOException& r)
256 (void)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());
263 #endif
264 return ERRCODE_IO_BROKENPACKAGE;
266 catch(const io::IOException& r)
268 (void)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());
275 #endif
276 return ERR_SWG_READ_ERROR;
278 catch(const uno::Exception& r)
280 (void)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());
287 #endif
288 return ERR_SWG_READ_ERROR;
291 // success!
292 return 0;
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 )
328 return 0;
330 // if so, does the stream exist?
331 sStreamName = OUString::createFromAscii(pCompatibilityStreamName);
334 bContainsStream = xStorage->isStreamElement(sStreamName);
336 catch( container::NoSuchElementException& )
340 if (! bContainsStream )
341 return 0;
344 // set Base URL
345 uno::Reference< beans::XPropertySet > xInfoSet;
346 if( rFilterArguments.getLength() > 0 )
347 rFilterArguments.getConstArray()[0] >>= xInfoSet;
348 OSL_ENSURE( xInfoSet.is(), "missing property set" );
349 if( xInfoSet.is() )
351 OUString sPropName("StreamName");
352 xInfoSet->setPropertyValue( sPropName, makeAny( sStreamName ) );
357 // get input stream
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;
392 // #i44177#
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 ];
399 String sStyleName;
400 for ( sal_uInt8 i = 0; i < MAXLEVEL; ++i )
402 sStyleName =
403 SwStyleNameMapper::GetProgName( static_cast< sal_uInt16 >(RES_POOLCOLL_HEADLINE1 + i),
404 sStyleName );
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;
439 break;
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 )
449 // #i73361#
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() );
484 if( pOle2Obj )
486 // found an ole2 shape
487 SdrObjList* pObjList = pOle2Obj->GetObjList();
489 // get its graphic
490 Graphic aGraphic;
491 pOle2Obj->Connect();
492 const Graphic* pGraphic = pOle2Obj->GetGraphic();
493 if( pGraphic )
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;
527 if( pMedium )
528 xStorage = pMedium->GetStorage();
529 else
530 xStorage = xStg;
532 if( !xStorage.is() )
533 return ERR_SWG_READ_ERROR;
535 pGraphicHelper = SvXMLGraphicHelper::Create( xStorage,
536 GRAPHICHELPER_MODE_READ,
537 sal_False );
538 xGraphicResolver = pGraphicHelper;
539 SfxObjectShell *pPersist = rDoc.GetPersist();
540 if( pPersist )
542 pObjectHelper = SvXMLEmbeddedObjectHelper::Create(
543 xStorage, *pPersist,
544 EMBEDDEDOBJECTHELPER_MODE_READ,
545 sal_False );
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" );
552 if( !pDocSh )
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
563 // the user.
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)),
589 #else
590 &::getCppuType((Sequence<sal_Int8>*)0),
591 #endif
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
638 // will be sal_True.
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 );
653 if( xChild.is() )
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();
673 if (pSet)
675 const SfxUnoAnyItem* pItem = static_cast<const SfxUnoAnyItem*>(
676 pSet->GetItem(SID_PROGRESS_STATUSBAR_CONTROL) );
677 if (pItem)
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);
691 uno::Any aProgRange;
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() )
721 sal_Int32 nCount =
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();
751 Any aAny;
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) );
763 else
765 rPaM.GetBound(true).nContent.Assign(0, 0);
766 rPaM.GetBound(false).nContent.Assign(0, 0);
769 if( IsBlockMode() )
771 OUString sAutoTextMode("AutoTextMode");
772 sal_Bool bTmp = sal_True;
773 Any aAny;
774 aAny.setValue( &bTmp, ::getBooleanCppuType() );
775 xInfoSet->setPropertyValue( sAutoTextMode, aAny );
777 if( IsOrganizerMode() )
779 OUString sOrganizerMode("OrganizerMode");
780 sal_Bool bTmp = sal_True;
781 Any aAny;
782 aAny.setValue( &bTmp, ::getBooleanCppuType() );
783 xInfoSet->setPropertyValue( sOrganizerMode, aAny );
786 // Set base URI
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
797 OUString StreamPath;
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();
807 else
809 StreamPath = OUString("dummyObjectName");
812 if( !StreamPath.isEmpty() )
814 sPropName = OUString("StreamRelPath");
815 xInfoSet->setPropertyValue( sPropName, makeAny( StreamPath ) );
819 rDoc.acquire(); // prevent deletion
820 sal_uInt32 nRet = 0;
822 // save redline mode into import info property set
823 Any aAny;
824 sal_Bool bTmp;
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() ||
858 bInsertMode) )
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;
880 else
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() ||
902 bInsertMode) )
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 );
934 delete pStrm2;
936 catch ( uno::Exception& )
941 // Notify math objects
942 if( bInsertMode )
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();
951 // redline password
952 aAny = xInfoSet->getPropertyValue( sRedlineProtectionKey );
953 Sequence<sal_Int8> aKey;
954 aAny >>= 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;
965 else
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
976 if( pGraphicHelper )
977 SvXMLGraphicHelper::Destroy( pGraphicHelper );
978 xGraphicResolver = 0;
979 if( pObjectHelper )
980 SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper );
981 xObjectResolver = 0;
982 rDoc.release();
984 if ( !bOASIS )
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();
1006 // #i62875#
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
1017 if( xInfoSet.is() )
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!)
1037 return nRet;
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();
1060 // get filter
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 );
1067 // parse
1068 xParser->parseStream( aParserInput );
1070 catch( xml::sax::SAXParseException& )
1072 // re throw ?
1074 catch( xml::sax::SAXException& )
1076 // re throw ?
1078 catch( io::IOException& )
1080 // re throw ?
1082 catch( packages::WrongPasswordException& )
1084 // re throw ?
1087 return rStrings.size();
1090 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */