Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <rsc/rscsfx.hxx>
21 : #include <com/sun/star/embed/XStorage.hpp>
22 : #include <com/sun/star/embed/ElementModes.hpp>
23 : #include <comphelper/processfactory.hxx>
24 : #include <com/sun/star/xml/sax/InputSource.hpp>
25 : #include <com/sun/star/xml/sax/Parser.hpp>
26 : #include <com/sun/star/io/XActiveDataControl.hpp>
27 : #include <com/sun/star/text/XTextRange.hpp>
28 : #include <com/sun/star/container/XChild.hpp>
29 : #include <com/sun/star/document/NamedPropertyValues.hpp>
30 : #include <com/sun/star/beans/XPropertySetInfo.hpp>
31 : #include <com/sun/star/beans/PropertyValue.hpp>
32 : #include <com/sun/star/beans/NamedValue.hpp>
33 : #include <com/sun/star/beans/PropertyAttribute.hpp>
34 : #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
35 : #include <com/sun/star/io/XActiveDataSource.hpp>
36 : #include <com/sun/star/packages/zip/ZipIOException.hpp>
37 : #include <com/sun/star/packages/WrongPasswordException.hpp>
38 : #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
39 : #include <sfx2/docfile.hxx>
40 : #include <svtools/sfxecode.hxx>
41 : #include <svl/stritem.hxx>
42 : #include <unotools/streamwrap.hxx>
43 : #include <svx/xmlgrhlp.hxx>
44 : #include <svx/xmleohlp.hxx>
45 : #include <comphelper/genericpropertyset.hxx>
46 : #include <rtl/strbuf.hxx>
47 : #include <sfx2/frame.hxx>
48 : #include <unotools/ucbstreamhelper.hxx>
49 : #include <swerror.h>
50 : #include <fltini.hxx>
51 : #include <drawdoc.hxx>
52 : #include <doc.hxx>
53 : #include <docfunc.hxx>
54 : #include <IDocumentSettingAccess.hxx>
55 : #include <IDocumentDrawModelAccess.hxx>
56 : #include <IDocumentRedlineAccess.hxx>
57 : #include <docary.hxx>
58 : #include <docsh.hxx>
59 : #include <unotextrange.hxx>
60 : #include <swmodule.hxx>
61 : #include <SwXMLSectionList.hxx>
62 : #include <statstr.hrc>
63 :
64 : #include <SwStyleNameMapper.hxx>
65 : #include <poolfmt.hxx>
66 : #include <numrule.hxx>
67 : #include <paratr.hxx>
68 :
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>
75 : #include <istyleaccess.hxx>
76 :
77 : #include <sfx2/DocumentMetadataAccess.hxx>
78 :
79 : using namespace ::com::sun::star;
80 : using namespace ::com::sun::star::uno;
81 : using namespace ::com::sun::star::text;
82 : using namespace ::com::sun::star::container;
83 : using namespace ::com::sun::star::document;
84 : using namespace ::com::sun::star::lang;
85 :
86 291 : static void lcl_EnsureValidPam( SwPaM& rPam )
87 : {
88 291 : if( rPam.GetContentNode() != NULL )
89 : {
90 : // set proper point content
91 291 : if( rPam.GetContentNode() != rPam.GetPoint()->nContent.GetIdxReg() )
92 : {
93 291 : rPam.GetPoint()->nContent.Assign( rPam.GetContentNode(), 0 );
94 : }
95 : // else: point was already valid
96 :
97 : // if mark is invalid, we delete it
98 582 : if( ( rPam.GetContentNode( false ) == NULL ) ||
99 291 : ( rPam.GetContentNode( false ) != rPam.GetMark()->nContent.GetIdxReg() ) )
100 : {
101 0 : rPam.DeleteMark();
102 : }
103 : }
104 : else
105 : {
106 : // point is not valid, so move it into the first content
107 0 : rPam.DeleteMark();
108 0 : rPam.GetPoint()->nNode =
109 0 : *rPam.GetDoc()->GetNodes().GetEndOfContent().StartOfSectionNode();
110 0 : ++ rPam.GetPoint()->nNode;
111 0 : rPam.Move( fnMoveForward, fnGoContent ); // go into content
112 : }
113 291 : }
114 :
115 59 : XMLReader::XMLReader()
116 : {
117 59 : }
118 :
119 291 : int XMLReader::GetReaderType()
120 : {
121 291 : return SW_STORAGE_READER;
122 : }
123 :
124 : namespace
125 : {
126 :
127 : /// read a component (file + filter version)
128 1149 : sal_Int32 ReadThroughComponent(
129 : uno::Reference<io::XInputStream> xInputStream,
130 : uno::Reference<XComponent> xModelComponent,
131 : const OUString& rStreamName,
132 : uno::Reference<uno::XComponentContext> & rxContext,
133 : const sal_Char* pFilterName,
134 : const Sequence<Any>& rFilterArguments,
135 : const OUString& rName,
136 : bool bMustBeSuccessfull,
137 : bool bEncrypted )
138 : {
139 : OSL_ENSURE(xInputStream.is(), "input stream missing");
140 : OSL_ENSURE(xModelComponent.is(), "document missing");
141 : OSL_ENSURE(rxContext.is(), "factory missing");
142 : OSL_ENSURE(NULL != pFilterName,"I need a service name for the component!");
143 :
144 : // prepare ParserInputSrouce
145 1149 : xml::sax::InputSource aParserInput;
146 1149 : aParserInput.sSystemId = rName;
147 1149 : aParserInput.aInputStream = xInputStream;
148 :
149 : // get parser
150 2298 : uno::Reference< xml::sax::XParser > xParser = xml::sax::Parser::create(rxContext);
151 : SAL_INFO( "sw.filter", "parser created" );
152 : // get filter
153 2298 : const OUString aFilterName(OUString::createFromAscii(pFilterName));
154 : uno::Reference< xml::sax::XDocumentHandler > xFilter(
155 2298 : rxContext->getServiceManager()->createInstanceWithArgumentsAndContext(aFilterName, rFilterArguments, rxContext),
156 2298 : UNO_QUERY);
157 : SAL_WARN_IF(!xFilter.is(), "sw", "Can't instantiate filter component: " << aFilterName);
158 1149 : if( !xFilter.is() )
159 2 : return ERR_SWG_READ_ERROR;
160 : SAL_INFO( "sw.filter", "" << pFilterName << " created" );
161 : // connect parser and filter
162 1147 : xParser->setDocumentHandler( xFilter );
163 :
164 : // connect model and filter
165 2294 : uno::Reference < XImporter > xImporter( xFilter, UNO_QUERY );
166 1147 : xImporter->setTargetDocument( xModelComponent );
167 :
168 : // finally, parser the stream
169 : try
170 : {
171 1147 : xParser->parseStream( aParserInput );
172 : }
173 2 : catch( xml::sax::SAXParseException& r )
174 : {
175 : // sax parser sends wrapped exceptions,
176 : // try to find the original one
177 1 : xml::sax::SAXException aSaxEx = *static_cast<xml::sax::SAXException*>(&r);
178 1 : bool bTryChild = true;
179 :
180 4 : while( bTryChild )
181 : {
182 2 : xml::sax::SAXException aTmp;
183 2 : if ( aSaxEx.WrappedException >>= aTmp )
184 1 : aSaxEx = aTmp;
185 : else
186 1 : bTryChild = false;
187 2 : }
188 :
189 2 : packages::zip::ZipIOException aBrokenPackage;
190 1 : if ( aSaxEx.WrappedException >>= aBrokenPackage )
191 0 : return ERRCODE_IO_BROKENPACKAGE;
192 :
193 1 : if( bEncrypted )
194 0 : return ERRCODE_SFX_WRONGPASSWORD;
195 :
196 : #if OSL_DEBUG_LEVEL > 0
197 : OStringBuffer aError("SAX parse exception caught while importing:\n");
198 : aError.append(OUStringToOString(r.Message,
199 : RTL_TEXTENCODING_ASCII_US));
200 : OSL_FAIL(aError.getStr());
201 : #endif
202 :
203 : const OUString sErr( OUString::number( r.LineNumber )
204 2 : + ","
205 4 : + OUString::number( r.ColumnNumber ) );
206 :
207 1 : if( !rStreamName.isEmpty() )
208 : {
209 : return *new TwoStringErrorInfo(
210 : (bMustBeSuccessfull ? ERR_FORMAT_FILE_ROWCOL
211 : : WARN_FORMAT_FILE_ROWCOL),
212 : rStreamName, sErr,
213 1 : ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR );
214 : }
215 : else
216 : {
217 : OSL_ENSURE( bMustBeSuccessfull, "Warnings are not supported" );
218 : return *new StringErrorInfo( ERR_FORMAT_ROWCOL, sErr,
219 0 : ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR );
220 1 : }
221 : }
222 0 : catch(const xml::sax::SAXException& r)
223 : {
224 0 : packages::zip::ZipIOException aBrokenPackage;
225 0 : if ( r.WrappedException >>= aBrokenPackage )
226 0 : return ERRCODE_IO_BROKENPACKAGE;
227 :
228 0 : if( bEncrypted )
229 0 : return ERRCODE_SFX_WRONGPASSWORD;
230 :
231 : #if OSL_DEBUG_LEVEL > 0
232 : OStringBuffer aError("SAX exception caught while importing:\n");
233 : aError.append(OUStringToOString(r.Message,
234 : RTL_TEXTENCODING_ASCII_US));
235 : OSL_FAIL(aError.getStr());
236 : #endif
237 :
238 0 : return ERR_SWG_READ_ERROR;
239 : }
240 0 : catch(const packages::zip::ZipIOException& r)
241 : {
242 : (void)r;
243 : #if OSL_DEBUG_LEVEL > 0
244 : OStringBuffer aError("Zip exception caught while importing:\n");
245 : aError.append(OUStringToOString(r.Message,
246 : RTL_TEXTENCODING_ASCII_US));
247 : OSL_FAIL(aError.getStr());
248 : #endif
249 0 : return ERRCODE_IO_BROKENPACKAGE;
250 : }
251 0 : catch(const io::IOException& r)
252 : {
253 : (void)r;
254 : #if OSL_DEBUG_LEVEL > 0
255 : OStringBuffer aError("IO exception caught while importing:\n");
256 : aError.append(OUStringToOString(r.Message,
257 : RTL_TEXTENCODING_ASCII_US));
258 : OSL_FAIL(aError.getStr());
259 : #endif
260 0 : return ERR_SWG_READ_ERROR;
261 : }
262 0 : catch(const uno::Exception& r)
263 : {
264 : (void)r;
265 : #if OSL_DEBUG_LEVEL > 0
266 : OStringBuffer aError("uno exception caught while importing:\n");
267 : aError.append(OUStringToOString(r.Message,
268 : RTL_TEXTENCODING_ASCII_US));
269 : OSL_FAIL(aError.getStr());
270 : #endif
271 0 : return ERR_SWG_READ_ERROR;
272 : }
273 :
274 : // success!
275 2295 : return 0;
276 : }
277 :
278 : // read a component (storage version)
279 1153 : sal_Int32 ReadThroughComponent(
280 : uno::Reference<embed::XStorage> xStorage,
281 : uno::Reference<XComponent> xModelComponent,
282 : const sal_Char* pStreamName,
283 : const sal_Char* pCompatibilityStreamName,
284 : uno::Reference<uno::XComponentContext> & rxContext,
285 : const sal_Char* pFilterName,
286 : const Sequence<Any>& rFilterArguments,
287 : const OUString& rName,
288 : bool bMustBeSuccessfull)
289 : {
290 : OSL_ENSURE(xStorage.is(), "Need storage!");
291 : OSL_ENSURE(NULL != pStreamName, "Please, please, give me a name!");
292 :
293 : // open stream (and set parser input)
294 1153 : OUString sStreamName = OUString::createFromAscii(pStreamName);
295 1153 : bool bContainsStream = false;
296 : try
297 : {
298 1153 : bContainsStream = xStorage->isStreamElement(sStreamName);
299 : }
300 4 : catch( container::NoSuchElementException& )
301 : {
302 : }
303 :
304 1153 : if (!bContainsStream )
305 : {
306 : // stream name not found! Then try the compatibility name.
307 : // if no stream can be opened, return immediately with OK signal
308 :
309 : // do we even have an alternative name?
310 4 : if ( NULL == pCompatibilityStreamName )
311 0 : return 0;
312 :
313 : // if so, does the stream exist?
314 4 : sStreamName = OUString::createFromAscii(pCompatibilityStreamName);
315 : try
316 : {
317 4 : bContainsStream = xStorage->isStreamElement(sStreamName);
318 : }
319 4 : catch( container::NoSuchElementException& )
320 : {
321 : }
322 :
323 4 : if (! bContainsStream )
324 4 : return 0;
325 : }
326 :
327 : // set Base URL
328 2298 : uno::Reference< beans::XPropertySet > xInfoSet;
329 1149 : if( rFilterArguments.getLength() > 0 )
330 1149 : rFilterArguments.getConstArray()[0] >>= xInfoSet;
331 : OSL_ENSURE( xInfoSet.is(), "missing property set" );
332 1149 : if( xInfoSet.is() )
333 : {
334 1149 : xInfoSet->setPropertyValue( "StreamName", makeAny( sStreamName ) );
335 : }
336 :
337 : try
338 : {
339 : // get input stream
340 1149 : uno::Reference <io::XStream> xStream = xStorage->openStreamElement( sStreamName, embed::ElementModes::READ );
341 2298 : uno::Reference <beans::XPropertySet > xProps( xStream, uno::UNO_QUERY );
342 :
343 2298 : Any aAny = xProps->getPropertyValue("Encrypted");
344 :
345 2298 : bool bEncrypted = aAny.getValueType() == cppu::UnoType<bool>::get() &&
346 2298 : *static_cast<sal_Bool const *>(aAny.getValue());
347 :
348 2298 : uno::Reference <io::XInputStream> xInputStream = xStream->getInputStream();
349 :
350 : // read from the stream
351 : return ReadThroughComponent(
352 : xInputStream, xModelComponent, sStreamName, rxContext,
353 : pFilterName, rFilterArguments,
354 2298 : rName, bMustBeSuccessfull, bEncrypted );
355 : }
356 0 : catch ( packages::WrongPasswordException& )
357 : {
358 0 : return ERRCODE_SFX_WRONGPASSWORD;
359 : }
360 0 : catch( packages::zip::ZipIOException& )
361 : {
362 0 : return ERRCODE_IO_BROKENPACKAGE;
363 : }
364 0 : catch ( uno::Exception& )
365 : {
366 : OSL_FAIL( "Error on import" );
367 : // TODO/LATER: error handling
368 : }
369 :
370 1153 : return ERR_SWG_READ_ERROR;
371 : }
372 :
373 : }
374 :
375 : // #i44177#
376 0 : static void lcl_AdjustOutlineStylesForOOo(SwDoc& _rDoc)
377 : {
378 : // array containing the names of the default outline styles ('Heading 1',
379 : // 'Heading 2', ..., 'Heading 10')
380 0 : OUString aDefOutlStyleNames[ MAXLEVEL ];
381 : {
382 0 : OUString sStyleName;
383 0 : for ( sal_uInt8 i = 0; i < MAXLEVEL; ++i )
384 : {
385 : sStyleName =
386 : SwStyleNameMapper::GetProgName( RES_POOLCOLL_HEADLINE1 + i,
387 0 : sStyleName );
388 0 : aDefOutlStyleNames[i] = sStyleName;
389 0 : }
390 : }
391 :
392 : // array indicating, which outline level already has a style assigned.
393 : bool aOutlineLevelAssigned[ MAXLEVEL ];
394 : // array of the default outline styles, which are created for the document.
395 : SwTextFormatColl* aCreatedDefaultOutlineStyles[ MAXLEVEL ];
396 :
397 : {
398 0 : for ( sal_uInt8 i = 0; i < MAXLEVEL; ++i )
399 : {
400 0 : aOutlineLevelAssigned[ i ] = false;
401 0 : aCreatedDefaultOutlineStyles[ i ] = 0L;
402 : }
403 : }
404 :
405 : // determine, which outline level has already a style assigned and
406 : // which of the default outline styles is created.
407 0 : const SwTextFormatColls& rColls = *(_rDoc.GetTextFormatColls());
408 0 : for ( size_t n = 1; n < rColls.size(); ++n )
409 : {
410 0 : SwTextFormatColl* pColl = rColls[ n ];
411 0 : if ( pColl->IsAssignedToListLevelOfOutlineStyle() )
412 : {
413 0 : aOutlineLevelAssigned[ pColl->GetAssignedOutlineStyleLevel() ] = true;
414 : }
415 :
416 0 : for ( sal_uInt8 i = 0; i < MAXLEVEL; ++i )
417 : {
418 0 : if ( aCreatedDefaultOutlineStyles[ i ] == 0L &&
419 0 : pColl->GetName() == aDefOutlStyleNames[i] )
420 : {
421 0 : aCreatedDefaultOutlineStyles[ i ] = pColl;
422 0 : break;
423 : }
424 : }
425 : }
426 :
427 : // assign already created default outline style to outline level, which
428 : // doesn't have a style assigned to it.
429 0 : const SwNumRule* pOutlineRule = _rDoc.GetOutlineNumRule();
430 0 : for ( sal_uInt8 i = 0; i < MAXLEVEL; ++i )
431 : {
432 : // #i73361#
433 : // Do not change assignment of already created default outline style
434 : // to a certain outline level.
435 0 : if ( !aOutlineLevelAssigned[ i ] &&
436 0 : aCreatedDefaultOutlineStyles[ i ] != 0 &&
437 0 : ! aCreatedDefaultOutlineStyles[ i ]->IsAssignedToListLevelOfOutlineStyle() )
438 : {
439 : // apply outline level at created default outline style
440 0 : aCreatedDefaultOutlineStyles[ i ]->AssignToListLevelOfOutlineStyle(i);
441 :
442 : // apply outline numbering rule, if none is set.
443 : const SfxPoolItem& rItem =
444 0 : aCreatedDefaultOutlineStyles[ i ]->GetFormatAttr( RES_PARATR_NUMRULE, false );
445 0 : if ( static_cast<const SwNumRuleItem&>(rItem).GetValue().isEmpty() )
446 : {
447 0 : SwNumRuleItem aItem( pOutlineRule->GetName() );
448 0 : aCreatedDefaultOutlineStyles[ i ]->SetFormatAttr( aItem );
449 : }
450 : }
451 0 : }
452 0 : }
453 :
454 291 : static void lcl_ConvertSdrOle2ObjsToSdrGrafObjs(SwDoc& _rDoc)
455 : {
456 582 : if ( _rDoc.getIDocumentDrawModelAccess().GetDrawModel() &&
457 291 : _rDoc.getIDocumentDrawModelAccess().GetDrawModel()->GetPage( 0 ) )
458 : {
459 291 : const SdrPage& rSdrPage( *(_rDoc.getIDocumentDrawModelAccess().GetDrawModel()->GetPage( 0 )) );
460 :
461 : // iterate recursive with group objects over all shapes on the draw page
462 291 : SdrObjListIter aIter( rSdrPage );
463 1038 : while( aIter.IsMore() )
464 : {
465 456 : SdrOle2Obj* pOle2Obj = dynamic_cast< SdrOle2Obj* >( aIter.Next() );
466 456 : if( pOle2Obj )
467 : {
468 : // found an ole2 shape
469 0 : SdrObjList* pObjList = pOle2Obj->GetObjList();
470 :
471 : // get its graphic
472 0 : Graphic aGraphic;
473 0 : pOle2Obj->Connect();
474 0 : const Graphic* pGraphic = pOle2Obj->GetGraphic();
475 0 : if( pGraphic )
476 0 : aGraphic = *pGraphic;
477 0 : pOle2Obj->Disconnect();
478 :
479 : // create new graphic shape with the ole graphic and shape size
480 0 : SdrGrafObj* pGraphicObj = new SdrGrafObj( aGraphic, pOle2Obj->GetCurrentBoundRect() );
481 : // apply layer of ole2 shape at graphic shape
482 0 : pGraphicObj->SetLayer( pOle2Obj->GetLayer() );
483 :
484 : // replace ole2 shape with the new graphic object and delete the ol2 shape
485 0 : SdrObject* pReplaced = pObjList->ReplaceObject( pGraphicObj, pOle2Obj->GetOrdNum() );
486 0 : SdrObject::Free( pReplaced );
487 : }
488 291 : }
489 : }
490 291 : }
491 :
492 291 : sal_uLong XMLReader::Read( SwDoc &rDoc, const OUString& rBaseURL, SwPaM &rPaM, const OUString & rName )
493 : {
494 : // Get service factory
495 : uno::Reference< uno::XComponentContext > xContext =
496 291 : comphelper::getProcessComponentContext();
497 :
498 582 : uno::Reference< io::XActiveDataSource > xSource;
499 582 : uno::Reference< XInterface > xPipe;
500 582 : uno::Reference< document::XGraphicObjectResolver > xGraphicResolver;
501 291 : SvXMLGraphicHelper *pGraphicHelper = 0;
502 582 : uno::Reference< document::XEmbeddedObjectResolver > xObjectResolver;
503 291 : SvXMLEmbeddedObjectHelper *pObjectHelper = 0;
504 :
505 : // get the input stream (storage or stream)
506 582 : uno::Reference<io::XInputStream> xInputStream;
507 582 : uno::Reference<embed::XStorage> xStorage;
508 291 : if( pMedium )
509 291 : xStorage = pMedium->GetStorage();
510 : else
511 0 : xStorage = xStg;
512 :
513 291 : if( !xStorage.is() )
514 0 : return ERR_SWG_READ_ERROR;
515 :
516 : pGraphicHelper = SvXMLGraphicHelper::Create( xStorage,
517 : GRAPHICHELPER_MODE_READ,
518 291 : false );
519 291 : xGraphicResolver = pGraphicHelper;
520 291 : SfxObjectShell *pPersist = rDoc.GetPersist();
521 291 : if( pPersist )
522 : {
523 : pObjectHelper = SvXMLEmbeddedObjectHelper::Create(
524 : xStorage, *pPersist,
525 : EMBEDDEDOBJECTHELPER_MODE_READ,
526 291 : false );
527 291 : xObjectResolver = pObjectHelper;
528 : }
529 :
530 : // Get the docshell, the model, and finally the model's component
531 291 : SwDocShell *pDocSh = rDoc.GetDocShell();
532 : OSL_ENSURE( pDocSh, "XMLReader::Read: got no doc shell" );
533 291 : if( !pDocSh )
534 0 : return ERR_SWG_READ_ERROR;
535 582 : uno::Reference< lang::XComponent > xModelComp( pDocSh->GetModel(), UNO_QUERY );
536 : OSL_ENSURE( xModelComp.is(),
537 : "XMLReader::Read: got no model" );
538 291 : if( !xModelComp.is() )
539 0 : return ERR_SWG_READ_ERROR;
540 :
541 : // create and prepare the XPropertySet that gets passed through
542 : // the components, and the XStatusIndicator that shows progress to
543 : // the user.
544 :
545 : // create XPropertySet with three properties for status indicator
546 : comphelper::PropertyMapEntry const aInfoMap[] =
547 : {
548 : { OUString("ProgressRange"), 0,
549 291 : ::cppu::UnoType<sal_Int32>::get(),
550 : beans::PropertyAttribute::MAYBEVOID, 0},
551 : { OUString("ProgressMax"), 0,
552 291 : ::cppu::UnoType<sal_Int32>::get(),
553 : beans::PropertyAttribute::MAYBEVOID, 0},
554 : { OUString("ProgressCurrent"), 0,
555 291 : ::cppu::UnoType<sal_Int32>::get(),
556 : beans::PropertyAttribute::MAYBEVOID, 0},
557 : { OUString("NumberStyles"), 0,
558 291 : cppu::UnoType<container::XNameContainer>::get(),
559 : beans::PropertyAttribute::MAYBEVOID, 0},
560 : { OUString("RecordChanges"), 0,
561 291 : cppu::UnoType<bool>::get(),
562 : beans::PropertyAttribute::MAYBEVOID, 0 },
563 : { OUString("ShowChanges"), 0,
564 291 : cppu::UnoType<bool>::get(),
565 : beans::PropertyAttribute::MAYBEVOID, 0 },
566 : { OUString("RedlineProtectionKey"), 0,
567 291 : cppu::UnoType<Sequence<sal_Int8>>::get(),
568 : beans::PropertyAttribute::MAYBEVOID, 0 },
569 : { OUString("PrivateData"), 0,
570 291 : cppu::UnoType<XInterface>::get(),
571 : beans::PropertyAttribute::MAYBEVOID, 0 },
572 : { OUString("BaseURI"), 0,
573 291 : ::cppu::UnoType<OUString>::get(),
574 : beans::PropertyAttribute::MAYBEVOID, 0 },
575 : { OUString("StreamRelPath"), 0,
576 291 : ::cppu::UnoType<OUString>::get(),
577 : beans::PropertyAttribute::MAYBEVOID, 0 },
578 : { OUString("StreamName"), 0,
579 291 : ::cppu::UnoType<OUString>::get(),
580 : beans::PropertyAttribute::MAYBEVOID, 0 },
581 : // properties for insert modes
582 : { OUString("StyleInsertModeFamilies"), 0,
583 291 : cppu::UnoType<Sequence<OUString>>::get(),
584 : beans::PropertyAttribute::MAYBEVOID, 0 },
585 : { OUString("StyleInsertModeOverwrite"), 0,
586 291 : cppu::UnoType<bool>::get(),
587 : beans::PropertyAttribute::MAYBEVOID, 0 },
588 : { OUString("TextInsertModeRange"), 0,
589 291 : cppu::UnoType<text::XTextRange>::get(),
590 : beans::PropertyAttribute::MAYBEVOID, 0},
591 : { OUString("AutoTextMode"), 0,
592 291 : cppu::UnoType<bool>::get(),
593 : beans::PropertyAttribute::MAYBEVOID, 0 },
594 : { OUString("OrganizerMode"), 0,
595 291 : cppu::UnoType<bool>::get(),
596 : beans::PropertyAttribute::MAYBEVOID, 0 },
597 :
598 : // #i28749# - Add property, which indicates, if the
599 : // shape position attributes are given in horizontal left-to-right layout.
600 : // This is the case for the OpenOffice.org file format.
601 : { OUString("ShapePositionInHoriL2R"), 0,
602 291 : cppu::UnoType<bool>::get(),
603 : beans::PropertyAttribute::MAYBEVOID, 0 },
604 :
605 : { OUString("BuildId"), 0,
606 291 : ::cppu::UnoType<OUString>::get(),
607 : beans::PropertyAttribute::MAYBEVOID, 0 },
608 :
609 : // Add property, which indicates, if a text document in OpenOffice.org
610 : // file format is read.
611 : // Note: Text documents read via the binary filter are also finally
612 : // read using the OpenOffice.org file format. Thus, e.g. for text
613 : // documents in StarOffice 5.2 binary file format this property
614 : // will be true.
615 : { OUString("TextDocInOOoFileFormat"), 0,
616 291 : cppu::UnoType<bool>::get(),
617 : beans::PropertyAttribute::MAYBEVOID, 0 },
618 291 : { OUString("SourceStorage"), 0, cppu::UnoType<embed::XStorage>::get(),
619 : ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
620 : { OUString(), 0, css::uno::Type(), 0, 0 }
621 6402 : };
622 : uno::Reference< beans::XPropertySet > xInfoSet(
623 : comphelper::GenericPropertySet_CreateInstance(
624 582 : new comphelper::PropertySetInfo( aInfoMap ) ) );
625 :
626 : // get BuildId from parent container if available
627 582 : uno::Reference< container::XChild > xChild( xModelComp, uno::UNO_QUERY );
628 291 : if( xChild.is() )
629 : {
630 291 : uno::Reference< beans::XPropertySet > xParentSet( xChild->getParent(), uno::UNO_QUERY );
631 291 : if( xParentSet.is() )
632 : {
633 2 : uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xParentSet->getPropertySetInfo() );
634 4 : const OUString sPropName("BuildId" );
635 2 : if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(sPropName) )
636 : {
637 2 : xInfoSet->setPropertyValue( sPropName, xParentSet->getPropertyValue(sPropName) );
638 2 : }
639 291 : }
640 : }
641 :
642 : // try to get an XStatusIndicator from the Medium
643 582 : uno::Reference<task::XStatusIndicator> xStatusIndicator;
644 :
645 291 : if (pDocSh->GetMedium())
646 : {
647 291 : SfxItemSet* pSet = pDocSh->GetMedium()->GetItemSet();
648 291 : if (pSet)
649 : {
650 : const SfxUnoAnyItem* pItem = static_cast<const SfxUnoAnyItem*>(
651 291 : pSet->GetItem(SID_PROGRESS_STATUSBAR_CONTROL) );
652 291 : if (pItem)
653 : {
654 258 : pItem->GetValue() >>= xStatusIndicator;
655 : }
656 : }
657 : }
658 :
659 : // set progress range and start status indicator
660 291 : sal_Int32 nProgressRange(1000000);
661 291 : if (xStatusIndicator.is())
662 : {
663 258 : xStatusIndicator->start(SW_RESSTR(STR_STATSTR_SWGREAD), nProgressRange);
664 : }
665 582 : uno::Any aProgRange;
666 291 : aProgRange <<= nProgressRange;
667 291 : xInfoSet->setPropertyValue("ProgressRange", aProgRange);
668 :
669 582 : Reference< container::XNameAccess > xLateInitSettings( document::NamedPropertyValues::create(xContext), UNO_QUERY_THROW );
670 582 : beans::NamedValue aLateInitSettings( "LateInitSettings", makeAny( xLateInitSettings ) );
671 :
672 291 : xInfoSet->setPropertyValue( "SourceStorage", Any( xStorage ) );
673 :
674 : // prepare filter arguments, WARNING: the order is important!
675 582 : Sequence<Any> aFilterArgs( 5 );
676 291 : Any *pArgs = aFilterArgs.getArray();
677 291 : *pArgs++ <<= xInfoSet;
678 291 : *pArgs++ <<= xStatusIndicator;
679 291 : *pArgs++ <<= xGraphicResolver;
680 291 : *pArgs++ <<= xObjectResolver;
681 291 : *pArgs++ <<= aLateInitSettings;
682 :
683 582 : Sequence<Any> aEmptyArgs( 3 );
684 : // cppcheck-suppress redundantAssignment
685 291 : pArgs = aEmptyArgs.getArray();
686 291 : *pArgs++ <<= xInfoSet;
687 291 : *pArgs++ <<= xStatusIndicator;
688 :
689 : // prepare for special modes
690 291 : if( aOpt.IsFormatsOnly() )
691 : {
692 : sal_Int32 nCount =
693 0 : (aOpt.IsFrameFormats() ? 1 : 0) +
694 0 : (aOpt.IsPageDescs() ? 1 : 0) +
695 0 : (aOpt.IsTextFormats() ? 2 : 0) +
696 0 : (aOpt.IsNumRules() ? 1 : 0);
697 :
698 0 : Sequence< OUString> aFamiliesSeq( nCount );
699 0 : OUString *pSeq = aFamiliesSeq.getArray();
700 0 : if( aOpt.IsFrameFormats() )
701 : // SFX_STYLE_FAMILY_FRAME;
702 0 : *pSeq++ = "FrameStyles";
703 0 : if( aOpt.IsPageDescs() )
704 : // SFX_STYLE_FAMILY_PAGE;
705 0 : *pSeq++ = "PageStyles";
706 0 : if( aOpt.IsTextFormats() )
707 : {
708 : // (SFX_STYLE_FAMILY_CHAR|SFX_STYLE_FAMILY_PARA);
709 0 : *pSeq++ = "CharacterStyles";
710 0 : *pSeq++ = "ParagraphStyles";
711 : }
712 0 : if( aOpt.IsNumRules() )
713 : // SFX_STYLE_FAMILY_PSEUDO;
714 0 : *pSeq++ = "NumberingStyles";
715 :
716 0 : xInfoSet->setPropertyValue( "StyleInsertModeFamilies",
717 0 : makeAny(aFamiliesSeq) );
718 :
719 0 : xInfoSet->setPropertyValue( "StyleInsertModeOverwrite", makeAny(!aOpt.IsMerge()) );
720 : }
721 291 : else if( bInsertMode )
722 : {
723 : const uno::Reference<text::XTextRange> xInsertTextRange =
724 0 : SwXTextRange::CreateXTextRange(rDoc, *rPaM.GetPoint(), 0);
725 0 : xInfoSet->setPropertyValue( "TextInsertModeRange",
726 0 : makeAny(xInsertTextRange) );
727 : }
728 : else
729 : {
730 291 : rPaM.GetBound(true).nContent.Assign(0, 0);
731 291 : rPaM.GetBound(false).nContent.Assign(0, 0);
732 : }
733 :
734 291 : if( IsBlockMode() )
735 : {
736 2 : xInfoSet->setPropertyValue( "AutoTextMode", makeAny(true) );
737 : }
738 291 : if( IsOrganizerMode() )
739 : {
740 4 : xInfoSet->setPropertyValue( "OrganizerMode", makeAny(true) );
741 : }
742 :
743 : // Set base URI
744 : // there is ambiguity which medium should be used here
745 : // for now the own medium has a preference
746 291 : SfxMedium* pMedDescrMedium = pMedium ? pMedium : pDocSh->GetMedium();
747 : OSL_ENSURE( pMedDescrMedium, "There is no medium to get MediaDescriptor from!\n" );
748 :
749 291 : xInfoSet->setPropertyValue( "BaseURI", makeAny( rBaseURL ) );
750 :
751 : // TODO/LATER: separate links from usual embedded objects
752 582 : OUString StreamPath;
753 291 : if( SfxObjectCreateMode::EMBEDDED == rDoc.GetDocShell()->GetCreateMode() )
754 : {
755 11 : if ( pMedDescrMedium && pMedDescrMedium->GetItemSet() )
756 : {
757 : const SfxStringItem* pDocHierarchItem = static_cast<const SfxStringItem*>(
758 11 : pMedDescrMedium->GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) );
759 11 : if ( pDocHierarchItem )
760 2 : StreamPath = pDocHierarchItem->GetValue();
761 : }
762 : else
763 : {
764 0 : StreamPath = "dummyObjectName";
765 : }
766 :
767 11 : if( !StreamPath.isEmpty() )
768 : {
769 2 : xInfoSet->setPropertyValue( "StreamRelPath", makeAny( StreamPath ) );
770 : }
771 : }
772 :
773 291 : (void)rDoc.acquire(); // prevent deletion
774 291 : sal_uInt32 nRet = 0;
775 :
776 : // save redline mode into import info property set
777 582 : const OUString sShowChanges("ShowChanges");
778 582 : const OUString sRecordChanges("RecordChanges");
779 582 : const OUString sRedlineProtectionKey("RedlineProtectionKey");
780 291 : xInfoSet->setPropertyValue( sShowChanges,
781 291 : makeAny(IDocumentRedlineAccess::IsShowChanges(rDoc.getIDocumentRedlineAccess().GetRedlineMode())) );
782 291 : xInfoSet->setPropertyValue( sRecordChanges,
783 291 : makeAny(IDocumentRedlineAccess::IsRedlineOn(rDoc.getIDocumentRedlineAccess().GetRedlineMode())) );
784 291 : xInfoSet->setPropertyValue( sRedlineProtectionKey,
785 291 : makeAny(rDoc.getIDocumentRedlineAccess().GetRedlinePassword()) );
786 :
787 : // force redline mode to "none"
788 291 : rDoc.getIDocumentRedlineAccess().SetRedlineMode_intern( nsRedlineMode_t::REDLINE_NONE );
789 :
790 291 : const bool bOASIS = ( SotStorage::GetVersion( xStorage ) > SOFFICE_FILEFORMAT_60 );
791 : // #i28749# - set property <ShapePositionInHoriL2R>
792 : {
793 291 : const bool bShapePositionInHoriL2R = !bOASIS;
794 291 : xInfoSet->setPropertyValue(
795 : "ShapePositionInHoriL2R",
796 291 : makeAny( bShapePositionInHoriL2R ) );
797 : }
798 : {
799 291 : const bool bTextDocInOOoFileFormat = !bOASIS;
800 291 : xInfoSet->setPropertyValue(
801 : "TextDocInOOoFileFormat",
802 291 : makeAny( bTextDocInOOoFileFormat ) );
803 : }
804 :
805 291 : sal_uInt32 nWarnRDF = 0;
806 869 : if ( !(IsOrganizerMode() || IsBlockMode() || aOpt.IsFormatsOnly() ||
807 576 : bInsertMode) )
808 : {
809 : // RDF metadata - must be read before styles/content
810 : // N.B.: embedded documents have their own manifest.rdf!
811 : try
812 : {
813 : const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(xModelComp,
814 285 : uno::UNO_QUERY_THROW);
815 : const uno::Reference<rdf::XURI> xBaseURI( ::sfx2::createBaseURI(
816 402 : xContext, xStorage, rBaseURL, StreamPath) );
817 : const uno::Reference<task::XInteractionHandler> xHandler(
818 234 : pDocSh->GetMedium()->GetInteractionHandler() );
819 402 : xDMA->loadMetadataFromStorage(xStorage, xBaseURI, xHandler);
820 : }
821 0 : catch (const lang::WrappedTargetException & e)
822 : {
823 0 : ucb::InteractiveAugmentedIOException iaioe;
824 0 : if (e.TargetException >>= iaioe)
825 : {
826 : // import error that was not ignored by InteractionHandler!
827 0 : nWarnRDF = ERR_SWG_READ_ERROR;
828 : }
829 : else
830 : {
831 0 : nWarnRDF = WARN_SWG_FEATURES_LOST; // uhh... something wrong?
832 0 : }
833 : }
834 336 : catch (uno::Exception &)
835 : {
836 168 : nWarnRDF = WARN_SWG_FEATURES_LOST; // uhh... something went wrong?
837 : }
838 : }
839 :
840 : // read storage streams
841 :
842 : // #i103539#: always read meta.xml for generator
843 : sal_uInt32 const nWarn = ReadThroughComponent(
844 : xStorage, xModelComp, "meta.xml", "Meta.xml", xContext,
845 : (bOASIS ? "com.sun.star.comp.Writer.XMLOasisMetaImporter"
846 : : "com.sun.star.comp.Writer.XMLMetaImporter"),
847 291 : aEmptyArgs, rName, false );
848 :
849 291 : sal_uInt32 nWarn2 = 0;
850 869 : if( !(IsOrganizerMode() || IsBlockMode() || aOpt.IsFormatsOnly() ||
851 576 : bInsertMode) )
852 : {
853 : nWarn2 = ReadThroughComponent(
854 : xStorage, xModelComp, "settings.xml", NULL, xContext,
855 : (bOASIS ? "com.sun.star.comp.Writer.XMLOasisSettingsImporter"
856 : : "com.sun.star.comp.Writer.XMLSettingsImporter"),
857 285 : aFilterArgs, rName, false );
858 : }
859 :
860 : nRet = ReadThroughComponent(
861 : xStorage, xModelComp, "styles.xml", NULL, xContext,
862 : (bOASIS ? "com.sun.star.comp.Writer.XMLOasisStylesImporter"
863 : : "com.sun.star.comp.Writer.XMLStylesImporter"),
864 291 : aFilterArgs, rName, true );
865 :
866 291 : if( !nRet && !(IsOrganizerMode() || aOpt.IsFormatsOnly()) )
867 : nRet = ReadThroughComponent(
868 : xStorage, xModelComp, "content.xml", "Content.xml", xContext,
869 : (bOASIS ? "com.sun.star.comp.Writer.XMLOasisContentImporter"
870 : : "com.sun.star.comp.Writer.XMLContentImporter"),
871 286 : aFilterArgs, rName, true );
872 :
873 869 : if( !(IsOrganizerMode() || IsBlockMode() || bInsertMode ||
874 576 : aOpt.IsFormatsOnly() ) )
875 : {
876 : try
877 : {
878 529 : uno::Reference < io::XStream > xStm = xStorage->openStreamElement( "layout-cache", embed::ElementModes::READ );
879 41 : SvStream* pStrm2 = utl::UcbStreamHelper::CreateStream( xStm );
880 41 : if( !pStrm2->GetError() )
881 41 : rDoc.ReadLayoutCache( *pStrm2 );
882 41 : delete pStrm2;
883 : }
884 244 : catch (const uno::Exception&)
885 : {
886 : }
887 : }
888 :
889 : // Notify math objects
890 291 : if( bInsertMode )
891 0 : rDoc.PrtOLENotify( false );
892 291 : else if ( rDoc.IsOLEPrtNotifyPending() )
893 20 : rDoc.PrtOLENotify( true );
894 :
895 291 : nRet = nRet ? nRet : (nWarn ? nWarn : (nWarn2 ? nWarn2 : nWarnRDF ) );
896 :
897 291 : aOpt.ResetAllFormatsOnly();
898 :
899 : // redline password
900 582 : Any aAny = xInfoSet->getPropertyValue( sRedlineProtectionKey );
901 582 : Sequence<sal_Int8> aKey;
902 291 : aAny >>= aKey;
903 291 : rDoc.getIDocumentRedlineAccess().SetRedlinePassword( aKey );
904 :
905 : // restore redline mode from import info property set
906 291 : sal_Int16 nRedlineMode = nsRedlineMode_t::REDLINE_SHOW_INSERT;
907 291 : aAny = xInfoSet->getPropertyValue( sShowChanges );
908 291 : if ( *static_cast<sal_Bool const *>(aAny.getValue()) )
909 287 : nRedlineMode |= nsRedlineMode_t::REDLINE_SHOW_DELETE;
910 291 : aAny = xInfoSet->getPropertyValue( sRecordChanges );
911 291 : if ( *static_cast<sal_Bool const *>(aAny.getValue()) || (aKey.getLength() > 0) )
912 3 : nRedlineMode |= nsRedlineMode_t::REDLINE_ON;
913 : else
914 288 : nRedlineMode |= nsRedlineMode_t::REDLINE_NONE;
915 :
916 : // ... restore redline mode
917 : // (First set bogus mode to make sure the mode in getIDocumentRedlineAccess().SetRedlineMode()
918 : // is different from it's previous mode.)
919 291 : rDoc.getIDocumentRedlineAccess().SetRedlineMode_intern((RedlineMode_t)( ~nRedlineMode ));
920 291 : rDoc.getIDocumentRedlineAccess().SetRedlineMode( (RedlineMode_t)( nRedlineMode ));
921 :
922 291 : lcl_EnsureValidPam( rPaM ); // move Pam into valid content
923 :
924 291 : if( pGraphicHelper )
925 291 : SvXMLGraphicHelper::Destroy( pGraphicHelper );
926 291 : xGraphicResolver = 0;
927 291 : if( pObjectHelper )
928 291 : SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper );
929 291 : xObjectResolver = 0;
930 291 : (void)rDoc.release();
931 :
932 291 : if ( !bOASIS )
933 : {
934 : // #i44177# - assure that for documents in OpenOffice.org
935 : // file format the relation between outline numbering rule and styles is
936 : // filled-up accordingly.
937 : // Note: The OpenOffice.org file format, which has no content that applys
938 : // a certain style, which is related to the outline numbering rule,
939 : // has lost the information, that this certain style is related to
940 : // the outline numbering rule.
941 : // #i70748# - only for templates
942 10 : if ( pMedium && pMedium->GetFilter() &&
943 3 : pMedium->GetFilter()->IsOwnTemplateFormat() )
944 : {
945 0 : lcl_AdjustOutlineStylesForOOo( rDoc );
946 : }
947 : // Fix #i58251#: Unfortunately is the static default different to SO7 behaviour,
948 : // so we have to set a dynamic default after importing SO7
949 7 : rDoc.SetDefault( SfxBoolItem( RES_ROW_SPLIT, false ) );
950 : }
951 :
952 291 : rDoc.PropagateOutlineRule();
953 :
954 : // #i62875#
955 291 : if ( rDoc.getIDocumentSettingAccess().get(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE) && !docfunc::ExistsDrawObjs( rDoc ) )
956 : {
957 3 : rDoc.getIDocumentSettingAccess().set(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE, false);
958 : }
959 :
960 : // Convert all instances of <SdrOle2Obj> into <SdrGrafObj>, because the
961 : // Writer doesn't support such objects.
962 291 : lcl_ConvertSdrOle2ObjsToSdrGrafObjs( rDoc );
963 :
964 : // set BuildId on XModel for later OLE object loading
965 291 : if( xInfoSet.is() )
966 : {
967 291 : uno::Reference< beans::XPropertySet > xModelSet( xModelComp, uno::UNO_QUERY );
968 291 : if( xModelSet.is() )
969 : {
970 291 : uno::Reference< beans::XPropertySetInfo > xModelSetInfo( xModelSet->getPropertySetInfo() );
971 582 : const OUString sName("BuildId" );
972 291 : if( xModelSetInfo.is() && xModelSetInfo->hasPropertyByName(sName) )
973 : {
974 291 : xModelSet->setPropertyValue( sName, xInfoSet->getPropertyValue(sName) );
975 291 : }
976 291 : }
977 : }
978 :
979 291 : if (xStatusIndicator.is())
980 : {
981 258 : xStatusIndicator->end();
982 : }
983 :
984 291 : rDoc.GetIStyleAccess().clearCaches(); // Clear Automatic-Style-Caches(shared_pointer!)
985 582 : return nRet;
986 : }
987 :
988 : // read the sections of the document, which is equal to the medium.
989 : // returns the count of it
990 0 : size_t XMLReader::GetSectionList( SfxMedium& rMedium,
991 : std::vector<OUString*>& rStrings ) const
992 : {
993 : uno::Reference< uno::XComponentContext > xContext =
994 0 : comphelper::getProcessComponentContext();
995 0 : uno::Reference < embed::XStorage > xStg2;
996 0 : if( ( xStg2 = rMedium.GetStorage() ).is() )
997 : {
998 : try
999 : {
1000 0 : xml::sax::InputSource aParserInput;
1001 0 : const OUString sDocName( "content.xml" );
1002 0 : aParserInput.sSystemId = sDocName;
1003 :
1004 0 : uno::Reference < io::XStream > xStm = xStg2->openStreamElement( sDocName, embed::ElementModes::READ );
1005 0 : aParserInput.aInputStream = xStm->getInputStream();
1006 :
1007 : // get filter
1008 0 : uno::Reference< xml::sax::XDocumentHandler > xFilter = new SwXMLSectionList( xContext, rStrings );
1009 :
1010 : // connect parser and filter
1011 0 : uno::Reference< xml::sax::XParser > xParser = xml::sax::Parser::create(xContext);
1012 0 : xParser->setDocumentHandler( xFilter );
1013 :
1014 : // parse
1015 0 : xParser->parseStream( aParserInput );
1016 : }
1017 0 : catch( xml::sax::SAXParseException& )
1018 : {
1019 : // re throw ?
1020 : }
1021 0 : catch( xml::sax::SAXException& )
1022 : {
1023 : // re throw ?
1024 : }
1025 0 : catch( io::IOException& )
1026 : {
1027 : // re throw ?
1028 : }
1029 0 : catch( packages::WrongPasswordException& )
1030 : {
1031 : // re throw ?
1032 : }
1033 : }
1034 0 : return rStrings.size();
1035 177 : }
1036 :
1037 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|