LibreOffice Module sw (master)  1
xmlimpit.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 
20 #include "xmlimpit.hxx"
21 
22 #include <sal/log.hxx>
23 #include <sax/tools/converter.hxx>
24 #include <utility>
25 #include <xmloff/xmluconv.hxx>
26 #include <svl/itempool.hxx>
27 #include <svl/poolitem.hxx>
28 #include <svl/itemset.hxx>
29 #include <xmloff/namespacemap.hxx>
30 #include <editeng/xmlcnitm.hxx>
31 #include <editeng/memberids.h>
32 #include <osl/diagnose.h>
33 
34 #include <hintids.hxx>
35 #include <unomid.h>
36 #include <svx/unomid.hxx>
37 #include <editeng/lrspitem.hxx>
38 #include <editeng/ulspitem.hxx>
39 #include <editeng/shaditem.hxx>
40 #include <editeng/boxitem.hxx>
42 #include <editeng/keepitem.hxx>
43 #include <editeng/brushitem.hxx>
44 #include <editeng/frmdir.hxx>
45 #include <fmtpdsc.hxx>
46 #include <fmtornt.hxx>
47 #include <fmtfsize.hxx>
48 
49 #include <xmloff/prhdlfac.hxx>
50 #include <xmloff/xmltypes.hxx>
51 #include <xmloff/xmlprhdl.hxx>
52 #include <xmloff/xmlimp.hxx>
53 #include <xmloff/xmlnamespace.hxx>
54 #include "xmlithlp.hxx"
55 #include <com/sun/star/uno/Any.hxx>
56 
57 using ::editeng::SvxBorderLine;
58 using namespace ::com::sun::star;
59 using namespace ::xmloff::token;
60 using uno::Any;
61 
62 constexpr sal_uInt16 nUnknownWhich = RES_UNKNOWNATR_CONTAINER;
63 
65  SvXMLItemMapEntriesRef const & rMapEntries ) :
66  mrMapEntries( rMapEntries )
67 {
68 }
69 
71 {
72 }
73 
74 void
76 {
77  mrMapEntries = std::move(rMapEntries);
78 }
79 
80 // fills the given itemset with the attributes in the given list
82  uno::Reference< xml::sax::XFastAttributeList > const & xAttrList,
83  const SvXMLUnitConverter& rUnitConverter,
84  const SvXMLNamespaceMap& rNamespaceMap )
85 {
86  std::unique_ptr<SvXMLAttrContainerItem> pUnknownItem;
87  for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
88  {
89  if( IsTokenInNamespace(aIter.getToken(), XML_NAMESPACE_XMLNS) )
90  continue;
91 
92  sal_Int32 nToken = aIter.getToken();
93  const OUString sValue = aIter.toString();
94 
95  // find a map entry for this attribute
96  sal_Int32 nLookupToken = nToken;
97  // compatibility namespaces need to be transformed into current namespace before looking up
99  nLookupToken = XML_ELEMENT(FO, (nLookupToken & TOKEN_MASK));
100  SvXMLItemMapEntry const * pEntry = mrMapEntries->getByName( nLookupToken );
101 
102  if( pEntry )
103  {
104  // we have a valid map entry here, so lets use it...
105  if( 0 == (pEntry->nMemberId & (MID_SW_FLAG_NO_ITEM_IMPORT|
107  {
108  // first get item from itemset
109  const SfxPoolItem* pItem = nullptr;
110  SfxItemState eState = rSet.GetItemState( pEntry->nWhichId, true,
111  &pItem );
112 
113  // if it's not set, try the pool
114  if (SfxItemState::SET != eState && SfxItemPool::IsWhich(pEntry->nWhichId))
115  pItem = &rSet.GetPool()->GetDefaultItem(pEntry->nWhichId);
116 
117  // do we have an item?
118  if(eState >= SfxItemState::DEFAULT && pItem)
119  {
120  std::unique_ptr<SfxPoolItem> pNewItem(pItem->Clone());
121  bool bPut = false;
122 
123  if( 0 == (pEntry->nMemberId&MID_SW_FLAG_SPECIAL_ITEM_IMPORT) )
124  {
125  bPut = PutXMLValue( *pNewItem, sValue,
126  o3tl::narrowing<sal_uInt16>( pEntry->nMemberId & MID_SW_FLAG_MASK ),
127  rUnitConverter );
128 
129  }
130  else
131  {
132  bPut = handleSpecialItem( *pEntry, *pNewItem, rSet,
133  sValue, rUnitConverter );
134  }
135 
136  if( bPut )
137  rSet.Put( *pNewItem );
138  }
139  else
140  {
141  OSL_FAIL( "Could not get a needed item for xml import!" );
142  }
143  }
144  else if( 0 != (pEntry->nMemberId & MID_SW_FLAG_NO_ITEM_IMPORT) )
145  {
146  handleNoItem( *pEntry, rSet, sValue, rUnitConverter,
147  rNamespaceMap );
148  }
149  }
150  else
151  {
152  if( !pUnknownItem )
153  {
154  const SfxPoolItem* pItem = nullptr;
155  if( SfxItemState::SET == rSet.GetItemState( nUnknownWhich, true,
156  &pItem ) )
157  {
158  pUnknownItem.reset( static_cast<SvXMLAttrContainerItem*>( pItem->Clone() ) );
159  }
160  else
161  {
162  pUnknownItem.reset( new SvXMLAttrContainerItem( nUnknownWhich ) );
163  }
164  }
165  if( pUnknownItem )
166  {
168  pUnknownItem->AddAttr( SvXMLImport::getNameFromToken( nToken ), sValue );
169  else
170  {
171  const OUString& rAttrNamespacePrefix = SvXMLImport::getNamespacePrefixFromToken(nToken, &rNamespaceMap);
172  OUString sAttrName = SvXMLImport::getNameFromToken( nToken );
173  if ( !rAttrNamespacePrefix.isEmpty() )
174  sAttrName = rAttrNamespacePrefix + SvXMLImport::aNamespaceSeparator + sAttrName;
175  OUString aLocalName, aPrefix, aNamespace;
176  rNamespaceMap.GetKeyByAttrName( sAttrName, &aPrefix, &aLocalName,
177  &aNamespace );
178  if ( !rAttrNamespacePrefix.isEmpty() )
179  pUnknownItem->AddAttr( rAttrNamespacePrefix, aNamespace, aLocalName,
180  sValue );
181  else
182  pUnknownItem->AddAttr( aLocalName, sValue );
183  }
184  }
185  }
186  }
187 
188  importXMLUnknownAttributes(rSet, xAttrList, rUnitConverter, pUnknownItem);
189 
190  if( pUnknownItem )
191  {
192  rSet.Put( *pUnknownItem );
193  }
194 
195  finished(rSet, rUnitConverter);
196 }
197 
199  uno::Reference< xml::sax::XFastAttributeList > const & xAttrList,
200  const SvXMLUnitConverter& rUnitConverter,
201  std::unique_ptr<SvXMLAttrContainerItem>& pUnknownItem)
202 {
203  const css::uno::Sequence< css::xml::Attribute > unknownAttributes = xAttrList->getUnknownAttributes();
204  for (const auto & rAttribute : unknownAttributes)
205  {
206  if( !pUnknownItem )
207  {
208  const SfxPoolItem* pItem = nullptr;
209  if( SfxItemState::SET == rSet.GetItemState( nUnknownWhich, true,
210  &pItem ) )
211  {
212  pUnknownItem.reset( static_cast<SvXMLAttrContainerItem*>( pItem->Clone() ) );
213  }
214  else
215  {
216  pUnknownItem.reset( new SvXMLAttrContainerItem( nUnknownWhich ) );
217  }
218  }
219  if( pUnknownItem )
220  {
221  if( rAttribute.NamespaceURL.isEmpty() )
222  pUnknownItem->AddAttr( rAttribute.Name, rAttribute.Value );
223  else
224  {
225  OUString sPrefix;
226  OUString sName = rAttribute.Name;
227  int i = sName.indexOf(':');
228  if (i != -1)
229  {
230  sPrefix = sName.copy(0, i-1);
231  sName = sName.copy(i+1);
232  }
233  // the sax parser doesn't reject these, strangely
234  if (sName.indexOf(':') == -1)
235  pUnknownItem->AddAttr( sPrefix, rAttribute.NamespaceURL, sName,
236  rAttribute.Value );
237  else
238  SAL_WARN("sw", "ignoring dodgy attribute: " + rAttribute.Name);
239  }
240  }
241  }
242 
243  if( pUnknownItem )
244  {
245  rSet.Put( *pUnknownItem );
246  }
247 
248  finished(rSet, rUnitConverter);
249 }
250 
253 bool
255  SfxPoolItem& /*rItem*/,
256  SfxItemSet& /*rSet*/,
257  const OUString& /*rValue*/,
258  const SvXMLUnitConverter& /*rUnitConverter*/ )
259 {
260  OSL_FAIL( "unsupported special item in xml import" );
261  return false;
262 }
263 
267  SfxItemSet& /*rSet*/,
268  const OUString& /*rValue*/,
269  const SvXMLUnitConverter& /*rUnitConverter*/,
270  const SvXMLNamespaceMap& /*rNamespaceMap*/ )
271 {
272  OSL_FAIL( "unsupported no item in xml import" );
273  return false;
274 }
275 
276 void
278 {
279  // nothing to do here
280 }
281 
282 namespace {
283 
284 struct BoxHolder
285 {
286  std::unique_ptr<SvxBorderLine> pTop;
287  std::unique_ptr<SvxBorderLine> pBottom;
288  std::unique_ptr<SvxBorderLine> pLeft;
289  std::unique_ptr<SvxBorderLine> pRight;
290 
291  BoxHolder(BoxHolder const&) = delete;
292  BoxHolder& operator=(BoxHolder const&) = delete;
293 
294  explicit BoxHolder(SvxBoxItem const & rBox)
295  {
296  if (rBox.GetTop())
297  pTop.reset(new SvxBorderLine( *rBox.GetTop() ));
298  if (rBox.GetBottom())
299  pBottom.reset(new SvxBorderLine( *rBox.GetBottom() ));
300  if (rBox.GetLeft())
301  pLeft.reset(new SvxBorderLine( *rBox.GetLeft() ));
302  if (rBox.GetRight())
303  pRight.reset(new SvxBorderLine( *rBox.GetRight() ));
304  }
305 };
306 
307 }
308 
309 // put an XML-string value into an item
311  SfxPoolItem& rItem,
312  const OUString& rValue,
313  sal_uInt16 nMemberId,
314  const SvXMLUnitConverter& rUnitConverter )
315 {
316  bool bOk = false;
317 
318  switch (rItem.Which())
319  {
320  case RES_LR_SPACE:
321  {
322  SvxLRSpaceItem& rLRSpace = dynamic_cast<SvxLRSpaceItem&>(rItem);
323 
324  switch( nMemberId )
325  {
326  case MID_L_MARGIN:
327  case MID_R_MARGIN:
328  {
329  sal_Int32 nProp = 100;
330  sal_Int32 nAbs = 0;
331 
332  if( rValue.indexOf( '%' ) != -1 )
333  bOk = ::sax::Converter::convertPercent(nProp, rValue);
334  else
335  bOk = rUnitConverter.convertMeasureToCore(nAbs, rValue);
336 
337  if( bOk )
338  {
339  switch( nMemberId )
340  {
341  case MID_L_MARGIN:
342  rLRSpace.SetTextLeft( nAbs, o3tl::narrowing<sal_uInt16>(nProp) );
343  break;
344  case MID_R_MARGIN:
345  rLRSpace.SetRight( nAbs, o3tl::narrowing<sal_uInt16>(nProp) );
346  break;
347  }
348  }
349  }
350  break;
351 
353  {
354  sal_Int32 nProp = 100;
355  sal_Int32 nAbs = 0;
356 
357  if( rValue.indexOf( '%' ) != -1 )
358  bOk = ::sax::Converter::convertPercent(nProp, rValue);
359  else
360  bOk = rUnitConverter.convertMeasureToCore(nAbs, rValue,
361  -0x7fff, 0x7fff );
362 
363  rLRSpace.SetTextFirstLineOffset( static_cast<short>(nAbs), o3tl::narrowing<sal_uInt16>(nProp) );
364  }
365  break;
366 
367  case MID_FIRST_AUTO:
368  {
369  bool bAutoFirst(false);
370  bOk = ::sax::Converter::convertBool( bAutoFirst, rValue );
371  if( bOk )
372  rLRSpace.SetAutoFirst( bAutoFirst );
373  }
374  break;
375 
376  default:
377  OSL_FAIL( "unknown member id!");
378  }
379  }
380  break;
381 
382  case RES_UL_SPACE:
383  {
384  SvxULSpaceItem& rULSpace = dynamic_cast<SvxULSpaceItem&>(rItem);
385 
386  sal_Int32 nProp = 100;
387  sal_Int32 nAbs = 0;
388 
389  if( rValue.indexOf( '%' ) != -1 )
390  bOk = ::sax::Converter::convertPercent( nProp, rValue );
391  else
392  bOk = rUnitConverter.convertMeasureToCore( nAbs, rValue );
393 
394  switch( nMemberId )
395  {
396  case MID_UP_MARGIN:
397  rULSpace.SetUpper( o3tl::narrowing<sal_uInt16>(nAbs), o3tl::narrowing<sal_uInt16>(nProp) );
398  break;
399  case MID_LO_MARGIN:
400  rULSpace.SetLower( o3tl::narrowing<sal_uInt16>(nAbs), o3tl::narrowing<sal_uInt16>(nProp) );
401  break;
402  default:
403  OSL_FAIL("unknown MemberId");
404  }
405  }
406  break;
407 
408  case RES_SHADOW:
409  {
410  SvxShadowItem& rShadow = dynamic_cast<SvxShadowItem&>(rItem);
411 
412  bool bColorFound = false;
413  bool bOffsetFound = false;
414 
415  SvXMLTokenEnumerator aTokenEnum( rValue );
416 
417  Color aColor( 128,128, 128 );
418  rShadow.SetLocation( SvxShadowLocation::BottomRight );
419 
420  std::u16string_view aToken;
421  while( aTokenEnum.getNextToken( aToken ) )
422  {
423  if( IsXMLToken( aToken, XML_NONE ) )
424  {
425  rShadow.SetLocation( SvxShadowLocation::NONE );
426  bOk = true;
427  }
428  else if( !bColorFound && aToken.substr(0,1) == u"#" )
429  {
430  bOk = ::sax::Converter::convertColor( aColor, aToken );
431  if( !bOk )
432  return false;
433 
434  bColorFound = true;
435  }
436  else if( !bOffsetFound )
437  {
438  sal_Int32 nX = 0, nY = 0;
439 
440  bOk = rUnitConverter.convertMeasureToCore( nX, aToken );
441  if( bOk && aTokenEnum.getNextToken( aToken ) )
442  bOk = rUnitConverter.convertMeasureToCore( nY, aToken );
443 
444  if( bOk )
445  {
446  if( nX < 0 )
447  {
448  if( nY < 0 )
449  {
450  rShadow.SetLocation( SvxShadowLocation::TopLeft );
451  }
452  else
453  {
454  rShadow.SetLocation( SvxShadowLocation::BottomLeft );
455  }
456  }
457  else
458  {
459  if( nY < 0 )
460  {
461  rShadow.SetLocation( SvxShadowLocation::TopRight );
462  }
463  else
464  {
465  rShadow.SetLocation( SvxShadowLocation::BottomRight );
466  }
467  }
468 
469  if( nX < 0 ) nX *= -1;
470  if( nY < 0 ) nY *= -1;
471 
472  rShadow.SetWidth( static_cast< sal_uInt16 >( (nX + nY) >> 1 ) );
473  }
474  }
475  }
476 
477  if( bOk && ( bColorFound || bOffsetFound ) )
478  {
479  rShadow.SetColor(aColor);
480  }
481  else
482  bOk = false;
483  }
484  break;
485 
486  case RES_BOX:
487  {
488  SvxBoxItem& rBox = dynamic_cast<SvxBoxItem&>(rItem);
489 
490  // copy SvxBorderLines
491  BoxHolder aBoxes(rBox);
492 
493  sal_Int32 nTemp;
494 
495  switch( nMemberId )
496  {
497  case ALL_BORDER_PADDING:
498  case LEFT_BORDER_PADDING:
500  case TOP_BORDER_PADDING:
502  if (!rUnitConverter.convertMeasureToCore( nTemp, rValue,
503  0, 0xffff ))
504  {
505  return false;
506  }
507 
508  if( nMemberId == LEFT_BORDER_PADDING ||
509  nMemberId == ALL_BORDER_PADDING )
510  rBox.SetDistance( o3tl::narrowing<sal_uInt16>(nTemp), SvxBoxItemLine::LEFT );
511  if( nMemberId == RIGHT_BORDER_PADDING ||
512  nMemberId == ALL_BORDER_PADDING )
513  rBox.SetDistance( o3tl::narrowing<sal_uInt16>(nTemp), SvxBoxItemLine::RIGHT );
514  if( nMemberId == TOP_BORDER_PADDING ||
515  nMemberId == ALL_BORDER_PADDING )
516  rBox.SetDistance( o3tl::narrowing<sal_uInt16>(nTemp), SvxBoxItemLine::TOP );
517  if( nMemberId == BOTTOM_BORDER_PADDING ||
518  nMemberId == ALL_BORDER_PADDING )
519  rBox.SetDistance( o3tl::narrowing<sal_uInt16>(nTemp), SvxBoxItemLine::BOTTOM);
520  break;
521 
522  case ALL_BORDER:
523  case LEFT_BORDER:
524  case RIGHT_BORDER:
525  case TOP_BORDER:
526  case BOTTOM_BORDER:
527  {
528  bool bHasStyle = false;
529  bool bHasWidth = false;
530  bool bHasColor = false;
531 
532  sal_uInt16 nStyle = USHRT_MAX;
533  sal_uInt16 nWidth = 0;
534  sal_uInt16 nNamedWidth = USHRT_MAX;
535 
536  Color aColor( COL_BLACK );
537 
538  if( !sw_frmitems_parseXMLBorder( rValue, rUnitConverter,
539  bHasStyle, nStyle,
540  bHasWidth, nWidth, nNamedWidth,
541  bHasColor, aColor ) )
542  return false;
543 
544  if( TOP_BORDER == nMemberId || ALL_BORDER == nMemberId )
545  sw_frmitems_setXMLBorder( aBoxes.pTop,
546  bHasStyle, nStyle,
547  bHasWidth, nWidth, nNamedWidth,
548  bHasColor, aColor );
549 
550  if( BOTTOM_BORDER == nMemberId || ALL_BORDER == nMemberId )
551  sw_frmitems_setXMLBorder( aBoxes.pBottom,
552  bHasStyle, nStyle,
553  bHasWidth, nWidth, nNamedWidth,
554  bHasColor, aColor );
555 
556  if( LEFT_BORDER == nMemberId || ALL_BORDER == nMemberId )
557  sw_frmitems_setXMLBorder( aBoxes.pLeft,
558  bHasStyle, nStyle,
559  bHasWidth, nWidth, nNamedWidth,
560  bHasColor, aColor );
561 
562  if( RIGHT_BORDER == nMemberId || ALL_BORDER == nMemberId )
563  sw_frmitems_setXMLBorder( aBoxes.pRight,
564  bHasStyle, nStyle,
565  bHasWidth, nWidth, nNamedWidth,
566  bHasColor, aColor );
567  }
568  break;
574  {
575  SvXMLTokenEnumerator aTokenEnum( rValue );
576 
577  sal_Int32 nInWidth, nDistance, nOutWidth;
578 
579  std::u16string_view aToken;
580  if( !aTokenEnum.getNextToken( aToken ) )
581  return false;
582 
583  if (!rUnitConverter.convertMeasureToCore(nInWidth, aToken))
584  return false;
585 
586  if( !aTokenEnum.getNextToken( aToken ) )
587  return false;
588 
589  if (!rUnitConverter.convertMeasureToCore(nDistance, aToken))
590  return false;
591 
592  if( !aTokenEnum.getNextToken( aToken ) )
593  return false;
594 
595  if (!rUnitConverter.convertMeasureToCore(nOutWidth, aToken))
596  return false;
597 
598  // #i61946: accept line style even it's not part of our "normal" set of line styles
599  sal_uInt16 nWidth = 0;
600 
601  if( TOP_BORDER_LINE_WIDTH == nMemberId ||
602  ALL_BORDER_LINE_WIDTH == nMemberId )
603  sw_frmitems_setXMLBorder( aBoxes.pTop, nWidth,
604  static_cast< sal_uInt16 >( nOutWidth ),
605  static_cast< sal_uInt16 >( nInWidth ),
606  static_cast< sal_uInt16 >( nDistance ) );
607 
608  if( BOTTOM_BORDER_LINE_WIDTH == nMemberId ||
609  ALL_BORDER_LINE_WIDTH == nMemberId )
610  sw_frmitems_setXMLBorder( aBoxes.pBottom, nWidth,
611  static_cast< sal_uInt16 >( nOutWidth ),
612  static_cast< sal_uInt16 >( nInWidth ),
613  static_cast< sal_uInt16 >( nDistance ) );
614 
615  if( LEFT_BORDER_LINE_WIDTH == nMemberId ||
616  ALL_BORDER_LINE_WIDTH == nMemberId )
617  sw_frmitems_setXMLBorder( aBoxes.pLeft, nWidth,
618  static_cast< sal_uInt16 >( nOutWidth ),
619  static_cast< sal_uInt16 >( nInWidth ),
620  static_cast< sal_uInt16 >( nDistance ) );
621 
622  if( RIGHT_BORDER_LINE_WIDTH == nMemberId ||
623  ALL_BORDER_LINE_WIDTH == nMemberId )
624  sw_frmitems_setXMLBorder( aBoxes.pRight, nWidth,
625  static_cast< sal_uInt16 >( nOutWidth ),
626  static_cast< sal_uInt16 >( nInWidth ),
627  static_cast< sal_uInt16 >( nDistance ) );
628  }
629  break;
630  }
631 
632  rBox.SetLine( aBoxes.pTop.get(), SvxBoxItemLine::TOP );
633  rBox.SetLine( aBoxes.pBottom.get(), SvxBoxItemLine::BOTTOM );
634  rBox.SetLine( aBoxes.pLeft.get(), SvxBoxItemLine::LEFT );
635  rBox.SetLine( aBoxes.pRight.get(), SvxBoxItemLine::RIGHT );
636 
637  bOk = true;
638  }
639  break;
640 
641  case RES_BREAK:
642  {
643  SvxFormatBreakItem& rFormatBreak = dynamic_cast<SvxFormatBreakItem&>(rItem);
644  sal_uInt16 eEnum{};
645 
646  if( !SvXMLUnitConverter::convertEnum( eEnum, rValue, psXML_BreakType ) )
647  return false;
648 
649  if( eEnum == 0 )
650  {
651  rFormatBreak.SetValue( SvxBreak::NONE );
652  bOk = true;
653  }
654  else
655  {
656  switch( nMemberId )
657  {
658  case MID_BREAK_BEFORE:
659  rFormatBreak.SetValue( eEnum == 1 ?
660  SvxBreak::ColumnBefore :
661  SvxBreak::PageBefore );
662  break;
663  case MID_BREAK_AFTER:
664  rFormatBreak.SetValue( eEnum == 1 ?
665  SvxBreak::ColumnAfter :
666  SvxBreak::PageAfter );
667  break;
668  }
669  bOk = true;
670  }
671  }
672  break;
673 
674  case RES_KEEP:
675  {
676  SvxFormatKeepItem& rFormatKeep = dynamic_cast<SvxFormatKeepItem&>(rItem);
677 
678  if( IsXMLToken( rValue, XML_ALWAYS ) ||
679  IsXMLToken( rValue, XML_TRUE ) )
680  {
681  rFormatKeep.SetValue( true );
682  bOk = true;
683  }
684  else if( IsXMLToken( rValue, XML_AUTO ) ||
685  IsXMLToken( rValue, XML_FALSE ) )
686  {
687  rFormatKeep.SetValue( false );
688  bOk = true;
689  }
690  }
691  break;
692 
693  case RES_BACKGROUND:
694  {
695  SvxBrushItem& rBrush = dynamic_cast<SvxBrushItem&>(rItem);
696 
697  Color aTempColor;
698  switch( nMemberId )
699  {
700  case MID_BACK_COLOR:
701  if( IsXMLToken( rValue, XML_TRANSPARENT ) )
702  {
703  rBrush.GetColor().SetAlpha(0);
704  bOk = true;
705  }
706  else if (::sax::Converter::convertColor(aTempColor, rValue))
707  {
708  aTempColor.SetAlpha(255);
709  rBrush.SetColor( aTempColor );
710  bOk = true;
711  }
712  break;
713 
714  case MID_GRAPHIC_REPEAT:
715  {
716  SvxGraphicPosition eGraphicPos = rBrush.GetGraphicPos();
718  if( SvXMLUnitConverter::convertEnum( nPos, rValue,
720  {
721  if( GPOS_MM != nPos || GPOS_NONE == eGraphicPos ||
722  GPOS_AREA == eGraphicPos || GPOS_TILED == eGraphicPos )
723  rBrush.SetGraphicPos( nPos );
724  bOk = true;
725  }
726  }
727  break;
728 
730  {
732  SvxGraphicPosition nTmp;
733  SvXMLTokenEnumerator aTokenEnum( rValue );
734  std::u16string_view aToken;
735  bool bHori = false, bVert = false;
736  bOk = true;
737  while( bOk && aTokenEnum.getNextToken( aToken ) )
738  {
739  if( bHori && bVert )
740  {
741  bOk = false;
742  }
743  else if( std::u16string_view::npos != aToken.find( '%' ) )
744  {
745  sal_Int32 nPrc = 50;
746  if (::sax::Converter::convertPercent(nPrc, aToken))
747  {
748  if( !bHori )
749  {
750  ePos = nPrc < 25 ? GPOS_LT :
751  (nPrc < 75 ? GPOS_MM : GPOS_RB);
752  bHori = true;
753  }
754  else
755  {
756  eTmp = nPrc < 25 ? GPOS_LT:
757  (nPrc < 75 ? GPOS_LM : GPOS_LB);
758  sw_frmitems_MergeXMLVertPos( ePos, eTmp );
759  bVert = true;
760  }
761  }
762  else
763  {
764  // wrong percentage
765  bOk = false;
766  }
767  }
768  else if( IsXMLToken( aToken, XML_CENTER ) )
769  {
770  if( bHori )
772  else if ( bVert )
774  else
775  ePos = GPOS_MM;
776  }
777  else if( SvXMLUnitConverter::convertEnum( nTmp, aToken,
779  {
780  if( bVert )
782  ePos, nTmp );
783  else if( !bHori )
784  ePos = nTmp;
785  else
786  bOk = false;
787  bHori = true;
788  }
789  else if( SvXMLUnitConverter::convertEnum( nTmp, aToken,
791  {
792  if( bHori )
794  ePos, nTmp );
795  else if( !bVert )
796  ePos = nTmp;
797  else
798  bOk = false;
799  bVert = true;
800  }
801  else
802  {
803  bOk = false;
804  }
805  }
806 
807  if( GPOS_NONE == ePos ) bOk = false;
808  if( bOk )
809  rBrush.SetGraphicPos( ePos );
810  }
811  break;
812 
813  case MID_GRAPHIC_FILTER:
814  rBrush.SetGraphicFilter( rValue );
815  bOk = true;
816  break;
817  }
818  }
819  break;
820 
821  case RES_PAGEDESC:
822  {
823  SwFormatPageDesc& rPageDesc = dynamic_cast<SwFormatPageDesc&>(rItem);
824 
825  if( MID_PAGEDESC_PAGENUMOFFSET==nMemberId )
826  {
827  sal_Int32 nVal;
829  nVal, rValue, 0, USHRT_MAX);
830  // i#114163 tdf#77111: OOo < 3.3 had a bug where it wrote
831  // "auto" as "0" for tables - now that we support a real offset
832  // 0, this fake "0" MUST NOT be imported as offset 0!
833  if( bOk && nVal > 0 )
834  rPageDesc.SetNumOffset( o3tl::narrowing<sal_uInt16>(nVal) );
835  }
836  }
837  break;
838 
839  case RES_LAYOUT_SPLIT:
840  case RES_ROW_SPLIT:
841  {
842  SfxBoolItem& rSplit = dynamic_cast<SfxBoolItem&>(rItem);
843 
844  if( IsXMLToken( rValue, XML_AUTO ) ||
845  IsXMLToken( rValue, XML_TRUE ) )
846  {
847  rSplit.SetValue( true );
848  bOk = true;
849  }
850  else if( IsXMLToken( rValue, XML_ALWAYS ) ||
851  IsXMLToken( rValue, XML_FALSE ) )
852  {
853  rSplit.SetValue( false );
854  bOk = true;
855  }
856  }
857  break;
858 
859  case RES_PRINT:
860  {
861  SfxBoolItem& rHasTextChangesOnly = dynamic_cast<SfxBoolItem&>(rItem);
862 
863  if( IsXMLToken( rValue, XML_TRUE ) )
864  {
865  rHasTextChangesOnly.SetValue( true );
866  bOk = true;
867  }
868  else if( IsXMLToken( rValue, XML_FALSE ) )
869  {
870  rHasTextChangesOnly.SetValue( false );
871  bOk = true;
872  }
873  }
874  break;
875 
876  case RES_HORI_ORIENT:
877  {
878  SwFormatHoriOrient& rHoriOrient = dynamic_cast<SwFormatHoriOrient&>(rItem);
879 
880  sal_Int16 nValue;
881  bOk = SvXMLUnitConverter::convertEnum( nValue, rValue,
883  if( bOk )
884  rHoriOrient.SetHoriOrient( nValue );
885  }
886  break;
887 
888  case RES_VERT_ORIENT:
889  {
890  SwFormatVertOrient& rVertOrient = dynamic_cast<SwFormatVertOrient&>(rItem);
891 
892  sal_Int16 nValue;
893  bOk = SvXMLUnitConverter::convertEnum( nValue, rValue,
895  if( bOk )
896  rVertOrient.SetVertOrient( nValue );
897  //#i8855# text::VertOrientation::NONE is stored as empty string and should be applied here
898  else if(rValue.isEmpty())
899  {
901  bOk = true;
902  }
903  }
904  break;
905 
906  case RES_FRM_SIZE:
907  {
908  SwFormatFrameSize& rFrameSize = dynamic_cast<SwFormatFrameSize&>(rItem);
909 
910  bool bSetHeight = false;
911  bool bSetWidth = false;
912  bool bSetSizeType = false;
914  sal_Int32 nMin = MINLAY;
915 
916  switch( nMemberId )
917  {
919  {
920  sal_Int32 nValue;
921  bOk = ::sax::Converter::convertPercent( nValue, rValue );
922  if( bOk )
923  {
924  if( nValue < 1 )
925  nValue = 1;
926  else if( nValue > 100 )
927  nValue = 100;
928 
929  rFrameSize.SetWidthPercent( static_cast<sal_Int8>(nValue) );
930  }
931  }
932  break;
933  case MID_FRMSIZE_WIDTH:
934  bSetWidth = true;
935  break;
937  eSizeType = SwFrameSize::Minimum;
938  bSetHeight = true;
939  nMin = 1;
940  bSetSizeType = true;
941  break;
943  eSizeType = SwFrameSize::Fixed;
944  bSetHeight = true;
945  nMin = 1;
946  bSetSizeType = true;
947  break;
949  eSizeType = SwFrameSize::Fixed;
950  bSetWidth = true;
951  bSetSizeType = true;
952  break;
954  {
955  sal_Int32 nPos = rValue.indexOf( '*' );
956  if( -1 != nPos )
957  {
958  sal_Int32 nValue = rValue.toInt32();
959  if( nValue < MINLAY )
960  nValue = MINLAY;
961  else if( nValue > SAL_MAX_UINT16 )
962  nValue = SAL_MAX_UINT16;
963 
964  rFrameSize.SetWidth( o3tl::narrowing<sal_uInt16>(nValue) );
966  bOk = true;
967  }
968  }
969  break;
970  }
971 
972  if( bSetHeight || bSetWidth )
973  {
974  sal_Int32 nValue;
975  bOk = rUnitConverter.convertMeasureToCore(nValue, rValue, nMin,
976  USHRT_MAX );
977  if( bOk )
978  {
979  if( bSetWidth )
980  rFrameSize.SetWidth( o3tl::narrowing<sal_uInt16>(nValue) );
981  if( bSetHeight )
982  rFrameSize.SetHeight( o3tl::narrowing<sal_uInt16>(nValue) );
983  if( bSetSizeType )
984  rFrameSize.SetHeightSizeType( eSizeType );
985  }
986  }
987  }
988  break;
989 
990  case RES_FRAMEDIR:
991  {
992  if (IsXMLToken(rValue, XML_BT_LR))
993  {
994  // Read bt-lr from the extension namespace, handle other values
995  // below.
996  Any aAny;
997  aAny <<= static_cast<sal_uInt16>(SvxFrameDirection::Vertical_LR_BT);
998  bOk = rItem.PutValue(aAny, 0);
999  }
1000  else
1001  {
1002  std::unique_ptr<XMLPropertyHandler> pWritingModeHandler =
1005  Any aAny;
1006  bOk = pWritingModeHandler->importXML( rValue, aAny,
1007  rUnitConverter );
1008  if( bOk )
1009  bOk = rItem.PutValue( aAny, 0 );
1010  }
1011  }
1012  break;
1013 
1015  {
1016  SfxBoolItem& rBorders = dynamic_cast<SfxBoolItem&>(rItem);
1017 
1018  if( IsXMLToken( rValue, XML_COLLAPSING ) )
1019  {
1020  rBorders.SetValue(true);
1021  bOk = true;
1022  }
1023  else if( IsXMLToken( rValue, XML_SEPARATING ) )
1024  {
1025  rBorders.SetValue(false);
1026  bOk = true;
1027  }
1028  else
1029  bOk = false;
1030  }
1031  break;
1032 
1033  default:
1034  OSL_FAIL("Item not implemented!");
1035  break;
1036  }
1037 
1038  return bOk;
1039 }
1040 
1041 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
constexpr TypedWhichId< SvxFrameDirectionItem > RES_FRAMEDIR(120)
constexpr TypedWhichId< SwFormatPageDesc > RES_PAGEDESC(93)
constexpr TypedWhichId< SvXMLAttrContainerItem > RES_UNKNOWNATR_CONTAINER(RES_UNKNOWNATR_BEGIN)
bool convertMeasureToCore(sal_Int32 &rValue, std::u16string_view rString, sal_Int32 nMin=SAL_MIN_INT32, sal_Int32 nMax=SAL_MAX_INT32) const
void SetRight(const tools::Long nR, const sal_uInt16 nProp=100)
void SetAlpha(sal_uInt8 nAlpha)
constexpr TypedWhichId< SvxPrintItem > RES_PRINT(98)
Pagedescriptor Client of SwPageDesc that is "described" by the attribute.
Definition: fmtpdsc.hxx:35
void SetHeight(tools::Long n)
void sw_frmitems_MergeXMLHoriPos(SvxGraphicPosition &ePos, SvxGraphicPosition eHori)
Definition: xmlithlp.cxx:238
SvXMLImportItemMapper(SvXMLItemMapEntriesRef const &rMapEntries)
Definition: xmlimpit.cxx:64
#define MID_FIRST_AUTO
virtual SfxPoolItem * Clone(SfxItemPool *pPool=nullptr) const =0
SvXMLItemMapEntry const * getByName(sal_Int32 nElement) const
Definition: xmlitmpr.cxx:51
constexpr TypedWhichId< SvxFormatKeepItem > RES_KEEP(110)
GPOS_NONE
GPOS_LT
static std::unique_ptr< XMLPropertyHandler > CreatePropertyHandler(sal_Int32 nType)
constexpr TypedWhichId< SwFormatFrameSize > RES_FRM_SIZE(89)
#define MID_FRMSIZE_MIN_HEIGHT
Definition: unomid.h:79
sal_uInt16 nWhichId
Definition: xmlitmap.hxx:43
virtual bool handleNoItem(const SvXMLItemMapEntry &rEntry, SfxItemSet &rSet, const OUString &rValue, const SvXMLUnitConverter &rUnitConverter, const SvXMLNamespaceMap &rNamespaceMap)
this method is called for every item that has the MID_SW_FLAG_NO_ITEM_IMPORT flag set ...
Definition: xmlimpit.cxx:266
#define MID_FRMSIZE_REL_WIDTH
Definition: unomid.h:72
void SetColor(const Color &rNew)
#define LEFT_BORDER_PADDING
#define MINLAY
Definition: swtypes.hxx:61
XML_ALWAYS
#define MID_PAGEDESC_PAGENUMOFFSET
Definition: unomid.h:27
constexpr sal_uInt16 XML_NAMESPACE_FO_COMPAT
constexpr TypedWhichId< SvxFormatBreakItem > RES_BREAK(94)
bool IsXMLToken(std::u16string_view rString, enum XMLTokenEnum eToken)
#define MID_BACK_COLOR
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
const editeng::SvxBorderLine * GetRight() const
css::chart::ChartAxisLabelPosition ePos
sal_uInt16 GetKeyByAttrName(const OUString &rAttrName, OUString *pPrefix, OUString *pLocalName, OUString *pNamespace) const
#define MID_FIRST_LINE_INDENT
#define LEFT_BORDER
const struct SvXMLEnumMapEntry< sal_Int16 > aXMLTableVAlignMap[]
Definition: xmlithlp.cxx:319
Value in Var-direction gives minimum (can be exceeded but not be less).
const struct SvXMLEnumMapEntry< SvxGraphicPosition > psXML_BrushVertPos[]
Definition: xmlithlp.cxx:231
#define TOP_BORDER_LINE_WIDTH
constexpr TypedWhichId< SwFormatLayoutSplit > RES_LAYOUT_SPLIT(113)
bool sw_frmitems_parseXMLBorder(std::u16string_view rValue, const SvXMLUnitConverter &rUnitConverter, bool &rHasStyle, sal_uInt16 &rStyle, bool &rHasWidth, sal_uInt16 &rWidth, sal_uInt16 &rNamedWidth, bool &rHasColor, Color &rColor)
Define various helper variables and functions for xmlimpit.cxx and xmlexpit.cxx.
Definition: xmlithlp.cxx:78
#define ALL_BORDER_LINE_WIDTH
const sal_uInt16 XML_NAMESPACE_XMLNS
constexpr TypedWhichId< SwFormatVertOrient > RES_VERT_ORIENT(102)
GPOS_TILED
void SetTextLeft(const tools::Long nL, const sal_uInt16 nProp=100)
SvxGraphicPosition GetGraphicPos() const
void SetHoriOrient(sal_Int16 eNew)
Definition: fmtornt.hxx:89
#define XML_TYPE_TEXT_WRITING_MODE_WITH_DEFAULT
GPOS_LM
constexpr TypedWhichId< SwFormatHoriOrient > RES_HORI_ORIENT(103)
static constexpr OUStringLiteral aNamespaceSeparator
#define SAL_MAX_UINT16
#define MID_SW_FLAG_MASK
Definition: xmlitmap.hxx:28
#define MID_FRMSIZE_REL_COL_WIDTH
Definition: unomid.h:82
#define MID_FRMSIZE_FIX_HEIGHT
Definition: unomid.h:80
#define MID_GRAPHIC_REPEAT
virtual void setMapEntries(SvXMLItemMapEntriesRef rMapEntries)
Definition: xmlimpit.cxx:75
virtual bool PutValue(const css::uno::Any &rVal, sal_uInt8 nMemberId)
constexpr sal_uInt16 nUnknownWhich
Definition: xmlimpit.cxx:62
XML_FALSE
const char * sName
void SetColor(const Color &rCol)
void SetLower(const sal_uInt16 nL, const sal_uInt16 nProp=100)
constexpr TypedWhichId< SwFormatRowSplit > RES_ROW_SPLIT(122)
const struct SvXMLEnumMapEntry< sal_Int16 > aXMLTableAlignMap[]
Definition: xmlithlp.cxx:308
const Color & GetColor() const
#define MID_FRMSIZE_WIDTH
Definition: unomid.h:74
#define MID_L_MARGIN
const editeng::SvxBorderLine * GetTop() const
const editeng::SvxBorderLine * GetLeft() const
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
int i
#define BOTTOM_BORDER_PADDING
void SetVertOrient(sal_Int16 eNew)
Definition: fmtornt.hxx:56
bool getNextToken(std::u16string_view &rToken)
SvXMLItemMapEntriesRef mrMapEntries
Definition: xmlimpit.hxx:35
#define TOP_BORDER
void SetTextFirstLineOffset(const short nF, const sal_uInt16 nProp=100)
constexpr TypedWhichId< SfxBoolItem > RES_COLLAPSING_BORDERS(124)
SvxGraphicPosition
XML_BT_LR
float u
static bool convertColor(sal_Int32 &rColor, std::u16string_view rValue)
#define TOP_BORDER_PADDING
GPOS_MM
static OUString getNamespacePrefixFromToken(sal_Int32 nToken, const SvXMLNamespaceMap *pMap)
XML_CENTER
virtual void finished(SfxItemSet &rSet, SvXMLUnitConverter const &rUnitConverter) const
This method is called when all attributes have benn processed.
Definition: xmlimpit.cxx:277
SwFrameSize
Definition: fmtfsize.hxx:35
XML_SEPARATING
void SetDistance(sal_uInt16 nNew, SvxBoxItemLine nLine)
#define MID_R_MARGIN
virtual ~SvXMLImportItemMapper()
Definition: xmlimpit.cxx:70
void importXMLUnknownAttributes(SfxItemSet &rSet, css::uno::Reference< css::xml::sax::XFastAttributeList > const &xAttrList, const SvXMLUnitConverter &rUnitConverter, std::unique_ptr< SvXMLAttrContainerItem > &pUnknownItem)
Definition: xmlimpit.cxx:198
#define MID_GRAPHIC_POSITION
const sal_uInt16 XML_NAMESPACE_NONE
OUString sPrefix
static bool PutXMLValue(SfxPoolItem &rItem, const OUString &rValue, sal_uInt16 nMemberId, const SvXMLUnitConverter &rUnitConverter)
This method is called for every item that should be set based upon an XML attribute value...
Definition: xmlimpit.cxx:310
GPOS_AREA
const SfxPoolItem & GetDefaultItem(sal_uInt16 nWhich) const
bool sw_frmitems_setXMLBorder(std::unique_ptr< SvxBorderLine > &rpLine, bool bHasStyle, sal_uInt16 nStyle, bool bHasWidth, sal_uInt16 nWidth, sal_uInt16 nNamedWidth, bool bHasColor, const Color &rColor)
Definition: xmlithlp.cxx:139
SfxItemPool * GetPool() const
Frame cannot be moved in Var-direction.
#define MID_SW_FLAG_SPECIAL_ITEM_IMPORT
Definition: xmlitmap.hxx:31
void SetValue(bool const bTheValue)
void SetWidth(tools::Long n)
static bool convertBool(bool &rBool, std::u16string_view rString)
static const OUString & getNameFromToken(sal_Int32 nToken)
static bool convertPercent(sal_Int32 &rValue, std::u16string_view rString)
virtual bool handleSpecialItem(const SvXMLItemMapEntry &rEntry, SfxPoolItem &rItem, SfxItemSet &rSet, const OUString &rValue, const SvXMLUnitConverter &rUnitConverter)
this method is called for every item that has the MID_SW_FLAG_SPECIAL_ITEM_IMPORT flag set ...
Definition: xmlimpit.cxx:254
#define ALL_BORDER_PADDING
void SetGraphicPos(SvxGraphicPosition eNew)
sal_uInt32 nMemberId
Definition: xmlitmap.hxx:48
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
DefTokenId nToken
#define MID_SW_FLAG_NO_ITEM_IMPORT
Definition: xmlitmap.hxx:32
#define LEFT_BORDER_LINE_WIDTH
#define RIGHT_BORDER_LINE_WIDTH
#define BOTTOM_BORDER
SfxItemState
#define MID_BREAK_AFTER
constexpr TypedWhichId< SvxBrushItem > RES_BACKGROUND(105)
#define RIGHT_BORDER_PADDING
constexpr bool IsTokenInNamespace(sal_Int32 nToken, sal_uInt16 nNamespacePrefix)
void importXML(SfxItemSet &rSet, css::uno::Reference< css::xml::sax::XFastAttributeList > const &xAttrList, const SvXMLUnitConverter &rUnitConverter, const SvXMLNamespaceMap &rNamespaceMap)
fills the given itemset with the attributes in the given list
Definition: xmlimpit.cxx:81
void SetWidth(sal_uInt16 nNew)
void SetWidthPercent(sal_uInt8 n)
Definition: fmtfsize.hxx:95
void SetLocation(SvxShadowLocation eNew)
const struct SvXMLEnumMapEntry< SvxGraphicPosition > psXML_BrushHoriPos[]
Definition: xmlithlp.cxx:224
#define XML_ELEMENT(prefix, name)
void SetGraphicFilter(const OUString &rNew)
static bool convertEnum(EnumT &rEnum, std::u16string_view rValue, const SvXMLEnumMapEntry< EnumT > *pMap)
#define MID_LO_MARGIN
void sw_frmitems_MergeXMLVertPos(SvxGraphicPosition &ePos, SvxGraphicPosition eVert)
Definition: xmlithlp.cxx:268
#define MID_GRAPHIC_FILTER
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BLACK
constexpr TypedWhichId< SvxLRSpaceItem > RES_LR_SPACE(91)
XML_COLLAPSING
constexpr TypedWhichId< SvxBoxItem > RES_BOX(106)
const struct SvXMLEnumMapEntry< sal_uInt16 > psXML_BreakType[]
Definition: xmlithlp.cxx:298
XML_NONE
XML_TRUE
#define ALL_BORDER
#define SAL_WARN(area, stream)
#define RIGHT_BORDER
constexpr sal_Int32 TOKEN_MASK
void SetNumOffset(const ::std::optional< sal_uInt16 > &oNum)
Definition: fmtpdsc.hxx:65
#define MID_FRMSIZE_COL_WIDTH
Definition: unomid.h:81
GPOS_RB
GPOS_LB
Frame is variable in Var-direction.
void SetAutoFirst(const bool bNew)
#define MID_BREAK_BEFORE
void SetUpper(const sal_uInt16 nU, const sal_uInt16 nProp=100)
#define MID_SW_FLAG_ELEMENT_ITEM_IMPORT
Definition: xmlitmap.hxx:35
void SetHeightSizeType(SwFrameSize eSize)
Definition: fmtfsize.hxx:81
XML_AUTO
const editeng::SvxBorderLine * GetBottom() const
constexpr TypedWhichId< SvxULSpaceItem > RES_UL_SPACE(92)
#define BOTTOM_BORDER_LINE_WIDTH
sal_uInt16 Which() const
constexpr TypedWhichId< SvxShadowItem > RES_SHADOW(107)
static bool IsWhich(sal_uInt16 nId)
sal_uInt16 nPos
sal_Int16 nValue
const struct SvXMLEnumMapEntry< SvxGraphicPosition > psXML_BrushRepeat[]
Definition: xmlithlp.cxx:216
static bool convertNumber(sal_Int32 &rValue, std::u16string_view aString, sal_Int32 nMin=SAL_MIN_INT32, sal_Int32 nMax=SAL_MAX_INT32)
XML_TRANSPARENT
void SetLine(const editeng::SvxBorderLine *pNew, SvxBoxItemLine nLine)
#define MID_UP_MARGIN