LibreOffice Module xmloff (master)  1
txtparai.cxx
Go to the documentation of this file.
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 
21 
22 #include <memory>
23 #include <vector>
24 
25 #include <rtl/ustring.hxx>
26 #include <rtl/ustrbuf.hxx>
27 #include <sal/log.hxx>
28 #include <tools/diagnose_ex.h>
29 #include <com/sun/star/frame/XModel.hpp>
30 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
31 #include <com/sun/star/text/XTextFrame.hpp>
32 #include <com/sun/star/text/XTextCursor.hpp>
33 #include <com/sun/star/beans/XPropertySet.hpp>
34 #include <com/sun/star/beans/XPropertySetInfo.hpp>
35 #include <com/sun/star/text/ControlCharacter.hpp>
36 #include <com/sun/star/container/XIndexReplace.hpp>
37 #include <com/sun/star/drawing/XShapes.hpp>
38 #include <com/sun/star/container/XEnumerationAccess.hpp>
39 #include <com/sun/star/rdf/XMetadatable.hpp>
40 
41 #include <sax/tools/converter.hxx>
42 
43 #include <xmloff/xmlictxt.hxx>
44 #include <xmloff/xmlimp.hxx>
45 #include <xmloff/xmltoken.hxx>
46 #include <xmloff/namespacemap.hxx>
47 #include <xmloff/xmlnamespace.hxx>
48 #include <xmloff/txtimp.hxx>
49 #include "txtparai.hxx"
50 #include <txtfldi.hxx>
53 #include "XMLTextFrameContext.hxx"
58 #include <txtlists.hxx>
59 
60 #include "txtparaimphint.hxx"
61 
62 using namespace ::com::sun::star;
63 using namespace ::com::sun::star::uno;
64 using namespace ::com::sun::star::text;
65 using namespace ::com::sun::star::drawing;
66 using namespace ::com::sun::star::beans;
67 using namespace ::xmloff::token;
68 using ::com::sun::star::container::XEnumerationAccess;
69 using ::com::sun::star::container::XEnumeration;
70 
72 {
73 private:
74 
75  std::vector<std::unique_ptr<XMLHint_Impl>> m_Hints;
76  std::unordered_map<OUString, XMLIndexMarkHint_Impl*> m_IndexHintsById;
77  uno::Reference<uno::XInterface> m_xCrossRefHeadingBookmark;
78 
79 public:
80  void push_back(std::unique_ptr<XMLHint_Impl> pHint)
81  {
82  m_Hints.push_back(std::move(pHint));
83  }
84 
85  void push_back(std::unique_ptr<XMLIndexMarkHint_Impl> pHint)
86  {
87  m_IndexHintsById.emplace(pHint->GetID(), pHint.get());
88  m_Hints.push_back(std::move(pHint));
89  }
90 
91  std::vector<std::unique_ptr<XMLHint_Impl>> const& GetHints() const
92  {
93  return m_Hints;
94  }
95 
97  {
98  auto it = m_IndexHintsById.find(sID);
99  return it == m_IndexHintsById.end() ? nullptr : it->second;
100  }
101 
102  uno::Reference<uno::XInterface> & GetCrossRefHeadingBookmark()
103  {
105  }
106 };
107 
109  SvXMLImport& rImport,
110  sal_uInt16 nPrfx,
111  const OUString& rLName,
112  const Reference< xml::sax::XAttributeList > & xAttrList,
113  sal_Unicode c,
114  bool bCount ) :
115  SvXMLImportContext( rImport, nPrfx, rLName )
116  ,m_nControl(0)
117  ,m_nCount(1)
118  ,m_c(c)
119 {
120  if( !bCount )
121  return;
122 
123  const SvXMLNamespaceMap& rMap = GetImport().GetNamespaceMap();
124  sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
125  for( sal_Int16 i=0; i < nAttrCount; i++ )
126  {
127  const OUString& rAttrName = xAttrList->getNameByIndex( i );
128 
129  OUString aLocalName;
130  sal_uInt16 nPrefix =rMap.GetKeyByAttrName( rAttrName,&aLocalName );
131  if( XML_NAMESPACE_TEXT == nPrefix &&
132  IsXMLToken( aLocalName, XML_C ) )
133  {
134  sal_Int32 nTmp = xAttrList->getValueByIndex(i).toInt32();
135  if( nTmp > 0 )
136  {
137  if( nTmp > SAL_MAX_UINT16 )
139  else
140  m_nCount = static_cast<sal_uInt16>(nTmp);
141  }
142  }
143  }
144 }
145 
147  SvXMLImport& rImport,
148  const Reference< xml::sax::XFastAttributeList > & xAttrList,
149  sal_Unicode c,
150  bool bCount ) :
151  SvXMLImportContext( rImport )
152  ,m_nControl(0)
153  ,m_nCount(1)
154  ,m_c(c)
155 {
156  if( !bCount )
157  return;
158 
159  for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
160  {
161  if( aIter.getToken() == XML_ELEMENT(TEXT, XML_C) )
162  {
163  sal_Int32 nTmp = aIter.toInt32();
164  if( nTmp > 0 )
165  {
166  if( nTmp > SAL_MAX_UINT16 )
168  else
169  m_nCount = static_cast<sal_uInt16>(nTmp);
170  }
171  }
172  else
173  XMLOFF_WARN_UNKNOWN("xmloff", aIter);
174  }
175 }
176 
178  SvXMLImport& rImp,
179  sal_uInt16 nPrfx,
180  const OUString& rLName,
181  const Reference< xml::sax::XAttributeList > &,
182  sal_Int16 nControl ) :
183  SvXMLImportContext( rImp, nPrfx, rLName )
184  ,m_nControl(nControl)
185  ,m_nCount(0)
186  ,m_c(0)
187 {
188 }
189 
191  SvXMLImport& rImp,
192  sal_Int16 nControl ) :
193  SvXMLImportContext( rImp )
194  ,m_nControl(nControl)
195  ,m_nCount(0)
196  ,m_c(0)
197 {
198 }
199 
201 {
202 }
204 {
205  if ( !m_nCount )
207  else
208  {
209  if( 1U == m_nCount )
210  {
211  OUString sBuff( &m_c, 1 );
212  InsertString(sBuff);
213  }
214  else
215  {
216  OUStringBuffer sBuff(static_cast<int>(m_nCount));
217  while( m_nCount-- )
218  sBuff.append( &m_c, 1 );
219 
220  InsertString(sBuff.makeStringAndClear() );
221  }
222  }
223 }
224 void XMLCharContext::InsertControlCharacter(sal_Int16 _nControl)
225 {
226  GetImport().GetTextImport()->InsertControlCharacter( _nControl );
227 }
228 void XMLCharContext::InsertString(const OUString& _sString)
229 {
230  GetImport().GetTextImport()->InsertString( _sString );
231 }
232 
233 namespace {
234 
236 class XMLStartReferenceContext_Impl : public SvXMLImportContext
237 {
238 public:
239 
240  // Do everything in constructor. Well ...
241  XMLStartReferenceContext_Impl (
242  SvXMLImport& rImport,
243  sal_uInt16 nPrefix,
244  const OUString& rLocalName,
245  XMLHints_Impl& rHints,
246  const Reference<xml::sax::XAttributeList> & xAttrList);
247 
248  static bool FindName(
249  SvXMLImport& rImport,
250  const Reference<xml::sax::XAttributeList> & xAttrList,
251  OUString& rName);
252 };
253 
254 }
255 
256 XMLStartReferenceContext_Impl::XMLStartReferenceContext_Impl(
257  SvXMLImport& rImport,
258  sal_uInt16 nPrefix,
259  const OUString& rLocalName,
260  XMLHints_Impl& rHints,
261  const Reference<xml::sax::XAttributeList> & xAttrList) :
262  SvXMLImportContext(rImport, nPrefix, rLocalName)
263 {
264  OUString sName;
265 
266  if (FindName(GetImport(), xAttrList, sName))
267  {
268  std::unique_ptr<XMLHint_Impl> pHint(new XMLReferenceHint_Impl(
269  sName, rImport.GetTextImport()->GetCursor()->getStart()));
270 
271  // degenerates to point reference, if no end is found!
272  pHint->SetEnd(rImport.GetTextImport()->GetCursor()->getStart() );
273 
274  rHints.push_back(std::move(pHint));
275  }
276 }
277 
278 bool XMLStartReferenceContext_Impl::FindName(
279  SvXMLImport& rImport,
280  const Reference<xml::sax::XAttributeList> & xAttrList,
281  OUString& rName)
282 {
283  bool bNameOK( false );
284 
285  // find name attribute first
286  const sal_Int16 nLength( xAttrList->getLength() );
287  for (sal_Int16 nAttr = 0; nAttr < nLength; nAttr++)
288  {
289  OUString sLocalName;
290  const sal_uInt16 nPrefix = rImport.GetNamespaceMap().
291  GetKeyByAttrName( xAttrList->getNameByIndex(nAttr),
292  &sLocalName );
293 
294  if ( (XML_NAMESPACE_TEXT == nPrefix) &&
295  IsXMLToken(sLocalName, XML_NAME) )
296  {
297  rName = xAttrList->getValueByIndex(nAttr);
298  bNameOK = true;
299  }
300  }
301 
302  return bNameOK;
303 }
304 
305 namespace {
306 
308 class XMLEndReferenceContext_Impl : public SvXMLImportContext
309 {
310 public:
311 
312  // Do everything in constructor. Well ...
313  XMLEndReferenceContext_Impl(
314  SvXMLImport& rImport,
315  sal_uInt16 nPrefix,
316  const OUString& rLocalName,
317  const XMLHints_Impl& rHints,
318  const Reference<xml::sax::XAttributeList> & xAttrList);
319 };
320 
321 }
322 
323 XMLEndReferenceContext_Impl::XMLEndReferenceContext_Impl(
324  SvXMLImport& rImport,
325  sal_uInt16 nPrefix,
326  const OUString& rLocalName,
327  const XMLHints_Impl& rHints,
328  const Reference<xml::sax::XAttributeList> & xAttrList) :
329  SvXMLImportContext(rImport, nPrefix, rLocalName)
330 {
331  OUString sName;
332 
333  // borrow from XMLStartReferenceContext_Impl
334  if (!XMLStartReferenceContext_Impl::FindName(GetImport(), xAttrList, sName))
335  return;
336 
337  // search for reference start
338  for (const auto& rHintPtr : rHints.GetHints())
339  {
340  XMLHint_Impl *const pHint = rHintPtr.get();
341  if ( pHint->IsReference() &&
342  sName == static_cast<XMLReferenceHint_Impl *>(pHint)->GetRefName() )
343  {
344  // set end and stop searching
345  pHint->SetEnd(GetImport().GetTextImport()->
346  GetCursor()->getStart() );
347  break;
348  }
349  }
350  // else: no start (in this paragraph) -> ignore
351 }
352 
353 namespace {
354 
355 class XMLImpSpanContext_Impl : public SvXMLImportContext
356 {
357  XMLHints_Impl& m_rHints;
358  XMLStyleHint_Impl *pHint;
359 
360  bool& rIgnoreLeadingSpace;
361 
362  sal_uInt8 nStarFontsConvFlags;
363 
364 public:
365 
366 
367  XMLImpSpanContext_Impl(
368  SvXMLImport& rImport,
369  sal_uInt16 nPrfx,
370  const OUString& rLName,
371  const Reference< xml::sax::XAttributeList > & xAttrList,
372  XMLHints_Impl& rHints,
373  bool& rIgnLeadSpace,
374  sal_uInt8 nSFConvFlags
375  );
376 
377  virtual ~XMLImpSpanContext_Impl() override;
378 
380  SvXMLImport& rImport,
381  sal_uInt16 nPrefix, const OUString& rLocalName,
382  const Reference< xml::sax::XAttributeList > & xAttrList,
383  sal_uInt16 nToken, XMLHints_Impl& rHints,
384  bool& rIgnLeadSpace,
385  sal_uInt8 nStarFontsConvFlags = 0
386  );
388  sal_uInt16 nPrefix, const OUString& rLocalName,
389  const Reference< xml::sax::XAttributeList > & xAttrList ) override;
390 
391  virtual void SAL_CALL characters( const OUString& rChars ) override;
392 };
393 
394 class XMLImpHyperlinkContext_Impl : public SvXMLImportContext
395 {
396  XMLHints_Impl& m_rHints;
397  XMLHyperlinkHint_Impl *mpHint;
398 
399  bool& mrbIgnoreLeadingSpace;
400 
401 public:
402 
403 
404  XMLImpHyperlinkContext_Impl(
405  SvXMLImport& rImport,
406  sal_uInt16 nPrfx,
407  const OUString& rLName,
408  const Reference< xml::sax::XAttributeList > & xAttrList,
409  XMLHints_Impl& rHints,
410  bool& rIgnLeadSpace );
411 
412  virtual ~XMLImpHyperlinkContext_Impl() override;
413 
415  sal_uInt16 nPrefix, const OUString& rLocalName,
416  const Reference< xml::sax::XAttributeList > & xAttrList ) override;
417 
418  virtual void SAL_CALL characters( const OUString& rChars ) override;
419 };
420 
421 }
422 
423 XMLImpHyperlinkContext_Impl::XMLImpHyperlinkContext_Impl(
424  SvXMLImport& rImport,
425  sal_uInt16 nPrfx,
426  const OUString& rLName,
427  const Reference< xml::sax::XAttributeList > & xAttrList,
428  XMLHints_Impl& rHints,
429  bool& rIgnLeadSpace )
430  : SvXMLImportContext( rImport, nPrfx, rLName )
431  , m_rHints( rHints )
432  , mpHint( new XMLHyperlinkHint_Impl( GetImport().GetTextImport()->GetCursorAsRange()->getStart() ) )
433  , mrbIgnoreLeadingSpace( rIgnLeadSpace )
434 {
435  OUString sShow;
436  const SvXMLTokenMap& rTokenMap = GetImport().GetTextImport()->GetTextHyperlinkAttrTokenMap();
437 
438  sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
439  for ( sal_Int16 i = 0; i < nAttrCount; i++ )
440  {
441  const OUString& rAttrName = xAttrList->getNameByIndex( i );
442  const OUString& rValue = xAttrList->getValueByIndex( i );
443 
444  OUString aLocalName;
445  const sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName );
446  switch (rTokenMap.Get( nPrefix, aLocalName ))
447  {
449  mpHint->SetHRef( GetImport().GetAbsoluteReference( rValue ) );
450  break;
452  mpHint->SetName( rValue );
453  break;
455  mpHint->SetTargetFrameName( rValue );
456  break;
458  sShow = rValue;
459  break;
461  mpHint->SetStyleName( rValue );
462  break;
464  mpHint->SetVisitedStyleName( rValue );
465  break;
466  }
467  }
468 
469  if( !sShow.isEmpty() && mpHint->GetTargetFrameName().isEmpty() )
470  {
471  if( IsXMLToken( sShow, XML_NEW ) )
472  mpHint->SetTargetFrameName(
473  "_blank" );
474  else if( IsXMLToken( sShow, XML_REPLACE ) )
475  mpHint->SetTargetFrameName(
476  "_self" );
477  }
478 
479  if ( mpHint->GetHRef().isEmpty() )
480  {
481  // hyperlink without a URL is not imported.
482  delete mpHint;
483  mpHint = nullptr;
484  }
485  else
486  {
487  m_rHints.push_back(std::unique_ptr<XMLHyperlinkHint_Impl>(mpHint));
488  }
489 }
490 
491 XMLImpHyperlinkContext_Impl::~XMLImpHyperlinkContext_Impl()
492 {
493  if (mpHint)
494  mpHint->SetEnd( GetImport().GetTextImport()
495  ->GetCursorAsRange()->getStart() );
496 }
497 
498 SvXMLImportContextRef XMLImpHyperlinkContext_Impl::CreateChildContext(
499  sal_uInt16 nPrefix, const OUString& rLocalName,
500  const Reference< xml::sax::XAttributeList > & xAttrList )
501 {
502  if ( (nPrefix == XML_NAMESPACE_OFFICE) &&
503  IsXMLToken(rLocalName, XML_EVENT_LISTENERS) )
504  {
505  XMLEventsImportContext* pCtxt = new XMLEventsImportContext(GetImport());
506  if (mpHint)
507  mpHint->SetEventsContext(pCtxt);
508  return pCtxt;
509  }
510  else
511  {
512  const SvXMLTokenMap& rTokenMap =
513  GetImport().GetTextImport()->GetTextPElemTokenMap();
514  sal_uInt16 nToken = rTokenMap.Get( nPrefix, rLocalName );
515 
516  return XMLImpSpanContext_Impl::CreateChildContext(
517  GetImport(), nPrefix, rLocalName, xAttrList,
518  nToken, m_rHints, mrbIgnoreLeadingSpace );
519  }
520 }
521 
522 void XMLImpHyperlinkContext_Impl::characters( const OUString& rChars )
523 {
524  GetImport().GetTextImport()->InsertString( rChars, mrbIgnoreLeadingSpace );
525 }
526 
527 namespace {
528 
529 class XMLImpRubyBaseContext_Impl : public SvXMLImportContext
530 {
531  XMLHints_Impl& m_rHints;
532 
533  bool& rIgnoreLeadingSpace;
534 
535 public:
536 
537 
538  XMLImpRubyBaseContext_Impl(
539  SvXMLImport& rImport,
540  sal_uInt16 nPrfx,
541  const OUString& rLName,
542  const Reference< xml::sax::XAttributeList > & xAttrList,
543  XMLHints_Impl& rHints,
544  bool& rIgnLeadSpace );
545 
547  sal_uInt16 nPrefix, const OUString& rLocalName,
548  const Reference< xml::sax::XAttributeList > & xAttrList ) override;
549 
550  virtual void SAL_CALL characters( const OUString& rChars ) override;
551 };
552 
553 }
554 
555 XMLImpRubyBaseContext_Impl::XMLImpRubyBaseContext_Impl(
556  SvXMLImport& rImport,
557  sal_uInt16 nPrfx,
558  const OUString& rLName,
559  const Reference< xml::sax::XAttributeList > &,
560  XMLHints_Impl& rHints,
561  bool& rIgnLeadSpace )
562  : SvXMLImportContext( rImport, nPrfx, rLName )
563  , m_rHints( rHints )
564  , rIgnoreLeadingSpace( rIgnLeadSpace )
565 {
566 }
567 
568 SvXMLImportContextRef XMLImpRubyBaseContext_Impl::CreateChildContext(
569  sal_uInt16 nPrefix, const OUString& rLocalName,
570  const Reference< xml::sax::XAttributeList > & xAttrList )
571 {
572  const SvXMLTokenMap& rTokenMap =
573  GetImport().GetTextImport()->GetTextPElemTokenMap();
574  sal_uInt16 nToken = rTokenMap.Get( nPrefix, rLocalName );
575 
576  return XMLImpSpanContext_Impl::CreateChildContext( GetImport(), nPrefix,
577  rLocalName, xAttrList,
578  nToken, m_rHints, rIgnoreLeadingSpace );
579 }
580 
581 void XMLImpRubyBaseContext_Impl::characters( const OUString& rChars )
582 {
583  GetImport().GetTextImport()->InsertString( rChars, rIgnoreLeadingSpace );
584 }
585 
586 namespace {
587 
588 class XMLImpRubyContext_Impl : public SvXMLImportContext
589 {
590  XMLHints_Impl& m_rHints;
591 
592  bool& rIgnoreLeadingSpace;
593 
594  Reference < XTextRange > m_xStart;
595  OUString m_sStyleName;
596  OUString m_sTextStyleName;
597  OUString m_sText;
598 
599 public:
600 
601 
602  XMLImpRubyContext_Impl(
603  SvXMLImport& rImport,
604  sal_uInt16 nPrfx,
605  const OUString& rLName,
606  const Reference< xml::sax::XAttributeList > & xAttrList,
607  XMLHints_Impl& rHints,
608  bool& rIgnLeadSpace );
609 
610  virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
611 
613  sal_uInt16 nPrefix, const OUString& rLocalName,
614  const Reference< xml::sax::XAttributeList > & xAttrList ) override;
615 
616  void SetTextStyleName( const OUString& s ) { m_sTextStyleName = s; }
617  void AppendText( const OUString& s ) { m_sText += s; }
618 };
619 
620 class XMLImpRubyTextContext_Impl : public SvXMLImportContext
621 {
622  XMLImpRubyContext_Impl & m_rRubyContext;
623 
624 public:
625 
626 
627  XMLImpRubyTextContext_Impl(
628  SvXMLImport& rImport,
629  sal_uInt16 nPrfx,
630  const OUString& rLName,
631  const Reference< xml::sax::XAttributeList > & xAttrList,
632  XMLImpRubyContext_Impl & rParent );
633 
634  virtual void SAL_CALL characters( const OUString& rChars ) override;
635 };
636 
637 }
638 
639 XMLImpRubyTextContext_Impl::XMLImpRubyTextContext_Impl(
640  SvXMLImport& rImport,
641  sal_uInt16 nPrfx,
642  const OUString& rLName,
643  const Reference< xml::sax::XAttributeList > & xAttrList,
644  XMLImpRubyContext_Impl & rParent )
645  : SvXMLImportContext( rImport, nPrfx, rLName )
646  , m_rRubyContext( rParent )
647 {
648  sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
649  for( sal_Int16 i=0; i < nAttrCount; i++ )
650  {
651  const OUString& rAttrName = xAttrList->getNameByIndex( i );
652  const OUString& rValue = xAttrList->getValueByIndex( i );
653 
654  OUString aLocalName;
655  sal_uInt16 nPrefix =
657  &aLocalName );
658  if( XML_NAMESPACE_TEXT == nPrefix &&
659  IsXMLToken( aLocalName, XML_STYLE_NAME ) )
660  {
661  m_rRubyContext.SetTextStyleName( rValue );
662  break;
663  }
664  }
665 }
666 
667 void XMLImpRubyTextContext_Impl::characters( const OUString& rChars )
668 {
669  m_rRubyContext.AppendText( rChars );
670 }
671 
672 
673 XMLImpRubyContext_Impl::XMLImpRubyContext_Impl(
674  SvXMLImport& rImport,
675  sal_uInt16 nPrfx,
676  const OUString& rLName,
677  const Reference< xml::sax::XAttributeList > & xAttrList,
678  XMLHints_Impl& rHints,
679  bool& rIgnLeadSpace )
680  : SvXMLImportContext( rImport, nPrfx, rLName )
681  , m_rHints( rHints )
682  , rIgnoreLeadingSpace( rIgnLeadSpace )
683  , m_xStart( GetImport().GetTextImport()->GetCursorAsRange()->getStart() )
684 {
685  sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
686  for( sal_Int16 i=0; i < nAttrCount; i++ )
687  {
688  const OUString& rAttrName = xAttrList->getNameByIndex( i );
689  const OUString& rValue = xAttrList->getValueByIndex( i );
690 
691  OUString aLocalName;
692  sal_uInt16 nPrefix =
694  &aLocalName );
695  if( XML_NAMESPACE_TEXT == nPrefix &&
696  IsXMLToken( aLocalName, XML_STYLE_NAME ) )
697  {
698  m_sStyleName = rValue;
699  break;
700  }
701  }
702 }
703 
704 void XMLImpRubyContext_Impl::endFastElement(sal_Int32 )
705 {
706  const rtl::Reference < XMLTextImportHelper > xTextImport(
707  GetImport().GetTextImport());
708  const Reference < XTextCursor > xAttrCursor(
709  xTextImport->GetText()->createTextCursorByRange( m_xStart ));
710  if (!xAttrCursor.is())
711  {
712  SAL_WARN("xmloff.text", "cannot insert ruby");
713  return;
714  }
715  xAttrCursor->gotoRange(xTextImport->GetCursorAsRange()->getStart(),
716  true);
717  xTextImport->SetRuby( GetImport(), xAttrCursor,
718  m_sStyleName, m_sTextStyleName, m_sText );
719 }
720 
721 SvXMLImportContextRef XMLImpRubyContext_Impl::CreateChildContext(
722  sal_uInt16 nPrefix, const OUString& rLocalName,
723  const Reference< xml::sax::XAttributeList > & xAttrList )
724 {
725  SvXMLImportContextRef xContext;
726  if( XML_NAMESPACE_TEXT == nPrefix )
727  {
728  if( IsXMLToken( rLocalName, XML_RUBY_BASE ) )
729  xContext = new XMLImpRubyBaseContext_Impl( GetImport(), nPrefix,
730  rLocalName,
731  xAttrList,
732  m_rHints,
733  rIgnoreLeadingSpace );
734  else if( IsXMLToken( rLocalName, XML_RUBY_TEXT ) )
735  xContext = new XMLImpRubyTextContext_Impl( GetImport(), nPrefix,
736  rLocalName,
737  xAttrList,
738  *this );
739  }
740 
741  return xContext;
742 }
743 
744 namespace {
745 
748 class XMLMetaImportContextBase : public SvXMLImportContext
749 {
750  XMLHints_Impl& m_rHints;
751 
752  bool& m_rIgnoreLeadingSpace;
753 
755  Reference<XTextRange> m_xStart;
756 
757 protected:
758  OUString m_XmlId;
759 
760 public:
761 
762  XMLMetaImportContextBase(
763  SvXMLImport& i_rImport,
764  const sal_uInt16 i_nPrefix,
765  const OUString& i_rLocalName,
766  XMLHints_Impl& i_rHints,
767  bool & i_rIgnoreLeadingSpace );
768 
769  virtual void SAL_CALL startFastElement(
770  sal_Int32 nElement,
771  const Reference<xml::sax::XFastAttributeList> & i_xAttrList) override;
772 
773  virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
774 
776  sal_uInt16 i_nPrefix, const OUString& i_rLocalName,
777  const Reference< xml::sax::XAttributeList > & i_xAttrList) override;
778 
779  virtual void SAL_CALL characters( const OUString& i_rChars ) override;
780 
781  virtual void ProcessAttribute(sal_Int32 nAttributeToken, OUString const & i_rValue);
782 
783  virtual void InsertMeta(const Reference<XTextRange> & i_xInsertionRange)
784  = 0;
785 };
786 
787 }
788 
789 XMLMetaImportContextBase::XMLMetaImportContextBase(
790  SvXMLImport& i_rImport,
791  const sal_uInt16 i_nPrefix,
792  const OUString& i_rLocalName,
793  XMLHints_Impl& i_rHints,
794  bool & i_rIgnoreLeadingSpace )
795  : SvXMLImportContext( i_rImport, i_nPrefix, i_rLocalName )
796  , m_rHints( i_rHints )
797  , m_rIgnoreLeadingSpace( i_rIgnoreLeadingSpace )
798  , m_xStart( GetImport().GetTextImport()->GetCursorAsRange()->getStart() )
799 {
800 }
801 
802 void XMLMetaImportContextBase::startFastElement(
803  sal_Int32 /*nElement*/,
804  const Reference<xml::sax::XFastAttributeList> & xAttrList)
805 {
806  for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
807  ProcessAttribute(aIter.getToken(), aIter.toString());
808 }
809 
810 void XMLMetaImportContextBase::endFastElement(sal_Int32 )
811 {
812  SAL_WARN_IF(!m_xStart.is(), "xmloff.text", "no mxStart?");
813  if (!m_xStart.is()) return;
814 
815  const Reference<XTextRange> xEndRange(
816  GetImport().GetTextImport()->GetCursorAsRange()->getStart() );
817 
818  // create range for insertion
819  const Reference<XTextCursor> xInsertionCursor(
820  GetImport().GetTextImport()->GetText()->createTextCursorByRange(
821  xEndRange) );
822  xInsertionCursor->gotoRange(m_xStart, true);
823 
824  InsertMeta(xInsertionCursor);
825 }
826 
827 SvXMLImportContextRef XMLMetaImportContextBase::CreateChildContext(
828  sal_uInt16 i_nPrefix, const OUString& i_rLocalName,
829  const Reference< xml::sax::XAttributeList > & i_xAttrList )
830 {
831  const SvXMLTokenMap& rTokenMap(
832  GetImport().GetTextImport()->GetTextPElemTokenMap() );
833  const sal_uInt16 nToken( rTokenMap.Get( i_nPrefix, i_rLocalName ) );
834 
835  return XMLImpSpanContext_Impl::CreateChildContext( GetImport(), i_nPrefix,
836  i_rLocalName, i_xAttrList, nToken, m_rHints, m_rIgnoreLeadingSpace );
837 }
838 
839 void XMLMetaImportContextBase::characters( const OUString& i_rChars )
840 {
841  GetImport().GetTextImport()->InsertString(i_rChars, m_rIgnoreLeadingSpace);
842 }
843 
844 void XMLMetaImportContextBase::ProcessAttribute(sal_Int32 nAttributeToken,
845  OUString const & i_rValue)
846 {
847  if ( nAttributeToken == XML_ELEMENT(XML, XML_ID) )
848  m_XmlId = i_rValue;
849  else
850  XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttributeToken, i_rValue);
851 }
852 
853 namespace {
854 
856 class XMLMetaImportContext : public XMLMetaImportContextBase
857 {
858  // RDFa
859  bool m_bHaveAbout;
860  OUString m_sAbout;
861  OUString m_sProperty;
862  OUString m_sContent;
863  OUString m_sDatatype;
864 
865 public:
866 
867  XMLMetaImportContext(
868  SvXMLImport& i_rImport,
869  const sal_uInt16 i_nPrefix,
870  const OUString& i_rLocalName,
871  XMLHints_Impl& i_rHints,
872  bool & i_rIgnoreLeadingSpace );
873 
874  virtual void ProcessAttribute(sal_Int32 nAttributeToken,
875  OUString const & i_rValue) override;
876 
877  virtual void InsertMeta(const Reference<XTextRange> & i_xInsertionRange) override;
878 };
879 
880 }
881 
882 XMLMetaImportContext::XMLMetaImportContext(
883  SvXMLImport& i_rImport,
884  const sal_uInt16 i_nPrefix,
885  const OUString& i_rLocalName,
886  XMLHints_Impl& i_rHints,
887  bool & i_rIgnoreLeadingSpace )
888  : XMLMetaImportContextBase( i_rImport, i_nPrefix, i_rLocalName,
889  i_rHints, i_rIgnoreLeadingSpace )
890  , m_bHaveAbout(false)
891 {
892 }
893 
894 void XMLMetaImportContext::ProcessAttribute(sal_Int32 nAttributeToken,
895  OUString const & i_rValue)
896 {
897  switch (nAttributeToken)
898  {
899  // RDFa
900  case XML_ELEMENT(XHTML, XML_ABOUT):
901  m_sAbout = i_rValue;
902  m_bHaveAbout = true;
903  break;
904  case XML_ELEMENT(XHTML, XML_PROPERTY):
905  m_sProperty = i_rValue;
906  break;
907  case XML_ELEMENT(XHTML, XML_CONTENT):
908  m_sContent = i_rValue;
909  break;
910  case XML_ELEMENT(XHTML, XML_DATATYPE):
911  m_sDatatype = i_rValue;
912  break;
913  default:
914  XMLMetaImportContextBase::ProcessAttribute(
915  nAttributeToken, i_rValue);
916  }
917 }
918 
919 void XMLMetaImportContext::InsertMeta(
920  const Reference<XTextRange> & i_xInsertionRange)
921 {
922  SAL_WARN_IF(m_bHaveAbout == m_sProperty.isEmpty(), "xmloff.text", "XMLMetaImportContext::InsertMeta: invalid RDFa?");
923  if (!m_XmlId.isEmpty() || (m_bHaveAbout && !m_sProperty.isEmpty()))
924  {
925  // insert mark
926  const uno::Reference<rdf::XMetadatable> xMeta(
928  GetImport(),
929  "com.sun.star.text.InContentMetadata",
930  OUString(),
931  i_xInsertionRange, m_XmlId),
932  uno::UNO_QUERY);
933  SAL_WARN_IF(!xMeta.is(), "xmloff.text", "cannot insert Meta?");
934 
935  if (xMeta.is() && m_bHaveAbout)
936  {
937  GetImport().AddRDFa(xMeta,
938  m_sAbout, m_sProperty, m_sContent, m_sDatatype);
939  }
940  }
941  else
942  {
943  SAL_INFO("xmloff.text", "invalid <text:meta>: no xml:id, no valid RDFa");
944  }
945 }
946 
947 namespace {
948 
950 class XMLMetaFieldImportContext : public XMLMetaImportContextBase
951 {
952  OUString m_DataStyleName;
953 
954 public:
955 
956  XMLMetaFieldImportContext(
957  SvXMLImport& i_rImport,
958  const sal_uInt16 i_nPrefix,
959  const OUString& i_rLocalName,
960  XMLHints_Impl& i_rHints,
961  bool & i_rIgnoreLeadingSpace );
962 
963  virtual void ProcessAttribute(sal_Int32 nAttributeToken,
964  OUString const & i_rValue) override;
965 
966  virtual void InsertMeta(const Reference<XTextRange> & i_xInsertionRange) override;
967 };
968 
969 }
970 
971 XMLMetaFieldImportContext::XMLMetaFieldImportContext(
972  SvXMLImport& i_rImport,
973  const sal_uInt16 i_nPrefix,
974  const OUString& i_rLocalName,
975  XMLHints_Impl& i_rHints,
976  bool & i_rIgnoreLeadingSpace )
977  : XMLMetaImportContextBase( i_rImport, i_nPrefix, i_rLocalName,
978  i_rHints, i_rIgnoreLeadingSpace )
979 {
980 }
981 
982 void XMLMetaFieldImportContext::ProcessAttribute(sal_Int32 nAttributeToken,
983  OUString const & i_rValue)
984 {
985  switch (nAttributeToken)
986  {
987  case XML_ELEMENT(STYLE, XML_DATA_STYLE_NAME):
988  m_DataStyleName = i_rValue;
989  break;
990  default:
991  XMLMetaImportContextBase::ProcessAttribute(
992  nAttributeToken, i_rValue);
993  }
994 }
995 
996 void XMLMetaFieldImportContext::InsertMeta(
997  const Reference<XTextRange> & i_xInsertionRange)
998 {
999  if (!m_XmlId.isEmpty()) // valid?
1000  {
1001  // insert mark
1002  const Reference<XPropertySet> xPropertySet(
1004  GetImport(),
1005  "com.sun.star.text.textfield.MetadataField",
1006  OUString(),
1007  i_xInsertionRange, m_XmlId),
1008  UNO_QUERY);
1009  SAL_WARN_IF(!xPropertySet.is(), "xmloff.text", "cannot insert MetaField?");
1010  if (!xPropertySet.is()) return;
1011 
1012  if (!m_DataStyleName.isEmpty())
1013  {
1014  bool isDefaultLanguage(true);
1015 
1016  const sal_Int32 nKey( GetImport().GetTextImport()->GetDataStyleKey(
1017  m_DataStyleName, & isDefaultLanguage) );
1018 
1019  if (-1 != nKey)
1020  {
1021  OUString sPropertyIsFixedLanguage("IsFixedLanguage");
1022  xPropertySet->setPropertyValue("NumberFormat", Any(nKey));
1023  if ( xPropertySet->getPropertySetInfo()->
1024  hasPropertyByName( sPropertyIsFixedLanguage ) )
1025  {
1026  xPropertySet->setPropertyValue( sPropertyIsFixedLanguage,
1027  Any(!isDefaultLanguage) );
1028  }
1029  }
1030  }
1031  }
1032  else
1033  {
1034  SAL_INFO("xmloff.text", "invalid <text:meta-field>: no xml:id");
1035  }
1036 }
1037 
1038 namespace {
1039 
1047 class XMLIndexMarkImportContext_Impl : public SvXMLImportContext
1048 {
1049  XMLHints_Impl& m_rHints;
1050  const enum XMLTextPElemTokens eToken;
1051  OUString sID;
1052 
1053 public:
1054 
1055  XMLIndexMarkImportContext_Impl(
1056  SvXMLImport& rImport,
1057  sal_uInt16 nPrefix,
1058  const OUString& rLocalName,
1059  enum XMLTextPElemTokens nTok,
1060  XMLHints_Impl& rHints);
1061 
1062  void SAL_CALL startFastElement(sal_Int32 nElement, const Reference<xml::sax::XFastAttributeList> & xAttrList) override;
1063 
1064 protected:
1065 
1067  void ProcessAttributes(const Reference<xml::sax::XFastAttributeList> & xAttrList,
1068  Reference<beans::XPropertySet>& rPropSet);
1069 
1078  virtual void ProcessAttribute(sal_Int32 nAttributeToken,
1079  const OUString& sValue,
1080  Reference<beans::XPropertySet>& rPropSet);
1081 
1082  static void GetServiceName(OUString& sServiceName,
1083  enum XMLTextPElemTokens nToken);
1084 
1085  bool CreateMark(Reference<beans::XPropertySet>& rPropSet,
1086  const OUString& rServiceName);
1087 };
1088 
1089 }
1090 
1091 XMLIndexMarkImportContext_Impl::XMLIndexMarkImportContext_Impl(
1092  SvXMLImport& rImport,
1093  sal_uInt16 nPrefix,
1094  const OUString& rLocalName,
1095  enum XMLTextPElemTokens eTok,
1096  XMLHints_Impl& rHints)
1097  : SvXMLImportContext(rImport, nPrefix, rLocalName)
1098  , m_rHints(rHints)
1099  , eToken(eTok)
1100 {
1101 }
1102 
1103 void XMLIndexMarkImportContext_Impl::startFastElement(
1104  sal_Int32 /*nElement*/,
1105  const Reference<xml::sax::XFastAttributeList> & xAttrList)
1106 {
1107  // get Cursor position (needed for all cases)
1108  Reference<XTextRange> xPos(
1109  GetImport().GetTextImport()->GetCursor()->getStart());
1111 
1112  switch (eToken)
1113  {
1114  case XML_TOK_TEXT_TOC_MARK:
1117  {
1118  // single mark: create mark and insert
1119  OUString sService;
1120  GetServiceName(sService, eToken);
1121  if (CreateMark(xMark, sService))
1122  {
1123  ProcessAttributes(xAttrList, xMark);
1124  m_rHints.push_back(
1125  std::make_unique<XMLIndexMarkHint_Impl>(xMark, xPos));
1126  }
1127  // else: can't create mark -> ignore
1128  break;
1129  }
1130 
1134  {
1135  // start: create mark and insert (if ID is found)
1136  OUString sService;
1137  GetServiceName(sService, eToken);
1138  if (CreateMark(xMark, sService))
1139  {
1140  ProcessAttributes(xAttrList, xMark);
1141  if (!sID.isEmpty())
1142  {
1143  // process only if we find an ID
1144  m_rHints.push_back(
1145  std::make_unique<XMLIndexMarkHint_Impl>(xMark, xPos, sID));
1146  }
1147  // else: no ID -> we'll never find the end -> ignore
1148  }
1149  // else: can't create mark -> ignore
1150  break;
1151  }
1152 
1156  {
1157  // end: search for ID and set end of mark
1158 
1159  // call process attributes with empty XPropertySet:
1160  ProcessAttributes(xAttrList, xMark);
1161  if (!sID.isEmpty())
1162  {
1163  // if we have an ID, find the hint and set the end position
1164  XMLIndexMarkHint_Impl *const pHint = m_rHints.GetIndexHintById(sID);
1165  if (pHint)
1166  // set end and stop searching
1167  pHint->SetEnd(xPos);
1168  }
1169  // else: no ID -> ignore
1170  break;
1171  }
1172 
1173  default:
1174  SAL_WARN("xmloff.text", "unknown index mark type!");
1175  break;
1176  }
1177 }
1178 
1179 void XMLIndexMarkImportContext_Impl::ProcessAttributes(
1180  const Reference<xml::sax::XFastAttributeList> & xAttrList,
1182 {
1183  // process attributes
1184  for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
1185  {
1186  ProcessAttribute(aIter.getToken(), aIter.toString(), rPropSet);
1187  }
1188 }
1189 
1190 void XMLIndexMarkImportContext_Impl::ProcessAttribute(
1191  sal_Int32 nAttributeToken,
1192  const OUString& sValue,
1194 {
1195  // we only know ID + string-value attribute;
1196  // (former: marks, latter: -start + -end-marks)
1197  // the remainder is handled in sub-classes
1198  switch (eToken)
1199  {
1200  case XML_TOK_TEXT_TOC_MARK:
1203  if ( nAttributeToken == XML_ELEMENT(TEXT, XML_STRING_VALUE) )
1204  {
1205  rPropSet->setPropertyValue("AlternativeText", uno::makeAny(sValue));
1206  }
1207  // else: ignore!
1208  break;
1209 
1216  if ( nAttributeToken == XML_ELEMENT(TEXT, XML_ID) )
1217  {
1218  sID = sValue;
1219  }
1220  // else: ignore
1221  break;
1222 
1223  default:
1224  SAL_WARN("xmloff.text", "unknown index mark type!");
1225  break;
1226  }
1227 }
1228 
1229 
1230 void XMLIndexMarkImportContext_Impl::GetServiceName(
1231  OUString& sServiceName,
1233 {
1234  switch (eToken)
1235  {
1236  case XML_TOK_TEXT_TOC_MARK:
1239  {
1240  sServiceName = "com.sun.star.text.ContentIndexMark";
1241  break;
1242  }
1243 
1247  {
1248  sServiceName = "com.sun.star.text.UserIndexMark";
1249  break;
1250  }
1251 
1255  {
1256  sServiceName = "com.sun.star.text.DocumentIndexMark";
1257  break;
1258  }
1259 
1260  default:
1261  {
1262  SAL_WARN("xmloff.text", "unknown index mark type!");
1263  sServiceName.clear();
1264  break;
1265  }
1266  }
1267 }
1268 
1269 bool XMLIndexMarkImportContext_Impl::CreateMark(
1271  const OUString& rServiceName)
1272 {
1273  Reference<lang::XMultiServiceFactory>
1274  xFactory(GetImport().GetModel(), UNO_QUERY);
1275 
1276  if( xFactory.is() )
1277  {
1278  Reference<beans::XPropertySet> xPropSet( xFactory->createInstance(rServiceName), UNO_QUERY );
1279  if (xPropSet.is())
1280  rPropSet = xPropSet;
1281  return true;
1282  }
1283 
1284  return false;
1285 }
1286 
1287 namespace {
1288 
1289 class XMLTOCMarkImportContext_Impl : public XMLIndexMarkImportContext_Impl
1290 {
1291 public:
1292 
1293  XMLTOCMarkImportContext_Impl(
1294  SvXMLImport& rImport,
1295  sal_uInt16 nPrefix,
1296  const OUString& rLocalName,
1297  enum XMLTextPElemTokens nTok,
1298  XMLHints_Impl& rHints);
1299 
1300 protected:
1301 
1303  virtual void ProcessAttribute(sal_Int32 nAttributeToken,
1304  const OUString& sValue,
1305  Reference<beans::XPropertySet>& rPropSet) override;
1306 };
1307 
1308 }
1309 
1310 XMLTOCMarkImportContext_Impl::XMLTOCMarkImportContext_Impl(
1311  SvXMLImport& rImport, sal_uInt16 nPrefix, const OUString& rLocalName,
1312  enum XMLTextPElemTokens nTok, XMLHints_Impl& rHints) :
1313  XMLIndexMarkImportContext_Impl(rImport, nPrefix, rLocalName,
1314  nTok, rHints)
1315 {
1316 }
1317 
1318 void XMLTOCMarkImportContext_Impl::ProcessAttribute(
1319  sal_Int32 nAttributeToken,
1320  const OUString& sValue,
1322 {
1323  SAL_WARN_IF(!rPropSet.is(), "xmloff.text", "need PropertySet");
1324 
1325  switch (nAttributeToken)
1326  {
1327  case XML_ELEMENT(TEXT, XML_OUTLINE_LEVEL):
1328  {
1329  // ouline level: set Level property
1330  sal_Int32 nTmp;
1331  if (::sax::Converter::convertNumber( nTmp, sValue )
1332  && nTmp >= 1
1333  && nTmp < GetImport().GetTextImport()->
1334  GetChapterNumbering()->getCount() )
1335  {
1336  rPropSet->setPropertyValue("Level", uno::makeAny(static_cast<sal_Int16>(nTmp - 1)));
1337  }
1338  // else: value out of range -> ignore
1339  break;
1340  }
1341  default:
1342  // else: delegate to superclass
1343  XMLIndexMarkImportContext_Impl::ProcessAttribute(
1344  nAttributeToken, sValue, rPropSet);
1345  }
1346 }
1347 
1348 namespace {
1349 
1350 class XMLUserIndexMarkImportContext_Impl : public XMLIndexMarkImportContext_Impl
1351 {
1352 public:
1353 
1354  XMLUserIndexMarkImportContext_Impl(
1355  SvXMLImport& rImport,
1356  sal_uInt16 nPrefix,
1357  const OUString& rLocalName,
1358  enum XMLTextPElemTokens nTok,
1359  XMLHints_Impl& rHints);
1360 
1361 protected:
1362 
1364  virtual void ProcessAttribute(sal_Int32 nAttributeToken,
1365  const OUString& sValue,
1366  Reference<beans::XPropertySet>& rPropSet) override;
1367 };
1368 
1369 }
1370 
1371 XMLUserIndexMarkImportContext_Impl::XMLUserIndexMarkImportContext_Impl(
1372  SvXMLImport& rImport, sal_uInt16 nPrefix, const OUString& rLocalName,
1373  enum XMLTextPElemTokens nTok, XMLHints_Impl& rHints) :
1374  XMLIndexMarkImportContext_Impl(rImport, nPrefix, rLocalName,
1375  nTok, rHints)
1376 {
1377 }
1378 
1379 void XMLUserIndexMarkImportContext_Impl::ProcessAttribute(
1380  sal_Int32 nAttributeToken, const OUString& sValue,
1382 {
1383  switch (nAttributeToken)
1384  {
1385  case XML_ELEMENT(TEXT, XML_INDEX_NAME):
1386  rPropSet->setPropertyValue("UserIndexName", uno::makeAny(sValue));
1387  break;
1388  case XML_ELEMENT(TEXT, XML_OUTLINE_LEVEL):
1389  {
1390  // ouline level: set Level property
1391  sal_Int32 nTmp;
1393  nTmp, sValue, 0,
1394  GetImport().GetTextImport()->GetChapterNumbering()->getCount()))
1395  {
1396  rPropSet->setPropertyValue("Level", uno::makeAny(static_cast<sal_Int16>(nTmp - 1)));
1397  }
1398  // else: value out of range -> ignore
1399  break;
1400  }
1401  default:
1402  // else: unknown text property: delegate to super class
1403  XMLIndexMarkImportContext_Impl::ProcessAttribute(
1404  nAttributeToken, sValue, rPropSet);
1405  }
1406 }
1407 
1408 namespace {
1409 
1410 class XMLAlphaIndexMarkImportContext_Impl : public XMLIndexMarkImportContext_Impl
1411 {
1412 public:
1413 
1414  XMLAlphaIndexMarkImportContext_Impl(
1415  SvXMLImport& rImport,
1416  sal_uInt16 nPrefix,
1417  const OUString& rLocalName,
1418  enum XMLTextPElemTokens nTok,
1419  XMLHints_Impl& rHints);
1420 
1421 protected:
1422 
1424  virtual void ProcessAttribute(sal_Int32 nAttributeToken,
1425  const OUString& sValue,
1426  Reference<beans::XPropertySet>& rPropSet) override;
1427 };
1428 
1429 }
1430 
1431 XMLAlphaIndexMarkImportContext_Impl::XMLAlphaIndexMarkImportContext_Impl(
1432  SvXMLImport& rImport, sal_uInt16 nPrefix, const OUString& rLocalName,
1433  enum XMLTextPElemTokens nTok, XMLHints_Impl& rHints) :
1434  XMLIndexMarkImportContext_Impl(rImport, nPrefix, rLocalName,
1435  nTok, rHints)
1436 {
1437 }
1438 
1439 void XMLAlphaIndexMarkImportContext_Impl::ProcessAttribute(
1440  sal_Int32 nAttributeToken, const OUString& sValue,
1442 {
1443  switch (nAttributeToken)
1444  {
1445  case XML_ELEMENT(TEXT, XML_KEY1):
1446  rPropSet->setPropertyValue("PrimaryKey", uno::makeAny(sValue));
1447  break;
1448  case XML_ELEMENT(TEXT, XML_KEY2):
1449  rPropSet->setPropertyValue("SecondaryKey", uno::makeAny(sValue));
1450  break;
1451  case XML_ELEMENT(TEXT, XML_KEY1_PHONETIC):
1452  rPropSet->setPropertyValue("PrimaryKeyReading", uno::makeAny(sValue));
1453  break;
1454  case XML_ELEMENT(TEXT, XML_KEY2_PHONETIC):
1455  rPropSet->setPropertyValue("SecondaryKeyReading", uno::makeAny(sValue));
1456  break;
1458  rPropSet->setPropertyValue("TextReading", uno::makeAny(sValue));
1459  break;
1460  case XML_ELEMENT(TEXT, XML_MAIN_ENTRY):
1461  {
1462  bool bMainEntry = false;
1463  bool bTmp(false);
1464 
1465  if (::sax::Converter::convertBool(bTmp, sValue))
1466  bMainEntry = bTmp;
1467 
1468  rPropSet->setPropertyValue("IsMainEntry", uno::makeAny(bMainEntry));
1469  break;
1470  }
1471  default:
1472  XMLIndexMarkImportContext_Impl::ProcessAttribute(
1473  nAttributeToken, sValue, rPropSet);
1474  }
1475 }
1476 
1477 
1478 XMLImpSpanContext_Impl::XMLImpSpanContext_Impl(
1479  SvXMLImport& rImport,
1480  sal_uInt16 nPrfx,
1481  const OUString& rLName,
1482  const Reference< xml::sax::XAttributeList > & xAttrList,
1483  XMLHints_Impl& rHints,
1484  bool& rIgnLeadSpace,
1485  sal_uInt8 nSFConvFlags
1486  )
1487 : SvXMLImportContext( rImport, nPrfx, rLName )
1488 , m_rHints( rHints )
1489 , pHint( nullptr )
1490 , rIgnoreLeadingSpace( rIgnLeadSpace )
1491 , nStarFontsConvFlags( nSFConvFlags & (CONV_FROM_STAR_BATS|CONV_FROM_STAR_MATH) )
1492 {
1493  OUString aStyleName;
1494 
1495  sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
1496  for( sal_Int16 i=0; i < nAttrCount; i++ )
1497  {
1498  const OUString& rAttrName = xAttrList->getNameByIndex( i );
1499 
1500  OUString aLocalName;
1501  sal_uInt16 nPrefix =
1503  &aLocalName );
1504  if( XML_NAMESPACE_TEXT == nPrefix &&
1505  IsXMLToken( aLocalName, XML_STYLE_NAME ) )
1506  aStyleName = xAttrList->getValueByIndex( i );
1507  }
1508 
1509  if( !aStyleName.isEmpty() )
1510  {
1511  pHint = new XMLStyleHint_Impl( aStyleName,
1512  GetImport().GetTextImport()->GetCursorAsRange()->getStart() );
1513  m_rHints.push_back(std::unique_ptr<XMLStyleHint_Impl>(pHint));
1514  }
1515 }
1516 
1517 XMLImpSpanContext_Impl::~XMLImpSpanContext_Impl()
1518 {
1519  if (!pHint)
1520  return;
1521 
1522  Reference<XTextRange> xCrsrRange(GetImport().GetTextImport()->GetCursorAsRange());
1523  if (!xCrsrRange.is())
1524  return; // Robust (defective file)
1525 
1526  pHint->SetEnd(xCrsrRange->getStart());
1527 }
1528 
1529 SvXMLImportContextRef XMLImpSpanContext_Impl::CreateChildContext(
1530  SvXMLImport& rImport,
1531  sal_uInt16 nPrefix, const OUString& rLocalName,
1532  const Reference< xml::sax::XAttributeList > & xAttrList,
1533  sal_uInt16 nToken,
1534  XMLHints_Impl& rHints,
1535  bool& rIgnoreLeadingSpace,
1536  sal_uInt8 nStarFontsConvFlags
1537  )
1538 {
1539  SvXMLImportContext *pContext = nullptr;
1540 
1541  switch( nToken )
1542  {
1543  case XML_TOK_TEXT_SPAN:
1544  pContext = new XMLImpSpanContext_Impl( rImport, nPrefix,
1545  rLocalName, xAttrList,
1546  rHints,
1547  rIgnoreLeadingSpace
1548  ,nStarFontsConvFlags
1549  );
1550  break;
1551 
1552  case XML_TOK_TEXT_TAB_STOP:
1553  pContext = new XMLCharContext( rImport, nPrefix,
1554  rLocalName, xAttrList,
1555  0x0009, false );
1556  rIgnoreLeadingSpace = false;
1557  break;
1558 
1560  pContext = new XMLCharContext( rImport, nPrefix,
1561  rLocalName, xAttrList,
1562  ControlCharacter::LINE_BREAK );
1563  rIgnoreLeadingSpace = false;
1564  break;
1565 
1566  case XML_TOK_TEXT_S:
1567  pContext = new XMLCharContext( rImport, nPrefix,
1568  rLocalName, xAttrList,
1569  0x0020, true );
1570  rIgnoreLeadingSpace = false;
1571  break;
1572 
1574  {
1575  // test for HyperLinkURL property. If present, insert link as
1576  // text property (StarWriter), else try to insert as text
1577  // field (StarCalc, StarDraw, ...)
1578  Reference< beans::XPropertySet > xPropSet( rImport.GetTextImport()->GetCursor(), UNO_QUERY );
1579 
1580  if ( xPropSet->getPropertySetInfo()->hasPropertyByName( "HyperLinkURL" ) )
1581  {
1582  pContext = new XMLImpHyperlinkContext_Impl(
1583  rImport,
1584  nPrefix,
1585  rLocalName,
1586  xAttrList,
1587  rHints,
1588  rIgnoreLeadingSpace );
1589  }
1590  else
1591  {
1592  pContext = new XMLUrlFieldImportContext(rImport, *rImport.GetTextImport(), nPrefix,
1593  rLocalName);
1594  //whitespace handling like other fields
1595  rIgnoreLeadingSpace = false;
1596 
1597  }
1598  break;
1599  }
1600 
1601  case XML_TOK_TEXT_RUBY:
1602  pContext = new XMLImpRubyContext_Impl( rImport, nPrefix,
1603  rLocalName, xAttrList,
1604  rHints,
1605  rIgnoreLeadingSpace );
1606  break;
1607 
1608  case XML_TOK_TEXT_NOTE:
1609  if (rImport.GetTextImport()->IsInFrame())
1610  {
1611  // we must not insert footnotes into text frames
1612  pContext = new SvXMLImportContext( rImport, nPrefix,
1613  rLocalName );
1614  }
1615  else
1616  {
1617  pContext = new XMLFootnoteImportContext(rImport, *rImport.GetTextImport(), nPrefix,
1618  rLocalName);
1619  }
1620  rIgnoreLeadingSpace = false;
1621  break;
1622 
1624  case XML_TOK_TEXT_BOOKMARK:
1627  pContext = new XMLTextMarkImportContext(rImport, *rImport.GetTextImport(),
1628  rHints.GetCrossRefHeadingBookmark(), nPrefix,
1629  rLocalName);
1630  break;
1631 
1635  pContext = new XMLTextMarkImportContext(rImport, *rImport.GetTextImport(),
1636  rHints.GetCrossRefHeadingBookmark(), nPrefix,
1637  rLocalName);
1638  break;
1639 
1641  pContext = new XMLStartReferenceContext_Impl( rImport,
1642  nPrefix, rLocalName,
1643  rHints, xAttrList );
1644  break;
1645 
1647  pContext = new XMLEndReferenceContext_Impl( rImport,
1648  nPrefix, rLocalName,
1649  rHints, xAttrList );
1650  break;
1651 
1652  case XML_TOK_TEXT_FRAME:
1653  {
1654  Reference < XTextRange > xAnchorPos =
1655  rImport.GetTextImport()->GetCursor()->getStart();
1656  XMLTextFrameContext *pTextFrameContext =
1657  new XMLTextFrameContext( rImport, nPrefix,
1658  rLocalName, xAttrList,
1659  TextContentAnchorType_AS_CHARACTER );
1660  // Remove check for text content. (#i33242#)
1661  // Check for text content is done on the processing of the hint
1662  if( TextContentAnchorType_AT_CHARACTER ==
1663  pTextFrameContext->GetAnchorType() )
1664  {
1665  rHints.push_back(std::make_unique<XMLTextFrameHint_Impl>(
1666  pTextFrameContext, xAnchorPos));
1667  }
1668  pContext = pTextFrameContext;
1669  rIgnoreLeadingSpace = false;
1670  }
1671  break;
1672  case XML_TOK_DRAW_A:
1673  {
1674  Reference < XTextRange > xAnchorPos(rImport.GetTextImport()->GetCursor()->getStart());
1675  pContext =
1676  new XMLTextFrameHyperlinkContext( rImport, nPrefix,
1677  rLocalName, xAttrList,
1678  TextContentAnchorType_AS_CHARACTER );
1679  rHints.push_back(
1680  std::make_unique<XMLTextFrameHint_Impl>(pContext, xAnchorPos));
1681  }
1682  break;
1683 
1684  case XML_TOK_TEXT_TOC_MARK:
1686  pContext = new XMLTOCMarkImportContext_Impl(
1687  rImport, nPrefix, rLocalName,
1688  static_cast<enum XMLTextPElemTokens>(nToken), rHints);
1689  break;
1690 
1693  pContext = new XMLUserIndexMarkImportContext_Impl(
1694  rImport, nPrefix, rLocalName,
1695  static_cast<enum XMLTextPElemTokens>(nToken), rHints);
1696  break;
1697 
1700  pContext = new XMLAlphaIndexMarkImportContext_Impl(
1701  rImport, nPrefix, rLocalName,
1702  static_cast<enum XMLTextPElemTokens>(nToken), rHints);
1703  break;
1704 
1708  pContext = new XMLIndexMarkImportContext_Impl(
1709  rImport, nPrefix, rLocalName, static_cast<enum XMLTextPElemTokens>(nToken),
1710  rHints);
1711  break;
1712 
1715  case XML_TOK_TEXTP_CHANGE:
1716  pContext = new XMLChangeImportContext(
1717  rImport, nPrefix, rLocalName,
1718  ((nToken == XML_TOK_TEXTP_CHANGE_END)
1720  : (nToken == XML_TOK_TEXTP_CHANGE_START)
1723  false);
1724  break;
1725 
1726  case XML_TOK_TEXT_META:
1727  pContext = new XMLMetaImportContext(rImport, nPrefix, rLocalName,
1728  rHints, rIgnoreLeadingSpace );
1729  break;
1730 
1732  pContext = new XMLMetaFieldImportContext(rImport, nPrefix, rLocalName,
1733  rHints, rIgnoreLeadingSpace );
1734  break;
1735 
1736  default:
1737  // none of the above? then it's probably a text field!
1739  rImport, *rImport.GetTextImport(), nPrefix, rLocalName, nToken);
1740  // #108784# import draw elements (except control shapes in headers)
1741  if( pContext == nullptr &&
1742  !( rImport.GetTextImport()->IsInHeaderFooter() &&
1743  nPrefix == XML_NAMESPACE_DRAW &&
1744  IsXMLToken( rLocalName, XML_CONTROL ) ) )
1745  {
1746  Reference < XShapes > xShapes;
1747  SvXMLShapeContext* pShapeContext = rImport.GetShapeImport()->CreateGroupChildContext(
1748  rImport, nPrefix, rLocalName, xAttrList, xShapes );
1749  pContext = pShapeContext;
1750  // OD 2004-04-20 #i26791# - keep shape in a text frame hint to
1751  // adjust its anchor position, if its at-character anchored
1752  Reference < XTextRange > xAnchorPos =
1753  rImport.GetTextImport()->GetCursor()->getStart();
1754  rHints.push_back(
1755  std::make_unique<XMLDrawHint_Impl>(pShapeContext, xAnchorPos));
1756  }
1757  // Behind fields, shapes and any unknown content blanks aren't ignored
1758  rIgnoreLeadingSpace = false;
1759  }
1760 
1761  return pContext;
1762 }
1763 
1764 SvXMLImportContextRef XMLImpSpanContext_Impl::CreateChildContext(
1765  sal_uInt16 nPrefix, const OUString& rLocalName,
1766  const Reference< xml::sax::XAttributeList > & xAttrList )
1767 {
1768  const SvXMLTokenMap& rTokenMap =
1769  GetImport().GetTextImport()->GetTextPElemTokenMap();
1770  sal_uInt16 nToken = rTokenMap.Get( nPrefix, rLocalName );
1771 
1772  return CreateChildContext( GetImport(), nPrefix, rLocalName, xAttrList,
1773  nToken, m_rHints, rIgnoreLeadingSpace
1774  ,nStarFontsConvFlags
1775  );
1776 }
1777 
1778 void XMLImpSpanContext_Impl::characters( const OUString& rChars )
1779 {
1780  OUString sStyleName;
1781  if( pHint )
1782  sStyleName = pHint->GetStyleName();
1783  OUString sChars =
1784  GetImport().GetTextImport()->ConvertStarFonts( rChars, sStyleName,
1785  nStarFontsConvFlags,
1786  false, GetImport() );
1787  GetImport().GetTextImport()->InsertString( sChars, rIgnoreLeadingSpace );
1788 }
1789 
1790 
1792  SvXMLImport& rImport,
1793  sal_uInt16 nPrfx,
1794  const OUString& rLName,
1795  const Reference< xml::sax::XAttributeList > & xAttrList,
1796  bool bHead ) :
1797  SvXMLImportContext( rImport, nPrfx, rLName ),
1798  xStart( rImport.GetTextImport()->GetCursorAsRange()->getStart() ),
1799  m_bHaveAbout(false),
1800  nOutlineLevel( IsXMLToken( rLName, XML_H ) ? 1 : -1 ),
1801  // Lost outline numbering in master document (#i73509#)
1802  mbOutlineLevelAttrFound( false ),
1803  mbOutlineContentVisible(true),
1804  bIgnoreLeadingSpace( true ),
1805  bHeading( bHead ),
1806  bIsListHeader( false ),
1807  bIsRestart (false),
1808  nStartValue(0),
1809  nStarFontsConvFlags( 0 )
1810 {
1811  const SvXMLTokenMap& rTokenMap =
1812  GetImport().GetTextImport()->GetTextPAttrTokenMap();
1813 
1814  bool bHaveXmlId( false );
1815  OUString aCondStyleName;
1816 
1817  sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
1818  for( sal_Int16 i=0; i < nAttrCount; i++ )
1819  {
1820  const OUString& rAttrName = xAttrList->getNameByIndex( i );
1821  const OUString& rValue = xAttrList->getValueByIndex( i );
1822 
1823  OUString aLocalName;
1824  sal_uInt16 nPrefix =
1826  &aLocalName );
1827  switch( rTokenMap.Get( nPrefix, aLocalName ) )
1828  {
1829  case XML_TOK_TEXT_P_XMLID:
1830  m_sXmlId = rValue;
1831  bHaveXmlId = true;
1832  break;
1833  case XML_TOK_TEXT_P_ABOUT:
1834  m_sAbout = rValue;
1835  m_bHaveAbout = true;
1836  break;
1838  m_sProperty = rValue;
1839  break;
1841  m_sContent = rValue;
1842  break;
1844  m_sDatatype = rValue;
1845  break;
1846  case XML_TOK_TEXT_P_TEXTID:
1847  if (!bHaveXmlId) { m_sXmlId = rValue; }
1848  break;
1850  sStyleName = rValue;
1851  break;
1853  aCondStyleName = rValue;
1854  break;
1855  case XML_TOK_TEXT_P_LEVEL:
1856  {
1857  sal_Int32 nTmp = rValue.toInt32();
1858  if( nTmp > 0 )
1859  {
1860  if( nTmp > 127 )
1861  nTmp = 127;
1862  nOutlineLevel = static_cast<sal_Int8>(nTmp);
1863  }
1864  // Lost outline numbering in master document (#i73509#)
1865  mbOutlineLevelAttrFound = true;
1866  }
1867  break;
1869  {
1870  bool bBool(false);
1871  if (::sax::Converter::convertBool(bBool, rValue))
1872  mbOutlineContentVisible = bBool;
1873  }
1874  break;
1876  {
1877  bool bBool(false);
1878  if (::sax::Converter::convertBool(bBool, rValue))
1879  bIsListHeader = bBool;
1880  }
1881  break;
1883  {
1884  bool bBool(false);
1885  if (::sax::Converter::convertBool(bBool, rValue))
1886  bIsRestart = bBool;
1887  }
1888  break;
1890  {
1891  nStartValue = sal::static_int_cast< sal_Int16 >(
1892  rValue.toInt32());
1893  }
1894  break;
1895  }
1896  }
1897 
1898  if( !aCondStyleName.isEmpty() )
1899  sStyleName = aCondStyleName;
1900 }
1901 
1903  SvXMLImport& rImport,
1904  sal_Int32 nElement,
1905  const Reference< xml::sax::XFastAttributeList > & xAttrList ) :
1906  SvXMLImportContext( rImport ),
1907  xStart( rImport.GetTextImport()->GetCursorAsRange()->getStart() ),
1908  m_bHaveAbout(false),
1909  nOutlineLevel( (nElement & TOKEN_MASK) == XML_H ? 1 : -1 ),
1910  // Lost outline numbering in master document (#i73509#)
1911  mbOutlineLevelAttrFound( false ),
1912  mbOutlineContentVisible(true),
1913  bIgnoreLeadingSpace( true ),
1914  bHeading( (nElement & TOKEN_MASK) == XML_H ),
1915  bIsListHeader( false ),
1916  bIsRestart (false),
1917  nStartValue(0),
1918  nStarFontsConvFlags( 0 )
1919 {
1920  bool bHaveXmlId( false );
1921  OUString aCondStyleName;
1922 
1923  for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
1924  {
1925  OUString sValue = aIter.toString();
1926  switch( aIter.getToken() )
1927  {
1928  case XML_ELEMENT(XML, XML_ID):
1929  m_sXmlId = sValue;
1930  bHaveXmlId = true;
1931  break;
1932  case XML_ELEMENT(XHTML, XML_ABOUT):
1933  m_sAbout = sValue;
1934  m_bHaveAbout = true;
1935  break;
1936  case XML_ELEMENT(XHTML, XML_PROPERTY):
1937  m_sProperty = sValue;
1938  break;
1939  case XML_ELEMENT(XHTML, XML_CONTENT):
1940  m_sContent = sValue;
1941  break;
1942  case XML_ELEMENT(XHTML, XML_DATATYPE):
1943  m_sDatatype = sValue;
1944  break;
1945  case XML_ELEMENT(TEXT, XML_ID):
1946  if (!bHaveXmlId) { m_sXmlId = sValue; }
1947  break;
1948  case XML_ELEMENT(TEXT, XML_STYLE_NAME):
1949  sStyleName = sValue;
1950  break;
1951  case XML_ELEMENT(TEXT, XML_COND_STYLE_NAME):
1952  aCondStyleName = sValue;
1953  break;
1954  case XML_ELEMENT(TEXT, XML_OUTLINE_LEVEL):
1955  {
1956  sal_Int32 nTmp = sValue.toInt32();
1957  if( nTmp > 0 )
1958  {
1959  if( nTmp > 127 )
1960  nTmp = 127;
1961  nOutlineLevel = static_cast<sal_Int8>(nTmp);
1962  }
1963  // Lost outline numbering in master document (#i73509#)
1964  mbOutlineLevelAttrFound = true;
1965  }
1966  break;
1968  {
1969  bool bBool(false);
1970  if (::sax::Converter::convertBool(bBool, sValue))
1971  mbOutlineContentVisible = bBool;
1972  }
1973  break;
1974  case XML_ELEMENT(TEXT, XML_IS_LIST_HEADER):
1975  {
1976  bool bBool(false);
1977  if (::sax::Converter::convertBool(bBool, sValue))
1978  bIsListHeader = bBool;
1979  }
1980  break;
1981  case XML_ELEMENT(TEXT, XML_RESTART_NUMBERING):
1982  {
1983  bool bBool(false);
1984  if (::sax::Converter::convertBool(bBool, sValue))
1985  bIsRestart = bBool;
1986  }
1987  break;
1988  case XML_ELEMENT(TEXT, XML_START_VALUE):
1989  {
1990  nStartValue = sal::static_int_cast< sal_Int16 >(
1991  sValue.toInt32());
1992  }
1993  break;
1994  default:
1995  XMLOFF_WARN_UNKNOWN("xmloff", aIter);
1996  }
1997  }
1998 
1999  if( !aCondStyleName.isEmpty() )
2000  sStyleName = aCondStyleName;
2001 }
2002 
2004 {
2006  GetImport().GetTextImport());
2007  Reference < XTextRange > xCrsrRange( xTxtImport->GetCursorAsRange() );
2008  if( !xCrsrRange.is() )
2009  return; // Robust (defective file)
2010  Reference < XTextRange > xEnd(xCrsrRange->getStart());
2011 
2012  // if we have an id set for this paragraph, get a cursor for this
2013  // paragraph and register it with the given identifier
2014  // FIXME: this is just temporary, and should be removed when
2015  // EditEngine paragraphs implement XMetadatable!
2016  if (!m_sXmlId.isEmpty())
2017  {
2018  Reference < XTextCursor > xIdCursor( xTxtImport->GetText()->createTextCursorByRange( xStart ) );
2019  if( xIdCursor.is() )
2020  {
2021  xIdCursor->gotoRange( xEnd, true );
2023  m_sXmlId, Reference<XInterface>( xIdCursor, UNO_QUERY ));
2024  }
2025  }
2026 
2027  // insert a paragraph break
2028  xTxtImport->InsertControlCharacter( ControlCharacter::APPEND_PARAGRAPH );
2029 
2030  // create a cursor that select the whole last paragraph
2031  Reference < XTextCursor > xAttrCursor;
2032  try {
2033  xAttrCursor = xTxtImport->GetText()->createTextCursorByRange( xStart );
2034  if( !xAttrCursor.is() )
2035  return; // Robust (defective file)
2036  } catch (const uno::Exception &) {
2037  // createTextCursorByRange() likes to throw runtime exception, even
2038  // though it just means 'we were unable to create the cursor'
2039  return;
2040  }
2041  xAttrCursor->gotoRange( xEnd, true );
2042 
2043  // xml:id for RDF metadata
2044  if (!m_sXmlId.isEmpty() || m_bHaveAbout || !m_sProperty.isEmpty())
2045  {
2046  try {
2047  const uno::Reference<container::XEnumerationAccess> xEA
2048  (xAttrCursor, uno::UNO_QUERY_THROW);
2049  const uno::Reference<container::XEnumeration> xEnum(
2050  xEA->createEnumeration(), uno::UNO_SET_THROW);
2051  SAL_WARN_IF(!xEnum->hasMoreElements(), "xmloff.text", "xml:id: no paragraph?");
2052  if (xEnum->hasMoreElements()) {
2053  uno::Reference<rdf::XMetadatable> xMeta;
2054  xEnum->nextElement() >>= xMeta;
2055  SAL_WARN_IF(!xMeta.is(), "xmloff.text", "xml:id: not XMetadatable");
2056  GetImport().SetXmlId(xMeta, m_sXmlId);
2057  if (m_bHaveAbout)
2058  {
2059  GetImport().AddRDFa(xMeta,
2061  }
2062  SAL_WARN_IF(xEnum->hasMoreElements(), "xmloff.text", "xml:id: > 1 paragraph?");
2063  }
2064  } catch (const uno::Exception &) {
2065  SAL_INFO("xmloff.text", "XMLParaContext::~XMLParaContext: exception");
2066  }
2067  }
2068 
2069  OUString const sCellParaStyleName(xTxtImport->GetCellParaStyleDefault());
2070  if( !sCellParaStyleName.isEmpty() )
2071  {
2072  /* Suppress handling of outline and list attributes,
2073  because of side effects of method <SetStyleAndAttrs(..)> (#i80724#)
2074  */
2075  xTxtImport->SetStyleAndAttrs( GetImport(), xAttrCursor,
2076  sCellParaStyleName,
2077  true,
2078  false, -1, // suppress outline handling
2079  false ); // suppress list attributes handling
2080  }
2081 
2082  // #103445# for headings without style name, find the proper style
2083  if( bHeading && sStyleName.isEmpty() )
2084  xTxtImport->FindOutlineStyleName( sStyleName, nOutlineLevel );
2085 
2086  // set style and hard attributes at the previous paragraph
2087  // Add parameter <mbOutlineLevelAttrFound> (#i73509#)
2088  sStyleName = xTxtImport->SetStyleAndAttrs( GetImport(), xAttrCursor,
2089  sStyleName,
2090  true,
2092  bHeading ? nOutlineLevel : -1,
2093  true,
2095 
2096  // handle list style header
2097  if (bHeading && (bIsListHeader || bIsRestart))
2098  {
2099  Reference<XPropertySet> xPropSet( xAttrCursor, UNO_QUERY );
2100 
2101  if (xPropSet.is())
2102  {
2103  if (bIsListHeader)
2104  {
2105  OUString sNumberingIsNumber
2106  ("NumberingIsNumber");
2107  if(xPropSet->getPropertySetInfo()->
2108  hasPropertyByName(sNumberingIsNumber))
2109  {
2110  xPropSet->setPropertyValue
2111  (sNumberingIsNumber, makeAny( false ) );
2112  }
2113  }
2114  if (bIsRestart)
2115  {
2116  OUString sParaIsNumberingRestart
2117  ("ParaIsNumberingRestart");
2118  OUString sNumberingStartValue
2119  ("NumberingStartValue");
2120  if (xPropSet->getPropertySetInfo()->
2121  hasPropertyByName(sParaIsNumberingRestart))
2122  {
2123  xPropSet->setPropertyValue
2124  (sParaIsNumberingRestart, makeAny(true));
2125  }
2126 
2127  if (xPropSet->getPropertySetInfo()->
2128  hasPropertyByName(sNumberingStartValue))
2129  {
2130  xPropSet->setPropertyValue
2131  (sNumberingStartValue, makeAny(nStartValue));
2132  }
2133  }
2134 
2135  }
2136  }
2137 
2138  if (m_xHints)
2139  {
2140  for (const auto & i : m_xHints->GetHints())
2141  {
2142  XMLHint_Impl *const pHint = i.get();
2143  xAttrCursor->gotoRange( pHint->GetStart(), false );
2144  xAttrCursor->gotoRange( pHint->GetEnd(), true );
2145  switch( pHint->GetType() )
2146  {
2147  case XML_HINT_STYLE:
2148  {
2149  const OUString& rStyleName =
2150  static_cast<XMLStyleHint_Impl *>(pHint)->GetStyleName();
2151  if( !rStyleName.isEmpty() )
2152  xTxtImport->SetStyleAndAttrs( GetImport(),
2153  xAttrCursor, rStyleName,
2154  false );
2155  }
2156  break;
2157  case XML_HINT_REFERENCE:
2158  {
2159  const OUString& rRefName =
2160  static_cast<XMLReferenceHint_Impl *>(pHint)->GetRefName();
2161  if( !rRefName.isEmpty() )
2162  {
2163  if( !pHint->GetEnd().is() )
2164  pHint->SetEnd(xEnd);
2165 
2166  // reference name uses rStyleName member
2167  // borrow from XMLTextMarkImportContext
2169  GetImport(),
2170  "com.sun.star.text.ReferenceMark",
2171  rRefName,
2172  xAttrCursor);
2173  }
2174  }
2175  break;
2176  case XML_HINT_HYPERLINK:
2177  {
2178  const XMLHyperlinkHint_Impl *pHHint =
2179  static_cast<const XMLHyperlinkHint_Impl *>(pHint);
2180  xTxtImport->SetHyperlink( GetImport(),
2181  xAttrCursor,
2182  pHHint->GetHRef(),
2183  pHHint->GetName(),
2184  pHHint->GetTargetFrameName(),
2185  pHHint->GetStyleName(),
2186  pHHint->GetVisitedStyleName(),
2187  pHHint->GetEventsContext() );
2188  }
2189  break;
2190  case XML_HINT_INDEX_MARK:
2191  {
2193  static_cast<const XMLIndexMarkHint_Impl *>(pHint)->GetMark());
2194  Reference<XTextContent> xContent(xMark, UNO_QUERY);
2195  try
2196  {
2197  xTxtImport->GetText()->insertTextContent(
2198  xAttrCursor, xContent, true );
2199  }
2200  catch (uno::RuntimeException const&)
2201  {
2202  TOOLS_INFO_EXCEPTION("xmloff.text", "could not insert index mark, presumably in editengine text");
2203  }
2204  }
2205  break;
2206  case XML_HINT_TEXT_FRAME:
2207  {
2208  const XMLTextFrameHint_Impl *pFHint =
2209  static_cast<const XMLTextFrameHint_Impl *>(pHint);
2210  // Check for text content (#i33242#)
2211  Reference < XTextContent > xTextContent =
2212  pFHint->GetTextContent();
2213  if ( xTextContent.is() )
2214  {
2215  /* Core impl. of the unification of drawing objects and
2216  Writer fly frames (#i26791#)
2217  */
2218  if ( pFHint->IsBoundAtChar() )
2219  {
2220  xTextContent->attach( xAttrCursor );
2221  }
2222  }
2223  /* Consider, that hint can also contain a shape -
2224  e.g. drawing object of type 'Text'. (#i33242#)
2225  */
2226  else
2227  {
2228  Reference < XShape > xShape = pFHint->GetShape();
2229  if ( xShape.is() )
2230  {
2231  // determine anchor type
2232  Reference < XPropertySet > xPropSet( xShape, UNO_QUERY );
2233  TextContentAnchorType eAnchorType =
2234  TextContentAnchorType_AT_PARAGRAPH;
2235  {
2236  Any aAny = xPropSet->getPropertyValue( "AnchorType" );
2237  aAny >>= eAnchorType;
2238  }
2239  if ( TextContentAnchorType_AT_CHARACTER == eAnchorType )
2240  {
2241  // set anchor position for at-character anchored objects
2242  xPropSet->setPropertyValue("TextRange", Any(xAttrCursor));
2243  }
2244  }
2245  }
2246  }
2247  break;
2248  /* Core impl. of the unification of drawing objects and
2249  Writer fly frames (#i26791#)
2250  */
2251  case XML_HINT_DRAW:
2252  {
2253  const XMLDrawHint_Impl *pDHint =
2254  static_cast<const XMLDrawHint_Impl*>(pHint);
2255  // Improvement: hint directly provides the shape. (#i33242#)
2256  const Reference < XShape >& xShape = pDHint->GetShape();
2257  if ( xShape.is() )
2258  {
2259  // determine anchor type
2260  Reference < XPropertySet > xPropSet( xShape, UNO_QUERY );
2261  TextContentAnchorType eAnchorType = TextContentAnchorType_AT_PARAGRAPH;
2262  {
2263  Any aAny = xPropSet->getPropertyValue( "AnchorType" );
2264  aAny >>= eAnchorType;
2265  }
2266  if ( TextContentAnchorType_AT_CHARACTER == eAnchorType )
2267  {
2268  // set anchor position for at-character anchored objects
2269  xPropSet->setPropertyValue("TextRange", Any(xAttrCursor));
2270  }
2271  }
2272  }
2273  break;
2274  default:
2275  SAL_WARN( "xmloff.text", "What's this" );
2276  break;
2277  }
2278  }
2279  }
2280  m_xHints.reset();
2281 }
2282 
2284  sal_uInt16 nPrefix, const OUString& rLocalName,
2285  const Reference< xml::sax::XAttributeList > & xAttrList )
2286 {
2287  const SvXMLTokenMap& rTokenMap =
2288  GetImport().GetTextImport()->GetTextPElemTokenMap();
2289  sal_uInt16 nToken = rTokenMap.Get( nPrefix, rLocalName );
2290  if (!m_xHints)
2291  m_xHints.reset(new XMLHints_Impl);
2292  return XMLImpSpanContext_Impl::CreateChildContext(
2293  GetImport(), nPrefix, rLocalName, xAttrList,
2294  nToken, *m_xHints, bIgnoreLeadingSpace,
2295  nStarFontsConvFlags);
2296 }
2297 
2298 void XMLParaContext::characters( const OUString& rChars )
2299 {
2300  OUString sChars =
2301  GetImport().GetTextImport()->ConvertStarFonts( rChars, sStyleName,
2302  nStarFontsConvFlags,
2303  true, GetImport() );
2304  GetImport().GetTextImport()->InsertString( sChars, bIgnoreLeadingSpace );
2305 }
2306 
2307 
2309  SvXMLImport& i_rImport,
2310  sal_uInt16 i_nPrefix,
2311  const OUString& i_rLocalName,
2312  const Reference< xml::sax::XAttributeList > & i_xAttrList ) :
2313  SvXMLImportContext( i_rImport, i_nPrefix, i_rLocalName ),
2314  m_Level(0),
2315  m_StartValue(-1),
2316  m_ListId(),
2317  m_xNumRules()
2318 {
2319  OUString StyleName;
2320 
2321  const SvXMLTokenMap& rTokenMap(
2322  i_rImport.GetTextImport()->GetTextNumberedParagraphAttrTokenMap() );
2323 
2324  const sal_Int16 nAttrCount( i_xAttrList.is() ?
2325  i_xAttrList->getLength() : 0 );
2326  for ( sal_Int16 i=0; i < nAttrCount; i++ )
2327  {
2328  const OUString& rAttrName( i_xAttrList->getNameByIndex( i ) );
2329  const OUString& rValue ( i_xAttrList->getValueByIndex( i ) );
2330 
2331  OUString aLocalName;
2332  const sal_uInt16 nPrefix(
2333  GetImport().GetNamespaceMap().GetKeyByAttrName(
2334  rAttrName, &aLocalName ) );
2335  switch( rTokenMap.Get( nPrefix, aLocalName ) )
2336  {
2338 //FIXME: there is no UNO API for lists
2339  break;
2341  m_ListId = rValue;
2342  break;
2344  {
2345  sal_Int32 nTmp = rValue.toInt32();
2346  if ( nTmp >= 1 && nTmp <= SHRT_MAX ) {
2347  m_Level = static_cast<sal_uInt16>(nTmp) - 1;
2348  }
2349  }
2350  break;
2352  StyleName = rValue;
2353  break;
2355  // this attribute is deprecated
2356 // ContinueNumbering = IsXMLToken(rValue, XML_TRUE);
2357  break;
2359  {
2360  sal_Int32 nTmp = rValue.toInt32();
2361  if ( nTmp >= 0 && nTmp <= SHRT_MAX ) {
2362  m_StartValue = static_cast<sal_Int16>(nTmp);
2363  }
2364  }
2365  break;
2366  }
2367  }
2368 
2369  XMLTextListsHelper& rTextListsHelper(
2370  i_rImport.GetTextImport()->GetTextListHelper() );
2371  if (m_ListId.isEmpty())
2372  {
2373  SAL_WARN_IF(0 <= i_rImport.GetODFVersion().compareTo("1.2"), "xmloff.text", "invalid numbered-paragraph: no list-id (1.2)");
2374  m_ListId = rTextListsHelper.GetNumberedParagraphListId(m_Level,
2375  StyleName);
2376  SAL_WARN_IF(m_ListId.isEmpty(), "xmloff.text", "numbered-paragraph: no ListId");
2377  if (m_ListId.isEmpty()) {
2378  return;
2379  }
2380  }
2381  m_xNumRules = rTextListsHelper.EnsureNumberedParagraph( i_rImport,
2382  m_ListId, m_Level, StyleName);
2383 
2384  SAL_WARN_IF(!m_xNumRules.is(), "xmloff.text", "numbered-paragraph: no NumRules");
2385 
2386  i_rImport.GetTextImport()->GetTextListHelper().PushListContext( this );
2387 }
2388 
2390 {
2391  if (!m_ListId.isEmpty()) {
2392  GetImport().GetTextImport()->PopListContext();
2393  }
2394 }
2395 
2396 css::uno::Reference< css::xml::sax::XFastContextHandler > XMLNumberedParaContext::createFastChildContext(
2397  sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
2398 {
2399  switch (nElement)
2400  {
2401  case XML_ELEMENT(TEXT, XML_H):
2402  case XML_ELEMENT(LO_EXT, XML_H):
2403  case XML_ELEMENT(TEXT, XML_P):
2404  case XML_ELEMENT(LO_EXT, XML_P):
2405  return new XMLParaContext( GetImport(), nElement, xAttrList );
2406  default:
2407  XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
2408  }
2409 
2410  return nullptr;
2411 }
2412 
2413 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override
endFastElement is called before a context will be destructed, but after an elements context has been ...
Definition: txtparai.cxx:2389
bool IsXMLToken(const OUString &rString, enum XMLTokenEnum eToken)
compare eToken to the string
Definition: xmltoken.cxx:3461
OUString m_XmlId
css::uno::Reference< css::container::XIndexReplace > m_xNumRules
text:style-name
Definition: txtparai.hxx:90
constexpr sal_uInt16 XML_NAMESPACE_OFFICE
css::uno::Reference< css::drawing::XShape > const & GetShape() const
virtual SvXMLImportContextRef CreateChildContext(sal_uInt16 nPrefix, const OUString &rLocalName, const css::uno::Reference< css::xml::sax::XAttributeList > &xAttrList) override
Create a children element context.
bool IsReference() const
void push_back(std::unique_ptr< XMLIndexMarkHint_Impl > pHint)
Definition: txtparai.cxx:85
static bool convertBool(bool &rBool, const OUString &rString)
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override
endFastElement is called before a context will be destructed, but after an elements context has been ...
Definition: txtparai.cxx:2003
virtual void InsertString(const OUString &_sString)
Definition: txtparai.cxx:228
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override
endFastElement is called before a context will be destructed, but after an elements context has been ...
Definition: txtparai.cxx:203
signed char sal_Int8
virtual void SAL_CALL startFastElement(sal_Int32 Element, const css::uno::Reference< css::xml::sax::XFastAttributeList > &Attribs) override
Definition: xmlictxt.cxx:68
std::vector< std::unique_ptr< XMLHint_Impl > > m_Hints
Definition: txtparai.cxx:75
bool mbOutlineContentVisible
Definition: txtparai.hxx:51
uno::Reference< uno::XInterface > m_xCrossRefHeadingBookmark
Definition: txtparai.cxx:77
sal_Int16 m_StartValue
text:start-value
Definition: txtparai.hxx:86
const css::uno::Reference< css::text::XTextRange > & GetEnd() const
SvXMLImport & GetImport()
Definition: xmlictxt.hxx:59
#define XMLOFF_WARN_UNKNOWN_ATTR(area, token, value)
Definition: xmlictxt.hxx:134
#define CONV_FROM_STAR_MATH
Definition: txtparai.hxx:34
XMLParaContext(SvXMLImport &rImport, sal_uInt16 nPrfx, const OUString &rLName, const css::uno::Reference< css::xml::sax::XAttributeList > &xAttrList, bool bHeading)
SvXMLNamespaceMap & GetNamespaceMap()
Definition: xmlimp.hxx:391
XMLNumberedParaContext(SvXMLImport &i_rImport, sal_uInt16 i_nPrefix, const OUString &i_rLocalName, const css::uno::Reference< css::xml::sax::XAttributeList > &i_xAttrList)
Definition: txtparai.cxx:2308
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
OUString m_sAbout
Definition: txtparai.hxx:42
sal_Int8 nOutlineLevel
Definition: txtparai.hxx:47
rtl::Reference< XMLTextImportHelper > const & GetTextImport()
Definition: xmlimp.hxx:595
#define CONV_FROM_STAR_BATS
Definition: txtparai.hxx:33
virtual void InsertControlCharacter(sal_Int16 _nControl)
Definition: txtparai.cxx:224
sal_uInt16 GetKeyByAttrName(const OUString &rAttrName, OUString *pPrefix, OUString *pLocalName, OUString *pNamespace) const
bool bIgnoreLeadingSpace
Definition: txtparai.hxx:52
const css::uno::Reference< css::text::XTextRange > & GetStart() const
css::uno::Any const & rValue
Definition: ImageStyle.hxx:38
sal_uInt16 sal_Unicode
static css::uno::Reference< css::text::XTextContent > CreateAndInsertMark(SvXMLImport &rImport, const OUString &sServiceName, const OUString &sMarkName, const css::uno::Reference< css::text::XTextRange > &rRange, const OUString &i_rXmlId=OUString())
#define SAL_MAX_UINT16
OUString m_sProperty
Definition: txtparai.hxx:43
#define XMLOFF_WARN_UNKNOWN(area, rIter)
Definition: xmlictxt.hxx:131
void SetEnd(const css::uno::Reference< css::text::XTextRange > &rPos)
OUString m_sContent
Definition: txtparai.hxx:44
::comphelper::UnoInterfaceToUniqueIdentifierMapper & getInterfaceToIdentifierMapper()
Definition: xmlimp.cxx:1846
static XMLTextFieldImportContext * CreateTextFieldImportContext(SvXMLImport &rImport, XMLTextImportHelper &rHlp, sal_uInt16 nPrefix, const OUString &rName, sal_uInt16 nToken)
create the appropriate field context from (for use in paragraph import)
Definition: txtfldi.cxx:217
css::text::TextContentAnchorType GetAnchorType() const
constexpr sal_uInt16 XML_NAMESPACE_DRAW
const char * sName
import hyperlinks as URL fields (Calc, Impress, Draw) ()
Definition: txtfldi.hxx:979
void AddRDFa(const css::uno::Reference< css::rdf::XMetadatable > &i_xObject, OUString const &i_rAbout, OUString const &i_rProperty, OUString const &i_rContent, OUString const &i_rDatatype)
Add a RDFa statement; parameters are XML attribute values.
Definition: xmlimp.cxx:1968
const OUString & GetStyleName() const
sal_uInt8 GetType() const
#define XML_HINT_HYPERLINK
int i
constexpr sal_uInt16 XML_NAMESPACE_TEXT
std::unique_ptr< XMLHints_Impl > m_xHints
Definition: txtparai.hxx:48
bool mbOutlineLevelAttrFound
Definition: txtparai.hxx:50
#define XML_HINT_INDEX_MARK
XMLCharContext(const XMLCharContext &)=delete
virtual void SAL_CALL characters(const OUString &rChars) override
This method is called for all characters that are contained in the current element.
Definition: txtparai.cxx:2298
XMLIndexMarkHint_Impl * GetIndexHintById(const OUString &sID)
Definition: txtparai.cxx:96
sal_uInt16 Get(sal_uInt16 nPrefix, const OUString &rLName) const
Definition: xmltkmap.cxx:99
virtual ~XMLCharContext() override
Definition: txtparai.cxx:200
const OUString & GetTargetFrameName() const
void push_back(std::unique_ptr< XMLHint_Impl > pHint)
Definition: txtparai.cxx:80
uno::Reference< uno::XInterface > & GetCrossRefHeadingBookmark()
Definition: txtparai.cxx:102
virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &AttrList) override
Definition: txtparai.cxx:2396
bool setPropertyValue(uno::Sequence< beans::PropertyValue > &aProp, const OUString &aName, const uno::Any &aValue)
std::unordered_map< OUString, XMLIndexMarkHint_Impl * > m_IndexHintsById
Definition: txtparai.cxx:76
bool IsBoundAtChar() const
bool bIsListHeader
Definition: txtparai.hxx:54
sal_Int16 m_Level
text:list-level MINUS 1
Definition: txtparai.hxx:84
XMLTextPElemTokens
Definition: txtimp.hxx:98
void SetXmlId(css::uno::Reference< css::uno::XInterface > const &i_xIfc, OUString const &i_rXmlId)
set the XmlId attribute of given UNO object (for RDF metadata)
Definition: xmlimp.cxx:1933
This class deliberately does not support XWeak, to improve performance when loading large documents...
Definition: xmlictxt.hxx:45
OUString m_sDatatype
Definition: txtparai.hxx:45
#define TOOLS_INFO_EXCEPTION(area, stream)
sal_Int16 m_nCount
DefTokenId nToken
XMLEventsImportContext * GetEventsContext() const
OUString m_ListId
text:list-id
Definition: txtparai.hxx:88
OUString GetODFVersion() const
Definition: xmlimp.cxx:1922
#define SAL_WARN_IF(condition, area, stream)
unsigned char sal_uInt8
css::uno::Reference< css::drawing::XShape > GetShape() const
virtual void SAL_CALL endFastElement(sal_Int32 Element) override
endFastElement is called before a context will be destructed, but after an elements context has been ...
Definition: xmlictxt.cxx:63
import bookmarks and reference marks ( , , , , , )
Handling of tokens in XML:
#define SAL_INFO(area, stream)
sal_Int16 nStartValue
Definition: txtparai.hxx:56
#define XML_ELEMENT(prefix, name)
Definition: xmlimp.hxx:94
const OUString & GetHRef() const
sal_Int16 m_nControl
virtual SvXMLImportContextRef CreateChildContext(sal_uInt16 nPrefix, const OUString &rLocalName, const css::uno::Reference< css::xml::sax::XAttributeList > &xAttrList)
Create a children element context.
Definition: xmlictxt.cxx:52
const OUString & GetName() const
sal_uInt16 m_nCount
uno::Reference< ucb::XContent > xContent
import footnote elements ()
bool m_bHaveAbout
Definition: txtparai.hxx:46
#define SAL_WARN(area, stream)
Reference< XSingleServiceFactory > xFactory
OUString m_sXmlId
Definition: txtparai.hxx:41
constexpr sal_Int32 TOKEN_MASK
Definition: xmlimp.hxx:91
#define XMLOFF_WARN_UNKNOWN_ELEMENT(area, token)
Definition: xmlictxt.hxx:137
std::vector< std::unique_ptr< XMLHint_Impl > > const & GetHints() const
Definition: txtparai.cxx:91
sal_Int32 nLength
Definition: xmltoken.cxx:36
if(!pCandidateA->getEnd().equal(pCandidateB->getStart()))
const OUString & registerReference(const css::uno::Reference< css::uno::XInterface > &rInterface)
returns a unique identifier for the given uno object.
XMLTokenEnum eToken
Definition: xmltoken.cxx:40
const OUString & GetVisitedStyleName() const
import change tracking/redlining markers , , ...
virtual void SAL_CALL characters(const OUString &aChars) override
This method is called for all characters that are contained in the current element.
Definition: xmlictxt.cxx:119
#define XML_HINT_STYLE
TEXT
css::uno::Reference< css::text::XTextRange > xStart
Definition: txtparai.hxx:39
css::uno::Reference< css::text::XTextContent > GetTextContent() const
#define XML_HINT_TEXT_FRAME
rtl::Reference< XMLShapeImportHelper > const & GetShapeImport()
Definition: xmlimp.hxx:603
#define XML_HINT_DRAW
#define XML_HINT_REFERENCE
static bool convertNumber(sal_Int32 &rValue, std::u16string_view aString, sal_Int32 nMin=SAL_MIN_INT32, sal_Int32 nMax=SAL_MAX_INT32)
sal_Unicode m_c
css::uno::Any SAL_CALL makeAny(const SharedUNOComponent< INTERFACE, COMPONENT > &value)