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