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