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 <sal/config.h>
21 #include <sal/log.hxx>
22
23 #include <cassert>
24
25 #include <com/sun/star/document/PrinterIndependentLayout.hpp>
26 #include <com/sun/star/drawing/XDrawPage.hpp>
27 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
28 #include <com/sun/star/text/XTextDocument.hpp>
29 #include <com/sun/star/text/XTextRange.hpp>
30
31 #include <o3tl/any.hxx>
32 #include <xmloff/xmlnamespace.hxx>
33 #include <xmloff/xmltkmap.hxx>
34 #include <xmloff/xmlictxt.hxx>
35 #include <xmloff/txtimp.hxx>
36 #include <xmloff/XMLTextShapeImportHelper.hxx>
37 #include <xmloff/XMLFontStylesContext.hxx>
38 #include <xmloff/ProgressBarHelper.hxx>
39 #include <doc.hxx>
40 #include <drawdoc.hxx>
41 #include <IDocumentSettingAccess.hxx>
42 #include <IDocumentDeviceAccess.hxx>
43 #include <IDocumentListsAccess.hxx>
44 #include <IDocumentStylePoolAccess.hxx>
45 #include <IDocumentDrawModelAccess.hxx>
46 #include <TextCursorHelper.hxx>
47 #include <unotext.hxx>
48 #include <unotextrange.hxx>
49 #include <poolfmt.hxx>
50 #include <ndtxt.hxx>
51 #include <editsh.hxx>
52 #include <strings.hrc>
53 #include <svl/stritem.hxx>
54 #include "xmlimp.hxx"
55 #include "xmlimpit.hxx"
56 #include "xmltexti.hxx"
57 #include <list.hxx>
58 #include <swdll.hxx>
59 #include <xmloff/DocumentSettingsContext.hxx>
60 #include <docsh.hxx>
61 #include <svx/xmlgrhlp.hxx>
62 #include <svx/xmleohlp.hxx>
63 #include <sfx2/printer.hxx>
64 #include <xmloff/xmluconv.hxx>
65 #include <unotools/saveopt.hxx>
66 #include <unotools/streamwrap.hxx>
67 #include <tools/UnitConversion.hxx>
68 #include <tools/diagnose_ex.h>
69
70 #include <vcl/svapp.hxx>
71 #include <unotxdoc.hxx>
72 #include <numrule.hxx>
73
74 #include <xmloff/xmlmetai.hxx>
75 #include <xmloff/xformsimport.hxx>
76 #include <comphelper/servicehelper.hxx>
77 #include <comphelper/processfactory.hxx>
78 #include <comphelper/propertysequence.hxx>
79
80 #include <unordered_set>
81
82 using namespace ::com::sun::star;
83 using namespace ::com::sun::star::uno;
84 using namespace ::com::sun::star::text;
85 using namespace ::com::sun::star::lang;
86 using namespace ::com::sun::star::beans;
87 using namespace ::com::sun::star::container;
88 using namespace ::com::sun::star::i18n;
89 using namespace ::com::sun::star::drawing;
90 using namespace ::com::sun::star::xforms;
91 using namespace ::xmloff::token;
92 using namespace ::std;
93
94 namespace {
95
96 class SwXMLBodyContext_Impl : public SvXMLImportContext
97 {
GetSwImport()98 SwXMLImport& GetSwImport() { return static_cast<SwXMLImport&>(GetImport()); }
99
100 public:
101
102 SwXMLBodyContext_Impl( SwXMLImport& rImport );
103
104 virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
105 sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
106 };
107
108 }
109
SwXMLBodyContext_Impl(SwXMLImport & rImport)110 SwXMLBodyContext_Impl::SwXMLBodyContext_Impl( SwXMLImport& rImport ) :
111 SvXMLImportContext( rImport )
112 {
113 // tdf#107211: if at this point we don't have a defined char style "Default"
114 // or "Default Style", add a mapping for it as it is not written
115 // into the file since it's not really a style but "no style"
116 // (hence referencing it actually makes no sense except for hyperlinks
117 // which default to something other than "Default")
118 OUString const sDefault(SwResId(STR_POOLCHR_STANDARD));
119 uno::Reference<container::XNameContainer> const& xStyles(
120 rImport.GetTextImport()->GetTextStyles());
121 if (!xStyles->hasByName("Default"))
122 { // this old name was used before LO 4.0
123 rImport.AddStyleDisplayName(XmlStyleFamily::TEXT_TEXT, "Default", sDefault);
124 }
125 if (!xStyles->hasByName("Default_20_Style"))
126 { // this new name contains a space which is converted to _20_ on export
127 rImport.AddStyleDisplayName(XmlStyleFamily::TEXT_TEXT, "Default_20_Style", sDefault);
128 }
129 bool isEncoded(false);
130 OUString const defaultEncoded(
131 rImport.GetMM100UnitConverter().encodeStyleName(sDefault, &isEncoded));
132 if (isEncoded && defaultEncoded != "Default_20_Style"
133 && !xStyles->hasByName(defaultEncoded))
134 { // new name may contain a space which is converted to _20_ on export
135 rImport.AddStyleDisplayName(XmlStyleFamily::TEXT_TEXT, defaultEncoded, sDefault);
136 }
137 }
138
createFastChildContext(sal_Int32,const css::uno::Reference<css::xml::sax::XFastAttributeList> &)139 css::uno::Reference< css::xml::sax::XFastContextHandler > SwXMLBodyContext_Impl::createFastChildContext(
140 sal_Int32 /*nElement*/,
141 const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/ )
142 {
143 return GetSwImport().CreateBodyContentContext();
144 }
145
146 namespace {
147
148 // #i69629#
149 // enhance class <SwXMLDocContext_Impl> in order to be able to create subclasses
150 // NB: virtually inherit so we can multiply inherit properly
151 // in SwXMLOfficeDocContext_Impl
152 class SwXMLDocContext_Impl : public virtual SvXMLImportContext
153 {
154 sal_Int32 mnElement;
155
156 protected: // #i69629#
GetSwImport()157 SwXMLImport& GetSwImport() { return static_cast<SwXMLImport&>(GetImport()); }
158
159 public:
160 SwXMLDocContext_Impl( SwXMLImport& rImport, sal_Int32 nElement );
161
162 virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
163 sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
164 };
165
166 }
167
SwXMLDocContext_Impl(SwXMLImport & rImport,sal_Int32 nElement)168 SwXMLDocContext_Impl::SwXMLDocContext_Impl( SwXMLImport& rImport, sal_Int32 nElement ) :
169 SvXMLImportContext( rImport ), mnElement(nElement)
170 {
171 }
172
createFastChildContext(sal_Int32 nElement,const uno::Reference<xml::sax::XFastAttributeList> &)173 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL SwXMLDocContext_Impl::createFastChildContext(
174 sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ )
175 {
176 switch (nElement)
177 {
178 case XML_ELEMENT(OFFICE, XML_SCRIPTS):
179 return GetSwImport().CreateScriptContext();
180 case XML_ELEMENT(OFFICE, XML_SETTINGS):
181 return new XMLDocumentSettingsContext( GetImport() );
182 case XML_ELEMENT(OFFICE, XML_STYLES):
183 GetSwImport().GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP );
184 return GetSwImport().CreateStylesContext( false );
185 case XML_ELEMENT(OFFICE, XML_AUTOMATIC_STYLES):
186 // don't use the autostyles from the styles-document for the progress
187 if ( mnElement != 0 && (mnElement & TOKEN_MASK) != XML_DOCUMENT_STYLES )
188 GetSwImport().GetProgressBarHelper()->Increment
189 ( PROGRESS_BAR_STEP );
190 return GetSwImport().CreateStylesContext( true );
191 case XML_ELEMENT(OFFICE, XML_MASTER_STYLES):
192 return GetSwImport().CreateMasterStylesContext();
193 case XML_ELEMENT(OFFICE, XML_FONT_FACE_DECLS):
194 return GetSwImport().CreateFontDeclsContext();
195 case XML_ELEMENT(OFFICE, XML_META):
196 OSL_FAIL(" XML_ELEMENT(OFFICE, XML_META): should not have come here, maybe document is invalid?");
197 break;
198 case XML_ELEMENT(OFFICE, XML_BODY):
199 GetSwImport().GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP );
200 return new SwXMLBodyContext_Impl( GetSwImport() );
201 case XML_ELEMENT(XFORMS, XML_MODEL):
202 return createXFormsModelContext(GetImport());
203 default:
204 XMLOFF_WARN_UNKNOWN_ELEMENT("sw", nElement);
205 }
206 return nullptr;
207 }
208
209 namespace {
210
211 // #i69629# - new subclass <SwXMLOfficeDocContext_Impl> of class <SwXMLDocContext_Impl>
212 class SwXMLOfficeDocContext_Impl :
213 public SwXMLDocContext_Impl, public SvXMLMetaDocumentContext
214 {
215 public:
216
217 SwXMLOfficeDocContext_Impl( SwXMLImport& rImport, sal_Int32 nElement,
218 const Reference< document::XDocumentProperties >& xDocProps);
219
220 virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
221 sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& Attribs ) override;
222 };
223
224 }
225
SwXMLOfficeDocContext_Impl(SwXMLImport & rImport,sal_Int32 nElement,const Reference<document::XDocumentProperties> & xDocProps)226 SwXMLOfficeDocContext_Impl::SwXMLOfficeDocContext_Impl(
227 SwXMLImport& rImport,
228 sal_Int32 nElement,
229 const Reference< document::XDocumentProperties >& xDocProps) :
230 SvXMLImportContext( rImport ),
231 SwXMLDocContext_Impl( rImport, nElement ),
232 SvXMLMetaDocumentContext( rImport, xDocProps )
233 {
234 }
235
createFastChildContext(sal_Int32 nElement,const uno::Reference<xml::sax::XFastAttributeList> & xAttrList)236 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL SwXMLOfficeDocContext_Impl::createFastChildContext(
237 sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
238 {
239 // assign paragraph styles to list levels of outline style after all styles
240 // are imported and finished. This is the case, when <office:body> starts
241 // in flat OpenDocument file format.
242 {
243 if( nElement == XML_ELEMENT( OFFICE, XML_BODY ) )
244 {
245 GetImport().GetTextImport()->SetOutlineStyles( true );
246 }
247 }
248
249 // behave like meta base class iff we encounter office:meta
250 if ( nElement == XML_ELEMENT( OFFICE, XML_META ) ) {
251 return SvXMLMetaDocumentContext::createFastChildContext(
252 nElement, xAttrList );
253 } else {
254 return SwXMLDocContext_Impl::createFastChildContext(
255 nElement, xAttrList );
256 }
257 }
258
259 namespace {
260
261 // #i69629# - new subclass <SwXMLDocStylesContext_Impl> of class <SwXMLDocContext_Impl>
262 class SwXMLDocStylesContext_Impl : public SwXMLDocContext_Impl
263 {
264 public:
265
266 SwXMLDocStylesContext_Impl( SwXMLImport& rImport, sal_Int32 nElement );
267
268 virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
269 };
270
271 }
272
SwXMLDocStylesContext_Impl(SwXMLImport & rImport,sal_Int32 nElement)273 SwXMLDocStylesContext_Impl::SwXMLDocStylesContext_Impl( SwXMLImport& rImport, sal_Int32 nElement ) :
274 SvXMLImportContext( rImport ),
275 SwXMLDocContext_Impl( rImport, nElement )
276 {
277 }
278
endFastElement(sal_Int32)279 void SwXMLDocStylesContext_Impl::endFastElement(sal_Int32 )
280 {
281 // assign paragraph styles to list levels of outline style after all styles
282 // are imported and finished.
283 SwXMLImport& rSwImport = dynamic_cast<SwXMLImport&>( GetImport());
284 GetImport().GetTextImport()->SetOutlineStyles(
285 bool(rSwImport.GetStyleFamilyMask() & SfxStyleFamily::Para));
286 }
287
CreateFastContext(sal_Int32 nElement,const uno::Reference<xml::sax::XFastAttributeList> &)288 SvXMLImportContext *SwXMLImport::CreateFastContext( sal_Int32 nElement,
289 const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ )
290 {
291 SvXMLImportContext *pContext = nullptr;
292
293 switch (nElement)
294 {
295 case XML_ELEMENT( OFFICE, XML_DOCUMENT_META ):
296 pContext = CreateMetaContext(nElement);
297 break;
298 case XML_ELEMENT( OFFICE, XML_DOCUMENT ):
299 {
300 uno::Reference<document::XDocumentProperties> const xDocProps(
301 GetDocumentProperties());
302 // flat OpenDocument file format
303 pContext = new SwXMLOfficeDocContext_Impl( *this, nElement, xDocProps );
304 }
305 break;
306 // #i69629# - own subclasses for <office:document> and <office:document-styles>
307 case XML_ELEMENT(OFFICE, XML_DOCUMENT_SETTINGS):
308 case XML_ELEMENT(OFFICE, XML_DOCUMENT_CONTENT):
309 pContext = new SwXMLDocContext_Impl( *this, nElement );
310 break;
311 case XML_ELEMENT(OFFICE, XML_DOCUMENT_STYLES):
312 pContext = new SwXMLDocStylesContext_Impl( *this, nElement );
313 break;
314 }
315 return pContext;
316 }
317
SwXMLImport(const uno::Reference<uno::XComponentContext> & rContext,OUString const & implementationName,SvXMLImportFlags nImportFlags)318 SwXMLImport::SwXMLImport(
319 const uno::Reference< uno::XComponentContext >& rContext,
320 OUString const & implementationName, SvXMLImportFlags nImportFlags)
321 : SvXMLImport( rContext, implementationName, nImportFlags ),
322 m_nStyleFamilyMask( SfxStyleFamily::All ),
323 m_bLoadDoc( true ),
324 m_bInsert( false ),
325 m_bBlock( false ),
326 m_bOrganizerMode( false ),
327 m_bInititedXForms( false ),
328 m_pDoc( nullptr )
329 {
330 InitItemImport();
331 }
332
~SwXMLImport()333 SwXMLImport::~SwXMLImport() noexcept
334 {
335 if (HasShapeImport())
336 {
337 SAL_WARN("sw", "endDocument skipped, dropping shapes now to avoid dangling SvTextShapeImportHelper pointing to this");
338 ClearShapeImport();
339 }
340 FinitItemImport();
341 }
342
setTextInsertMode(const Reference<XTextRange> & rInsertPos)343 void SwXMLImport::setTextInsertMode(
344 const Reference< XTextRange > & rInsertPos )
345 {
346 m_bInsert = true;
347
348 Reference < XText > xText = rInsertPos->getText();
349 Reference < XTextCursor > xTextCursor =
350 xText->createTextCursorByRange( rInsertPos );
351 GetTextImport()->SetCursor( xTextCursor );
352 }
353
setStyleInsertMode(SfxStyleFamily nFamilies,bool bOverwrite)354 void SwXMLImport::setStyleInsertMode( SfxStyleFamily nFamilies,
355 bool bOverwrite )
356 {
357 m_bInsert = !bOverwrite;
358 m_nStyleFamilyMask = nFamilies;
359 m_bLoadDoc = false;
360 }
361
getUnoTunnelId()362 const Sequence< sal_Int8 > & SwXMLImport::getUnoTunnelId() noexcept
363 {
364 static const UnoTunnelIdInit theSwXMLImportUnoTunnelId;
365 return theSwXMLImportUnoTunnelId.getSeq();
366 }
367
getSomething(const Sequence<sal_Int8> & rId)368 sal_Int64 SAL_CALL SwXMLImport::getSomething( const Sequence< sal_Int8 >& rId )
369 {
370 if( isUnoTunnelId<SwXMLImport>(rId) )
371 {
372 return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >(this) );
373 }
374 return SvXMLImport::getSomething( rId );
375 }
376
lcl_xml_GetSwXTextCursor(const Reference<XTextCursor> & rTextCursor)377 static OTextCursorHelper *lcl_xml_GetSwXTextCursor( const Reference < XTextCursor >& rTextCursor )
378 {
379 Reference<XUnoTunnel> xCursorTunnel( rTextCursor, UNO_QUERY );
380 OSL_ENSURE( xCursorTunnel.is(), "missing XUnoTunnel for Cursor" );
381 if( !xCursorTunnel.is() )
382 return nullptr;
383 OTextCursorHelper *pTextCursor = reinterpret_cast< OTextCursorHelper *>(
384 sal::static_int_cast< sal_IntPtr >( xCursorTunnel->getSomething( OTextCursorHelper::getUnoTunnelId() )));
385 OSL_ENSURE( pTextCursor, "SwXTextCursor missing" );
386 return pTextCursor;
387 }
388
startDocument()389 void SwXMLImport::startDocument()
390 {
391 // delegate to parent
392 SvXMLImport::startDocument();
393
394 OSL_ENSURE( GetModel().is(), "model is missing" );
395 if( !GetModel().is() )
396 return;
397
398 // this method will modify the document directly -> lock SolarMutex
399 SolarMutexGuard aGuard;
400
401 Reference< XPropertySet > xImportInfo( getImportInfo() );
402 Reference< XPropertySetInfo > xPropertySetInfo;
403 if( xImportInfo.is() )
404 xPropertySetInfo = xImportInfo->getPropertySetInfo();
405 if( xPropertySetInfo.is() )
406 {
407 Any aAny;
408 // insert style mode?
409 OUString sStyleInsertModeFamilies("StyleInsertModeFamilies");
410 if( xPropertySetInfo->hasPropertyByName(sStyleInsertModeFamilies) )
411 {
412 aAny = xImportInfo->getPropertyValue(sStyleInsertModeFamilies);
413 Sequence< OUString> aFamiliesSeq;
414 if( aAny >>= aFamiliesSeq )
415 {
416 SfxStyleFamily nFamilyMask = SfxStyleFamily::None;
417 for( const OUString& rFamily : std::as_const(aFamiliesSeq) )
418 {
419 if( rFamily=="FrameStyles" )
420 nFamilyMask |= SfxStyleFamily::Frame;
421 else if( rFamily=="PageStyles" )
422 nFamilyMask |= SfxStyleFamily::Page;
423 else if( rFamily=="CharacterStyles" )
424 nFamilyMask |= SfxStyleFamily::Char;
425 else if( rFamily=="ParagraphStyles" )
426 nFamilyMask |= SfxStyleFamily::Para;
427 else if( rFamily=="NumberingStyles" )
428 nFamilyMask |= SfxStyleFamily::Pseudo;
429 }
430
431 bool bOverwrite = false;
432 static const OUStringLiteral sStyleInsertModeOverwrite(u"StyleInsertModeOverwrite");
433 if( xPropertySetInfo->hasPropertyByName(sStyleInsertModeOverwrite) )
434 {
435 aAny = xImportInfo->getPropertyValue(sStyleInsertModeOverwrite);
436 if( auto b = o3tl::tryAccess<bool>(aAny) )
437 {
438 if( *b )
439 bOverwrite = true;
440 }
441 }
442
443 setStyleInsertMode( nFamilyMask, bOverwrite );
444 }
445 }
446
447 // text insert mode?
448 static const OUStringLiteral sTextInsertModeRange(u"TextInsertModeRange");
449 if( xPropertySetInfo->hasPropertyByName(sTextInsertModeRange) )
450 {
451 aAny = xImportInfo->getPropertyValue(sTextInsertModeRange);
452 Reference<XTextRange> xInsertTextRange;
453 if( aAny >>= xInsertTextRange )
454 setTextInsertMode( xInsertTextRange );
455 }
456
457 // auto text mode
458 static const OUStringLiteral sAutoTextMode(u"AutoTextMode");
459 if( xPropertySetInfo->hasPropertyByName(sAutoTextMode) )
460 {
461 aAny = xImportInfo->getPropertyValue(sAutoTextMode);
462 if( auto b = o3tl::tryAccess<bool>(aAny) )
463 {
464 if( *b )
465 m_bBlock = true;
466 }
467 }
468
469 // organizer mode
470 static const OUStringLiteral sOrganizerMode(u"OrganizerMode");
471 if( xPropertySetInfo->hasPropertyByName(sOrganizerMode) )
472 {
473 aAny = xImportInfo->getPropertyValue(sOrganizerMode);
474 if( auto b = o3tl::tryAccess<bool>(aAny) )
475 {
476 if( *b )
477 m_bOrganizerMode = true;
478 }
479 }
480
481 // default document properties
482 static const OUStringLiteral sDefSettings(u"DefaultDocumentSettings");
483 if (xPropertySetInfo->hasPropertyByName(sDefSettings))
484 {
485 aAny = xImportInfo->getPropertyValue(sDefSettings);
486 Sequence<PropertyValue> aProps;
487 if (aAny >>= aProps)
488 {
489 Reference<lang::XMultiServiceFactory> xFac(GetModel(), UNO_QUERY);
490 Reference<XPropertySet> xProps(
491 xFac->createInstance("com.sun.star.document.Settings"), UNO_QUERY);
492 Reference<XPropertySetInfo> xInfo(xProps->getPropertySetInfo());
493
494 if (xProps.is() && xInfo.is())
495 {
496 for (const auto& rProp : std::as_const(aProps))
497 {
498 if (xInfo->hasPropertyByName(rProp.Name))
499 {
500 xProps->setPropertyValue(rProp.Name, rProp.Value);
501 }
502 }
503 }
504 }
505 }
506 }
507
508 // There only is a text cursor by now if we are in insert mode. In any
509 // other case we have to create one at the start of the document.
510 // We also might change into the insert mode later, so we have to make
511 // sure to first set the insert mode and then create the text import
512 // helper. Otherwise it won't have the insert flag set!
513 OTextCursorHelper *pTextCursor = nullptr;
514 Reference < XTextCursor > xTextCursor;
515 if( HasTextImport() )
516 xTextCursor = GetTextImport()->GetCursor();
517 if( !xTextCursor.is() )
518 {
519 Reference < XTextDocument > xTextDoc( GetModel(), UNO_QUERY );
520 Reference < XText > xText = xTextDoc->getText();
521 xTextCursor = xText->createTextCursor();
522 SwCursorShell *pCursorSh = nullptr;
523 SwDoc *pDoc = nullptr;
524 if( SvXMLImportFlags::ALL == getImportFlags() )
525 {
526 pTextCursor = lcl_xml_GetSwXTextCursor( xTextCursor );
527 OSL_ENSURE( pTextCursor, "SwXTextCursor missing" );
528 if( !pTextCursor )
529 return;
530
531 pDoc = pTextCursor->GetDoc();
532 OSL_ENSURE( pDoc, "SwDoc missing" );
533 if( !pDoc )
534 return;
535
536 // Is there an edit shell. If yes, then we are currently inserting
537 // a document. We then have to insert at the current edit shell's
538 // cursor position. That not quite clean code, but there is no other
539 // way currently.
540 pCursorSh = pDoc->GetEditShell();
541 }
542 if( pCursorSh )
543 {
544 const uno::Reference<text::XTextRange> xInsertTextRange(
545 SwXTextRange::CreateXTextRange(
546 *pDoc, *pCursorSh->GetCursor()->GetPoint(), nullptr ) );
547 setTextInsertMode( xInsertTextRange );
548 xTextCursor = GetTextImport()->GetCursor();
549 pTextCursor = nullptr;
550 }
551 else
552 GetTextImport()->SetCursor( xTextCursor );
553 }
554
555 if( !(getImportFlags() & (SvXMLImportFlags::CONTENT|SvXMLImportFlags::MASTERSTYLES)) )
556 return;
557
558 if( !pTextCursor )
559 pTextCursor = lcl_xml_GetSwXTextCursor( xTextCursor );
560 OSL_ENSURE( pTextCursor, "SwXTextCursor missing" );
561 if( !pTextCursor )
562 return;
563
564 SwDoc *pDoc = pTextCursor->GetDoc();
565 OSL_ENSURE( pDoc, "SwDoc missing" );
566 if( !pDoc )
567 return;
568
569 if (SvXMLImportFlags::ALL == getImportFlags())
570 {
571 // for flat ODF - this is done in SwReader::Read() for package ODF
572 pDoc->SetInReading(true);
573 pDoc->SetInXMLImport(true);
574 }
575
576 if( (getImportFlags() & SvXMLImportFlags::CONTENT) && !IsStylesOnlyMode() )
577 {
578 m_pSttNdIdx.reset(new SwNodeIndex( pDoc->GetNodes() ));
579 if( IsInsertMode() )
580 {
581 SwPaM *pPaM = pTextCursor->GetPaM();
582 const SwPosition* pPos = pPaM->GetPoint();
583
584 // Split once and remember the node that has been split.
585 pDoc->getIDocumentContentOperations().SplitNode( *pPos, false );
586 *m_pSttNdIdx = pPos->nNode.GetIndex()-1;
587
588 // Split again.
589 pDoc->getIDocumentContentOperations().SplitNode( *pPos, false );
590
591 // Insert all content into the new node
592 pPaM->Move( fnMoveBackward );
593 pDoc->SetTextFormatColl
594 ( *pPaM, pDoc->getIDocumentStylePoolAccess().GetTextCollFromPool(RES_POOLCOLL_STANDARD, false ) );
595 }
596 }
597
598 // We need a draw model to be able to set the z order
599 pDoc->getIDocumentDrawModelAccess().GetOrCreateDrawModel(); // #i52858# - method name changed
600
601 // SJ: #i49801# locking the model to disable repaints
602 SwDrawModel* pDrawModel = pDoc->getIDocumentDrawModelAccess().GetDrawModel();
603 if ( pDrawModel )
604 pDrawModel->setLock(true);
605
606 if (!GetGraphicStorageHandler().is())
607 {
608 m_xGraphicStorageHandler = SvXMLGraphicHelper::Create(SvXMLGraphicHelperMode::Read);
609 SetGraphicStorageHandler(m_xGraphicStorageHandler);
610 }
611
612 if( !GetEmbeddedResolver().is() )
613 {
614 SfxObjectShell *pPersist = pDoc->GetPersist();
615 if( pPersist )
616 {
617 m_xEmbeddedResolver = SvXMLEmbeddedObjectHelper::Create(
618 *pPersist,
619 SvXMLEmbeddedObjectHelperMode::Read );
620 SetEmbeddedResolver( m_xEmbeddedResolver );
621 }
622 }
623 }
624
endDocument()625 void SwXMLImport::endDocument()
626 {
627 OSL_ENSURE( GetModel().is(), "model missing; maybe startDocument wasn't called?" );
628 if( !GetModel().is() )
629 return;
630
631 // this method will modify the document directly -> lock SolarMutex
632 SolarMutexGuard aGuard;
633
634 if (m_xGraphicStorageHandler)
635 m_xGraphicStorageHandler->dispose();
636 m_xGraphicStorageHandler.clear();
637
638 if( m_xEmbeddedResolver )
639 m_xEmbeddedResolver->dispose();
640 m_xEmbeddedResolver.clear();
641 // Clear the shape import to sort the shapes (and not in the
642 // destructor that might be called after the import has finished
643 // for Java filters.
644 if( HasShapeImport() )
645 ClearShapeImport();
646
647 SwDoc *pDoc = nullptr;
648 if( (getImportFlags() & SvXMLImportFlags::CONTENT) && !IsStylesOnlyMode() )
649 {
650 Reference<XUnoTunnel> xCursorTunnel( GetTextImport()->GetCursor(),
651 UNO_QUERY);
652 assert(xCursorTunnel.is() && "missing XUnoTunnel for Cursor");
653 OTextCursorHelper *pTextCursor = reinterpret_cast< OTextCursorHelper *>(
654 sal::static_int_cast< sal_IntPtr >( xCursorTunnel->getSomething( OTextCursorHelper::getUnoTunnelId() )));
655 assert(pTextCursor && "SwXTextCursor missing");
656 SwPaM *pPaM = pTextCursor->GetPaM();
657 if( IsInsertMode() && m_pSttNdIdx->GetIndex() )
658 {
659 // If we are in insert mode, join the split node that is in front
660 // of the new content with the first new node. Or in other words:
661 // Revert the first split node.
662 SwTextNode* pTextNode = m_pSttNdIdx->GetNode().GetTextNode();
663 SwNodeIndex aNxtIdx( *m_pSttNdIdx );
664 if( pTextNode && pTextNode->CanJoinNext( &aNxtIdx ) &&
665 m_pSttNdIdx->GetIndex() + 1 == aNxtIdx.GetIndex() )
666 {
667 // If the PaM points to the first new node, move the PaM to the
668 // end of the previous node.
669 if( pPaM->GetPoint()->nNode == aNxtIdx )
670 {
671 pPaM->GetPoint()->nNode = *m_pSttNdIdx;
672 pPaM->GetPoint()->nContent.Assign( pTextNode,
673 pTextNode->GetText().getLength());
674 }
675
676 #if OSL_DEBUG_LEVEL > 0
677 // !!! This should be impossible !!!!
678 OSL_ENSURE( m_pSttNdIdx->GetIndex()+1 !=
679 pPaM->GetBound().nNode.GetIndex(),
680 "PaM.Bound1 point to new node " );
681 OSL_ENSURE( m_pSttNdIdx->GetIndex()+1 !=
682 pPaM->GetBound( false ).nNode.GetIndex(),
683 "PaM.Bound2 points to new node" );
684
685 if( m_pSttNdIdx->GetIndex()+1 ==
686 pPaM->GetBound().nNode.GetIndex() )
687 {
688 const sal_Int32 nCntPos =
689 pPaM->GetBound().nContent.GetIndex();
690 pPaM->GetBound().nContent.Assign( pTextNode,
691 pTextNode->GetText().getLength() + nCntPos );
692 }
693 if( m_pSttNdIdx->GetIndex()+1 ==
694 pPaM->GetBound( false ).nNode.GetIndex() )
695 {
696 const sal_Int32 nCntPos =
697 pPaM->GetBound( false ).nContent.GetIndex();
698 pPaM->GetBound( false ).nContent.Assign( pTextNode,
699 pTextNode->GetText().getLength() + nCntPos );
700 }
701 #endif
702 // If the first new node isn't empty, convert the node's text
703 // attributes into hints. Otherwise, set the new node's
704 // paragraph style at the previous (empty) node.
705 SwTextNode* pDelNd = aNxtIdx.GetNode().GetTextNode();
706 if (!pTextNode->GetText().isEmpty())
707 pDelNd->FormatToTextAttr( pTextNode );
708 else
709 {
710 pTextNode->ResetAttr(RES_CHRATR_BEGIN, RES_CHRATR_END);
711 pTextNode->ChgFormatColl( pDelNd->GetTextColl() );
712 if (!pDelNd->GetNoCondAttr(RES_PARATR_LIST_ID, /*bInParents=*/false))
713 {
714 // MergeListsAtDocumentInsertPosition() will deal with lists below, copy
715 // paragraph direct formatting otherwise.
716 pDelNd->CopyCollFormat(*pTextNode);
717 }
718 }
719 pTextNode->JoinNext();
720 }
721 }
722
723 SwPosition* pPos = pPaM->GetPoint();
724 OSL_ENSURE( !pPos->nContent.GetIndex(), "last paragraph isn't empty" );
725 if( !pPos->nContent.GetIndex() )
726 {
727 SwTextNode* pCurrNd;
728 sal_uLong nNodeIdx = pPos->nNode.GetIndex();
729 pDoc = &pPaM->GetDoc();
730
731 OSL_ENSURE( pPos->nNode.GetNode().IsContentNode(),
732 "insert position is not a content node" );
733 if( !IsInsertMode() )
734 {
735 // If we're not in insert mode, the last node is deleted.
736 const SwNode *pPrev = pDoc->GetNodes()[nNodeIdx -1];
737 if( pPrev->IsContentNode() ||
738 ( pPrev->IsEndNode() &&
739 pPrev->StartOfSectionNode()->IsSectionNode() ) )
740 {
741 SwContentNode* pCNd = pPaM->GetContentNode();
742 if( pCNd && pCNd->StartOfSectionIndex()+2 <
743 pCNd->EndOfSectionIndex() )
744 {
745 pPaM->GetBound().nContent.Assign( nullptr, 0 );
746 pPaM->GetBound(false).nContent.Assign( nullptr, 0 );
747 pDoc->GetNodes().Delete( pPaM->GetPoint()->nNode );
748 }
749 }
750 }
751 else if( nullptr != (pCurrNd = pDoc->GetNodes()[nNodeIdx]->GetTextNode()) )
752 {
753 // Id we're in insert mode, the empty node is joined with
754 // the next and the previous one.
755 if( pCurrNd->CanJoinNext( &pPos->nNode ))
756 {
757 SwTextNode* pNextNd = pPos->nNode.GetNode().GetTextNode();
758 bool endNodeFound = pDoc->GetNodes()[nNodeIdx-1]->IsEndNode();
759 SwNode *pLastPar = pDoc->GetNodes()[nNodeIdx -2];
760 if ( !pLastPar->IsTextNode() ) {
761 pLastPar = pDoc->GetNodes()[nNodeIdx -1];
762 }
763 if ( !endNodeFound && pLastPar->IsTextNode() )
764 {
765 pNextNd->ChgFormatColl(pLastPar->GetTextNode()->GetTextColl());
766 }
767
768 pPos->nContent.Assign( pNextNd, 0 );
769 pPaM->SetMark(); pPaM->DeleteMark();
770 pNextNd->JoinPrev();
771
772 // Remove line break that has been inserted by the import,
773 // but only if one has been inserted and
774 // no endNode found to avoid removing section
775 if( pNextNd->CanJoinPrev(/* &pPos->nNode*/ ) && !endNodeFound &&
776 *m_pSttNdIdx != pPos->nNode )
777 {
778 pNextNd->JoinPrev();
779 }
780 }
781 else if (pCurrNd->GetText().isEmpty())
782 {
783 pPos->nContent.Assign( nullptr, 0 );
784 pPaM->SetMark(); pPaM->DeleteMark();
785 pDoc->GetNodes().Delete( pPos->nNode );
786 pPaM->Move( fnMoveBackward );
787 }
788 }
789
790 // tdf#113877
791 // when we insert one document with list inside into another one with list at the insert position,
792 // the resulting numbering in these lists is not consequent.
793 //
794 // Main document:
795 // 1. One
796 // 2. Two
797 // 3. Three
798 // 4. <-- insert position
799 //
800 // Inserted document:
801 // 1. One
802 // 2. Two
803 // 3. Three
804 // 4.
805 //
806 // Expected result
807 // 1. One
808 // 2. Two
809 // 3. Three
810 // 4. One
811 // 5. Two
812 // 6. Three
813 // 7.
814 //
815 MergeListsAtDocumentInsertPosition(pDoc);
816 }
817 }
818
819 /* Was called too early. Moved from SwXMLBodyContext_Impl::EndElement */
820
821 GetTextImport()->RedlineAdjustStartNodeCursor();
822
823 if( (getImportFlags() & SvXMLImportFlags::CONTENT) ||
824 ((getImportFlags() & SvXMLImportFlags::MASTERSTYLES) && IsStylesOnlyMode()) )
825 {
826 // pDoc might be 0. In this case UpdateTextCollCondition is looking
827 // for it itself.
828 UpdateTextCollConditions( pDoc );
829 }
830
831 GetTextImport()->ResetCursor();
832
833 m_pSttNdIdx.reset();
834
835 // SJ: #i49801# -> now permitting repaints
836 if ( pDoc )
837 {
838 if( getImportFlags() == SvXMLImportFlags::ALL )
839 {
840 // Notify math objects. If we are in the package filter this will
841 // be done by the filter object itself
842 if( IsInsertMode() )
843 pDoc->PrtOLENotify( false );
844 else if ( pDoc->IsOLEPrtNotifyPending() )
845 pDoc->PrtOLENotify( true );
846
847 assert(pDoc->IsInReading());
848 assert(pDoc->IsInXMLImport());
849 pDoc->SetInReading(false);
850 pDoc->SetInXMLImport(false);
851 }
852
853 SwDrawModel* pDrawModel = pDoc->getIDocumentDrawModelAccess().GetDrawModel();
854 if ( pDrawModel )
855 pDrawModel->setLock(false);
856 }
857
858 // #i90243#
859 if ( m_bInititedXForms )
860 {
861 Reference< xforms::XFormsSupplier > xFormsSupp( GetModel(), UNO_QUERY );
862 Reference< XNameAccess > xXForms;
863 if ( xFormsSupp.is() )
864 xXForms = xFormsSupp->getXForms().get();
865
866 if ( xXForms.is() )
867 {
868 try
869 {
870 Sequence< beans::PropertyValue > aXFormsSettings;
871
872 const OUString& sXFormsSettingsName( GetXMLToken( XML_XFORM_MODEL_SETTINGS ) );
873 if ( m_xLateInitSettings.is() && m_xLateInitSettings->hasByName( sXFormsSettingsName ) )
874 {
875 OSL_VERIFY( m_xLateInitSettings->getByName( sXFormsSettingsName ) >>= aXFormsSettings );
876 applyXFormsSettings( xXForms, aXFormsSettings );
877 }
878 }
879 catch( const Exception& )
880 {
881 }
882 }
883 }
884
885 #if 1
886 if (!pDoc) { pDoc = SwImport::GetDocFromXMLImport(*this); }
887 for (sal_uLong i = 0; i < pDoc->GetNodes().Count(); ++i)
888 {
889 if (SwTableNode *const pTableNode = pDoc->GetNodes()[i]->GetTableNode())
890 {
891 if (!pTableNode->GetTable().IsNewModel()
892 && pTableNode->GetTable().CanConvertSubtables())
893 {
894 pTableNode->GetTable().ConvertSubtables();
895 }
896 }
897 // don't skip to the end; nested tables could have subtables too...
898 }
899 #endif
900
901 // delegate to parent: takes care of error handling
902 SvXMLImport::endDocument();
903 ClearTextImport();
904 }
905
906 // tdf#113877
907 // when we insert one document with list inside into another one with list at the insert position,
908 // the resulting numbering in these lists is not consequent.
909 //
910 // CASE-1: Main document:
911 // 1. One
912 // 2. Two
913 // 3. Three
914 // 4. <-- insert position
915 //
916 // Inserted document:
917 // 1. One
918 // 2. Two
919 // 3. Three
920 // 4.
921 //
922 // Expected result
923 // 1. One
924 // 2. Two
925 // 3. Three
926 // 4. One
927 // 5. Two
928 // 6. Three
929 // 7.
930 //
931 // CASE-2: Main document:
932 // 1. One
933 // 2. Two
934 // 3. Three
935 // 4. <-- insert position
936 //
937 // Inserted document:
938 // A) One
939 // B) Two
940 // C) Three
941 // D)
942 //
943 // Expected result
944 // 1. One
945 // 2. Two
946 // 3. Three
947 // 4. One
948 // A) Two
949 // B) Three
950 // 5.
951 //
MergeListsAtDocumentInsertPosition(SwDoc * pDoc)952 void SwXMLImport::MergeListsAtDocumentInsertPosition(SwDoc *pDoc)
953 {
954 // 1. check environment
955 if (! pDoc)
956 return;
957
958 if (! IsInsertMode() || ! m_pSttNdIdx->GetIndex())
959 return;
960
961 sal_uLong index = 1;
962
963 // the last node of the main document where we have inserted a document
964 const SwNodePtr node1 = pDoc->GetNodes()[m_pSttNdIdx->GetIndex() + 0];
965
966 // the first node of the inserted document
967 SwNodePtr node2 = pDoc->GetNodes()[m_pSttNdIdx->GetIndex() + index];
968
969 if (! (node1 && node2
970 && (node1->GetNodeType() == node2->GetNodeType())
971 && (node1->IsTextNode() == node2->IsTextNode())
972 ))
973 {
974 // not a text node at insert position
975 return;
976 }
977
978 // 2. get the first node of the inserted document,
979 // which will be used to detect if inside inserted document a new list was started after the first list
980 const SfxPoolItem* pListId2Initial = nullptr;
981 {
982 SwContentNode* contentNode1 = static_cast<SwContentNode *>(node1);
983 SwContentNode* contentNode2 = static_cast<SwContentNode *>(node2);
984
985 // check if both lists have the same list properties
986 const SfxPoolItem* pListId1 = contentNode1->GetNoCondAttr( RES_PARATR_LIST_ID, false );
987 const SfxPoolItem* pListId2 = contentNode2->GetNoCondAttr( RES_PARATR_LIST_ID, false );
988
989 if (! pListId1)
990 return;
991 if (! pListId2)
992 return;
993
994 auto pStringListId1 = dynamic_cast<const SfxStringItem*>(pListId1);
995 assert(pStringListId1);
996 const OUString& sListId1 = pStringListId1->GetValue();
997 auto pStringListId2 = dynamic_cast<const SfxStringItem*>(pListId2);
998 assert(pStringListId2);
999 const OUString& sListId2 = pStringListId2->GetValue();
1000
1001 const SwList* pList1 = pDoc->getIDocumentListsAccess().getListByName( sListId1 );
1002 const SwList* pList2 = pDoc->getIDocumentListsAccess().getListByName( sListId2 );
1003
1004 if (! pList1)
1005 return;
1006 if (! pList2)
1007 return;
1008
1009 const OUString& sDefaultListStyleName1 = pList1->GetDefaultListStyleName();
1010 const OUString& sDefaultListStyleName2 = pList2->GetDefaultListStyleName();
1011
1012 if (sDefaultListStyleName1 != sDefaultListStyleName2)
1013 {
1014 const SwNumRule* pNumRule1 = pDoc->FindNumRulePtr( sDefaultListStyleName1 );
1015 const SwNumRule* pNumRule2 = pDoc->FindNumRulePtr( sDefaultListStyleName2 );
1016
1017 if (pNumRule1 && pNumRule2)
1018 {
1019 // check style of the each list level
1020 for( sal_uInt8 n = 0; n < MAXLEVEL; ++n )
1021 {
1022 if( pNumRule1->Get( n ) != pNumRule2->Get( n ) )
1023 {
1024 return;
1025 }
1026 }
1027
1028 // our list should be merged
1029 pListId2Initial = pListId2;
1030 }
1031 }
1032 else
1033 {
1034 // our list should be merged
1035 pListId2Initial = pListId2;
1036 }
1037 }
1038
1039 if (! pListId2Initial)
1040 {
1041 // two lists have different styles => they should not be merged
1042 return;
1043 }
1044
1045 // 3. merge two lists
1046 while (
1047 node1 && node2
1048 && (node1->GetNodeType() == node2->GetNodeType())
1049 && (node1->IsTextNode() == node2->IsTextNode())
1050 )
1051 {
1052 SwContentNode* contentNode1 = static_cast<SwContentNode *>( node1 );
1053 SwContentNode* contentNode2 = static_cast<SwContentNode *>( node2 );
1054
1055 const SfxPoolItem* pListId1 = contentNode1->GetNoCondAttr( RES_PARATR_LIST_ID, false );
1056 const SfxPoolItem* pListId2 = contentNode2->GetNoCondAttr( RES_PARATR_LIST_ID, false );
1057
1058 if (! pListId1)
1059 return;
1060 if (! pListId2)
1061 return;
1062
1063 if (*pListId2Initial != *pListId2)
1064 {
1065 // no more list items of the first list inside inserted document
1066 return;
1067 }
1068
1069 // set list style to this list element
1070 contentNode2->SetAttr(*pListId1);
1071
1072 // get next item
1073 index++;
1074 if (index >= pDoc->GetNodes().Count())
1075 {
1076 // no more items
1077 return;
1078 }
1079
1080 node2 = pDoc->GetNodes()[m_pSttNdIdx->GetIndex() + index];
1081 }
1082 }
1083
1084 namespace {
1085
1086 // Locally derive XMLTextShapeImportHelper, so we can take care of the
1087 // form import This is Writer, but not text specific, so it should go
1088 // here!
1089 class SvTextShapeImportHelper : public XMLTextShapeImportHelper
1090 {
1091 // hold own reference form import helper, because the SvxImport
1092 // stored in the superclass, from whom we originally got the
1093 // reference, is already destroyed when we want to use it in the
1094 // destructor
1095 rtl::Reference< ::xmloff::OFormLayerXMLImport > rFormImport;
1096
1097 // hold reference to the one page (if it exists) for calling startPage()
1098 // and endPage. If !xPage.is(), then this document doesn't have a
1099 // XDrawPage.
1100 Reference<drawing::XDrawPage> xPage;
1101
1102 public:
1103 explicit SvTextShapeImportHelper(SvXMLImport& rImp);
1104 virtual ~SvTextShapeImportHelper() override;
1105 };
1106
1107 }
1108
SvTextShapeImportHelper(SvXMLImport & rImp)1109 SvTextShapeImportHelper::SvTextShapeImportHelper(SvXMLImport& rImp) :
1110 XMLTextShapeImportHelper(rImp)
1111 {
1112 Reference<drawing::XDrawPageSupplier> xSupplier(rImp.GetModel(),UNO_QUERY);
1113 if (xSupplier.is())
1114 {
1115 if (rImp.GetFormImport().is())
1116 {
1117 rImp.GetFormImport()->startPage(xSupplier->getDrawPage());
1118 rFormImport = rImp.GetFormImport();
1119 }
1120
1121 xPage = xSupplier->getDrawPage();
1122 XMLShapeImportHelper::startPage( xPage );
1123 }
1124 }
1125
~SvTextShapeImportHelper()1126 SvTextShapeImportHelper::~SvTextShapeImportHelper()
1127 {
1128 rFormImport->endPage();
1129
1130 if (xPage.is())
1131 {
1132 XMLShapeImportHelper::endPage(xPage);
1133 }
1134 }
1135
CreateTextImport()1136 XMLTextImportHelper* SwXMLImport::CreateTextImport()
1137 {
1138 return new SwXMLTextImportHelper( GetModel(), *this, getImportInfo(),
1139 IsInsertMode(),
1140 IsStylesOnlyMode(),
1141 IsBlockMode(), m_bOrganizerMode );
1142 }
1143
CreateShapeImport()1144 XMLShapeImportHelper* SwXMLImport::CreateShapeImport()
1145 {
1146 return new SvTextShapeImportHelper( *this );
1147 }
1148
CreateFontDeclsContext()1149 SvXMLImportContext *SwXMLImport::CreateFontDeclsContext()
1150 {
1151 XMLFontStylesContext *pFSContext =
1152 new XMLFontStylesContext( *this, osl_getThreadTextEncoding() );
1153 SetFontDecls( pFSContext );
1154 return pFSContext;
1155 }
1156
SetViewSettings(const Sequence<PropertyValue> & aViewProps)1157 void SwXMLImport::SetViewSettings(const Sequence < PropertyValue > & aViewProps)
1158 {
1159 if (IsInsertMode() || IsStylesOnlyMode() || IsBlockMode() || m_bOrganizerMode || !GetModel().is() )
1160 return;
1161
1162 // this method will modify the document directly -> lock SolarMutex
1163 SolarMutexGuard aGuard;
1164
1165 SwDoc *pDoc = getDoc();
1166 tools::Rectangle aRect;
1167 if( pDoc->GetDocShell() )
1168 aRect = pDoc->GetDocShell()->GetVisArea( ASPECT_CONTENT );
1169 //TODO/LATER: why that cast?!
1170 //aRect = ((SfxInPlaceObject *)pDoc->GetDocShell())->GetVisArea();
1171
1172 sal_Int64 nTmp = 0;
1173 bool bShowRedlineChanges = false, bBrowseMode = false;
1174 bool bChangeShowRedline = false, bChangeBrowseMode = false;
1175
1176 //TODO/LATER: why that cast?!
1177 bool bTwip = pDoc->GetDocShell()->GetMapUnit ( ) == MapUnit::MapTwip;
1178 //sal_Bool bTwip = pDoc->GetDocShell()->SfxInPlaceObject::GetMapUnit ( ) == MapUnit::MapTwip;
1179
1180 for (const PropertyValue& rValue : aViewProps)
1181 {
1182 if ( rValue.Name == "ViewAreaTop" )
1183 {
1184 rValue.Value >>= nTmp;
1185 aRect.setY( static_cast< tools::Long >(bTwip ? sanitiseMm100ToTwip(nTmp) : nTmp) );
1186 }
1187 else if ( rValue.Name == "ViewAreaLeft" )
1188 {
1189 rValue.Value >>= nTmp;
1190 aRect.setX( static_cast< tools::Long >(bTwip ? sanitiseMm100ToTwip(nTmp) : nTmp) );
1191 }
1192 else if ( rValue.Name == "ViewAreaWidth" )
1193 {
1194 rValue.Value >>= nTmp;
1195 Size aSize( aRect.GetSize() );
1196 aSize.setWidth( static_cast< tools::Long >(bTwip ? sanitiseMm100ToTwip(nTmp) : nTmp) );
1197 aRect.SetSize( aSize );
1198 }
1199 else if ( rValue.Name == "ViewAreaHeight" )
1200 {
1201 rValue.Value >>= nTmp;
1202 Size aSize( aRect.GetSize() );
1203 aSize.setHeight( static_cast< tools::Long >(bTwip ? sanitiseMm100ToTwip(nTmp) : nTmp) );
1204 aRect.SetSize( aSize );
1205 }
1206 else if ( rValue.Name == "ShowRedlineChanges" )
1207 {
1208 bShowRedlineChanges = *o3tl::doAccess<bool>(rValue.Value);
1209 bChangeShowRedline = true;
1210 }
1211 // Headers and footers are not displayed in BrowseView anymore
1212 else if ( rValue.Name == "InBrowseMode" )
1213 {
1214 bBrowseMode = *o3tl::doAccess<bool>(rValue.Value);
1215 bChangeBrowseMode = true;
1216 }
1217 }
1218 if( pDoc->GetDocShell() )
1219 pDoc->GetDocShell()->SetVisArea ( aRect );
1220
1221 if (bChangeBrowseMode)
1222 pDoc->getIDocumentSettingAccess().set(DocumentSettingId::BROWSE_MODE, bBrowseMode );
1223
1224 if (bChangeShowRedline)
1225 GetTextImport()->SetShowChanges( bShowRedlineChanges );
1226 }
1227
1228 // Note: this will be called only if there are OOo elements in settings.xml.
1229 // So if a setting is missing there we can assume that it was written
1230 // by an OOo/LO version that is older than the introduction of the setting!
SetConfigurationSettings(const Sequence<PropertyValue> & aConfigProps)1231 void SwXMLImport::SetConfigurationSettings(const Sequence < PropertyValue > & aConfigProps)
1232 {
1233 // this method will modify the document directly -> lock SolarMutex
1234 SolarMutexGuard aGuard;
1235
1236 Reference< lang::XMultiServiceFactory > xFac( GetModel(), UNO_QUERY );
1237 if( !xFac.is() )
1238 return;
1239
1240 Reference< XPropertySet > xProps( xFac->createInstance("com.sun.star.document.Settings"), UNO_QUERY );
1241 if( !xProps.is() )
1242 return;
1243
1244 Reference< XPropertySetInfo > xInfo( xProps->getPropertySetInfo() );
1245 if( !xInfo.is() )
1246 return;
1247
1248 std::unordered_set< OUString > aExcludeAlways;
1249 aExcludeAlways.insert("LinkUpdateMode");
1250 // this should contain things that are actually user-settable, via Tools->Options
1251 std::unordered_set< OUString > aExcludeWhenNotLoadingUserSettings {
1252 "ForbiddenCharacters",
1253 "IsKernAsianPunctuation",
1254 "CharacterCompressionType",
1255 "FieldAutoUpdate",
1256 "ChartAutoUpdate",
1257 "AddParaTableSpacing",
1258 "AddParaTableSpacingAtStart",
1259 "PrintAnnotationMode",
1260 "PrintBlackFonts",
1261 "PrintControls",
1262 "PrintDrawings",
1263 "PrintGraphics",
1264 "PrintHiddenText",
1265 "PrintLeftPages",
1266 "PrintPageBackground",
1267 "PrintProspect",
1268 "PrintReversed",
1269 "PrintRightPages",
1270 "PrintFaxName",
1271 "PrintPaperFromSetup",
1272 "PrintTables",
1273 "PrintTextPlaceholder",
1274 "PrintSingleJobs",
1275 "UpdateFromTemplate",
1276 "PrinterIndependentLayout",
1277 "PrintEmptyPages",
1278 "ConsiderTextWrapOnObjPos",
1279 "DoNotJustifyLinesWithManualBreak",
1280 "ProtectForm",
1281 "MsWordCompTrailingBlanks",
1282 "SubtractFlysAnchoredAtFlys",
1283 "EmptyDbFieldHidesPara"
1284 };
1285
1286 SvtSaveOptions aSaveOpt;
1287 bool bAreUserSettingsFromDocument = aSaveOpt.IsLoadUserSettings();
1288
1289 // for some properties we don't want to use the application
1290 // default if they're missing. So we watch for them in the loop
1291 // below, and set them if not found
1292 bool bPrinterIndependentLayout = false;
1293 bool bUseOldNumbering = false;
1294 bool bAddExternalLeading = false;
1295 bool bAddParaSpacingToTableCells = false;
1296 bool bAddParaLineSpacingToTableCells = false;
1297 bool bUseFormerLineSpacing = false;
1298 bool bUseFormerObjectPositioning = false;
1299 bool bUseFormerTextWrapping = false;
1300 bool bConsiderWrapOnObjPos = false;
1301 bool bIgnoreFirstLineIndentInNumbering = false;
1302 bool bDoNotJustifyLinesWithManualBreak = false;
1303 bool bDoNotResetParaAttrsForNumFont = false;
1304 bool bLoadReadonly = false;
1305 bool bDoNotCaptureDrawObjsOnPage( false );
1306 bool bClipAsCharacterAnchoredWriterFlyFrames( false );
1307 bool bUnixForceZeroExtLeading = false;
1308 bool bSmallCapsPercentage66 = false;
1309 bool bTabOverflow = false;
1310 bool bUnbreakableNumberings = false;
1311 bool bClippedPictures = false;
1312 bool bBackgroundParaOverDrawings = false;
1313 bool bTabOverMargin = false;
1314 bool bTabOverMarginValue = false;
1315 bool bPropLineSpacingShrinksFirstLine = false;
1316 bool bSubtractFlysAnchoredAtFlys = false;
1317 bool bEmptyDbFieldHidesPara = false;
1318 bool bCollapseEmptyCellPara = false;
1319
1320 const PropertyValue* currentDatabaseDataSource = nullptr;
1321 const PropertyValue* currentDatabaseCommand = nullptr;
1322 const PropertyValue* currentDatabaseCommandType = nullptr;
1323 const PropertyValue* embeddedDatabaseName = nullptr;
1324
1325 for( const PropertyValue& rValue : aConfigProps )
1326 {
1327 bool bSet = aExcludeAlways.find(rValue.Name) == aExcludeAlways.end();
1328 if( bSet && !bAreUserSettingsFromDocument
1329 && (aExcludeWhenNotLoadingUserSettings.find(rValue.Name)
1330 != aExcludeWhenNotLoadingUserSettings.end()) )
1331 {
1332 bSet = false;
1333 }
1334
1335 if( bSet )
1336 {
1337 try
1338 {
1339 if( xInfo->hasPropertyByName( rValue.Name ) )
1340 {
1341 if( rValue.Name == "RedlineProtectionKey" )
1342 {
1343 Sequence<sal_Int8> aKey;
1344 rValue.Value >>= aKey;
1345 GetTextImport()->SetChangesProtectionKey( aKey );
1346 }
1347 else
1348 {
1349 // HACK: Setting these out of order does not work.
1350 if( rValue.Name == "CurrentDatabaseDataSource" )
1351 currentDatabaseDataSource = &rValue;
1352 else if( rValue.Name == "CurrentDatabaseCommand" )
1353 currentDatabaseCommand = &rValue;
1354 else if( rValue.Name == "CurrentDatabaseCommandType" )
1355 currentDatabaseCommandType = &rValue;
1356 else if (rValue.Name == "EmbeddedDatabaseName")
1357 embeddedDatabaseName = &rValue;
1358 else
1359 xProps->setPropertyValue( rValue.Name, rValue.Value );
1360 }
1361 }
1362
1363 // did we find any of the non-default cases?
1364 if ( rValue.Name == "PrinterIndependentLayout" )
1365 bPrinterIndependentLayout = true;
1366 else if ( rValue.Name == "AddExternalLeading" )
1367 bAddExternalLeading = true;
1368 else if ( rValue.Name == "AddParaSpacingToTableCells" )
1369 bAddParaSpacingToTableCells = true;
1370 else if ( rValue.Name == "AddParaLineSpacingToTableCells" )
1371 bAddParaLineSpacingToTableCells = true;
1372 else if ( rValue.Name == "UseFormerLineSpacing" )
1373 bUseFormerLineSpacing = true;
1374 else if ( rValue.Name == "UseFormerObjectPositioning" )
1375 bUseFormerObjectPositioning = true;
1376 else if ( rValue.Name == "UseFormerTextWrapping" )
1377 bUseFormerTextWrapping = true;
1378 else if ( rValue.Name == "UseOldNumbering" )
1379 bUseOldNumbering = true;
1380 else if ( rValue.Name == "ConsiderTextWrapOnObjPos" )
1381 bConsiderWrapOnObjPos = true;
1382 else if ( rValue.Name == "IgnoreFirstLineIndentInNumbering" )
1383 bIgnoreFirstLineIndentInNumbering = true;
1384 else if ( rValue.Name == "DoNotJustifyLinesWithManualBreak" )
1385 bDoNotJustifyLinesWithManualBreak = true;
1386 else if ( rValue.Name == "DoNotResetParaAttrsForNumFont" )
1387 bDoNotResetParaAttrsForNumFont = true;
1388 else if ( rValue.Name == "LoadReadonly" )
1389 bLoadReadonly = true;
1390 else if ( rValue.Name == "DoNotCaptureDrawObjsOnPage" )
1391 bDoNotCaptureDrawObjsOnPage = true;
1392 else if ( rValue.Name == "ClipAsCharacterAnchoredWriterFlyFrames" )
1393 bClipAsCharacterAnchoredWriterFlyFrames = true;
1394 else if ( rValue.Name == "UnxForceZeroExtLeading" )
1395 bUnixForceZeroExtLeading = true;
1396 else if ( rValue.Name == "SmallCapsPercentage66" )
1397 bSmallCapsPercentage66 = true;
1398 else if ( rValue.Name == "TabOverflow" )
1399 bTabOverflow = true;
1400 else if ( rValue.Name == "UnbreakableNumberings" )
1401 bUnbreakableNumberings = true;
1402 else if ( rValue.Name == "ClippedPictures" )
1403 bClippedPictures = true;
1404 else if ( rValue.Name == "BackgroundParaOverDrawings" )
1405 bBackgroundParaOverDrawings = true;
1406 else if ( rValue.Name == "TabOverMargin" )
1407 {
1408 bTabOverMargin = true;
1409 rValue.Value >>= bTabOverMarginValue;
1410 }
1411 else if ( rValue.Name == "PropLineSpacingShrinksFirstLine" )
1412 bPropLineSpacingShrinksFirstLine = true;
1413 else if (rValue.Name == "SubtractFlysAnchoredAtFlys")
1414 bSubtractFlysAnchoredAtFlys = true;
1415 else if (rValue.Name == "EmptyDbFieldHidesPara")
1416 bEmptyDbFieldHidesPara = true;
1417 else if (rValue.Name == "CollapseEmptyCellPara")
1418 bCollapseEmptyCellPara = true;
1419 }
1420 catch( Exception& )
1421 {
1422 TOOLS_WARN_EXCEPTION( "sw", "SwXMLImport::SetConfigurationSettings" );
1423 }
1424 }
1425 }
1426
1427 try
1428 {
1429 if( currentDatabaseDataSource != nullptr )
1430 xProps->setPropertyValue( currentDatabaseDataSource->Name, currentDatabaseDataSource->Value );
1431 if( currentDatabaseCommand != nullptr )
1432 xProps->setPropertyValue( currentDatabaseCommand->Name, currentDatabaseCommand->Value );
1433 if( currentDatabaseCommandType != nullptr )
1434 xProps->setPropertyValue( currentDatabaseCommandType->Name, currentDatabaseCommandType->Value );
1435 if (embeddedDatabaseName)
1436 xProps->setPropertyValue(embeddedDatabaseName->Name, embeddedDatabaseName->Value);
1437 } catch( Exception& )
1438 {
1439 TOOLS_WARN_EXCEPTION( "sw", "SwXMLImport::SetConfigurationSettings" );
1440 }
1441
1442 // finally, treat the non-default cases
1443 // introduce boolean, that indicates a document, written by version prior SO8.
1444 // If user settings are not loaded, we can't know if this is an old document. Better to assume no?
1445 const bool bDocumentPriorSO8 = !bConsiderWrapOnObjPos && bAreUserSettingsFromDocument;
1446
1447 // Use old behaviour if this setting didn't exist, but only if this setting is being read from the document.
1448 // (Obviously the setting doesn't exist if we are explicitly ignoring it, so then stick with program/user defaults)
1449 if(!bPrinterIndependentLayout && bAreUserSettingsFromDocument)
1450 {
1451 xProps->setPropertyValue( "PrinterIndependentLayout", Any(sal_Int16(document::PrinterIndependentLayout::DISABLED)) );
1452 }
1453
1454 if( ! bAddExternalLeading )
1455 {
1456 xProps->setPropertyValue( "AddExternalLeading", makeAny( false ) );
1457 }
1458
1459 if( ! bUseFormerLineSpacing )
1460 {
1461 xProps->setPropertyValue( "UseFormerLineSpacing", makeAny( true ) );
1462 }
1463
1464 if( !bUseFormerObjectPositioning )
1465 {
1466 xProps->setPropertyValue( "UseFormerObjectPositioning", makeAny( true ) );
1467 }
1468
1469 if( !bUseOldNumbering )
1470 {
1471 xProps->setPropertyValue( "UseOldNumbering", makeAny(true) );
1472 }
1473
1474 if( !bAddParaSpacingToTableCells )
1475 {
1476 xProps->setPropertyValue( "AddParaSpacingToTableCells",
1477 makeAny( false ) );
1478 }
1479 if (!bAddParaLineSpacingToTableCells)
1480 {
1481 xProps->setPropertyValue("AddParaLineSpacingToTableCells", makeAny(false));
1482 }
1483
1484 if( !bUseFormerTextWrapping )
1485 {
1486 xProps->setPropertyValue( "UseFormerTextWrapping", makeAny( true ) );
1487 }
1488
1489 if (!bConsiderWrapOnObjPos && bAreUserSettingsFromDocument)
1490 {
1491 xProps->setPropertyValue( "ConsiderTextWrapOnObjPos", makeAny( false ) );
1492 }
1493
1494 // #i47448#
1495 // For SO7pp4, part of the 'new numbering' stuff has been backported from
1496 // SO8. Unfortunately, only part of it and by using the same compatibility option
1497 // like in SO8. Therefore documents generated with SO7pp4, containing
1498 // numbered paragraphs with first line indent differ between SO7pp4 and
1499 // SO8. In order to fix this for SO8pp1, I introduce a new compatibility
1500 // flag 'bIgnoreFirstLineIndentInNumbering'. This flag has to be set for all
1501 // documents < SO8, but not for SO8. So if the property is not present, the
1502 // flag will be set to 'true'. SO8 documents surely have the
1503 // 'ConsiderWrapOnObjPos' property set (no matter if 'true' or 'false'),
1504 // therefore the correct condition to set this flag is this:
1505 if( !bIgnoreFirstLineIndentInNumbering && bDocumentPriorSO8 )
1506 {
1507 xProps->setPropertyValue( "IgnoreFirstLineIndentInNumbering",
1508 makeAny( true ) );
1509 }
1510
1511 // This flag has to be set for all documents < SO8
1512 if ( !bDoNotJustifyLinesWithManualBreak && bDocumentPriorSO8 )
1513 {
1514 xProps->setPropertyValue( "DoNotJustifyLinesWithManualBreak",
1515 makeAny( true ) );
1516 }
1517
1518 // This flag has to be set for all documents < SO8
1519 if ( !bDoNotResetParaAttrsForNumFont && bDocumentPriorSO8 )
1520 {
1521 xProps->setPropertyValue( "DoNotResetParaAttrsForNumFont",
1522 makeAny( true ) );
1523 }
1524
1525 if ( !bLoadReadonly )
1526 {
1527 xProps->setPropertyValue( "LoadReadonly", makeAny( false ) );
1528 }
1529
1530 // This flag has to be set for all documents < SO8
1531 if ( !bDoNotCaptureDrawObjsOnPage && bDocumentPriorSO8 )
1532 {
1533 xProps->setPropertyValue( "DoNotCaptureDrawObjsOnPage",
1534 makeAny( true ) );
1535 }
1536
1537 // This flag has to be set for all documents < SO8
1538 if ( !bClipAsCharacterAnchoredWriterFlyFrames && bDocumentPriorSO8 )
1539 {
1540 xProps->setPropertyValue( "ClipAsCharacterAnchoredWriterFlyFrames",
1541 makeAny( true ) );
1542 }
1543
1544 if ( !bUnixForceZeroExtLeading )
1545 {
1546 xProps->setPropertyValue( "UnxForceZeroExtLeading", makeAny( true ) );
1547 }
1548
1549 // Old LO versions had 66 as the value for small caps percentage, later changed to 80.
1550 // In order to keep backwards compatibility, SmallCapsPercentage66 option is written to .odt
1551 // files, and the default for new documents is 'false'. Files without this option
1552 // are considered to be old files, so set the compatibility option too.
1553 if ( !bSmallCapsPercentage66 )
1554 {
1555 xProps->setPropertyValue( "SmallCapsPercentage66", makeAny( true ) );
1556 }
1557
1558 if ( !bTabOverflow )
1559 {
1560 xProps->setPropertyValue( "TabOverflow", makeAny( false ) );
1561 }
1562
1563 if ( !bUnbreakableNumberings )
1564 {
1565 xProps->setPropertyValue( "UnbreakableNumberings", makeAny( false ) );
1566 }
1567
1568 if ( !bClippedPictures )
1569 {
1570 xProps->setPropertyValue( "ClippedPictures", makeAny( false ) );
1571 }
1572
1573 if ( !bBackgroundParaOverDrawings )
1574 xProps->setPropertyValue("BackgroundParaOverDrawings", makeAny( false ) );
1575
1576 if ( !bTabOverMargin )
1577 xProps->setPropertyValue("TabOverMargin", makeAny( false ) );
1578
1579 if (bTabOverMarginValue)
1580 // Let TabOverMargin imply the new default for
1581 // PrinterIndependentLayout, knowing the first is set by Word import
1582 // filters and Word defaults to our new default as well.
1583 xProps->setPropertyValue(
1584 "PrinterIndependentLayout",
1585 uno::Any(document::PrinterIndependentLayout::HIGH_RESOLUTION));
1586
1587 if (!bPropLineSpacingShrinksFirstLine)
1588 xProps->setPropertyValue("PropLineSpacingShrinksFirstLine", makeAny(false));
1589
1590 if (!bSubtractFlysAnchoredAtFlys && bAreUserSettingsFromDocument)
1591 xProps->setPropertyValue("SubtractFlysAnchoredAtFlys", makeAny(true));
1592
1593 if (!bEmptyDbFieldHidesPara && bAreUserSettingsFromDocument)
1594 xProps->setPropertyValue("EmptyDbFieldHidesPara", makeAny(false));
1595
1596 if (!bCollapseEmptyCellPara)
1597 xProps->setPropertyValue("CollapseEmptyCellPara", makeAny(false));
1598
1599 SwDoc *pDoc = getDoc();
1600 SfxPrinter *pPrinter = pDoc->getIDocumentDeviceAccess().getPrinter( false );
1601 if( pPrinter )
1602 {
1603 // If the printer is known, then the OLE objects will
1604 // already have correct sizes, and we don't have to call
1605 // PrtOLENotify again. Otherwise we have to call it.
1606 // The flag might be set from setting the printer, so it
1607 // it is required to clear it.
1608 pDoc->SetOLEPrtNotifyPending( !pPrinter->IsKnown() );
1609 }
1610 }
1611
SetDocumentSpecificSettings(const OUString & _rSettingsGroupName,const Sequence<PropertyValue> & _rSettings)1612 void SwXMLImport::SetDocumentSpecificSettings(
1613 const OUString& _rSettingsGroupName,
1614 const Sequence< PropertyValue>& _rSettings )
1615 {
1616 // the only doc-specific settings group we know so far are the XForms settings
1617 if ( !IsXMLToken( _rSettingsGroupName, XML_XFORM_MODEL_SETTINGS ) )
1618 return;
1619
1620 // preserve the settings for a later iteration - we are currently reading the settings.xml,
1621 // the content.xml will be read later, by another instance of SwXMLImport
1622 OSL_ENSURE( m_xLateInitSettings.is(), "SwXMLImport::SetDocumentSpecificSettings: no storage for those settings!" );
1623 if ( !m_xLateInitSettings.is() )
1624 return;
1625
1626 try
1627 {
1628 if ( m_xLateInitSettings->hasByName( _rSettingsGroupName ) )
1629 {
1630 m_xLateInitSettings->replaceByName( _rSettingsGroupName, makeAny( _rSettings ) );
1631 OSL_FAIL( "SwXMLImport::SetDocumentSpecificSettings: already have settings for this model!" );
1632 }
1633 else
1634 m_xLateInitSettings->insertByName( _rSettingsGroupName, makeAny( _rSettings ) );
1635 }
1636 catch( const Exception& )
1637 {
1638 }
1639 }
1640
initialize(const Sequence<Any> & aArguments)1641 void SwXMLImport::initialize(
1642 const Sequence<Any>& aArguments )
1643 {
1644 // delegate to super class
1645 SvXMLImport::initialize(aArguments);
1646
1647 // we are only looking for a NamedValue "LateInitSettings"
1648 for(const auto& rArgument : aArguments)
1649 {
1650 beans::NamedValue aNamedValue;
1651 if ( rArgument >>= aNamedValue )
1652 {
1653 if (aNamedValue.Name == "LateInitSettings")
1654 {
1655 OSL_VERIFY( aNamedValue.Value >>= m_xLateInitSettings );
1656 }
1657 }
1658 }
1659 }
1660
GetDocFromXMLImport(SvXMLImport const & rImport)1661 SwDoc* SwImport::GetDocFromXMLImport( SvXMLImport const & rImport )
1662 {
1663 auto pTextDoc = comphelper::getUnoTunnelImplementation<SwXTextDocument>(rImport.GetModel());
1664 assert( pTextDoc );
1665 assert( pTextDoc->GetDocShell() );
1666 SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();
1667 OSL_ENSURE( pDoc, "Where is my document?" );
1668 return pDoc;
1669 }
1670
initXForms()1671 void SwXMLImport::initXForms()
1672 {
1673 // obtain SwDoc
1674 auto pXTextDocument = comphelper::getUnoTunnelImplementation<SwXTextDocument>(GetModel());
1675 if( pXTextDocument == nullptr )
1676 return;
1677
1678 SwDoc *pDoc = pXTextDocument->GetDocShell()->GetDoc();
1679
1680 // init XForms (if not already done)
1681 // (no default model, since we'll load the models)
1682 if( ! pDoc->isXForms() )
1683 pDoc->initXForms( false );
1684
1685 m_bInititedXForms = true;
1686 }
1687
getDoc()1688 SwDoc* SwXMLImport::getDoc()
1689 {
1690 if( m_pDoc != nullptr )
1691 return m_pDoc;
1692 Reference < XTextDocument > xTextDoc( GetModel(), UNO_QUERY );
1693 Reference < XText > xText = xTextDoc->getText();
1694 Reference<XUnoTunnel> xTextTunnel( xText, UNO_QUERY);
1695 assert( xTextTunnel.is());
1696 SwXText *pText = reinterpret_cast< SwXText *>(
1697 sal::static_int_cast< sal_IntPtr >( xTextTunnel->getSomething( SwXText::getUnoTunnelId() )));
1698 assert( pText != nullptr );
1699 m_pDoc = pText->GetDoc();
1700 assert( m_pDoc != nullptr );
1701 return m_pDoc;
1702 }
1703
getDoc() const1704 const SwDoc* SwXMLImport::getDoc() const
1705 {
1706 return const_cast< SwXMLImport* >( this )->getDoc();
1707 }
1708
1709 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
com_sun_star_comp_Writer_XMLOasisImporter_get_implementation(css::uno::XComponentContext * context,css::uno::Sequence<css::uno::Any> const &)1710 com_sun_star_comp_Writer_XMLOasisImporter_get_implementation(css::uno::XComponentContext* context,
1711 css::uno::Sequence<css::uno::Any> const &)
1712 {
1713 return cppu::acquire(new SwXMLImport(context, "com.sun.star.comp.Writer.XMLOasisImporter",
1714 SvXMLImportFlags::ALL));
1715 }
1716
1717
1718 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
com_sun_star_comp_Writer_XMLOasisStylesImporter_get_implementation(css::uno::XComponentContext * context,css::uno::Sequence<css::uno::Any> const &)1719 com_sun_star_comp_Writer_XMLOasisStylesImporter_get_implementation(css::uno::XComponentContext* context,
1720 css::uno::Sequence<css::uno::Any> const &)
1721 {
1722 return cppu::acquire(new SwXMLImport(context, "com.sun.star.comp.Writer.XMLOasisStylesImporter",
1723 SvXMLImportFlags::STYLES | SvXMLImportFlags::MASTERSTYLES | SvXMLImportFlags::AUTOSTYLES |
1724 SvXMLImportFlags::FONTDECLS));
1725 }
1726
1727
1728 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
com_sun_star_comp_Writer_XMLOasisContentImporter_get_implementation(css::uno::XComponentContext * context,css::uno::Sequence<css::uno::Any> const &)1729 com_sun_star_comp_Writer_XMLOasisContentImporter_get_implementation(css::uno::XComponentContext* context,
1730 css::uno::Sequence<css::uno::Any> const &)
1731 {
1732 return cppu::acquire(new SwXMLImport(context, "com.sun.star.comp.Writer.XMLOasisContentImporter",
1733 SvXMLImportFlags::CONTENT | SvXMLImportFlags::SCRIPTS | SvXMLImportFlags::AUTOSTYLES |
1734 SvXMLImportFlags::FONTDECLS));
1735 }
1736
1737 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
com_sun_star_comp_Writer_XMLOasisMetaImporter_get_implementation(css::uno::XComponentContext * context,css::uno::Sequence<css::uno::Any> const &)1738 com_sun_star_comp_Writer_XMLOasisMetaImporter_get_implementation(css::uno::XComponentContext* context,
1739 css::uno::Sequence<css::uno::Any> const &)
1740 {
1741 return cppu::acquire(new SwXMLImport(context, "com.sun.star.comp.Writer.XMLOasisMetaImporter",
1742 SvXMLImportFlags::META));
1743 }
1744
1745
1746 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
com_sun_star_comp_Writer_XMLOasisSettingsImporter_get_implementation(css::uno::XComponentContext * context,css::uno::Sequence<css::uno::Any> const &)1747 com_sun_star_comp_Writer_XMLOasisSettingsImporter_get_implementation(css::uno::XComponentContext* context,
1748 css::uno::Sequence<css::uno::Any> const &)
1749 {
1750 return cppu::acquire(new SwXMLImport(context, "com.sun.star.comp.Writer.XMLOasisSettingsImporter",
1751 SvXMLImportFlags::SETTINGS));
1752 }
1753
TestImportFODT(SvStream & rStream)1754 extern "C" SAL_DLLPUBLIC_EXPORT bool TestImportFODT(SvStream &rStream)
1755 {
1756 SwGlobals::ensure();
1757
1758 SfxObjectShellLock xDocSh(new SwDocShell(SfxObjectCreateMode::INTERNAL));
1759 xDocSh->DoInitNew();
1760 uno::Reference<frame::XModel> xModel(xDocSh->GetModel());
1761
1762 uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(comphelper::getProcessServiceFactory());
1763 uno::Reference<io::XInputStream> xStream(new utl::OSeekableInputStreamWrapper(rStream));
1764 uno::Reference<uno::XInterface> xInterface(xMultiServiceFactory->createInstance("com.sun.star.comp.Writer.XmlFilterAdaptor"), uno::UNO_SET_THROW);
1765
1766 css::uno::Sequence<OUString> aUserData
1767 {
1768 "com.sun.star.comp.filter.OdfFlatXml",
1769 "",
1770 "com.sun.star.comp.Writer.XMLOasisImporter",
1771 "com.sun.star.comp.Writer.XMLOasisExporter",
1772 "",
1773 "",
1774 "true"
1775 };
1776 uno::Sequence<beans::PropertyValue> aAdaptorArgs(comphelper::InitPropertySequence(
1777 {
1778 { "UserData", uno::Any(aUserData) },
1779 }));
1780 css::uno::Sequence<uno::Any> aOuterArgs(1);
1781 aOuterArgs[0] <<= aAdaptorArgs;
1782
1783 uno::Reference<lang::XInitialization> xInit(xInterface, uno::UNO_QUERY_THROW);
1784 xInit->initialize(aOuterArgs);
1785
1786 uno::Reference<document::XImporter> xImporter(xInterface, uno::UNO_QUERY_THROW);
1787 uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
1788 {
1789 { "InputStream", uno::Any(xStream) },
1790 { "URL", uno::Any(OUString("private:stream")) },
1791 }));
1792 xImporter->setTargetDocument(xModel);
1793
1794 uno::Reference<document::XFilter> xFilter(xInterface, uno::UNO_QUERY_THROW);
1795 //SetLoading hack because the document properties will be re-initted
1796 //by the xml filter and during the init, while it's considered uninitialized,
1797 //setting a property will inform the document it's modified, which attempts
1798 //to update the properties, which throws cause the properties are uninitialized
1799 xDocSh->SetLoading(SfxLoadedFlags::NONE);
1800 bool ret = xFilter->filter(aArgs);
1801 xDocSh->SetLoading(SfxLoadedFlags::ALL);
1802
1803 xDocSh->DoClose();
1804
1805 return ret;
1806 }
1807
TestImportDOCX(SvStream & rStream)1808 extern "C" SAL_DLLPUBLIC_EXPORT bool TestImportDOCX(SvStream &rStream)
1809 {
1810 SwGlobals::ensure();
1811
1812 SfxObjectShellLock xDocSh(new SwDocShell(SfxObjectCreateMode::INTERNAL));
1813 xDocSh->DoInitNew();
1814 uno::Reference<frame::XModel> xModel(xDocSh->GetModel());
1815
1816 uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(comphelper::getProcessServiceFactory());
1817 uno::Reference<io::XInputStream> xStream(new utl::OSeekableInputStreamWrapper(rStream));
1818
1819 uno::Reference<document::XFilter> xFilter(xMultiServiceFactory->createInstance("com.sun.star.comp.Writer.WriterFilter"), uno::UNO_QUERY_THROW);
1820
1821 uno::Reference<document::XImporter> xImporter(xFilter, uno::UNO_QUERY_THROW);
1822 uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
1823 {
1824 { "InputStream", uno::makeAny(xStream) },
1825 { "InputMode", uno::makeAny(true) },
1826 }));
1827 xImporter->setTargetDocument(xModel);
1828
1829 //SetLoading hack because the document properties will be re-initted
1830 //by the xml filter and during the init, while it's considered uninitialized,
1831 //setting a property will inform the document it's modified, which attempts
1832 //to update the properties, which throws cause the properties are uninitialized
1833 xDocSh->SetLoading(SfxLoadedFlags::NONE);
1834 bool ret = false;
1835 try
1836 {
1837 ret = xFilter->filter(aArgs);
1838 }
1839 catch (...)
1840 {
1841 }
1842 xDocSh->SetLoading(SfxLoadedFlags::ALL);
1843
1844 xDocSh->DoClose();
1845
1846 return ret;
1847 }
1848
1849 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1850