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 <memory>
21 #include <optional>
22 #include <tuple>
23 #include <vector>
24
25 #include <com/sun/star/container/XEnumerationAccess.hpp>
26 #include <com/sun/star/frame/XModel.hpp>
27 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
28 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
29 #include <com/sun/star/text/ReferenceFieldSource.hpp>
30 #include <com/sun/star/text/XChapterNumberingSupplier.hpp>
31 #include <com/sun/star/text/XTextFrame.hpp>
32 #include <com/sun/star/text/XTextFieldsSupplier.hpp>
33 #include <com/sun/star/text/XTextFramesSupplier.hpp>
34 #include <com/sun/star/text/XTextGraphicObjectsSupplier.hpp>
35 #include <com/sun/star/text/XTextEmbeddedObjectsSupplier.hpp>
36 #include <com/sun/star/text/XFormField.hpp>
37 #include <com/sun/star/ucb/XAnyCompareFactory.hpp>
38 #include <com/sun/star/container/XNamed.hpp>
39 #include <com/sun/star/style/XStyle.hpp>
40 #include <xmloff/xmlnamespace.hxx>
41 #include <xmloff/txtstyli.hxx>
42 #include <xmloff/xmlnumi.hxx>
43 #include <xmloff/maptype.hxx>
44
45 #include <sal/log.hxx>
46 #include "txtparai.hxx"
47 #include <xmloff/txtprmap.hxx>
48 #include <xmloff/txtimppr.hxx>
49 #include <xmloff/xmlimp.hxx>
50 #include <txtvfldi.hxx>
51 #include <xmloff/i18nmap.hxx>
52 #include "XMLTextListItemContext.hxx"
53 #include "XMLTextListBlockContext.hxx"
54 #include "XMLTextFrameContext.hxx"
55 #include "XMLTextFrameHyperlinkContext.hxx"
56 #include "XMLSectionImportContext.hxx"
57 #include "XMLIndexTOCContext.hxx"
58 #include <xmloff/XMLEventsImportContext.hxx>
59 #include "XMLTrackedChangesImportContext.hxx"
60 #include "XMLChangeImportContext.hxx"
61 #include "XMLAutoMarkFileContext.hxx"
62 #include <xmloff/ProgressBarHelper.hxx>
63
64 #include "XMLCalculationSettingsContext.hxx"
65 #include <XMLNumberStylesImport.hxx>
66 #include <PageMasterStyleMap.hxx>
67 #include <PageMasterPropHdlFactory.hxx>
68 #include <PageMasterPropMapper.hxx>
69 // XML import: reconstruction of assignment of paragraph style to outline levels (#i69629#)
70 #include <com/sun/star/beans/XPropertyState.hpp>
71 #include <txtlists.hxx>
72 #include <xmloff/odffields.hxx>
73 #include <comphelper/attributelist.hxx>
74
75 using ::com::sun::star::ucb::XAnyCompare;
76
77 using namespace ::std;
78 using namespace ::com::sun::star;
79 using namespace ::com::sun::star::uno;
80 using namespace ::com::sun::star::beans;
81 using namespace ::com::sun::star::text;
82 using namespace ::com::sun::star::frame;
83 using namespace ::com::sun::star::style;
84 using namespace ::com::sun::star::container;
85 using namespace ::com::sun::star::drawing;
86 using namespace ::com::sun::star::xml::sax;
87 using namespace ::com::sun::star::lang;
88 using namespace ::xmloff::token;
89 using namespace ::com::sun::star::ucb;
90
91
92 // maximum allowed length of combined characters field
93 #define MAX_COMBINED_CHARACTERS 6
94
95 struct XMLTextImportHelper::Impl
96 {
97 std::optional< std::vector<OUString> > m_xPrevFrmNames;
98 std::optional< std::vector<OUString> > m_xNextFrmNames;
99 std::unique_ptr<XMLTextListsHelper> m_xTextListsHelper;
100
101 rtl::Reference<SvXMLStylesContext> m_xAutoStyles;
102
103 rtl::Reference< SvXMLImportPropertyMapper > m_xParaImpPrMap;
104 rtl::Reference< SvXMLImportPropertyMapper > m_xTextImpPrMap;
105 rtl::Reference< SvXMLImportPropertyMapper > m_xFrameImpPrMap;
106 rtl::Reference< SvXMLImportPropertyMapper > m_xSectionImpPrMap;
107 rtl::Reference< SvXMLImportPropertyMapper > m_xRubyImpPrMap;
108
109 std::unique_ptr<SvI18NMap> m_xRenameMap;
110
111 /* Change and extend data structure:
112 - data structure contains candidates of paragraph styles, which
113 will be assigned to the outline style
114 - data structure contains more than one candidate for each list level
115 of the outline style (#i69629#)
116 */
117 std::unique_ptr< std::vector< OUString > []>
118 m_xOutlineStylesCandidates;
119
120 // start range, xml:id, RDFa stuff
121 typedef std::tuple<
122 uno::Reference<text::XTextRange>, OUString,
123 std::shared_ptr< ::xmloff::ParsedRDFaAttributes > >
124 BookmarkMapEntry_t;
125 /// start ranges for open bookmarks
126 std::map< OUString, BookmarkMapEntry_t > m_BookmarkStartRanges;
127
128 std::vector< OUString > m_BookmarkVector;
129
130 /// name of the last 'open' redline that started between paragraphs
131 OUString m_sOpenRedlineIdentifier;
132
133 // Used for frame deduplication, the name of the last frame imported directly before the current one
134 OUString msLastImportedFrameName;
135
136 std::map< OUString, bool > m_bBookmarkHidden;
137 std::map< OUString, OUString > m_sBookmarkCondition;
138
139 uno::Reference<text::XText> m_xText;
140 uno::Reference<text::XTextCursor> m_xCursor;
141 uno::Reference<text::XTextRange> m_xCursorAsRange;
142 uno::Reference<container::XNameContainer> m_xParaStyles;
143 uno::Reference<container::XNameContainer> m_xTextStyles;
144 uno::Reference<container::XNameContainer> m_xNumStyles;
145 uno::Reference<container::XNameContainer> m_xFrameStyles;
146 uno::Reference<container::XNameContainer> m_xPageStyles;
147 uno::Reference<container::XNameContainer> m_xCellStyles;
148 uno::Reference<container::XIndexReplace> m_xChapterNumbering;
149 uno::Reference<container::XNameAccess> m_xTextFrames;
150 uno::Reference<container::XNameAccess> m_xGraphics;
151 uno::Reference<container::XNameAccess> m_xObjects;
152 uno::Reference<lang::XMultiServiceFactory> m_xServiceFactory;
153
154 SvXMLImport & m_rSvXMLImport;
155
156 bool m_bInsertMode : 1;
157 bool m_bStylesOnlyMode : 1;
158 bool m_bBlockMode : 1;
159 bool m_bProgress : 1;
160 bool m_bOrganizerMode : 1;
161 bool m_bBodyContentStarted : 1;
162
163 /// Are we inside a <text:deletion> element (deleted redline section)
164 bool m_bInsideDeleteContext : 1;
165
166 typedef ::std::pair< OUString, OUString> field_name_type_t;
167 typedef ::std::pair< OUString, OUString > field_param_t;
168 typedef ::std::vector< field_param_t > field_params_t;
169 typedef ::std::tuple<field_name_type_t, field_params_t, uno::Reference<text::XFormField>> field_stack_item_t;
170 typedef ::std::stack< field_stack_item_t > field_stack_t;
171
172 field_stack_t m_FieldStack;
173
174 OUString m_sCellParaStyleDefault;
175
176 std::optional<std::map<OUString, OUString>> m_xCrossRefHeadingBookmarkMap;
177
ImplXMLTextImportHelper::Impl178 Impl( uno::Reference<frame::XModel> const& rModel,
179 SvXMLImport & rImport,
180 bool const bInsertMode, bool const bStylesOnlyMode,
181 bool const bProgress, bool const bBlockMode,
182 bool const bOrganizerMode)
183 : m_xTextListsHelper( new XMLTextListsHelper() )
184 // XML import: reconstruction of assignment of paragraph style to outline levels (#i69629#)
185 , m_xServiceFactory( rModel, UNO_QUERY )
186 , m_rSvXMLImport( rImport )
187 , m_bInsertMode( bInsertMode )
188 , m_bStylesOnlyMode( bStylesOnlyMode )
189 , m_bBlockMode( bBlockMode )
190 , m_bProgress( bProgress )
191 , m_bOrganizerMode( bOrganizerMode )
192 , m_bBodyContentStarted( true )
193 , m_bInsideDeleteContext( false )
194 {
195 }
196 Impl(const Impl&) = delete;
197 Impl& operator=(const Impl&) = delete;
198
InitOutlineStylesCandidatesXMLTextImportHelper::Impl199 void InitOutlineStylesCandidates()
200 {
201 if (!m_xOutlineStylesCandidates)
202 {
203 size_t const size(m_xChapterNumbering->getCount());
204 m_xOutlineStylesCandidates.reset(
205 new ::std::vector< OUString >[size] );
206 }
207 }
208
209 };
210
211
GetText()212 uno::Reference< text::XText > & XMLTextImportHelper::GetText()
213 {
214 return m_xImpl->m_xText;
215 }
216
GetCursor()217 uno::Reference< text::XTextCursor > & XMLTextImportHelper::GetCursor()
218 {
219 return m_xImpl->m_xCursor;
220 }
221
GetCursorAsRange()222 uno::Reference< text::XTextRange > & XMLTextImportHelper::GetCursorAsRange()
223 {
224 return m_xImpl->m_xCursorAsRange;
225 }
226
IsInsertMode() const227 bool XMLTextImportHelper::IsInsertMode() const
228 {
229 return m_xImpl->m_bInsertMode;
230 }
231
IsStylesOnlyMode() const232 bool XMLTextImportHelper::IsStylesOnlyMode() const
233 {
234 return m_xImpl->m_bStylesOnlyMode;
235 }
236
IsBlockMode() const237 bool XMLTextImportHelper::IsBlockMode() const
238 {
239 return m_xImpl->m_bBlockMode;
240 }
241
IsOrganizerMode() const242 bool XMLTextImportHelper::IsOrganizerMode() const
243 {
244 return m_xImpl->m_bOrganizerMode;
245 }
246
IsProgress() const247 bool XMLTextImportHelper::IsProgress() const
248 {
249 return m_xImpl->m_bProgress;
250 }
251
252 uno::Reference<container::XNameContainer> const&
GetParaStyles() const253 XMLTextImportHelper::GetParaStyles() const
254 {
255 return m_xImpl->m_xParaStyles;
256 }
257
258 uno::Reference<container::XNameContainer> const&
GetTextStyles() const259 XMLTextImportHelper::GetTextStyles() const
260 {
261 return m_xImpl->m_xTextStyles;
262 }
263
264 uno::Reference<container::XNameContainer> const&
GetNumberingStyles() const265 XMLTextImportHelper::GetNumberingStyles() const
266 {
267 return m_xImpl->m_xNumStyles;
268 }
269
270 uno::Reference<container::XNameContainer> const&
GetFrameStyles() const271 XMLTextImportHelper::GetFrameStyles() const
272 {
273 return m_xImpl->m_xFrameStyles;
274 }
275
276 uno::Reference<container::XNameContainer> const&
GetPageStyles() const277 XMLTextImportHelper::GetPageStyles() const
278 {
279 return m_xImpl->m_xPageStyles;
280 }
281
282 uno::Reference<container::XNameContainer> const&
GetCellStyles() const283 XMLTextImportHelper::GetCellStyles() const
284 {
285 return m_xImpl->m_xCellStyles;
286 }
287
288 uno::Reference<container::XIndexReplace> const&
GetChapterNumbering() const289 XMLTextImportHelper::GetChapterNumbering() const
290 {
291 return m_xImpl->m_xChapterNumbering;
292 }
293
294 rtl::Reference< SvXMLImportPropertyMapper > const&
GetParaImportPropertySetMapper() const295 XMLTextImportHelper::GetParaImportPropertySetMapper() const
296 {
297 return m_xImpl->m_xParaImpPrMap;
298 }
299
300 rtl::Reference< SvXMLImportPropertyMapper > const&
GetTextImportPropertySetMapper() const301 XMLTextImportHelper::GetTextImportPropertySetMapper() const
302 {
303 return m_xImpl->m_xTextImpPrMap;
304 }
305
306 rtl::Reference< SvXMLImportPropertyMapper > const&
GetSectionImportPropertySetMapper() const307 XMLTextImportHelper::GetSectionImportPropertySetMapper() const
308 {
309 return m_xImpl->m_xSectionImpPrMap;
310 }
311
312 rtl::Reference< SvXMLImportPropertyMapper > const&
GetRubyImportPropertySetMapper() const313 XMLTextImportHelper::GetRubyImportPropertySetMapper() const
314 {
315 return m_xImpl->m_xRubyImpPrMap;
316 }
317
SetInsideDeleteContext(bool const bNew)318 void XMLTextImportHelper::SetInsideDeleteContext(bool const bNew)
319 {
320 m_xImpl->m_bInsideDeleteContext = bNew;
321 }
322
IsInsideDeleteContext() const323 bool XMLTextImportHelper::IsInsideDeleteContext() const
324 {
325 return m_xImpl->m_bInsideDeleteContext;
326 }
327
GetXMLImport()328 SvXMLImport & XMLTextImportHelper::GetXMLImport()
329 {
330 return m_xImpl->m_rSvXMLImport;
331 }
332
GetTextListHelper()333 XMLTextListsHelper & XMLTextImportHelper::GetTextListHelper()
334 {
335 return *m_xImpl->m_xTextListsHelper;
336 }
337
338 namespace
339 {
340 class FieldParamImporter
341 {
342 public:
343 typedef pair<OUString,OUString> field_param_t;
344 typedef vector<field_param_t> field_params_t;
FieldParamImporter(const field_params_t * const pInParams,Reference<XNameContainer> const & xOutParams)345 FieldParamImporter(const field_params_t* const pInParams, Reference<XNameContainer> const & xOutParams)
346 : m_pInParams(pInParams)
347 , m_xOutParams(xOutParams)
348 { };
349 void Import();
350
351 private:
352 const field_params_t* const m_pInParams;
353 Reference<XNameContainer> m_xOutParams;
354 };
355
Import()356 void FieldParamImporter::Import()
357 {
358 ::std::vector<OUString> vListEntries;
359 ::std::map<OUString, Any> vOutParams;
360 for(const auto& rCurrent : *m_pInParams)
361 {
362 if(rCurrent.first == ODF_FORMDROPDOWN_RESULT)
363 {
364 // sal_Int32
365 vOutParams[rCurrent.first] <<= rCurrent.second.toInt32();
366 }
367 else if(rCurrent.first == ODF_FORMCHECKBOX_RESULT)
368 {
369 // bool
370 vOutParams[rCurrent.first] <<= rCurrent.second.toBoolean();
371 }
372 else if(rCurrent.first == ODF_FORMDROPDOWN_LISTENTRY)
373 {
374 // sequence
375 vListEntries.push_back(rCurrent.second);
376 }
377 else
378 vOutParams[rCurrent.first] <<= rCurrent.second;
379 }
380 if(!vListEntries.empty())
381 {
382 Sequence<OUString> vListEntriesSeq(vListEntries.size());
383 copy(vListEntries.begin(), vListEntries.end(), vListEntriesSeq.begin());
384 vOutParams[OUString(ODF_FORMDROPDOWN_LISTENTRY)] <<= vListEntriesSeq;
385 }
386 for(const auto& rCurrent : vOutParams)
387 {
388 try
389 {
390 m_xOutParams->insertByName(rCurrent.first, rCurrent.second);
391 }
392 catch(const ElementExistException&)
393 {
394 SAL_INFO("xmloff.text", "duplicate fieldmark param");
395 }
396 }
397 }
398 }
399
XMLTextImportHelper(uno::Reference<frame::XModel> const & rModel,SvXMLImport & rImport,bool const bInsertMode,bool const bStylesOnlyMode,bool const bProgress,bool const bBlockMode,bool const bOrganizerMode)400 XMLTextImportHelper::XMLTextImportHelper(
401 uno::Reference<frame::XModel> const& rModel,
402 SvXMLImport& rImport,
403 bool const bInsertMode, bool const bStylesOnlyMode,
404 bool const bProgress, bool const bBlockMode,
405 bool const bOrganizerMode)
406 : m_xImpl( new Impl(rModel, rImport, bInsertMode, bStylesOnlyMode,
407 bProgress, bBlockMode, bOrganizerMode) )
408 , m_xBackpatcherImpl( MakeBackpatcherImpl() )
409 {
410 static constexpr OUStringLiteral s_PropNameDefaultListId = u"DefaultListId";
411
412 Reference< XChapterNumberingSupplier > xCNSupplier( rModel, UNO_QUERY );
413
414 if (xCNSupplier.is())
415 {
416 // note: m_xChapterNumbering is accessed to import some fields
417 m_xImpl->m_xChapterNumbering = xCNSupplier->getChapterNumberingRules();
418 // the AutoCorrect document doesn't have a proper outline numbering
419 if (!IsBlockMode() && m_xImpl->m_xChapterNumbering.is())
420 {
421 Reference< XPropertySet > const xNumRuleProps(
422 m_xImpl->m_xChapterNumbering, UNO_QUERY);
423 if ( xNumRuleProps.is() )
424 {
425 Reference< XPropertySetInfo > xNumRulePropSetInfo(
426 xNumRuleProps->getPropertySetInfo());
427 if (xNumRulePropSetInfo.is() &&
428 xNumRulePropSetInfo->hasPropertyByName(
429 s_PropNameDefaultListId))
430 {
431 OUString sListId;
432 xNumRuleProps->getPropertyValue(s_PropNameDefaultListId)
433 >>= sListId;
434 assert( !sListId.isEmpty() &&
435 "no default list id found at chapter numbering rules instance. Serious defect." );
436 if ( !sListId.isEmpty() )
437 {
438 Reference< XNamed > const xChapterNumNamed(
439 m_xImpl->m_xChapterNumbering, UNO_QUERY);
440 if ( xChapterNumNamed.is() )
441 {
442 m_xImpl->m_xTextListsHelper->KeepListAsProcessed(
443 sListId,
444 xChapterNumNamed->getName(),
445 OUString() );
446 }
447 }
448 }
449 }
450 }
451 }
452
453 Reference< XStyleFamiliesSupplier > xFamiliesSupp( rModel, UNO_QUERY );
454 // SAL_WARN_IF( !xFamiliesSupp.is(), "xmloff", "no chapter numbering supplier" ); for clipboard there may be documents without styles
455
456 if( xFamiliesSupp.is() )
457 {
458 Reference< XNameAccess > xFamilies(xFamiliesSupp->getStyleFamilies());
459
460 static const OUStringLiteral aParaStyles(u"ParagraphStyles");
461 if( xFamilies->hasByName( aParaStyles ) )
462 {
463 m_xImpl->m_xParaStyles.set(xFamilies->getByName(aParaStyles),
464 UNO_QUERY);
465 }
466
467 static const OUStringLiteral aCharStyles(u"CharacterStyles");
468 if( xFamilies->hasByName( aCharStyles ) )
469 {
470 m_xImpl->m_xTextStyles.set(xFamilies->getByName(aCharStyles),
471 UNO_QUERY);
472 }
473
474 static const OUStringLiteral aNumStyles(u"NumberingStyles");
475 if( xFamilies->hasByName( aNumStyles ) )
476 {
477 m_xImpl->m_xNumStyles.set(xFamilies->getByName(aNumStyles),
478 UNO_QUERY);
479 }
480
481 static const OUStringLiteral aFrameStyles(u"FrameStyles");
482 if( xFamilies->hasByName( aFrameStyles ) )
483 {
484 m_xImpl->m_xFrameStyles.set(xFamilies->getByName(aFrameStyles),
485 UNO_QUERY);
486 }
487
488 static const OUStringLiteral aPageStyles(u"PageStyles");
489 if( xFamilies->hasByName( aPageStyles ) )
490 {
491 m_xImpl->m_xPageStyles.set(xFamilies->getByName(aPageStyles),
492 UNO_QUERY);
493 }
494
495 static const OUStringLiteral aCellStyles(u"CellStyles");
496 if( xFamilies->hasByName( aCellStyles ) )
497 {
498 m_xImpl->m_xCellStyles.set(xFamilies->getByName(aCellStyles),
499 UNO_QUERY);
500 }
501 }
502
503 Reference < XTextFramesSupplier > xTFS( rModel, UNO_QUERY );
504 if( xTFS.is() )
505 {
506 m_xImpl->m_xTextFrames.set(xTFS->getTextFrames());
507 }
508
509 Reference < XTextGraphicObjectsSupplier > xTGOS( rModel, UNO_QUERY );
510 if( xTGOS.is() )
511 {
512 m_xImpl->m_xGraphics.set(xTGOS->getGraphicObjects());
513 }
514
515 Reference < XTextEmbeddedObjectsSupplier > xTEOS( rModel, UNO_QUERY );
516 if( xTEOS.is() )
517 {
518 m_xImpl->m_xObjects.set(xTEOS->getEmbeddedObjects());
519 }
520
521 XMLPropertySetMapper *pPropMapper =
522 new XMLTextPropertySetMapper( TextPropMap::PARA, false );
523 m_xImpl->m_xParaImpPrMap =
524 new XMLTextImportPropertyMapper( pPropMapper, rImport );
525
526 pPropMapper = new XMLTextPropertySetMapper( TextPropMap::TEXT, false );
527 m_xImpl->m_xTextImpPrMap =
528 new XMLTextImportPropertyMapper( pPropMapper, rImport );
529
530 pPropMapper = new XMLTextPropertySetMapper( TextPropMap::FRAME, false );
531 m_xImpl->m_xFrameImpPrMap =
532 new XMLTextImportPropertyMapper( pPropMapper, rImport );
533
534 pPropMapper = new XMLTextPropertySetMapper( TextPropMap::SECTION, false );
535 m_xImpl->m_xSectionImpPrMap =
536 new XMLTextImportPropertyMapper( pPropMapper, rImport );
537
538 pPropMapper = new XMLTextPropertySetMapper( TextPropMap::RUBY, false );
539 m_xImpl->m_xRubyImpPrMap =
540 new SvXMLImportPropertyMapper( pPropMapper, rImport );
541 }
542
~XMLTextImportHelper()543 XMLTextImportHelper::~XMLTextImportHelper()
544 {
545 }
546
dispose()547 void XMLTextImportHelper::dispose()
548 {
549 if (m_xImpl->m_xAutoStyles)
550 m_xImpl->m_xAutoStyles->dispose();
551 }
552
CreateShapeExtPropMapper(SvXMLImport & rImport)553 SvXMLImportPropertyMapper *XMLTextImportHelper::CreateShapeExtPropMapper(SvXMLImport& rImport)
554 {
555 XMLPropertySetMapper *pPropMapper =
556 new XMLTextPropertySetMapper( TextPropMap::FRAME, false );
557 return new XMLTextImportPropertyMapper( pPropMapper, rImport );
558 }
559
CreateParaExtPropMapper(SvXMLImport & rImport)560 SvXMLImportPropertyMapper *XMLTextImportHelper::CreateParaExtPropMapper(SvXMLImport& rImport)
561 {
562 XMLPropertySetMapper *pPropMapper =
563 new XMLTextPropertySetMapper( TextPropMap::SHAPE_PARA, false );
564 return new XMLTextImportPropertyMapper( pPropMapper, rImport );
565 }
566
CreateParaDefaultExtPropMapper(SvXMLImport & rImport)567 SvXMLImportPropertyMapper *XMLTextImportHelper::CreateParaDefaultExtPropMapper(SvXMLImport& rImport)
568 {
569 XMLPropertySetMapper* pPropMapper =
570 new XMLTextPropertySetMapper( TextPropMap::SHAPE_PARA, false );
571 SvXMLImportPropertyMapper* pImportMapper = new XMLTextImportPropertyMapper( pPropMapper, rImport );
572
573 pPropMapper =
574 new XMLTextPropertySetMapper( TextPropMap::TEXT_ADDITIONAL_DEFAULTS, false );
575 pImportMapper->ChainImportMapper( new XMLTextImportPropertyMapper( pPropMapper, rImport ) );
576
577 return pImportMapper;
578 }
579
580 SvXMLImportPropertyMapper*
CreateTableDefaultExtPropMapper(SvXMLImport & rImport)581 XMLTextImportHelper::CreateTableDefaultExtPropMapper(
582 SvXMLImport& rImport )
583 {
584 XMLPropertySetMapper *pPropMapper =
585 new XMLTextPropertySetMapper( TextPropMap::TABLE_DEFAULTS, false );
586 return new SvXMLImportPropertyMapper( pPropMapper, rImport );
587 }
588
589 SvXMLImportPropertyMapper*
CreateTableRowDefaultExtPropMapper(SvXMLImport & rImport)590 XMLTextImportHelper::CreateTableRowDefaultExtPropMapper(
591 SvXMLImport& rImport )
592 {
593 XMLPropertySetMapper *pPropMapper =
594 new XMLTextPropertySetMapper( TextPropMap::TABLE_ROW_DEFAULTS, false );
595 return new SvXMLImportPropertyMapper( pPropMapper, rImport );
596 }
597
598 SvXMLImportPropertyMapper*
CreateTableCellExtPropMapper(SvXMLImport & rImport)599 XMLTextImportHelper::CreateTableCellExtPropMapper(
600 SvXMLImport& rImport )
601 {
602 XMLPropertySetMapper *pPropMapper =
603 new XMLTextPropertySetMapper( TextPropMap::CELL, false );
604 return new XMLTextImportPropertyMapper( pPropMapper, rImport );
605 }
606
607 SvXMLImportPropertyMapper*
CreateDrawingPageExtPropMapper(SvXMLImport & rImport)608 XMLTextImportHelper::CreateDrawingPageExtPropMapper(SvXMLImport& rImport)
609 {
610 rtl::Reference<XMLPropertyHandlerFactory> const pFactory(new XMLPageMasterPropHdlFactory);
611 XMLPropertySetMapper *const pPropMapper(
612 new XMLPropertySetMapper(g_XMLPageMasterDrawingPageStyleMap, pFactory, false));
613 return new SvXMLImportPropertyMapper(pPropMapper, rImport);
614 }
615
SetCursor(const Reference<XTextCursor> & rCursor)616 void XMLTextImportHelper::SetCursor( const Reference < XTextCursor > & rCursor )
617 {
618 m_xImpl->m_xCursor.set(rCursor);
619 m_xImpl->m_xText.set(rCursor->getText());
620 m_xImpl->m_xCursorAsRange = rCursor;
621 }
622
ResetCursor()623 void XMLTextImportHelper::ResetCursor()
624 {
625 m_xImpl->m_xCursor.set(nullptr);
626 m_xImpl->m_xText.set(nullptr);
627 m_xImpl->m_xCursorAsRange.set(nullptr);
628 }
629
630
HasFrameByName(const OUString & rName) const631 bool XMLTextImportHelper::HasFrameByName( const OUString& rName ) const
632 {
633 return (m_xImpl->m_xTextFrames.is() &&
634 m_xImpl->m_xTextFrames->hasByName(rName))
635 || (m_xImpl->m_xGraphics.is() &&
636 m_xImpl->m_xGraphics->hasByName(rName))
637 || (m_xImpl->m_xObjects.is() &&
638 m_xImpl->m_xObjects->hasByName(rName));
639 }
640
IsDuplicateFrame(const OUString & sName,sal_Int32 nX,sal_Int32 nY,sal_Int32 nWidth,sal_Int32 nHeight) const641 bool XMLTextImportHelper::IsDuplicateFrame(const OUString& sName, sal_Int32 nX, sal_Int32 nY, sal_Int32 nWidth, sal_Int32 nHeight) const
642 {
643 if (HasFrameByName(sName))
644 {
645 uno::Reference<beans::XPropertySet> xOtherFrame;
646 if(m_xImpl->m_xTextFrames.is() && m_xImpl->m_xTextFrames->hasByName(sName))
647 xOtherFrame.set(m_xImpl->m_xTextFrames->getByName(sName), uno::UNO_QUERY);
648 else if(m_xImpl->m_xGraphics.is() && m_xImpl->m_xGraphics->hasByName(sName))
649 xOtherFrame.set(m_xImpl->m_xGraphics->getByName(sName), uno::UNO_QUERY);
650 else if (m_xImpl->m_xObjects.is() && m_xImpl->m_xObjects->hasByName(sName))
651 xOtherFrame.set(m_xImpl->m_xObjects->getByName(sName), uno::UNO_QUERY);
652
653 Reference< XPropertySetInfo > xPropSetInfo = xOtherFrame->getPropertySetInfo();
654 if(xPropSetInfo->hasPropertyByName("Width"))
655 {
656 sal_Int32 nOtherWidth = 0;
657 xOtherFrame->getPropertyValue("Width") >>= nOtherWidth;
658 if(nWidth != nOtherWidth)
659 return false;
660 }
661
662 if (xPropSetInfo->hasPropertyByName("Height"))
663 {
664 sal_Int32 nOtherHeight = 0;
665 xOtherFrame->getPropertyValue("Height") >>= nOtherHeight;
666 if (nHeight != nOtherHeight)
667 return false;
668 }
669
670 if (xPropSetInfo->hasPropertyByName("HoriOrientPosition"))
671 {
672 sal_Int32 nOtherX = 0;
673 xOtherFrame->getPropertyValue("HoriOrientPosition") >>= nOtherX;
674 if (nX != nOtherX)
675 return false;
676 }
677
678 if (xPropSetInfo->hasPropertyByName("VertOrientPosition"))
679 {
680 sal_Int32 nOtherY = 0;
681 xOtherFrame->getPropertyValue("VertOrientPosition") >>= nOtherY;
682 if (nY != nOtherY)
683 return false;
684 }
685
686 // In some case, position is not defined for frames, so check whether the two frames follow each other (are anchored to the same position)
687 return m_xImpl->msLastImportedFrameName == sName;
688 }
689 return false;
690 }
691
StoreLastImportedFrameName(const OUString & rName)692 void XMLTextImportHelper::StoreLastImportedFrameName(const OUString& rName)
693 {
694 m_xImpl->msLastImportedFrameName = rName;
695 }
696
ClearLastImportedTextFrameName()697 void XMLTextImportHelper::ClearLastImportedTextFrameName()
698 {
699 m_xImpl->msLastImportedFrameName.clear();
700 }
701
InsertString(const OUString & rChars)702 void XMLTextImportHelper::InsertString( const OUString& rChars )
703 {
704 assert(m_xImpl->m_xText.is());
705 assert(m_xImpl->m_xCursorAsRange.is());
706 if (m_xImpl->m_xText.is())
707 {
708 m_xImpl->m_xText->insertString(m_xImpl->m_xCursorAsRange,
709 rChars, false);
710 }
711 }
712
InsertString(const OUString & rChars,bool & rIgnoreLeadingSpace)713 void XMLTextImportHelper::InsertString( const OUString& rChars,
714 bool& rIgnoreLeadingSpace )
715 {
716 assert(m_xImpl->m_xText.is());
717 assert(m_xImpl->m_xCursorAsRange.is());
718 if (m_xImpl->m_xText.is())
719 {
720 sal_Int32 nLen = rChars.getLength();
721 OUStringBuffer sChars( nLen );
722
723 for( sal_Int32 i=0; i < nLen; i++ )
724 {
725 sal_Unicode c = rChars[i];
726 switch( c )
727 {
728 case 0x20:
729 case 0x09:
730 case 0x0a:
731 case 0x0d:
732 if( !rIgnoreLeadingSpace )
733 sChars.append( u' ' );
734 rIgnoreLeadingSpace = true;
735 break;
736 default:
737 rIgnoreLeadingSpace = false;
738 sChars.append( c );
739 break;
740 }
741 }
742 m_xImpl->m_xText->insertString(m_xImpl->m_xCursorAsRange,
743 sChars.makeStringAndClear(), false);
744 }
745 }
746
InsertControlCharacter(sal_Int16 nControl)747 void XMLTextImportHelper::InsertControlCharacter( sal_Int16 nControl )
748 {
749 assert(m_xImpl->m_xText.is());
750 assert(m_xImpl->m_xCursorAsRange.is());
751 if (m_xImpl->m_xText.is())
752 {
753 m_xImpl->m_xText->insertControlCharacter(
754 m_xImpl->m_xCursorAsRange, nControl, false);
755 }
756 }
757
InsertTextContent(Reference<XTextContent> const & xContent)758 void XMLTextImportHelper::InsertTextContent(
759 Reference < XTextContent > const & xContent )
760 {
761 assert(m_xImpl->m_xText.is());
762 assert(m_xImpl->m_xCursorAsRange.is());
763 if (m_xImpl->m_xText.is())
764 {
765 // note: this may throw IllegalArgumentException and callers handle it
766 m_xImpl->m_xText->insertTextContent( m_xImpl->m_xCursorAsRange, xContent, false);
767 }
768 }
769
DeleteParagraph()770 void XMLTextImportHelper::DeleteParagraph()
771 {
772 assert(m_xImpl->m_xText.is());
773 assert(m_xImpl->m_xCursor.is());
774 assert(m_xImpl->m_xCursorAsRange.is());
775
776 bool bDelete = true;
777 Reference < XEnumerationAccess > const xEnumAccess(
778 m_xImpl->m_xCursor, UNO_QUERY);
779 if( xEnumAccess.is() )
780 {
781 Reference < XEnumeration > xEnum(xEnumAccess->createEnumeration());
782 SAL_WARN_IF(!xEnum->hasMoreElements(), "xmloff.text",
783 "empty text enumeration");
784 if( xEnum->hasMoreElements() )
785 {
786 Reference < XComponent > xComp( xEnum->nextElement(), UNO_QUERY );
787 assert(xComp.is());
788 if( xComp.is() )
789 {
790 xComp->dispose();
791 bDelete = false;
792 }
793 }
794 }
795 if( bDelete )
796 {
797 if (m_xImpl->m_xCursor->goLeft( 1, true ))
798 {
799 m_xImpl->m_xText->insertString(m_xImpl->m_xCursorAsRange,
800 "", true);
801 }
802 }
803 }
804
ConvertStarFonts(const OUString & rChars,const OUString & rStyleName,sal_uInt8 & rFlags,bool bPara,SvXMLImport & rImport) const805 OUString XMLTextImportHelper::ConvertStarFonts( const OUString& rChars,
806 const OUString& rStyleName,
807 sal_uInt8& rFlags,
808 bool bPara,
809 SvXMLImport& rImport ) const
810 {
811 OUStringBuffer sChars( rChars );
812 bool bConverted = false;
813 for( sal_Int32 j=0; j<rChars.getLength(); j++ )
814 {
815 sal_Unicode c = rChars[j];
816 if( c >= 0xf000 && c <= 0xf0ff )
817 {
818 if( (rFlags & CONV_STAR_FONT_FLAGS_VALID) == 0 )
819 {
820 XMLTextStyleContext *pStyle = nullptr;
821 XmlStyleFamily nFamily = bPara ? XmlStyleFamily::TEXT_PARAGRAPH
822 : XmlStyleFamily::TEXT_TEXT;
823 if (!rStyleName.isEmpty() && m_xImpl->m_xAutoStyles.is())
824 {
825 const SvXMLStyleContext* pTempStyle =
826 m_xImpl->m_xAutoStyles->
827 FindStyleChildContext( nFamily, rStyleName,
828 true );
829 pStyle = const_cast<XMLTextStyleContext*>( dynamic_cast< const XMLTextStyleContext* >(pTempStyle));
830 }
831
832 if( pStyle )
833 {
834 sal_Int32 nCount = pStyle->GetProperties_().size();
835 if( nCount )
836 {
837 rtl::Reference < SvXMLImportPropertyMapper > xImpPrMap =
838 m_xImpl->m_xAutoStyles->GetImportPropertyMapper(nFamily);
839 if( xImpPrMap.is() )
840 {
841 rtl::Reference<XMLPropertySetMapper> rPropMapper =
842 xImpPrMap->getPropertySetMapper();
843 for( sal_Int32 i=0; i < nCount; i++ )
844 {
845 const XMLPropertyState& rProp = pStyle->GetProperties_()[i];
846 sal_Int32 nIdx = rProp.mnIndex;
847 sal_uInt32 nContextId = rPropMapper->GetEntryContextId(nIdx);
848 if( CTF_FONTFAMILYNAME == nContextId )
849 {
850 rFlags &= ~(CONV_FROM_STAR_BATS|CONV_FROM_STAR_MATH);
851 OUString sFontName;
852 rProp.maValue >>= sFontName;
853 if( sFontName.equalsIgnoreAsciiCase( "StarBats" ) )
854 rFlags |= CONV_FROM_STAR_BATS;
855 else if( sFontName.equalsIgnoreAsciiCase( "StarMath" ) )
856 rFlags |= CONV_FROM_STAR_MATH;
857 break;
858 }
859 }
860 }
861 }
862
863 }
864
865 rFlags |= CONV_STAR_FONT_FLAGS_VALID;
866 }
867 if( (rFlags & CONV_FROM_STAR_BATS ) != 0 )
868 {
869 sChars[j] = rImport.ConvStarBatsCharToStarSymbol( c );
870 bConverted = true;
871 }
872 else if( (rFlags & CONV_FROM_STAR_MATH ) != 0 )
873 {
874 sChars[j] = rImport.ConvStarMathCharToStarSymbol( c );
875 bConverted = true;
876 }
877 }
878 }
879
880 return bConverted ? sChars.makeStringAndClear() : rChars;
881 }
882
883 /* Helper method to determine, if a paragraph style has a list style (inclusive
884 an empty one) inherits a list style (inclusive an empty one) from one of its parents (#i69629#)
885 */
886 /* Apply special case, that found list style equals the chapter numbering, also
887 to the found list styles of the parent styles. (#i73973#)
888 */
lcl_HasListStyle(const OUString & sStyleName,const Reference<XNameContainer> & xParaStyles,SvXMLImport const & rImport,const OUString & sNumberingStyleName,std::u16string_view sOutlineStyleName)889 static bool lcl_HasListStyle( const OUString& sStyleName,
890 const Reference < XNameContainer >& xParaStyles,
891 SvXMLImport const & rImport,
892 const OUString& sNumberingStyleName,
893 std::u16string_view sOutlineStyleName )
894 {
895 bool bRet( false );
896
897 if ( !xParaStyles->hasByName( sStyleName ) )
898 {
899 // error case
900 return true;
901 }
902
903 Reference< XPropertyState > xPropState( xParaStyles->getByName( sStyleName ),
904 UNO_QUERY );
905 if ( !xPropState.is() )
906 {
907 // error case
908 return false;
909 }
910
911 if ( xPropState->getPropertyState( sNumberingStyleName ) == PropertyState_DIRECT_VALUE )
912 {
913 // list style found
914 bRet = true;
915 // special case: the set list style equals the chapter numbering
916 Reference< XPropertySet > xPropSet( xPropState, UNO_QUERY );
917 if ( xPropSet.is() )
918 {
919 OUString sListStyle;
920 xPropSet->getPropertyValue( sNumberingStyleName ) >>= sListStyle;
921 if ( !sListStyle.isEmpty() &&
922 sListStyle == sOutlineStyleName )
923 {
924 bRet = false;
925 }
926 }
927 }
928 else
929 {
930 // Tools.Outline settings lost on Save (#i77708#)
931 sal_Int32 nUPD( 0 );
932 sal_Int32 nBuild( 0 );
933 // Don't use UPD for versioning: xmloff/source/text/txtstyli.cxx and txtimp.cxx (#i86058#)
934 const bool bBuildIdFound = rImport.getBuildIds( nUPD, nBuild );
935 // search list style at parent
936 Reference<XStyle> xStyle( xPropState, UNO_QUERY );
937 while ( xStyle.is() )
938 {
939 OUString aParentStyle( xStyle->getParentStyle() );
940 if ( !aParentStyle.isEmpty() )
941 {
942 aParentStyle =
943 rImport.GetStyleDisplayName( XmlStyleFamily::TEXT_PARAGRAPH,
944 aParentStyle );
945 }
946 if ( aParentStyle.isEmpty() || !xParaStyles->hasByName( aParentStyle ) )
947 {
948 // no list style found
949 break;
950 }
951 else
952 {
953 xPropState.set( xParaStyles->getByName( aParentStyle ),
954 UNO_QUERY );
955 if ( !xPropState.is() )
956 {
957 // error case
958 return true;
959 }
960 if ( xPropState->getPropertyState( sNumberingStyleName ) == PropertyState_DIRECT_VALUE )
961 {
962 // list style found
963 bRet = true;
964 // Special case: the found list style equals the chapter numbering (#i73973#)
965 Reference< XPropertySet > xPropSet( xPropState, UNO_QUERY );
966 if ( xPropSet.is() )
967 {
968 OUString sListStyle;
969 xPropSet->getPropertyValue( sNumberingStyleName ) >>= sListStyle;
970 if ( !sListStyle.isEmpty() &&
971 sListStyle == sOutlineStyleName )
972 {
973 bRet = false;
974 }
975 // Special handling for text documents from OOo version prior OOo 2.4 (#i77708#)
976 /* Check explicitly on certain versions and on import of
977 text documents in OpenOffice.org file format (#i86058#)
978 */
979 else if ( sListStyle.isEmpty() &&
980 ( rImport.IsTextDocInOOoFileFormat() ||
981 ( bBuildIdFound &&
982 ( ( nUPD == 641 ) || ( nUPD == 645 ) || // prior OOo 2.0
983 ( nUPD == 680 && nBuild <= 9238 ) ) ) ) ) // OOo 2.0 - OOo 2.3.1
984 {
985 bRet = false;
986 }
987 }
988 break;
989 }
990 else
991 {
992 // search list style at parent
993 Reference<XStyle> xParentStyle(xPropState, UNO_QUERY);
994 if (xStyle == xParentStyle)
995 {
996 // error case
997 return true;
998 }
999 xStyle = xParentStyle;
1000 }
1001 }
1002 }
1003 }
1004
1005 return bRet;
1006 }
SetStyleAndAttrs(SvXMLImport const & rImport,const Reference<XTextCursor> & rCursor,const OUString & rStyleName,bool bPara,bool bOutlineLevelAttrFound,sal_Int8 nOutlineLevel,bool bSetListAttrs,bool bOutlineContentVisible)1007 OUString XMLTextImportHelper::SetStyleAndAttrs(
1008 SvXMLImport const & rImport,
1009 const Reference < XTextCursor >& rCursor,
1010 const OUString& rStyleName,
1011 bool bPara,
1012 bool bOutlineLevelAttrFound,
1013 sal_Int8 nOutlineLevel,
1014 // Numberings/Bullets in table not visible after save/reload (#i80724#)
1015 bool bSetListAttrs,
1016 bool bOutlineContentVisible)
1017 {
1018 static constexpr OUStringLiteral s_NumberingRules = u"NumberingRules";
1019 static constexpr OUStringLiteral s_NumberingIsNumber = u"NumberingIsNumber";
1020 static constexpr OUStringLiteral s_NumberingLevel = u"NumberingLevel";
1021 static constexpr OUStringLiteral s_ParaIsNumberingRestart = u"ParaIsNumberingRestart";
1022 static constexpr OUStringLiteral s_NumberingStartValue = u"NumberingStartValue";
1023 static constexpr OUStringLiteral s_PropNameListId = u"ListId";
1024 static constexpr OUStringLiteral s_PageDescName = u"PageDescName";
1025 static constexpr OUStringLiteral s_OutlineLevel = u"OutlineLevel";
1026
1027 const XmlStyleFamily nFamily = bPara ? XmlStyleFamily::TEXT_PARAGRAPH
1028 : XmlStyleFamily::TEXT_TEXT;
1029 XMLTextStyleContext *pStyle = nullptr;
1030 OUString sStyleName( rStyleName );
1031 if (!sStyleName.isEmpty() && m_xImpl->m_xAutoStyles.is())
1032 {
1033 const SvXMLStyleContext* pTempStyle =
1034 m_xImpl->m_xAutoStyles->FindStyleChildContext( nFamily, sStyleName, true );
1035 pStyle = const_cast<XMLTextStyleContext*>(dynamic_cast< const XMLTextStyleContext* >(pTempStyle));
1036 }
1037 if( pStyle )
1038 sStyleName = pStyle->GetParentName();
1039
1040 Reference < XPropertySet > xPropSet( rCursor, UNO_QUERY );
1041 Reference< XPropertySetInfo > xPropSetInfo(
1042 xPropSet->getPropertySetInfo());
1043
1044 // style
1045 if( !sStyleName.isEmpty() )
1046 {
1047 sStyleName = rImport.GetStyleDisplayName( nFamily, sStyleName );
1048 const OUString rPropName = bPara ? OUString("ParaStyleName") : OUString("CharStyleName");
1049 const Reference < XNameContainer > & rStyles = bPara
1050 ? m_xImpl->m_xParaStyles
1051 : m_xImpl->m_xTextStyles;
1052 if( rStyles.is() &&
1053 xPropSetInfo->hasPropertyByName( rPropName ) &&
1054 rStyles->hasByName( sStyleName ) )
1055 {
1056 xPropSet->setPropertyValue( rPropName, makeAny(sStyleName) );
1057 }
1058 else
1059 sStyleName.clear();
1060 }
1061
1062 /* The outline level needs to be only applied as list level, if the heading
1063 is not inside a list and if it by default applies the outline style. (#i70748#)
1064 */
1065 bool bApplyOutlineLevelAsListLevel( false );
1066 // Numberings/Bullets in table not visible after save/reload (#i80724#)
1067 if (bSetListAttrs && bPara
1068 && xPropSetInfo->hasPropertyByName( s_NumberingRules))
1069 {
1070 // Set numbering rules
1071 Reference< XIndexReplace > const xNumRules(
1072 xPropSet->getPropertyValue(s_NumberingRules), UNO_QUERY);
1073
1074 XMLTextListBlockContext * pListBlock(nullptr);
1075 XMLTextListItemContext * pListItem(nullptr);
1076 XMLNumberedParaContext * pNumberedParagraph(nullptr);
1077 GetTextListHelper().ListContextTop(
1078 pListBlock, pListItem, pNumberedParagraph);
1079
1080 assert(!(pListBlock && pNumberedParagraph) && "XMLTextImportHelper::"
1081 "SetStyleAndAttrs: both list and numbered-paragraph???");
1082
1083 Reference < XIndexReplace > xNewNumRules;
1084 sal_Int8 nLevel(-1);
1085 OUString sListId;
1086 sal_Int16 nStartValue(-1);
1087 bool bNumberingIsNumber(true);
1088
1089 if (pListBlock) {
1090
1091 if (!pListItem) {
1092 bNumberingIsNumber = false; // list-header
1093 }
1094 // consider text:style-override property of <text:list-item>
1095 xNewNumRules.set(
1096 (pListItem != nullptr && pListItem->HasNumRulesOverride())
1097 ? pListItem->GetNumRulesOverride()
1098 : pListBlock->GetNumRules() );
1099 nLevel = static_cast<sal_Int8>(pListBlock->GetLevel());
1100
1101 if ( pListItem && pListItem->HasStartValue() ) {
1102 nStartValue = pListItem->GetStartValue();
1103 }
1104
1105 // Inconsistent behavior regarding lists (#i92811#)
1106 sListId = m_xImpl->m_xTextListsHelper->GetListIdForListBlock(
1107 *pListBlock);
1108 }
1109 else if (pNumberedParagraph)
1110 {
1111 xNewNumRules.set(pNumberedParagraph->GetNumRules());
1112 nLevel = static_cast<sal_Int8>(pNumberedParagraph->GetLevel());
1113 sListId = pNumberedParagraph->GetListId();
1114 nStartValue = pNumberedParagraph->GetStartValue();
1115 }
1116
1117
1118 if (pListBlock || pNumberedParagraph)
1119 {
1120 // Assure that list style of automatic paragraph style is applied at paragraph. (#i101349#)
1121 bool bApplyNumRules = pStyle && pStyle->IsListStyleSet();
1122 if ( !bApplyNumRules )
1123 {
1124 bool bSameNumRules = xNewNumRules == xNumRules;
1125 if( !bSameNumRules && xNewNumRules.is() && xNumRules.is() )
1126 {
1127 // If the interface pointers are different, then this does
1128 // not mean that the num rules are different. Further tests
1129 // are required then. However, if only one num rule is
1130 // set, no tests are required of course.
1131 Reference< XNamed > xNewNamed( xNewNumRules, UNO_QUERY );
1132 Reference< XNamed > xNamed( xNumRules, UNO_QUERY );
1133 if( xNewNamed.is() && xNamed.is() )
1134 {
1135 bSameNumRules = xNewNamed->getName() == xNamed->getName();
1136 }
1137 else
1138 {
1139 Reference< XAnyCompare > xNumRuleCompare( xNumRules, UNO_QUERY );
1140 if( xNumRuleCompare.is() )
1141 {
1142 bSameNumRules = (xNumRuleCompare->compare( Any(xNumRules), Any(xNewNumRules) ) == 0);
1143 }
1144 }
1145 }
1146 bApplyNumRules = !bSameNumRules;
1147 }
1148
1149 if ( bApplyNumRules )
1150 {
1151 // #102607# This may except when xNewNumRules contains
1152 // a Writer-NumRule-Implementation bug gets applied to
1153 // a shape. Since this may occur inside a document
1154 // (e.g. when edited), this must be handled
1155 // gracefully.
1156 try
1157 {
1158 xPropSet->setPropertyValue(
1159 s_NumberingRules, makeAny(xNewNumRules) );
1160 }
1161 catch(const Exception&)
1162 {
1163 ; // I would really like to use a warning here,
1164 // but I can't access the XMLErrorHandler from
1165 // here.
1166 }
1167 }
1168
1169 if (!bNumberingIsNumber &&
1170 xPropSetInfo->hasPropertyByName(s_NumberingIsNumber))
1171 {
1172 xPropSet->setPropertyValue(s_NumberingIsNumber, Any(false));
1173 }
1174
1175 xPropSet->setPropertyValue( s_NumberingLevel, Any(nLevel) );
1176
1177 if( pListBlock && pListBlock->IsRestartNumbering() )
1178 {
1179 // TODO: property missing
1180 if (xPropSetInfo->hasPropertyByName(s_ParaIsNumberingRestart))
1181 {
1182 xPropSet->setPropertyValue(s_ParaIsNumberingRestart,
1183 makeAny(true) );
1184 }
1185 pListBlock->ResetRestartNumbering();
1186 }
1187
1188 if ( 0 <= nStartValue &&
1189 xPropSetInfo->hasPropertyByName(s_NumberingStartValue))
1190 {
1191 xPropSet->setPropertyValue(s_NumberingStartValue,
1192 makeAny(nStartValue));
1193 }
1194
1195 if (xPropSetInfo->hasPropertyByName(s_PropNameListId))
1196 {
1197 if (!sListId.isEmpty()) {
1198 xPropSet->setPropertyValue(s_PropNameListId,
1199 makeAny(sListId) );
1200 }
1201 }
1202
1203 GetTextListHelper().SetListItem( nullptr );
1204 }
1205 else
1206 {
1207 /* If the paragraph is not in a list but its style, remove it from
1208 the list. Do not remove it, if the list of the style is
1209 the chapter numbering rule.
1210 */
1211 if( xNumRules.is() )
1212 {
1213 bool bRemove( true );
1214 // Special handling for document from OOo 2.x (#i70748#)
1215 sal_Int32 nUPD( 0 );
1216 sal_Int32 nBuild( 0 );
1217 const bool bBuildIdFound = rImport.getBuildIds( nUPD, nBuild );
1218 if ( ( bBuildIdFound && nUPD == 680 ) ||
1219 !pStyle || !pStyle->IsListStyleSet() )
1220 {
1221 if (m_xImpl->m_xChapterNumbering.is())
1222 {
1223 Reference< XNamed > xNumNamed( xNumRules, UNO_QUERY );
1224 Reference< XNamed > const xChapterNumNamed (
1225 m_xImpl->m_xChapterNumbering, UNO_QUERY);
1226 if ( xNumNamed.is() && xChapterNumNamed.is() &&
1227 xNumNamed->getName() == xChapterNumNamed->getName() )
1228 {
1229 bRemove = false;
1230 // RFE: inserting headings into text documents (#i70748#)
1231 bApplyOutlineLevelAsListLevel = true;
1232 }
1233 }
1234 }
1235 else
1236 {
1237 SAL_INFO_IF(!pStyle->GetListStyle().isEmpty(),
1238 "xmloff.text",
1239 "automatic paragraph style with list style name, but paragraph not in list???");
1240 }
1241 if ( bRemove )
1242 {
1243 xPropSet->setPropertyValue( s_NumberingRules, Any() );
1244 }
1245 }
1246 }
1247 }
1248
1249 // hard paragraph properties
1250 if( pStyle )
1251 {
1252 pStyle->FillPropertySet( xPropSet );
1253 if( bPara && pStyle->HasMasterPageName() &&
1254 xPropSetInfo->hasPropertyByName(s_PageDescName))
1255 {
1256 OUString sDisplayName(
1257 rImport.GetStyleDisplayName(
1258 XmlStyleFamily::MASTER_PAGE,
1259 pStyle->GetMasterPageName()) );
1260 if( sDisplayName.isEmpty() ||
1261 (m_xImpl->m_xPageStyles.is() &&
1262 m_xImpl->m_xPageStyles->hasByName( sDisplayName)))
1263 {
1264 xPropSet->setPropertyValue(s_PageDescName,
1265 makeAny(sDisplayName));
1266 }
1267 }
1268 if( bPara && !pStyle->GetDropCapStyleName().isEmpty() &&
1269 m_xImpl->m_xTextStyles.is())
1270 {
1271 OUString sDisplayName(
1272 rImport.GetStyleDisplayName(
1273 XmlStyleFamily::TEXT_TEXT,
1274 pStyle->GetDropCapStyleName()) );
1275 if (m_xImpl->m_xTextStyles->hasByName(sDisplayName) &&
1276 xPropSetInfo->hasPropertyByName("DropCapCharStyleName"))
1277 {
1278 xPropSet->setPropertyValue("DropCapCharStyleName", makeAny(sDisplayName));
1279 }
1280 }
1281
1282 // combined characters special treatment
1283 if (!bPara && pStyle->HasCombinedCharactersLetter())
1284 {
1285 // insert combined characters text field
1286 if (m_xImpl->m_xServiceFactory.is())
1287 {
1288 uno::Reference<beans::XPropertySet> const xTmp(
1289 m_xImpl->m_xServiceFactory->createInstance(
1290 "com.sun.star.text.TextField.CombinedCharacters"), UNO_QUERY);
1291 if( xTmp.is() )
1292 {
1293 // fix cursor if larger than possible for
1294 // combined characters field
1295 if (rCursor->getString().getLength() >
1296 MAX_COMBINED_CHARACTERS)
1297 {
1298 rCursor->gotoRange(rCursor->getStart(), false);
1299 rCursor->goRight(MAX_COMBINED_CHARACTERS, true);
1300 }
1301
1302 // set field value (the combined character string)
1303 xTmp->setPropertyValue("Content",
1304 makeAny(rCursor->getString()));
1305
1306 // insert the field over it's original text
1307 Reference<XTextContent> xTextContent(xTmp, UNO_QUERY);
1308 if (m_xImpl->m_xText.is() && rCursor.is())
1309 {
1310 // #i107225# the combined characters need to be inserted first
1311 // the selected text has to be removed afterwards
1312 m_xImpl->m_xText->insertTextContent( rCursor->getStart(), xTextContent, true );
1313
1314 if( !rCursor->getString().isEmpty() )
1315 {
1316 try
1317 {
1318 uno::Reference< text::XTextCursor > xCrsr = rCursor->getText()->createTextCursorByRange( rCursor->getStart() );
1319 xCrsr->goLeft( 1, true );
1320 uno::Reference< beans::XPropertySet> xCrsrProperties( xCrsr, uno::UNO_QUERY_THROW );
1321 //the hard properties of the removed text need to be applied to the combined characters field
1322 pStyle->FillPropertySet( xCrsrProperties );
1323 xCrsr->collapseToEnd();
1324 xCrsr->gotoRange( rCursor->getEnd(), true );
1325 xCrsr->setString( OUString() );
1326 }
1327 catch(const uno::Exception&)
1328 {
1329 }
1330 }
1331 }
1332 }
1333 }
1334 }
1335 }
1336
1337 // outline level; set after list style has been set
1338 // Complete re-worked and corrected: (#i53198#)
1339 // - set outline level at paragraph
1340 // - set numbering level at paragraph, if none is already set
1341 // - assure that style is marked as an outline style for the corresponding
1342 // outline level.
1343 // - DO NOT set type of numbering rule to outline.
1344 // - DO NOT set numbering rule directly at the paragraph.
1345
1346 // Some minor rework and adjust access to paragraph styles (#i70748#)
1347 if ( bPara )
1348 {
1349 // Headings not numbered anymore in 3.1 (#i103817#)
1350 sal_Int16 nCurrentOutlineLevelInheritedFromParagraphStyle = 0;
1351 const bool bHasOutlineLevelProp(
1352 xPropSetInfo->hasPropertyByName(s_OutlineLevel));
1353 if ( bHasOutlineLevelProp )
1354 {
1355 xPropSet->getPropertyValue(s_OutlineLevel)
1356 >>= nCurrentOutlineLevelInheritedFromParagraphStyle;
1357 }
1358 if ( nOutlineLevel > 0 )
1359 {
1360 if ( bHasOutlineLevelProp )
1361 {
1362 // In case that the value equals the value of its paragraph style
1363 // attribute outline level, the paragraph attribute value is left unset
1364 if ( nCurrentOutlineLevelInheritedFromParagraphStyle != nOutlineLevel )
1365 {
1366 xPropSet->setPropertyValue( s_OutlineLevel,
1367 makeAny( static_cast<sal_Int16>(nOutlineLevel) ) );
1368 }
1369 }
1370 if (!bOutlineContentVisible)
1371 {
1372 uno::Sequence<beans::PropertyValue> aGrabBag;
1373 xPropSet->getPropertyValue("ParaInteropGrabBag") >>= aGrabBag;
1374 sal_Int32 length = aGrabBag.getLength();
1375 aGrabBag.realloc(length + 1);
1376 aGrabBag[length].Name = "OutlineContentVisibleAttr";
1377 aGrabBag[length].Value <<= bool(bOutlineContentVisible);
1378 xPropSet->setPropertyValue("ParaInteropGrabBag", uno::makeAny(aGrabBag));
1379 }
1380 // RFE: inserting headings into text documents (#i70748#)
1381 if ( bApplyOutlineLevelAsListLevel )
1382 {
1383 sal_Int16 nNumLevel = -1;
1384 xPropSet->getPropertyValue( s_NumberingLevel ) >>= nNumLevel;
1385 if ( nNumLevel == -1 ||
1386 nNumLevel != (nOutlineLevel - 1) )
1387 {
1388 xPropSet->setPropertyValue( s_NumberingLevel,
1389 makeAny( static_cast<sal_Int8>(nOutlineLevel - 1) ) );
1390 }
1391 }
1392 /* Correction: (#i69629#)
1393 - for text document from version OOo 2.0.4/SO 8 PU4 and earlier
1394 the paragraph style of a heading should be assigned to the
1395 corresponding list level of the outline style.
1396 - for other text documents the paragraph style of a heading is only
1397 a candidate for an assignment to the list level of the outline
1398 style, if it has no direct list style property and (if exists) the
1399 automatic paragraph style has also no direct list style set.
1400 */
1401 if (m_xImpl->m_xParaStyles.is() && m_xImpl->m_xParaStyles->hasByName(sStyleName))
1402 {
1403 bool bOutlineStyleCandidate( false );
1404
1405 sal_Int32 nUPD( 0 );
1406 sal_Int32 nBuild( 0 );
1407 const bool bBuildIdFound = rImport.getBuildIds( nUPD, nBuild );
1408 // Lost outline numbering in master document (#i73509#)
1409 // Check explicitly on certain versions (#i86058#)
1410 if ( rImport.IsTextDocInOOoFileFormat() ||
1411 ( bBuildIdFound &&
1412 ( nUPD == 645 || nUPD == 641 ) ) )
1413 {
1414 bOutlineStyleCandidate = true;
1415 }
1416 else if ( nUPD == 680 && nBuild <= 9073 ) /* BuildId of OOo 2.0.4/SO8 PU4 */
1417 {
1418 bOutlineStyleCandidate = bOutlineLevelAttrFound;
1419 }
1420 if ( bOutlineStyleCandidate )
1421 {
1422 AddOutlineStyleCandidate( nOutlineLevel, sStyleName );
1423 }
1424 // Assure that heading applies the outline style (#i103817#)
1425 if ( ( !pStyle || !pStyle->IsListStyleSet() ) &&
1426 !bOutlineStyleCandidate &&
1427 m_xImpl->m_xChapterNumbering.is())
1428 {
1429 if ( !lcl_HasListStyle( sStyleName,
1430 m_xImpl->m_xParaStyles, GetXMLImport(),
1431 u"NumberingStyleName",
1432 u"" ) )
1433 {
1434 // heading not in a list --> apply outline style
1435 xPropSet->setPropertyValue( s_NumberingRules,
1436 makeAny(m_xImpl->m_xChapterNumbering) );
1437 xPropSet->setPropertyValue( s_NumberingLevel,
1438 makeAny(static_cast<sal_Int8>(nOutlineLevel - 1)));
1439 }
1440 }
1441 }
1442 }
1443 //handle for text:p,if the paragraphstyle outlinelevel is set to[1~10]
1444 else if( bHasOutlineLevelProp )
1445 {
1446 if ( nCurrentOutlineLevelInheritedFromParagraphStyle != 0 )
1447 {
1448 xPropSet->setPropertyValue(s_OutlineLevel,
1449 makeAny( sal_Int16(0) ));
1450 }
1451 }
1452 }
1453
1454 return sStyleName;
1455 }
1456
FindOutlineStyleName(OUString & rStyleName,sal_Int8 nOutlineLevel)1457 void XMLTextImportHelper::FindOutlineStyleName( OUString& rStyleName,
1458 sal_Int8 nOutlineLevel )
1459 {
1460 // style name empty?
1461 if( rStyleName.isEmpty() )
1462 {
1463 // Empty? Then we need o do stuff. Let's do error checking first.
1464 if (m_xImpl->m_xChapterNumbering.is() &&
1465 ( nOutlineLevel > 0 ) &&
1466 (nOutlineLevel <= m_xImpl->m_xChapterNumbering->getCount()))
1467 {
1468 nOutlineLevel--; // for the remainder, the level's are 0-based
1469
1470 // empty style name: look-up previously used name
1471
1472 // if we don't have a previously used name, we'll use the default
1473 m_xImpl->InitOutlineStylesCandidates();
1474 if (m_xImpl->m_xOutlineStylesCandidates[nOutlineLevel].empty())
1475 {
1476 // no other name used previously? Then use default
1477
1478 // iterate over property value sequence to find the style name
1479 Sequence<PropertyValue> aProperties;
1480 m_xImpl->m_xChapterNumbering->getByIndex( nOutlineLevel )
1481 >>= aProperties;
1482 auto pProp = std::find_if(aProperties.begin(), aProperties.end(),
1483 [](const PropertyValue& rProp) { return rProp.Name == "HeadingStyleName"; });
1484 if (pProp != aProperties.end())
1485 {
1486 OUString aOutlineStyle;
1487 pProp->Value >>= aOutlineStyle;
1488 m_xImpl->m_xOutlineStylesCandidates[nOutlineLevel]
1489 .push_back( aOutlineStyle );
1490 }
1491 }
1492
1493 // finally, we'll use the previously used style name for this
1494 // format (or the default we've just put into that style)
1495 // take last added one (#i71249#)
1496 rStyleName =
1497 m_xImpl->m_xOutlineStylesCandidates[nOutlineLevel].back();
1498 }
1499 // else: nothing we can do, so we'll leave it empty
1500 }
1501 // else: we already had a style name, so we let it pass.
1502 }
1503
AddOutlineStyleCandidate(const sal_Int8 nOutlineLevel,const OUString & rStyleName)1504 void XMLTextImportHelper::AddOutlineStyleCandidate( const sal_Int8 nOutlineLevel,
1505 const OUString& rStyleName )
1506 {
1507 if (!rStyleName.isEmpty()
1508 && m_xImpl->m_xChapterNumbering.is()
1509 && (nOutlineLevel > 0)
1510 && (nOutlineLevel <= m_xImpl->m_xChapterNumbering->getCount()))
1511 {
1512 m_xImpl->InitOutlineStylesCandidates();
1513 m_xImpl->m_xOutlineStylesCandidates[nOutlineLevel-1].push_back(
1514 rStyleName);
1515 }
1516 }
1517
SetOutlineStyles(bool bSetEmptyLevels)1518 void XMLTextImportHelper::SetOutlineStyles( bool bSetEmptyLevels )
1519 {
1520 if (!(m_xImpl->m_xOutlineStylesCandidates != nullptr || bSetEmptyLevels) ||
1521 !m_xImpl->m_xChapterNumbering.is() ||
1522 IsInsertMode())
1523 return;
1524
1525 bool bChooseLastOne( false );
1526 {
1527 if ( GetXMLImport().IsTextDocInOOoFileFormat() )
1528 {
1529 bChooseLastOne = true;
1530 }
1531 else
1532 {
1533 sal_Int32 nUPD( 0 );
1534 sal_Int32 nBuild( 0 );
1535 if ( GetXMLImport().getBuildIds( nUPD, nBuild ) )
1536 {
1537 // check explicitly on certain versions
1538 bChooseLastOne = ( nUPD == 641 ) || ( nUPD == 645 ) || // prior OOo 2.0
1539 ( nUPD == 680 && nBuild <= 9073 ); // OOo 2.0 - OOo 2.0.4
1540 }
1541 }
1542 }
1543
1544 OUString sOutlineStyleName;
1545 {
1546 Reference<XPropertySet> xChapterNumRule(
1547 m_xImpl->m_xChapterNumbering, UNO_QUERY);
1548 xChapterNumRule->getPropertyValue("Name") >>= sOutlineStyleName;
1549 }
1550
1551 const sal_Int32 nCount = m_xImpl->m_xChapterNumbering->getCount();
1552 /* First collect all paragraph styles chosen for assignment to each
1553 list level of the outline style, then perform the intrinsic assignment.
1554 Reason: The assignment of a certain paragraph style to a list level
1555 of the outline style causes side effects on the children
1556 paragraph styles in Writer. (#i106218#)
1557 */
1558 ::std::vector<OUString> sChosenStyles(nCount);
1559 for( sal_Int32 i=0; i < nCount; ++i )
1560 {
1561 if ( bSetEmptyLevels ||
1562 (m_xImpl->m_xOutlineStylesCandidates &&
1563 !m_xImpl->m_xOutlineStylesCandidates[i].empty()))
1564 {
1565 // determine, which candidate is one to be assigned to the list
1566 // level of the outline style
1567 if (m_xImpl->m_xOutlineStylesCandidates &&
1568 !m_xImpl->m_xOutlineStylesCandidates[i].empty())
1569 {
1570 if ( bChooseLastOne )
1571 {
1572 sChosenStyles[i] =
1573 m_xImpl->m_xOutlineStylesCandidates[i].back();
1574 }
1575 else
1576 {
1577 for (size_t j = 0;
1578 j < m_xImpl->m_xOutlineStylesCandidates[i].size();
1579 ++j)
1580 {
1581 if (!lcl_HasListStyle(
1582 m_xImpl->m_xOutlineStylesCandidates[i][j],
1583 m_xImpl->m_xParaStyles,
1584 GetXMLImport(),
1585 "NumberingStyleName",
1586 sOutlineStyleName))
1587 {
1588 sChosenStyles[i] =
1589 m_xImpl->m_xOutlineStylesCandidates[i][j];
1590 break;
1591 }
1592 }
1593 }
1594 }
1595 }
1596 }
1597 // Trashed outline numbering in ODF 1.1 text document created by OOo 3.x (#i106218#)
1598 Sequence < PropertyValue > aProps( 1 );
1599 PropertyValue *pProps = aProps.getArray();
1600 pProps->Name = "HeadingStyleName";
1601 for ( sal_Int32 i = 0; i < nCount; ++i )
1602 {
1603 // Paragraph style assignments in Outline of template lost from second level on (#i107610#)
1604 if ( bSetEmptyLevels || !sChosenStyles[i].isEmpty() )
1605 {
1606 pProps->Value <<= sChosenStyles[i];
1607 m_xImpl->m_xChapterNumbering->replaceByIndex(i,
1608 makeAny( aProps ));
1609 }
1610 }
1611
1612 }
1613
SetHyperlink(SvXMLImport const & rImport,const Reference<XTextCursor> & rCursor,const OUString & rHRef,const OUString & rName,const OUString & rTargetFrameName,const OUString & rStyleName,const OUString & rVisitedStyleName,XMLEventsImportContext * pEvents)1614 void XMLTextImportHelper::SetHyperlink(
1615 SvXMLImport const & rImport,
1616 const Reference < XTextCursor >& rCursor,
1617 const OUString& rHRef,
1618 const OUString& rName,
1619 const OUString& rTargetFrameName,
1620 const OUString& rStyleName,
1621 const OUString& rVisitedStyleName,
1622 XMLEventsImportContext* pEvents)
1623 {
1624 static constexpr OUStringLiteral s_HyperLinkURL = u"HyperLinkURL";
1625 static constexpr OUStringLiteral s_HyperLinkName = u"HyperLinkName";
1626 static constexpr OUStringLiteral s_HyperLinkTarget = u"HyperLinkTarget";
1627 static constexpr OUStringLiteral s_UnvisitedCharStyleName = u"UnvisitedCharStyleName";
1628 static constexpr OUStringLiteral s_VisitedCharStyleName = u"VisitedCharStyleName";
1629 static constexpr OUStringLiteral s_HyperLinkEvents = u"HyperLinkEvents";
1630
1631 Reference < XPropertySet > xPropSet( rCursor, UNO_QUERY );
1632 Reference < XPropertySetInfo > xPropSetInfo(
1633 xPropSet->getPropertySetInfo());
1634 if (!xPropSetInfo.is() || !xPropSetInfo->hasPropertyByName(s_HyperLinkURL))
1635 return;
1636
1637 xPropSet->setPropertyValue(s_HyperLinkURL, makeAny(rHRef));
1638
1639 if (xPropSetInfo->hasPropertyByName(s_HyperLinkName))
1640 {
1641 xPropSet->setPropertyValue(s_HyperLinkName, makeAny(rName));
1642 }
1643
1644 if (xPropSetInfo->hasPropertyByName(s_HyperLinkTarget))
1645 {
1646 xPropSet->setPropertyValue(s_HyperLinkTarget,
1647 makeAny(rTargetFrameName));
1648 }
1649
1650 if ( (pEvents != nullptr) &&
1651 xPropSetInfo->hasPropertyByName(s_HyperLinkEvents))
1652 {
1653 // The API treats events at hyperlinks differently from most
1654 // other properties: You have to set a name replace with the
1655 // events in it. The easiest way to do this is to 1) get
1656 // events, 2) set new ones, and 3) then put events back.
1657 uno::Reference<XNameReplace> const xReplace(
1658 xPropSet->getPropertyValue(s_HyperLinkEvents), UNO_QUERY);
1659 if (xReplace.is())
1660 {
1661 // set events
1662 pEvents->SetEvents(xReplace);
1663
1664 // put events
1665 xPropSet->setPropertyValue(s_HyperLinkEvents, makeAny(xReplace));
1666 }
1667 }
1668
1669 if (m_xImpl->m_xTextStyles.is())
1670 {
1671 OUString sDisplayName(
1672 rImport.GetStyleDisplayName(
1673 XmlStyleFamily::TEXT_TEXT, rStyleName ) );
1674 if( !sDisplayName.isEmpty() &&
1675 xPropSetInfo->hasPropertyByName(s_UnvisitedCharStyleName) &&
1676 m_xImpl->m_xTextStyles->hasByName(sDisplayName))
1677 {
1678 xPropSet->setPropertyValue(s_UnvisitedCharStyleName,
1679 makeAny(sDisplayName));
1680 }
1681
1682 sDisplayName =
1683 rImport.GetStyleDisplayName(
1684 XmlStyleFamily::TEXT_TEXT, rVisitedStyleName );
1685 if( !sDisplayName.isEmpty() &&
1686 xPropSetInfo->hasPropertyByName(s_VisitedCharStyleName) &&
1687 m_xImpl->m_xTextStyles->hasByName(sDisplayName))
1688 {
1689 xPropSet->setPropertyValue(s_VisitedCharStyleName,
1690 makeAny(sDisplayName));
1691 }
1692 }
1693 }
1694
SetRuby(SvXMLImport const & rImport,const Reference<XTextCursor> & rCursor,const OUString & rStyleName,const OUString & rTextStyleName,const OUString & rText)1695 void XMLTextImportHelper::SetRuby(
1696 SvXMLImport const & rImport,
1697 const Reference < XTextCursor >& rCursor,
1698 const OUString& rStyleName,
1699 const OUString& rTextStyleName,
1700 const OUString& rText )
1701 {
1702 Reference<XPropertySet> xPropSet(rCursor, UNO_QUERY);
1703
1704 OUString sRubyText("RubyText");
1705
1706 // if we have one Ruby property, we assume all of them are present
1707 if (xPropSet.is() &&
1708 xPropSet->getPropertySetInfo()->hasPropertyByName( sRubyText ))
1709 {
1710 // the ruby text
1711 xPropSet->setPropertyValue(sRubyText, makeAny(rText));
1712
1713 // the ruby style (ruby-adjust)
1714 if (!rStyleName.isEmpty() && m_xImpl->m_xAutoStyles.is())
1715 {
1716 const SvXMLStyleContext* pTempStyle =
1717 m_xImpl->m_xAutoStyles->FindStyleChildContext( XmlStyleFamily::TEXT_RUBY,
1718 rStyleName, true );
1719 XMLPropStyleContext *pStyle = const_cast<XMLPropStyleContext*>(dynamic_cast< const XMLPropStyleContext* >(pTempStyle));
1720
1721 if (nullptr != pStyle)
1722 pStyle->FillPropertySet( xPropSet );
1723 }
1724
1725 // the ruby text character style
1726 if (m_xImpl->m_xTextStyles.is())
1727 {
1728 OUString sDisplayName(
1729 rImport.GetStyleDisplayName(
1730 XmlStyleFamily::TEXT_TEXT, rTextStyleName ) );
1731 if( (!sDisplayName.isEmpty()) &&
1732 m_xImpl->m_xTextStyles->hasByName( sDisplayName ))
1733 {
1734 xPropSet->setPropertyValue("RubyCharStyleName", makeAny(sDisplayName));
1735 }
1736 }
1737 }
1738 }
1739
SetAutoStyles(SvXMLStylesContext * pStyles)1740 void XMLTextImportHelper::SetAutoStyles( SvXMLStylesContext *pStyles )
1741 {
1742 m_xImpl->m_xAutoStyles = pStyles;
1743 }
1744
CreateTextChildContext(SvXMLImport & rImport,sal_Int32 nElement,const Reference<XFastAttributeList> & xAttrList,XMLTextType eType)1745 SvXMLImportContext *XMLTextImportHelper::CreateTextChildContext(
1746 SvXMLImport& rImport,
1747 sal_Int32 nElement,
1748 const Reference< XFastAttributeList > & xAttrList,
1749 XMLTextType eType )
1750 {
1751 SvXMLImportContext *pContext = nullptr;
1752
1753 bool bContent = true;
1754 switch( nElement )
1755 {
1756 case XML_ELEMENT(TEXT, XML_H):
1757 case XML_ELEMENT(TEXT, XML_P):
1758 case XML_ELEMENT(LO_EXT, XML_P):
1759 pContext = new XMLParaContext( rImport,
1760 nElement,
1761 xAttrList );
1762 if (m_xImpl->m_bProgress && XMLTextType::Shape != eType)
1763 {
1764 rImport.GetProgressBarHelper()->Increment();
1765 }
1766 break;
1767 // #i52127#
1768 case XML_ELEMENT(TEXT, XML_NUMBERED_PARAGRAPH):
1769 pContext = new XMLNumberedParaContext(
1770 rImport, nElement, xAttrList );
1771 break;
1772 case XML_ELEMENT(TEXT, XML_LIST):
1773 pContext = new XMLTextListBlockContext( rImport, *this,
1774 xAttrList );
1775 break;
1776 case XML_ELEMENT(TABLE,XML_TABLE):
1777 case XML_ELEMENT(LO_EXT, XML_TABLE):
1778 if( XMLTextType::Body == eType ||
1779 XMLTextType::TextBox == eType ||
1780 XMLTextType::Section == eType ||
1781 XMLTextType::HeaderFooter == eType ||
1782 XMLTextType::ChangedRegion == eType ||
1783 XMLTextType::Cell == eType )
1784 pContext = CreateTableChildContext( rImport, nElement, xAttrList );
1785 break;
1786 case XML_ELEMENT(TEXT, XML_SEQUENCE_DECLS):
1787 if ((XMLTextType::Body == eType && m_xImpl->m_bBodyContentStarted) ||
1788 XMLTextType::HeaderFooter == eType )
1789 {
1790 pContext = new XMLVariableDeclsImportContext(
1791 rImport, *this, VarTypeSequence);
1792 bContent = false;
1793 }
1794 break;
1795 case XML_ELEMENT(TEXT, XML_VARIABLE_DECLS):
1796 if ((XMLTextType::Body == eType && m_xImpl->m_bBodyContentStarted) ||
1797 XMLTextType::HeaderFooter == eType )
1798 {
1799 pContext = new XMLVariableDeclsImportContext(
1800 rImport, *this, VarTypeSimple);
1801 bContent = false;
1802 }
1803 break;
1804 case XML_ELEMENT(TEXT, XML_USER_FIELD_DECLS):
1805 if ((XMLTextType::Body == eType && m_xImpl->m_bBodyContentStarted)||
1806 XMLTextType::HeaderFooter == eType )
1807 {
1808 pContext = new XMLVariableDeclsImportContext(
1809 rImport, *this, VarTypeUserField);
1810 bContent = false;
1811 }
1812 break;
1813 case XML_ELEMENT(TEXT, XML_DDE_CONNECTION_DECLS):
1814 if ((XMLTextType::Body == eType && m_xImpl->m_bBodyContentStarted) ||
1815 XMLTextType::HeaderFooter == eType )
1816 {
1817 pContext = new XMLDdeFieldDeclsImportContext(rImport);
1818 bContent = false;
1819 }
1820 break;
1821 case XML_ELEMENT(DRAW, XML_FRAME):
1822 if ((XMLTextType::Body == eType && m_xImpl->m_bBodyContentStarted) ||
1823 XMLTextType::TextBox == eType ||
1824 XMLTextType::ChangedRegion == eType )
1825 {
1826 TextContentAnchorType eAnchorType =
1827 XMLTextType::TextBox == eType ? TextContentAnchorType_AT_FRAME
1828 : TextContentAnchorType_AT_PAGE;
1829 pContext = new XMLTextFrameContext( rImport, xAttrList,
1830 eAnchorType );
1831 bContent = false;
1832 }
1833 break;
1834 case XML_ELEMENT(DRAW, XML_A):
1835 if ((XMLTextType::Body == eType && m_xImpl->m_bBodyContentStarted) ||
1836 XMLTextType::TextBox == eType ||
1837 XMLTextType::ChangedRegion == eType)
1838 {
1839 TextContentAnchorType eAnchorType =
1840 XMLTextType::TextBox == eType ? TextContentAnchorType_AT_FRAME
1841 : TextContentAnchorType_AT_PAGE;
1842 pContext = new XMLTextFrameHyperlinkContext( rImport, nElement,
1843 xAttrList,
1844 eAnchorType );
1845 bContent = false;
1846 }
1847 break;
1848 case XML_ELEMENT(TEXT, XML_INDEX_TITLE):
1849 case XML_ELEMENT(TEXT, XML_SECTION):
1850 pContext = new XMLSectionImportContext( rImport );
1851 break;
1852 case XML_ELEMENT(TEXT, XML_TABLE_OF_CONTENT):
1853 case XML_ELEMENT(TEXT, XML_OBJECT_INDEX):
1854 case XML_ELEMENT(TEXT, XML_TABLE_INDEX):
1855 case XML_ELEMENT(TEXT, XML_ILLUSTRATION_INDEX):
1856 case XML_ELEMENT(TEXT, XML_USER_INDEX):
1857 case XML_ELEMENT(TEXT, XML_ALPHABETICAL_INDEX):
1858 case XML_ELEMENT(TEXT, XML_BIBLIOGRAPHY):
1859 if( XMLTextType::Shape != eType )
1860 pContext = new XMLIndexTOCContext( rImport, nElement );
1861 break;
1862 case XML_ELEMENT(TEXT, XML_TRACKED_CHANGES):
1863 pContext = new XMLTrackedChangesImportContext( rImport );
1864 bContent = false;
1865 break;
1866 case XML_ELEMENT(TEXT, XML_CHANGE):
1867 case XML_ELEMENT(TEXT, XML_CHANGE_START):
1868 case XML_ELEMENT(TEXT, XML_CHANGE_END):
1869 pContext = new XMLChangeImportContext(
1870 rImport,
1871 ((nElement == XML_ELEMENT(TEXT, XML_CHANGE_END))
1872 ? XMLChangeImportContext::Element::END
1873 : (nElement == XML_ELEMENT(TEXT, XML_CHANGE_START))
1874 ? XMLChangeImportContext::Element::START
1875 : XMLChangeImportContext::Element::POINT),
1876 true);
1877 break;
1878 case XML_ELEMENT(OFFICE, XML_FORMS):
1879 pContext = xmloff::OFormLayerXMLImport::createOfficeFormsContext(rImport);
1880 bContent = false;
1881 break;
1882 case XML_ELEMENT(TEXT, XML_ALPHABETICAL_INDEX_AUTO_MARK_FILE):
1883 if( XMLTextType::Body == eType )
1884 {
1885 pContext = new XMLAutoMarkFileContext(rImport);
1886 }
1887 bContent = false;
1888 break;
1889 case XML_ELEMENT(TABLE, XML_CALCULATION_SETTINGS):
1890 pContext = new XMLCalculationSettingsContext ( rImport, nElement, xAttrList);
1891 bContent = false;
1892 break;
1893
1894 default:
1895 if ((XMLTextType::Body == eType && m_xImpl->m_bBodyContentStarted) ||
1896 XMLTextType::TextBox == eType ||
1897 XMLTextType::ChangedRegion == eType )
1898 {
1899 Reference < XShapes > xShapes;
1900 pContext = XMLShapeImportHelper::CreateGroupChildContext(
1901 rImport, nElement, xAttrList, xShapes );
1902 bContent = false;
1903 }
1904 }
1905
1906 // handle open redlines
1907 if ( (XML_ELEMENT(TEXT, XML_CHANGE) != nElement) &&
1908 (XML_ELEMENT(TEXT, XML_CHANGE_END) != nElement) &&
1909 (XML_ELEMENT(TEXT, XML_CHANGE_START) != nElement) )
1910 {
1911 // ResetOpenRedlineId();
1912 }
1913
1914 if( XMLTextType::Body == eType && bContent )
1915 {
1916 m_xImpl->m_bBodyContentStarted = false;
1917 }
1918
1919 if( nElement != XML_ELEMENT(DRAW, XML_FRAME) )
1920 ClearLastImportedTextFrameName();
1921
1922 if (!pContext)
1923 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
1924
1925 return pContext;
1926 }
1927
CreateTableChildContext(SvXMLImport &,sal_Int32,const Reference<XFastAttributeList> &)1928 SvXMLImportContext *XMLTextImportHelper::CreateTableChildContext(
1929 SvXMLImport&,
1930 sal_Int32 /*nElement*/,
1931 const Reference< XFastAttributeList > & )
1932 {
1933 return nullptr;
1934 }
1935
1936 /// get data style key for use with NumberFormat property
GetDataStyleKey(const OUString & sStyleName,bool * pIsSystemLanguage)1937 sal_Int32 XMLTextImportHelper::GetDataStyleKey(const OUString& sStyleName,
1938 bool* pIsSystemLanguage )
1939 {
1940 if (!m_xImpl->m_xAutoStyles.is())
1941 return -1;
1942
1943 const SvXMLStyleContext* pStyle =
1944 m_xImpl->m_xAutoStyles->FindStyleChildContext( XmlStyleFamily::DATA_STYLE,
1945 sStyleName, true );
1946
1947 // get appropriate context
1948
1949
1950 // first check if it's an Impress and draw only number format
1951 // this is needed since it's also a SvXMLNumFormatContext,
1952 // that was needed to support them for controls in impress/draw also
1953 const SdXMLNumberFormatImportContext* pSdNumStyle = dynamic_cast<const SdXMLNumberFormatImportContext*>( pStyle );
1954 if( pSdNumStyle )
1955 {
1956 return pSdNumStyle->GetDrawKey();
1957 }
1958 else
1959 {
1960 SvXMLNumFormatContext* pNumStyle = const_cast<SvXMLNumFormatContext*>(dynamic_cast<const SvXMLNumFormatContext*>( pStyle ) );
1961 if( pNumStyle )
1962 {
1963 if( pIsSystemLanguage != nullptr )
1964 *pIsSystemLanguage = pNumStyle->IsSystemLanguage();
1965
1966 // return key
1967 return pNumStyle->GetKey();
1968 }
1969 }
1970 return -1;
1971 }
1972
FindAutoListStyle(const OUString & rName) const1973 const SvxXMLListStyleContext *XMLTextImportHelper::FindAutoListStyle( const OUString& rName ) const
1974 {
1975 const SvxXMLListStyleContext *pStyle = nullptr;
1976 if (m_xImpl->m_xAutoStyles.is())
1977 {
1978 const SvXMLStyleContext* pTempStyle =
1979 m_xImpl->m_xAutoStyles->FindStyleChildContext( XmlStyleFamily::TEXT_LIST, rName,
1980 true );
1981 pStyle = dynamic_cast< const SvxXMLListStyleContext* >(pTempStyle);
1982 }
1983
1984 return pStyle;
1985 }
1986
FindAutoFrameStyle(const OUString & rName) const1987 XMLPropStyleContext *XMLTextImportHelper::FindAutoFrameStyle( const OUString& rName ) const
1988 {
1989 XMLPropStyleContext *pStyle = nullptr;
1990 if (m_xImpl->m_xAutoStyles.is())
1991 {
1992 const SvXMLStyleContext* pTempStyle =
1993 m_xImpl->m_xAutoStyles->FindStyleChildContext( XmlStyleFamily::SD_GRAPHICS_ID, rName,
1994 true );
1995 pStyle = const_cast<XMLPropStyleContext*>(dynamic_cast< const XMLPropStyleContext* >(pTempStyle));
1996 }
1997
1998 return pStyle;
1999 }
2000
FindSectionStyle(const OUString & rName) const2001 XMLPropStyleContext* XMLTextImportHelper::FindSectionStyle(
2002 const OUString& rName ) const
2003 {
2004 XMLPropStyleContext* pStyle = nullptr;
2005 if (m_xImpl->m_xAutoStyles.is())
2006 {
2007 const SvXMLStyleContext* pTempStyle =
2008 m_xImpl->m_xAutoStyles->FindStyleChildContext(
2009 XmlStyleFamily::TEXT_SECTION,
2010 rName, true );
2011 pStyle = const_cast<XMLPropStyleContext*>(dynamic_cast< const XMLPropStyleContext* >(pTempStyle));
2012 }
2013
2014 return pStyle;
2015 }
2016
FindPageMaster(const OUString & rName) const2017 XMLPropStyleContext* XMLTextImportHelper::FindPageMaster(
2018 const OUString& rName ) const
2019 {
2020 XMLPropStyleContext* pStyle = nullptr;
2021 if (m_xImpl->m_xAutoStyles.is())
2022 {
2023 const SvXMLStyleContext* pTempStyle =
2024 m_xImpl->m_xAutoStyles->FindStyleChildContext(
2025 XmlStyleFamily::PAGE_MASTER,
2026 rName, true );
2027 pStyle = const_cast<XMLPropStyleContext*>(dynamic_cast< const XMLPropStyleContext* >(pTempStyle));
2028 }
2029
2030 return pStyle;
2031 }
2032
FindDrawingPage(OUString const & rName) const2033 XMLPropStyleContext * XMLTextImportHelper::FindDrawingPage(OUString const& rName) const
2034 {
2035 if (!m_xImpl->m_xAutoStyles.is())
2036 {
2037 return nullptr;
2038 }
2039 SvXMLStyleContext const* pStyle(
2040 m_xImpl->m_xAutoStyles->FindStyleChildContext(
2041 XmlStyleFamily::SD_DRAWINGPAGE_ID, rName, true));
2042 assert(pStyle == nullptr || dynamic_cast<XMLPropStyleContext const*>(pStyle) != nullptr);
2043 return const_cast<XMLPropStyleContext*>(static_cast<XMLPropStyleContext const*>(pStyle));
2044 }
2045
PushListContext()2046 void XMLTextImportHelper::PushListContext()
2047 {
2048 GetTextListHelper().PushListContext(static_cast<XMLTextListBlockContext*>(nullptr));
2049 }
2050
PopListContext()2051 void XMLTextImportHelper::PopListContext()
2052 {
2053 GetTextListHelper().PopListContext();
2054 }
2055
2056
GetRenameMap()2057 SvI18NMap& XMLTextImportHelper::GetRenameMap()
2058 {
2059 if (!m_xImpl->m_xRenameMap)
2060 {
2061 m_xImpl->m_xRenameMap.reset( new SvI18NMap );
2062 }
2063 return *m_xImpl->m_xRenameMap;
2064 }
2065
InsertBookmarkStartRange(const OUString & sName,const Reference<XTextRange> & rRange,OUString const & i_rXmlId,std::shared_ptr<::xmloff::ParsedRDFaAttributes> & i_rpRDFaAttributes)2066 void XMLTextImportHelper::InsertBookmarkStartRange(
2067 const OUString & sName,
2068 const Reference<XTextRange> & rRange,
2069 OUString const& i_rXmlId,
2070 std::shared_ptr< ::xmloff::ParsedRDFaAttributes > & i_rpRDFaAttributes)
2071 {
2072 m_xImpl->m_BookmarkStartRanges[sName] =
2073 std::make_tuple(rRange, i_rXmlId, i_rpRDFaAttributes);
2074 m_xImpl->m_BookmarkVector.push_back(sName);
2075 }
2076
FindAndRemoveBookmarkStartRange(const OUString & sName,Reference<XTextRange> & o_rRange,OUString & o_rXmlId,std::shared_ptr<::xmloff::ParsedRDFaAttributes> & o_rpRDFaAttributes)2077 bool XMLTextImportHelper::FindAndRemoveBookmarkStartRange(
2078 const OUString & sName,
2079 Reference<XTextRange> & o_rRange,
2080 OUString & o_rXmlId,
2081 std::shared_ptr< ::xmloff::ParsedRDFaAttributes > & o_rpRDFaAttributes)
2082 {
2083 if (m_xImpl->m_BookmarkStartRanges.count(sName))
2084 {
2085 Impl::BookmarkMapEntry_t & rEntry =
2086 (*m_xImpl->m_BookmarkStartRanges.find(sName)).second;
2087 o_rRange.set(std::get<0>(rEntry));
2088 o_rXmlId = std::get<1>(rEntry);
2089 o_rpRDFaAttributes = std::get<2>(rEntry);
2090 m_xImpl->m_BookmarkStartRanges.erase(sName);
2091 auto it = std::find(m_xImpl->m_BookmarkVector.begin(), m_xImpl->m_BookmarkVector.end(), sName);
2092 if (it!=m_xImpl->m_BookmarkVector.end())
2093 {
2094 m_xImpl->m_BookmarkVector.erase(it);
2095 }
2096 return true;
2097 }
2098 else
2099 {
2100 return false;
2101 }
2102 }
2103
pushFieldCtx(const OUString & name,const OUString & type)2104 void XMLTextImportHelper::pushFieldCtx( const OUString& name, const OUString& type )
2105 {
2106 m_xImpl->m_FieldStack.push(Impl::field_stack_item_t(
2107 Impl::field_name_type_t(name, type), Impl::field_params_t(), uno::Reference<text::XFormField>{}));
2108 }
2109
2110 uno::Reference<text::XFormField>
popFieldCtx()2111 XMLTextImportHelper::popFieldCtx()
2112 {
2113 uno::Reference<text::XFormField> xRet;
2114 if ( !m_xImpl->m_FieldStack.empty() )
2115 {
2116 xRet = std::get<2>(m_xImpl->m_FieldStack.top());
2117 m_xImpl->m_FieldStack.pop();
2118 }
2119 else
2120 {
2121 SAL_INFO("xmloff.text", "unexpected fieldmark end");
2122 }
2123 return xRet;
2124 }
2125
addFieldParam(const OUString & name,const OUString & value)2126 void XMLTextImportHelper::addFieldParam( const OUString& name, const OUString& value )
2127 {
2128 assert(!m_xImpl->m_FieldStack.empty());
2129 if (!m_xImpl->m_FieldStack.empty()) {
2130 Impl::field_stack_item_t & FieldStackItem(m_xImpl->m_FieldStack.top());
2131 std::get<1>(FieldStackItem).emplace_back( name, value );
2132 }
2133 }
2134
getCurrentFieldType()2135 OUString XMLTextImportHelper::getCurrentFieldType()
2136 {
2137 assert(!m_xImpl->m_FieldStack.empty());
2138 if (!m_xImpl->m_FieldStack.empty())
2139 {
2140 return std::get<0>(m_xImpl->m_FieldStack.top()).second;
2141 }
2142 else
2143 {
2144 return OUString();
2145 }
2146 }
2147
hasCurrentFieldCtx() const2148 bool XMLTextImportHelper::hasCurrentFieldCtx() const
2149 {
2150 return !m_xImpl->m_FieldStack.empty();
2151 }
2152
setCurrentFieldParamsTo(css::uno::Reference<css::text::XFormField> const & xFormField)2153 void XMLTextImportHelper::setCurrentFieldParamsTo(css::uno::Reference< css::text::XFormField> const &xFormField)
2154 {
2155 assert(!m_xImpl->m_FieldStack.empty());
2156 if (!m_xImpl->m_FieldStack.empty() && xFormField.is())
2157 {
2158 FieldParamImporter(&std::get<1>(m_xImpl->m_FieldStack.top()),
2159 xFormField->getParameters()).Import();
2160 std::get<2>(m_xImpl->m_FieldStack.top()) = xFormField;
2161 }
2162 }
2163
2164
ConnectFrameChains(const OUString & rFrmName,const OUString & rNextFrmName,const Reference<XPropertySet> & rFrmPropSet)2165 void XMLTextImportHelper::ConnectFrameChains(
2166 const OUString& rFrmName,
2167 const OUString& rNextFrmName,
2168 const Reference < XPropertySet >& rFrmPropSet )
2169 {
2170 if( rFrmName.isEmpty() )
2171 return;
2172
2173 if( !rNextFrmName.isEmpty() )
2174 {
2175 OUString sNextFrmName(GetRenameMap().Get( XML_TEXT_RENAME_TYPE_FRAME,
2176 rNextFrmName ));
2177 if (m_xImpl->m_xTextFrames.is()
2178 && m_xImpl->m_xTextFrames->hasByName(sNextFrmName))
2179 {
2180 rFrmPropSet->setPropertyValue("ChainNextName",
2181 makeAny(sNextFrmName));
2182 }
2183 else
2184 {
2185 if (!m_xImpl->m_xPrevFrmNames)
2186 {
2187 m_xImpl->m_xPrevFrmNames.emplace();
2188 m_xImpl->m_xNextFrmNames.emplace();
2189 }
2190 m_xImpl->m_xPrevFrmNames->push_back(rFrmName);
2191 m_xImpl->m_xNextFrmNames->push_back(sNextFrmName);
2192 }
2193 }
2194 if (m_xImpl->m_xPrevFrmNames && !m_xImpl->m_xPrevFrmNames->empty())
2195 {
2196 for(std::vector<OUString>::iterator i = m_xImpl->m_xPrevFrmNames->begin(), j = m_xImpl->m_xNextFrmNames->begin(); i != m_xImpl->m_xPrevFrmNames->end() && j != m_xImpl->m_xNextFrmNames->end(); ++i, ++j)
2197 {
2198 if((*j) == rFrmName)
2199 {
2200 // The previous frame must exist, because it existing than
2201 // inserting the entry
2202 rFrmPropSet->setPropertyValue("ChainPrevName", makeAny(*i));
2203
2204 i = m_xImpl->m_xPrevFrmNames->erase(i);
2205 j = m_xImpl->m_xNextFrmNames->erase(j);
2206
2207 // There cannot be more than one previous frames
2208 break;
2209 }
2210 }
2211 }
2212 }
2213
IsInFrame() const2214 bool XMLTextImportHelper::IsInFrame() const
2215 {
2216 static constexpr OUStringLiteral s_TextFrame = u"TextFrame";
2217
2218 bool bIsInFrame = false;
2219
2220 // are we currently in a text frame? yes, if the cursor has a
2221 // TextFrame property and it's non-NULL
2222 Reference<XPropertySet> xPropSet(const_cast<XMLTextImportHelper*>(this)->GetCursor(), UNO_QUERY);
2223 if (xPropSet.is())
2224 {
2225 if (xPropSet->getPropertySetInfo()->hasPropertyByName(s_TextFrame))
2226 {
2227 uno::Reference<XTextFrame> const xFrame(
2228 xPropSet->getPropertyValue(s_TextFrame), UNO_QUERY);
2229
2230 if (xFrame.is())
2231 {
2232 bIsInFrame = true;
2233 }
2234 }
2235 }
2236
2237 return bIsInFrame;
2238 }
2239
IsInHeaderFooter() const2240 bool XMLTextImportHelper::IsInHeaderFooter() const
2241 {
2242 return false;
2243 }
2244
createAndInsertOLEObject(SvXMLImport &,const OUString &,const OUString &,const OUString &,sal_Int32,sal_Int32)2245 Reference< XPropertySet> XMLTextImportHelper::createAndInsertOLEObject(
2246 SvXMLImport&,
2247 const OUString& /*rHRef*/,
2248 const OUString& /*rStyleName*/,
2249 const OUString& /*rTblName*/,
2250 sal_Int32 /*nWidth*/, sal_Int32 /*nHeight*/ )
2251 {
2252 Reference< XPropertySet> xPropSet;
2253 return xPropSet;
2254 }
2255
createAndInsertOOoLink(SvXMLImport &,const OUString &,const OUString &,const OUString &,sal_Int32,sal_Int32)2256 Reference< XPropertySet> XMLTextImportHelper::createAndInsertOOoLink(
2257 SvXMLImport&,
2258 const OUString& /*rHRef*/,
2259 const OUString& /*rStyleName*/,
2260 const OUString& /*rTblName*/,
2261 sal_Int32 /*nWidth*/, sal_Int32 /*nHeight*/ )
2262 {
2263 Reference< XPropertySet> xPropSet;
2264 return xPropSet;
2265 }
2266
createAndInsertApplet(const OUString &,const OUString &,bool,const OUString &,sal_Int32,sal_Int32)2267 Reference< XPropertySet> XMLTextImportHelper::createAndInsertApplet(
2268 const OUString& /*rCode*/,
2269 const OUString& /*rName*/,
2270 bool /*bMayScript*/,
2271 const OUString& /*rHRef*/,
2272 sal_Int32 /*nWidth*/, sal_Int32 /*nHeight*/ )
2273 {
2274 Reference< XPropertySet> xPropSet;
2275 return xPropSet;
2276 }
createAndInsertPlugin(const OUString &,const OUString &,sal_Int32,sal_Int32)2277 Reference< XPropertySet> XMLTextImportHelper::createAndInsertPlugin(
2278 const OUString& /*rMimeType*/,
2279 const OUString& /*rHRef*/,
2280 sal_Int32 /*nWidth*/, sal_Int32 /*nHeight*/ )
2281 {
2282 Reference< XPropertySet> xPropSet;
2283 return xPropSet;
2284 }
createAndInsertFloatingFrame(const OUString &,const OUString &,const OUString &,sal_Int32,sal_Int32)2285 Reference< XPropertySet> XMLTextImportHelper::createAndInsertFloatingFrame(
2286 const OUString& /*rName*/,
2287 const OUString& /*rHRef*/,
2288 const OUString& /*rStyleName*/,
2289 sal_Int32 /*nWidth*/, sal_Int32 /*nHeight*/ )
2290 {
2291 Reference< XPropertySet> xPropSet;
2292 return xPropSet;
2293 }
2294
endAppletOrPlugin(const Reference<XPropertySet> &,std::map<const OUString,OUString> &)2295 void XMLTextImportHelper::endAppletOrPlugin(
2296 const Reference < XPropertySet> &,
2297 std::map < const OUString, OUString > &)
2298 {
2299 }
2300 // redline helper: dummy implementation to be overridden in sw/filter/xml
RedlineAdd(const OUString &,const OUString &,const OUString &,const OUString &,const util::DateTime &,bool)2301 void XMLTextImportHelper::RedlineAdd( const OUString& /*rType*/,
2302 const OUString& /*rId*/,
2303 const OUString& /*rAuthor*/,
2304 const OUString& /*rComment*/,
2305 const util::DateTime& /*rDateTime*/,
2306 bool /*bMergeLastPara*/)
2307 {
2308 // dummy implementation: do nothing
2309 }
2310
RedlineCreateText(Reference<XTextCursor> &,const OUString &)2311 Reference<XTextCursor> XMLTextImportHelper::RedlineCreateText(
2312 Reference<XTextCursor> & /*rOldCursor*/,
2313 const OUString& /*rId*/)
2314 {
2315 // dummy implementation: do nothing
2316 Reference<XTextCursor> xRet;
2317 return xRet;
2318 }
2319
RedlineSetCursor(const OUString &,bool,bool)2320 void XMLTextImportHelper::RedlineSetCursor(
2321 const OUString& /*rId*/,
2322 bool /*bStart*/,
2323 bool /*bIsOutsideOfParagraph*/)
2324 {
2325 // dummy implementation: do nothing
2326 }
2327
RedlineAdjustStartNodeCursor()2328 void XMLTextImportHelper::RedlineAdjustStartNodeCursor()
2329 {
2330 // dummy implementation: do nothing
2331 }
2332
SetShowChanges(bool)2333 void XMLTextImportHelper::SetShowChanges( bool )
2334 {
2335 // dummy implementation: do nothing
2336 }
2337
SetRecordChanges(bool)2338 void XMLTextImportHelper::SetRecordChanges( bool )
2339 {
2340 // dummy implementation: do nothing
2341 }
SetChangesProtectionKey(const Sequence<sal_Int8> &)2342 void XMLTextImportHelper::SetChangesProtectionKey(const Sequence<sal_Int8> &)
2343 {
2344 // dummy implementation: do nothing
2345 }
2346
2347
GetOpenRedlineId() const2348 OUString const & XMLTextImportHelper::GetOpenRedlineId() const
2349 {
2350 return m_xImpl->m_sOpenRedlineIdentifier;
2351 }
2352
SetOpenRedlineId(OUString const & rId)2353 void XMLTextImportHelper::SetOpenRedlineId( OUString const & rId)
2354 {
2355 m_xImpl->m_sOpenRedlineIdentifier = rId;
2356 }
2357
ResetOpenRedlineId()2358 void XMLTextImportHelper::ResetOpenRedlineId()
2359 {
2360 SetOpenRedlineId("");
2361 }
2362
2363 void
SetCellParaStyleDefault(OUString const & rNewValue)2364 XMLTextImportHelper::SetCellParaStyleDefault(OUString const& rNewValue)
2365 {
2366 m_xImpl->m_sCellParaStyleDefault = rNewValue;
2367 }
2368
GetCellParaStyleDefault() const2369 OUString const& XMLTextImportHelper::GetCellParaStyleDefault() const
2370 {
2371 return m_xImpl->m_sCellParaStyleDefault;
2372 }
2373
AddCrossRefHeadingMapping(OUString const & rFrom,OUString const & rTo)2374 void XMLTextImportHelper::AddCrossRefHeadingMapping(OUString const& rFrom, OUString const& rTo)
2375 {
2376 if (!m_xImpl->m_xCrossRefHeadingBookmarkMap)
2377 {
2378 m_xImpl->m_xCrossRefHeadingBookmarkMap.emplace();
2379 }
2380 m_xImpl->m_xCrossRefHeadingBookmarkMap->insert(std::make_pair(rFrom, rTo));
2381 }
2382
2383 // tdf#94804: hack to map cross reference fields that reference duplicate marks
2384 // note that we can't really check meta:generator for this since the file might
2385 // be round-tripped by different versions preserving duplicates => always map
MapCrossRefHeadingFieldsHorribly()2386 void XMLTextImportHelper::MapCrossRefHeadingFieldsHorribly()
2387 {
2388 if (!m_xImpl->m_xCrossRefHeadingBookmarkMap)
2389 {
2390 return;
2391 }
2392
2393 uno::Reference<text::XTextFieldsSupplier> const xFieldsSupplier(
2394 m_xImpl->m_rSvXMLImport.GetModel(), uno::UNO_QUERY);
2395 if (!xFieldsSupplier.is())
2396 {
2397 return;
2398 }
2399 uno::Reference<container::XEnumerationAccess> const xFieldsEA(
2400 xFieldsSupplier->getTextFields());
2401 uno::Reference<container::XEnumeration> const xFields(
2402 xFieldsEA->createEnumeration());
2403 while (xFields->hasMoreElements())
2404 {
2405 uno::Reference<lang::XServiceInfo> const xFieldInfo(
2406 xFields->nextElement(), uno::UNO_QUERY);
2407 if (!xFieldInfo->supportsService("com.sun.star.text.textfield.GetReference"))
2408 {
2409 continue;
2410 }
2411 uno::Reference<beans::XPropertySet> const xField(
2412 xFieldInfo, uno::UNO_QUERY);
2413 sal_uInt16 nType(0);
2414 xField->getPropertyValue("ReferenceFieldSource") >>= nType;
2415 if (text::ReferenceFieldSource::BOOKMARK != nType)
2416 {
2417 continue;
2418 }
2419 OUString name;
2420 xField->getPropertyValue("SourceName") >>= name;
2421 auto const iter(m_xImpl->m_xCrossRefHeadingBookmarkMap->find(name));
2422 if (iter == m_xImpl->m_xCrossRefHeadingBookmarkMap->end())
2423 {
2424 continue;
2425 }
2426 xField->setPropertyValue("SourceName", uno::makeAny(iter->second));
2427 }
2428 }
2429
setBookmarkAttributes(OUString const & bookmark,bool hidden,OUString const & condition)2430 void XMLTextImportHelper::setBookmarkAttributes(OUString const& bookmark, bool hidden, OUString const& condition)
2431 {
2432 m_xImpl->m_bBookmarkHidden[bookmark] = hidden;
2433 m_xImpl->m_sBookmarkCondition[bookmark] = condition;
2434 }
2435
getBookmarkHidden(OUString const & bookmark) const2436 bool XMLTextImportHelper::getBookmarkHidden(OUString const& bookmark) const
2437 {
2438 return m_xImpl->m_bBookmarkHidden[bookmark];
2439 }
2440
getBookmarkCondition(OUString const & bookmark) const2441 const OUString& XMLTextImportHelper::getBookmarkCondition(OUString const& bookmark) const
2442 {
2443 return m_xImpl->m_sBookmarkCondition[bookmark];
2444 }
2445
2446 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
2447