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  static_cast<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, static_cast<sal_uInt16>(nProp) );
343  break;
344  case MID_R_MARGIN:
345  rLRSpace.SetRight( nAbs, static_cast<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), static_cast<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( static_cast<sal_uInt16>(nAbs), static_cast<sal_uInt16>(nProp) );
398  break;
399  case MID_LO_MARGIN:
400  rULSpace.SetLower( static_cast<sal_uInt16>(nAbs), static_cast<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  OUString 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.startsWith("#") )
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( static_cast<sal_uInt16>(nTemp), SvxBoxItemLine::LEFT );
511  if( nMemberId == RIGHT_BORDER_PADDING ||
512  nMemberId == ALL_BORDER_PADDING )
513  rBox.SetDistance( static_cast<sal_uInt16>(nTemp), SvxBoxItemLine::RIGHT );
514  if( nMemberId == TOP_BORDER_PADDING ||
515  nMemberId == ALL_BORDER_PADDING )
516  rBox.SetDistance( static_cast<sal_uInt16>(nTemp), SvxBoxItemLine::TOP );
517  if( nMemberId == BOTTOM_BORDER_PADDING ||
518  nMemberId == ALL_BORDER_PADDING )
519  rBox.SetDistance( static_cast<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  OUString 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  sal_Int32 nTempColor(0);
698  switch( nMemberId )
699  {
700  case MID_BACK_COLOR:
701  if( IsXMLToken( rValue, XML_TRANSPARENT ) )
702  {
703  rBrush.GetColor().SetTransparency(0xff);
704  bOk = true;
705  }
706  else if (::sax::Converter::convertColor(nTempColor, rValue))
707  {
708  Color aTempColor(nTempColor);
709  aTempColor.SetTransparency(0);
710  rBrush.SetColor( aTempColor );
711  bOk = true;
712  }
713  break;
714 
715  case MID_GRAPHIC_REPEAT:
716  {
717  SvxGraphicPosition eGraphicPos = rBrush.GetGraphicPos();
719  if( SvXMLUnitConverter::convertEnum( nPos, rValue,
721  {
722  if( GPOS_MM != nPos || GPOS_NONE == eGraphicPos ||
723  GPOS_AREA == eGraphicPos || GPOS_TILED == eGraphicPos )
724  rBrush.SetGraphicPos( nPos );
725  bOk = true;
726  }
727  }
728  break;
729 
731  {
733  SvxGraphicPosition nTmp;
734  SvXMLTokenEnumerator aTokenEnum( rValue );
735  OUString aToken;
736  bool bHori = false, bVert = false;
737  bOk = true;
738  while( bOk && aTokenEnum.getNextToken( aToken ) )
739  {
740  if( bHori && bVert )
741  {
742  bOk = false;
743  }
744  else if( -1 != aToken.indexOf( '%' ) )
745  {
746  sal_Int32 nPrc = 50;
747  if (::sax::Converter::convertPercent(nPrc, aToken))
748  {
749  if( !bHori )
750  {
751  ePos = nPrc < 25 ? GPOS_LT :
752  (nPrc < 75 ? GPOS_MM : GPOS_RB);
753  bHori = true;
754  }
755  else
756  {
757  eTmp = nPrc < 25 ? GPOS_LT:
758  (nPrc < 75 ? GPOS_LM : GPOS_LB);
759  sw_frmitems_MergeXMLVertPos( ePos, eTmp );
760  bVert = true;
761  }
762  }
763  else
764  {
765  // wrong percentage
766  bOk = false;
767  }
768  }
769  else if( IsXMLToken( aToken, XML_CENTER ) )
770  {
771  if( bHori )
773  else if ( bVert )
775  else
776  ePos = GPOS_MM;
777  }
778  else if( SvXMLUnitConverter::convertEnum( nTmp, aToken,
780  {
781  if( bVert )
783  ePos, nTmp );
784  else if( !bHori )
785  ePos = nTmp;
786  else
787  bOk = false;
788  bHori = true;
789  }
790  else if( SvXMLUnitConverter::convertEnum( nTmp, aToken,
792  {
793  if( bHori )
795  ePos, nTmp );
796  else if( !bVert )
797  ePos = nTmp;
798  else
799  bOk = false;
800  bVert = true;
801  }
802  else
803  {
804  bOk = false;
805  }
806  }
807 
808  if( GPOS_NONE == ePos ) bOk = false;
809  if( bOk )
810  rBrush.SetGraphicPos( ePos );
811  }
812  break;
813 
814  case MID_GRAPHIC_FILTER:
815  rBrush.SetGraphicFilter( rValue );
816  bOk = true;
817  break;
818  }
819  }
820  break;
821 
822  case RES_PAGEDESC:
823  {
824  SwFormatPageDesc& rPageDesc = dynamic_cast<SwFormatPageDesc&>(rItem);
825 
826  if( MID_PAGEDESC_PAGENUMOFFSET==nMemberId )
827  {
828  sal_Int32 nVal;
830  nVal, rValue, 0, USHRT_MAX);
831  // i#114163 tdf#77111: OOo < 3.3 had a bug where it wrote
832  // "auto" as "0" for tables - now that we support a real offset
833  // 0, this fake "0" MUST NOT be imported as offset 0!
834  if( bOk && nVal > 0 )
835  rPageDesc.SetNumOffset( static_cast<sal_uInt16>(nVal) );
836  }
837  }
838  break;
839 
840  case RES_LAYOUT_SPLIT:
841  case RES_ROW_SPLIT:
842  {
843  SfxBoolItem& rSplit = dynamic_cast<SfxBoolItem&>(rItem);
844 
845  if( IsXMLToken( rValue, XML_AUTO ) ||
846  IsXMLToken( rValue, XML_TRUE ) )
847  {
848  rSplit.SetValue( true );
849  bOk = true;
850  }
851  else if( IsXMLToken( rValue, XML_ALWAYS ) ||
852  IsXMLToken( rValue, XML_FALSE ) )
853  {
854  rSplit.SetValue( false );
855  bOk = true;
856  }
857  }
858  break;
859 
860  case RES_HORI_ORIENT:
861  {
862  SwFormatHoriOrient& rHoriOrient = dynamic_cast<SwFormatHoriOrient&>(rItem);
863 
864  sal_Int16 nValue;
865  bOk = SvXMLUnitConverter::convertEnum( nValue, rValue,
867  if( bOk )
868  rHoriOrient.SetHoriOrient( nValue );
869  }
870  break;
871 
872  case RES_VERT_ORIENT:
873  {
874  SwFormatVertOrient& rVertOrient = dynamic_cast<SwFormatVertOrient&>(rItem);
875 
876  sal_Int16 nValue;
877  bOk = SvXMLUnitConverter::convertEnum( nValue, rValue,
879  if( bOk )
880  rVertOrient.SetVertOrient( nValue );
881  //#i8855# text::VertOrientation::NONE is stored as empty string and should be applied here
882  else if(rValue.isEmpty())
883  {
885  bOk = true;
886  }
887  }
888  break;
889 
890  case RES_FRM_SIZE:
891  {
892  SwFormatFrameSize& rFrameSize = dynamic_cast<SwFormatFrameSize&>(rItem);
893 
894  bool bSetHeight = false;
895  bool bSetWidth = false;
896  bool bSetSizeType = false;
898  sal_Int32 nMin = MINLAY;
899 
900  switch( nMemberId )
901  {
903  {
904  sal_Int32 nValue;
905  bOk = ::sax::Converter::convertPercent( nValue, rValue );
906  if( bOk )
907  {
908  if( nValue < 1 )
909  nValue = 1;
910  else if( nValue > 100 )
911  nValue = 100;
912 
913  rFrameSize.SetWidthPercent( static_cast<sal_Int8>(nValue) );
914  }
915  }
916  break;
917  case MID_FRMSIZE_WIDTH:
918  bSetWidth = true;
919  break;
921  eSizeType = SwFrameSize::Minimum;
922  bSetHeight = true;
923  nMin = 1;
924  bSetSizeType = true;
925  break;
927  eSizeType = SwFrameSize::Fixed;
928  bSetHeight = true;
929  nMin = 1;
930  bSetSizeType = true;
931  break;
933  eSizeType = SwFrameSize::Fixed;
934  bSetWidth = true;
935  bSetSizeType = true;
936  break;
938  {
939  sal_Int32 nPos = rValue.indexOf( '*' );
940  if( -1 != nPos )
941  {
942  sal_Int32 nValue = rValue.toInt32();
943  if( nValue < MINLAY )
944  nValue = MINLAY;
945  else if( nValue > SAL_MAX_UINT16 )
946  nValue = SAL_MAX_UINT16;
947 
948  rFrameSize.SetWidth( static_cast<sal_uInt16>(nValue) );
950  bOk = true;
951  }
952  }
953  break;
954  }
955 
956  if( bSetHeight || bSetWidth )
957  {
958  sal_Int32 nValue;
959  bOk = rUnitConverter.convertMeasureToCore(nValue, rValue, nMin,
960  USHRT_MAX );
961  if( bOk )
962  {
963  if( bSetWidth )
964  rFrameSize.SetWidth( static_cast<sal_uInt16>(nValue) );
965  if( bSetHeight )
966  rFrameSize.SetHeight( static_cast<sal_uInt16>(nValue) );
967  if( bSetSizeType )
968  rFrameSize.SetHeightSizeType( eSizeType );
969  }
970  }
971  }
972  break;
973 
974  case RES_FRAMEDIR:
975  {
976  if (IsXMLToken(rValue, XML_BT_LR))
977  {
978  // Read bt-lr from the extension namespace, handle other values
979  // below.
980  Any aAny;
981  aAny <<= static_cast<sal_uInt16>(SvxFrameDirection::Vertical_LR_BT);
982  bOk = rItem.PutValue(aAny, 0);
983  }
984  else
985  {
986  std::unique_ptr<XMLPropertyHandler> pWritingModeHandler =
989  Any aAny;
990  bOk = pWritingModeHandler->importXML( rValue, aAny,
991  rUnitConverter );
992  if( bOk )
993  bOk = rItem.PutValue( aAny, 0 );
994  }
995  }
996  break;
997 
999  {
1000  SfxBoolItem& rBorders = dynamic_cast<SfxBoolItem&>(rItem);
1001 
1002  if( IsXMLToken( rValue, XML_COLLAPSING ) )
1003  {
1004  rBorders.SetValue(true);
1005  bOk = true;
1006  }
1007  else if( IsXMLToken( rValue, XML_SEPARATING ) )
1008  {
1009  rBorders.SetValue(false);
1010  bOk = true;
1011  }
1012  else
1013  bOk = false;
1014  }
1015  break;
1016 
1017  default:
1018  OSL_FAIL("Item not implemented!");
1019  break;
1020  }
1021 
1022  return bOk;
1023 }
1024 
1025 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
constexpr TypedWhichId< SvxFrameDirectionItem > RES_FRAMEDIR(120)
bool IsXMLToken(const OUString &rString, enum XMLTokenEnum eToken)
constexpr TypedWhichId< SwFormatPageDesc > RES_PAGEDESC(93)
constexpr TypedWhichId< SvXMLAttrContainerItem > RES_UNKNOWNATR_CONTAINER(RES_UNKNOWNATR_BEGIN)
void SetRight(const tools::Long nR, const sal_uInt16 nProp=100)
static bool convertEnum(EnumT &rEnum, const OUString &rValue, const SvXMLEnumMapEntry< EnumT > *pMap)
void SetTransparency(sal_uInt8 nTransparency)
Pagedescriptor Client of SwPageDesc that is "described" by the attribute.
Definition: fmtpdsc.hxx:35
void SetHeight(tools::Long n)
static bool convertBool(bool &rBool, const OUString &rString)
bool sw_frmitems_parseXMLBorder(const OUString &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:77
void sw_frmitems_MergeXMLHoriPos(SvxGraphicPosition &ePos, SvxGraphicPosition eHori)
Definition: xmlithlp.cxx:237
SvXMLImportItemMapper(SvXMLItemMapEntriesRef const &rMapEntries)
Definition: xmlimpit.cxx:64
#define MID_FIRST_AUTO
virtual SfxPoolItem * Clone(SfxItemPool *pPool=nullptr) const =0
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:66
XML_ALWAYS
#define MID_PAGEDESC_PAGENUMOFFSET
Definition: unomid.h:27
constexpr sal_uInt16 XML_NAMESPACE_FO_COMPAT
constexpr TypedWhichId< SvxFormatBreakItem > RES_BREAK(94)
#define MID_BACK_COLOR
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
bool getNextToken(OUString &rToken)
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:318
Value in Var-direction gives minimum (can be exceeded but not be less).
const struct SvXMLEnumMapEntry< SvxGraphicPosition > psXML_BrushVertPos[]
Definition: xmlithlp.cxx:230
#define TOP_BORDER_LINE_WIDTH
constexpr TypedWhichId< SwFormatLayoutSplit > RES_LAYOUT_SPLIT(113)
#define ALL_BORDER_LINE_WIDTH
const sal_uInt16 XML_NAMESPACE_XMLNS
constexpr TypedWhichId< SwFormatVertOrient > RES_VERT_ORIENT(102)
GPOS_TILED
bool convertMeasureToCore(sal_Int32 &rValue, const OUString &rString, sal_Int32 nMin=SAL_MIN_INT32, sal_Int32 nMax=SAL_MAX_INT32) const
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:307
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
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
#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:138
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 const OUString & getNameFromToken(sal_Int32 nToken)
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)
static bool convertColor(sal_Int32 &rColor, const OUString &rValue)
void SetWidthPercent(sal_uInt8 n)
Definition: fmtfsize.hxx:95
const o3tl::enumarray< SvxAdjust, unsigned short > aSvxToUnoAdjust USHRT_MAX
Definition: unosett.cxx:254
void SetLocation(SvxShadowLocation eNew)
const struct SvXMLEnumMapEntry< SvxGraphicPosition > psXML_BrushHoriPos[]
Definition: xmlithlp.cxx:223
#define XML_ELEMENT(prefix, name)
void SetGraphicFilter(const OUString &rNew)
#define MID_LO_MARGIN
void sw_frmitems_MergeXMLVertPos(SvxGraphicPosition &ePos, SvxGraphicPosition eVert)
Definition: xmlithlp.cxx:267
#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:297
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:66
#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
static bool convertPercent(sal_Int32 &rValue, const OUString &rString)
const struct SvXMLEnumMapEntry< SvxGraphicPosition > psXML_BrushRepeat[]
Definition: xmlithlp.cxx:215
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