LibreOffice Module sw (master)  1
xmlexpit.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 "xmlexpit.hxx"
21 
22 #include <osl/diagnose.h>
23 #include <rtl/ustrbuf.hxx>
24 #include <sax/tools/converter.hxx>
25 #include <svl/poolitem.hxx>
26 #include <svl/itemset.hxx>
27 #include <utility>
28 #include <xmloff/xmluconv.hxx>
29 #include <xmloff/attrlist.hxx>
30 #include <xmloff/nmspmap.hxx>
31 #include <xmloff/xmlnmspe.hxx>
32 #include <xmloff/prhdlfac.hxx>
33 #include <xmloff/xmltypes.hxx>
34 #include <editeng/xmlcnitm.hxx>
35 #include <xmloff/xmlexp.hxx>
36 #include <xmloff/xmlprhdl.hxx>
37 #include <editeng/memberids.h>
38 #include <hintids.hxx>
39 #include <unomid.h>
40 #include <svx/unomid.hxx>
41 #include <editeng/lrspitem.hxx>
42 #include <editeng/ulspitem.hxx>
43 #include <editeng/shaditem.hxx>
44 #include <editeng/boxitem.hxx>
46 #include <editeng/keepitem.hxx>
47 #include <editeng/brushitem.hxx>
48 #include <editeng/frmdiritem.hxx>
49 #include <fmtpdsc.hxx>
50 #include <fmtornt.hxx>
51 #include <fmtfsize.hxx>
52 
53 #include "xmlithlp.hxx"
54 
55 #include <fmtrowsplt.hxx>
56 
57 using ::editeng::SvxBorderLine;
58 using namespace ::com::sun::star;
59 using namespace ::xmloff::token;
60 using uno::Any;
61 
62 // fills the given attribute list with the items in the given set
64  SvXMLAttributeList& rAttrList,
65  const SfxItemSet& rSet,
66  const SvXMLUnitConverter& rUnitConverter,
67  const SvXMLNamespaceMap& rNamespaceMap,
68  std::vector<sal_uInt16> *pIndexArray ) const
69 {
70  const sal_uInt16 nCount = mrMapEntries->getCount();
71  sal_uInt16 nIndex = 0;
72 
73  while( nIndex < nCount )
74  {
75  SvXMLItemMapEntry const & rEntry = mrMapEntries->getByIndex( nIndex );
76 
77  // we have a valid map entry here, so lets use it...
78  if( 0 == (rEntry.nMemberId & MID_SW_FLAG_NO_ITEM_EXPORT) )
79  {
80  const SfxPoolItem* pItem = GetItem( rSet, rEntry.nWhichId );
81  // do we have an item?
82  if(pItem)
83  {
84  if( 0 != (rEntry.nMemberId & MID_SW_FLAG_ELEMENT_ITEM_EXPORT) )
85  {
86  // element items do not add any properties,
87  // we export it later
88  if( pIndexArray )
89  pIndexArray->push_back( nIndex );
90 
91  }
92  else
93  {
94  exportXML( rExport, rAttrList, *pItem, rEntry, rUnitConverter,
95  rNamespaceMap, &rSet );
96  }
97  }
98  }
99  else
100  {
101  OSL_FAIL( "no item not handled in xml export" );
102  }
103  nIndex++;
104  }
105 }
106 
108  SvXMLAttributeList& rAttrList,
109  const SfxPoolItem& rItem,
110  const SvXMLItemMapEntry& rEntry,
111  const SvXMLUnitConverter& rUnitConverter,
112  const SvXMLNamespaceMap& rNamespaceMap,
113  const SfxItemSet *pSet ) const
114 {
115  if( 0 != (rEntry.nMemberId & MID_SW_FLAG_SPECIAL_ITEM_EXPORT) )
116  {
117  if( dynamic_cast<const SwFormatRowSplit*>( &rItem) != nullptr )
118  {
119  OUString aValue;
120  bool bAddAttribute = true;
121  if( rEntry.nNameSpace == XML_NAMESPACE_STYLE )
122  {
123  bAddAttribute = false;
124  }
125  else
126  {
127  OUStringBuffer aOut;
128  const SfxBoolItem* pSplit = dynamic_cast<const SfxBoolItem*>( &rItem );
129  assert(pSplit && "Wrong Which-ID");
130  const sal_uInt16 eEnum = (pSplit && pSplit->GetValue()) ? 1 : 0;
132  aValue = aOut.makeStringAndClear();
133  }
134  if( bAddAttribute )
135  {
136  const OUString sName( rNamespaceMap.GetQNameByKey( rEntry.nNameSpace,
137  GetXMLToken(rEntry.eLocalName) ) );
138  rAttrList.AddAttribute( sName, aValue );
139  }
140  }
141 
142  if (const SvXMLAttrContainerItem *pUnknown = dynamic_cast<const SvXMLAttrContainerItem*>(&rItem))
143  {
144  std::unique_ptr<SvXMLNamespaceMap> pNewNamespaceMap;
145  const SvXMLNamespaceMap *pNamespaceMap = &rNamespaceMap;
146 
147  const sal_uInt16 nCount = pUnknown->GetAttrCount();
148  for( sal_uInt16 i=0; i < nCount; i++ )
149  {
150  const OUString sPrefix( pUnknown->GetAttrPrefix( i ) );
151  if( !sPrefix.isEmpty() )
152  {
153  const OUString sNamespace( pUnknown->GetAttrNamespace( i ) );
154 
155  // if the prefix isn't defined yet or has another meaning,
156  // we have to redefine it now.
157  const sal_uInt16 nIdx = pNamespaceMap->GetIndexByPrefix( sPrefix );
158  if( USHRT_MAX == nIdx ||
159  pNamespaceMap->GetNameByIndex( nIdx ) != sNamespace )
160  {
161  if( !pNewNamespaceMap )
162  {
163  pNewNamespaceMap.reset(
164  new SvXMLNamespaceMap( rNamespaceMap ));
165  pNamespaceMap = pNewNamespaceMap.get();
166  }
167  pNewNamespaceMap->Add( sPrefix, sNamespace );
168 
169  rAttrList.AddAttribute( GetXMLToken(XML_XMLNS) + ":" + sPrefix,
170  sNamespace );
171  }
172 
173  rAttrList.AddAttribute( sPrefix + ":" + pUnknown->GetAttrLName(i),
174  pUnknown->GetAttrValue(i) );
175  }
176  else
177  {
178  rAttrList.AddAttribute( pUnknown->GetAttrLName(i),
179  pUnknown->GetAttrValue(i) );
180  }
181  }
182  }
183  else
184  {
185  handleSpecialItem( rAttrList, rEntry, rItem, rUnitConverter,
186  rNamespaceMap, pSet );
187  }
188  }
189  else if( 0 == (rEntry.nMemberId & MID_SW_FLAG_ELEMENT_ITEM_EXPORT) )
190  {
191  bool bDone = false;
192  switch (rItem.Which())
193  {
194  case RES_FRAMEDIR:
195  {
196  // Write bt-lr to the extension namespace, handle other values
197  // below.
198  auto pDirection = static_cast<const SvxFrameDirectionItem*>(&rItem);
199  if (rEntry.nNameSpace == XML_NAMESPACE_LO_EXT
200  && pDirection->GetValue() == SvxFrameDirection::Vertical_LR_BT)
201  {
202  const OUString sName(rNamespaceMap.GetQNameByKey(
205  }
206  if (rEntry.nNameSpace == XML_NAMESPACE_LO_EXT
207  || pDirection->GetValue() == SvxFrameDirection::Vertical_LR_BT)
208  bDone = true;
209  break;
210  }
211  }
212 
213  if (!bDone)
214  {
215  OUString aValue;
216  if( QueryXMLValue(rItem, aValue,
217  static_cast< sal_uInt16 >(
218  rEntry.nMemberId & MID_SW_FLAG_MASK ),
219  rUnitConverter ) )
220  {
221  const OUString sName(
222  rNamespaceMap.GetQNameByKey( rEntry.nNameSpace,
223  GetXMLToken(rEntry.eLocalName)));
224  rAttrList.AddAttribute( sName, aValue );
225  }
226  }
227  }
228 }
229 
231  SvXMLExport& rExport,
232  const SfxItemSet &rSet,
233  const std::vector<sal_uInt16> &rIndexArray ) const
234 {
235  const size_t nCount = rIndexArray.size();
236 
237  bool bItemsExported = false;
238  for( size_t nIndex = 0; nIndex < nCount; ++nIndex )
239  {
240  const sal_uInt16 nElement = rIndexArray[ nIndex ];
241  SvXMLItemMapEntry const & rEntry = mrMapEntries->getByIndex( nElement );
242  OSL_ENSURE( 0 != (rEntry.nMemberId & MID_SW_FLAG_ELEMENT_ITEM_EXPORT),
243  "wrong mid flag!" );
244 
245  const SfxPoolItem* pItem = GetItem( rSet, rEntry.nWhichId );
246  // do we have an item?
247  if(pItem)
248  {
249  rExport.IgnorableWhitespace();
250  handleElementItem( rEntry, *pItem );
251  bItemsExported = true;
252  }
253  }
254 
255  if( bItemsExported )
256  rExport.IgnorableWhitespace();
257 }
258 
263  sal_uInt16 nWhichId)
264 {
265  // first get item from itemset
266  const SfxPoolItem* pItem;
267  SfxItemState eState = rSet.GetItemState( nWhichId, false, &pItem );
268 
269  if( SfxItemState::SET == eState )
270  {
271  return pItem;
272  }
273  else
274  {
275  return nullptr;
276  }
277 }
278 
280  : mrMapEntries(std::move(rMapEntries))
281 {
282 }
283 
285 {
286 }
287 
289  const SfxItemSet& rSet,
290  const SvXMLUnitConverter& rUnitConverter,
291  XMLTokenEnum ePropToken ) const
292 {
293  std::vector<sal_uInt16> aIndexArray;
294 
295  exportXML( rExport, rExport.GetAttrList(), rSet, rUnitConverter,
296  rExport.GetNamespaceMap(), &aIndexArray );
297 
298  if( rExport.GetAttrList().getLength() > 0 || !aIndexArray.empty() )
299  {
300  rExport.IgnorableWhitespace();
301 
302  SvXMLElementExport aElem( rExport, XML_NAMESPACE_STYLE, ePropToken,
303  false, false );
304  exportElementItems( rExport, rSet, aIndexArray );
305  }
306 }
307 
311  const SvXMLItemMapEntry& /*rEntry*/,
312  const SfxPoolItem& /*rItem*/,
313  const SvXMLUnitConverter& /*rUnitConverter*/,
314  const SvXMLNamespaceMap& /*rNamespaceMap*/,
315  const SfxItemSet* /*pSet*/ /* = NULL */ ) const
316 {
317  OSL_FAIL( "special item not handled in xml export" );
318 }
319 
323  const SvXMLItemMapEntry& /*rEntry*/,
324  const SfxPoolItem& /*rItem*/ ) const
325 {
326  OSL_FAIL( "element item not handled in xml export" );
327 }
328 
329 static bool lcl_isOdfDoubleLine( const SvxBorderLine* pLine )
330 {
331  bool bIsOdfDouble = false;
332  switch (pLine->GetBorderLineStyle())
333  {
334  case SvxBorderLineStyle::DOUBLE:
335  case SvxBorderLineStyle::THINTHICK_SMALLGAP:
336  case SvxBorderLineStyle::THINTHICK_MEDIUMGAP:
337  case SvxBorderLineStyle::THINTHICK_LARGEGAP:
338  case SvxBorderLineStyle::THICKTHIN_SMALLGAP:
339  case SvxBorderLineStyle::THICKTHIN_MEDIUMGAP:
340  case SvxBorderLineStyle::THICKTHIN_LARGEGAP:
341  bIsOdfDouble = true;
342  break;
343  default:
344  break;
345  }
346  return bIsOdfDouble;
347 }
348 
350  const SfxPoolItem& rItem,
351  OUString& rValue,
352  sal_uInt16 nMemberId,
353  const SvXMLUnitConverter& rUnitConverter )
354 {
355  bool bOk = false;
356  OUStringBuffer aOut;
357 
358  switch ( rItem.Which() )
359  {
360 
361  case RES_LR_SPACE:
362  {
363  const SvxLRSpaceItem& rLRSpace = dynamic_cast<const SvxLRSpaceItem&>(rItem);
364 
365  bOk = true;
366  switch( nMemberId )
367  {
368  case MID_L_MARGIN:
369  if (rLRSpace.GetPropLeft() != 100)
370  {
372  aOut, rLRSpace.GetPropLeft() );
373  }
374  else
375  {
376  rUnitConverter.convertMeasureToXML(
377  aOut, rLRSpace.GetLeft() );
378  }
379  break;
380 
381  case MID_R_MARGIN:
382  if (rLRSpace.GetPropRight() != 100)
383  {
385  aOut, rLRSpace.GetPropRight() );
386  }
387  else
388  {
389  rUnitConverter.convertMeasureToXML(
390  aOut, rLRSpace.GetRight() );
391  }
392  break;
393 
394  case MID_FIRST_AUTO:
395  if (rLRSpace.IsAutoFirst())
396  {
398  aOut, rLRSpace.IsAutoFirst() );
399  }
400  else
401  bOk = false;
402  break;
403 
405  if (!rLRSpace.IsAutoFirst())
406  {
407  if (rLRSpace.GetPropTextFirstLineOffset() != 100)
408  {
410  aOut, rLRSpace.GetPropTextFirstLineOffset() );
411  }
412  else
413  {
414  rUnitConverter.convertMeasureToXML(
415  aOut, rLRSpace.GetTextFirstLineOffset() );
416  }
417  }
418  else
419  bOk = false;
420  break;
421 
422  default:
423  OSL_FAIL( "unknown member id!");
424  bOk = false;
425  break;
426  }
427  }
428  break;
429 
430  case RES_UL_SPACE:
431  {
432  const SvxULSpaceItem& rULSpace = dynamic_cast<const SvxULSpaceItem&>(rItem);
433 
434  switch( nMemberId )
435  {
436  case MID_UP_MARGIN:
437  if (rULSpace.GetPropUpper() != 100)
438  {
440  aOut, rULSpace.GetPropUpper() );
441  }
442  else
443  {
444  rUnitConverter.convertMeasureToXML(
445  aOut, rULSpace.GetUpper() );
446  }
447  break;
448 
449  case MID_LO_MARGIN:
450  if (rULSpace.GetPropLower() != 100)
451  {
453  aOut, rULSpace.GetPropLower() );
454  }
455  else
456  {
457  rUnitConverter.convertMeasureToXML(
458  aOut, rULSpace.GetLower() );
459  }
460  break;
461 
462  default:
463  OSL_FAIL("unknown MemberId");
464  };
465 
466  bOk = true;
467  }
468  break;
469 
470  case RES_SHADOW:
471  {
472  const SvxShadowItem* pShadow = dynamic_cast<const SvxShadowItem*>( &rItem );
473  assert(pShadow && "Wrong Which-ID");
474  if (pShadow)
475  {
476  sal_Int32 nX = 1, nY = 1;
477  switch( pShadow->GetLocation() )
478  {
479  case SvxShadowLocation::TopLeft:
480  nX = -1;
481  nY = -1;
482  break;
483  case SvxShadowLocation::TopRight:
484  nY = -1;
485  break;
486  case SvxShadowLocation::BottomLeft:
487  nX = -1;
488  break;
489  case SvxShadowLocation::BottomRight:
490  break;
491  case SvxShadowLocation::NONE:
492  default:
493  rValue = GetXMLToken(XML_NONE);
494  return true;
495  }
496 
497  nX *= pShadow->GetWidth();
498  nY *= pShadow->GetWidth();
499 
500  ::sax::Converter::convertColor(aOut, pShadow->GetColor());
501  aOut.append( ' ' );
502  rUnitConverter.convertMeasureToXML( aOut, nX );
503  aOut.append( ' ' );
504  rUnitConverter.convertMeasureToXML( aOut, nY );
505 
506  bOk = true;
507  }
508  }
509  break;
510 
511  case RES_BOX:
512  {
513  const SvxBoxItem* pBox = dynamic_cast<const SvxBoxItem*>( &rItem );
514  assert(pBox && "Wrong Which-ID");
515  if (pBox)
516  {
539  const SvxBorderLine* pLeft = pBox->GetLeft();
540  const SvxBorderLine* pRight = pBox->GetRight();
541  const SvxBorderLine* pTop = pBox->GetTop();
542  const SvxBorderLine* pBottom = pBox->GetBottom();
543  const sal_uInt16 nTopDist = pBox->GetDistance( SvxBoxItemLine::TOP );
544  const sal_uInt16 nBottomDist = pBox->GetDistance( SvxBoxItemLine::BOTTOM );
545  const sal_uInt16 nLeftDist = pBox->GetDistance( SvxBoxItemLine::LEFT );
546  const sal_uInt16 nRightDist = pBox->GetDistance( SvxBoxItemLine::RIGHT );
547 
548  // check if we need to export it
549  switch( nMemberId )
550  {
551  case ALL_BORDER_PADDING:
552  case LEFT_BORDER_PADDING:
554  case TOP_BORDER_PADDING:
556  {
557  bool bEqual = nLeftDist == nRightDist &&
558  nLeftDist == nTopDist &&
559  nLeftDist == nBottomDist;
560  // don't export individual paddings if all paddings are equal and
561  // don't export all padding if some paddings are not equal
562  if( (bEqual && ALL_BORDER_PADDING != nMemberId) ||
563  (!bEqual && ALL_BORDER_PADDING == nMemberId) )
564  return false;
565  }
566  break;
567  case ALL_BORDER:
568  case LEFT_BORDER:
569  case RIGHT_BORDER:
570  case TOP_BORDER:
571  case BOTTOM_BORDER:
572  {
573  bool bEqual = ( nullptr == pTop && nullptr == pBottom &&
574  nullptr == pLeft && nullptr == pRight ) ||
575  ( pTop && pBottom && pLeft && pRight &&
576  *pTop == *pBottom && *pTop == *pLeft &&
577  *pTop == *pRight );
578 
579  // don't export individual borders if all are the same and
580  // don't export all borders if some are not equal
581  if( (bEqual && ALL_BORDER != nMemberId) ||
582  (!bEqual && ALL_BORDER == nMemberId) )
583  return false;
584  }
585  break;
591  {
592  // if no line is set, there is nothing to export
593  if( !pTop && !pBottom && !pLeft && !pRight )
594  return false;
595 
596  bool bEqual = nullptr != pTop &&
597  nullptr != pBottom &&
598  nullptr != pLeft &&
599  nullptr != pRight;
600 
601  if( bEqual )
602  {
603  const sal_uInt16 nDistance = pTop->GetDistance();
604  const sal_uInt16 nInWidth = pTop->GetInWidth();
605  const sal_uInt16 nOutWidth = pTop->GetOutWidth();
606  const long nWidth = pTop->GetWidth();
607 
608  bEqual = nDistance == pLeft->GetDistance() &&
609  nInWidth == pLeft->GetInWidth() &&
610  nOutWidth == pLeft->GetOutWidth() &&
611  nWidth == pLeft->GetWidth() &&
612  nDistance == pRight->GetDistance() &&
613  nInWidth == pRight->GetInWidth() &&
614  nOutWidth == pRight->GetOutWidth() &&
615  nWidth == pRight->GetWidth() &&
616  nDistance == pBottom->GetDistance() &&
617  nInWidth == pBottom->GetInWidth() &&
618  nOutWidth == pBottom->GetOutWidth() &&
619  nWidth == pBottom->GetWidth();
620  }
621 
622  switch( nMemberId )
623  {
625  if( !bEqual || pTop->GetDistance() == 0 ||
626  !lcl_isOdfDoubleLine( pTop ) )
627  return false;
628  break;
630  if( bEqual || nullptr == pLeft ||
631  0 == pLeft->GetDistance() ||
632  !lcl_isOdfDoubleLine( pLeft ) )
633  return false;
634  break;
636  if( bEqual || nullptr == pRight ||
637  0 == pRight->GetDistance() ||
638  !lcl_isOdfDoubleLine( pRight ) )
639  return false;
640  break;
642  if( bEqual || nullptr == pTop ||
643  0 == pTop->GetDistance() ||
644  !lcl_isOdfDoubleLine( pTop ) )
645  return false;
646  break;
648  if( bEqual || nullptr == pBottom ||
649  0 == pBottom->GetDistance() ||
650  !lcl_isOdfDoubleLine( pBottom ) )
651  return false;
652  break;
653  }
654  }
655  break;
656  }
657 
658  // now export it export
659  switch( nMemberId )
660  {
661  // padding
662  case ALL_BORDER_PADDING:
663  case LEFT_BORDER_PADDING:
664  rUnitConverter.convertMeasureToXML( aOut, nLeftDist );
665  break;
667  rUnitConverter.convertMeasureToXML( aOut, nRightDist );
668  break;
669  case TOP_BORDER_PADDING:
670  rUnitConverter.convertMeasureToXML( aOut, nTopDist );
671  break;
673  rUnitConverter.convertMeasureToXML( aOut, nBottomDist );
674  break;
675 
676  // border
677  case ALL_BORDER:
678  case LEFT_BORDER:
679  case RIGHT_BORDER:
680  case TOP_BORDER:
681  case BOTTOM_BORDER:
682  {
683  const SvxBorderLine* pLine;
684  switch( nMemberId )
685  {
686  case ALL_BORDER:
687  case LEFT_BORDER:
688  pLine = pLeft;
689  break;
690  case RIGHT_BORDER:
691  pLine = pRight;
692  break;
693  case TOP_BORDER:
694  pLine = pTop;
695  break;
696  case BOTTOM_BORDER:
697  pLine = pBottom;
698  break;
699  default:
700  pLine = nullptr;
701  break;
702  }
703 
704  if( nullptr != pLine )
705  {
706  sal_Int32 nWidth = pLine->GetWidth();
707 
708  enum XMLTokenEnum eStyle = XML_SOLID;
709  bool bNoBorder = false;
710  switch (pLine->GetBorderLineStyle())
711  {
712  case SvxBorderLineStyle::SOLID:
713  eStyle = XML_SOLID;
714  break;
715  case SvxBorderLineStyle::DOTTED:
716  eStyle = XML_DOTTED;
717  break;
718  case SvxBorderLineStyle::DASHED:
719  eStyle = XML_DASHED;
720  break;
721  case SvxBorderLineStyle::FINE_DASHED:
722  eStyle = XML_FINE_DASHED;
723  break;
724  case SvxBorderLineStyle::DASH_DOT:
725  eStyle = XML_DASH_DOT;
726  break;
727  case SvxBorderLineStyle::DASH_DOT_DOT:
728  eStyle = XML_DASH_DOT_DOT;
729  break;
730  case SvxBorderLineStyle::DOUBLE_THIN:
731  eStyle = XML_DOUBLE_THIN;
732  break;
733  case SvxBorderLineStyle::DOUBLE:
734  case SvxBorderLineStyle::THINTHICK_SMALLGAP:
735  case SvxBorderLineStyle::THINTHICK_MEDIUMGAP:
736  case SvxBorderLineStyle::THINTHICK_LARGEGAP:
737  case SvxBorderLineStyle::THICKTHIN_SMALLGAP:
738  case SvxBorderLineStyle::THICKTHIN_MEDIUMGAP:
739  case SvxBorderLineStyle::THICKTHIN_LARGEGAP:
740  eStyle = XML_DOUBLE;
741  break;
742  case SvxBorderLineStyle::EMBOSSED:
743  eStyle = XML_RIDGE;
744  break;
745  case SvxBorderLineStyle::ENGRAVED:
746  eStyle = XML_GROOVE;
747  break;
748  case SvxBorderLineStyle::INSET:
749  eStyle = XML_INSET;
750  break;
751  case SvxBorderLineStyle::OUTSET:
752  eStyle = XML_OUTSET;
753  break;
754  default:
755  bNoBorder = true;
756  }
757 
758  if ( !bNoBorder )
759  {
761  util::MeasureUnit::TWIP,
762  util::MeasureUnit::POINT);
763  aOut.append( ' ' );
764  aOut.append( GetXMLToken( eStyle ) );
765  aOut.append( ' ' );
767  pLine->GetColor());
768  }
769  }
770  else
771  {
772  aOut.append( GetXMLToken(XML_NONE) );
773  }
774  }
775  break;
776 
777  // width
783  const SvxBorderLine* pLine;
784  switch( nMemberId )
785  {
788  pLine = pLeft;
789  break;
791  pLine = pRight;
792  break;
794  pLine = pTop;
795  break;
797  pLine = pBottom;
798  break;
799  default:
800  return false;
801  }
802  rUnitConverter.convertMeasureToXML( aOut, pLine->GetInWidth() );
803  aOut.append( ' ' );
804  rUnitConverter.convertMeasureToXML( aOut, pLine->GetDistance() );
805  aOut.append( ' ' );
806  rUnitConverter.convertMeasureToXML( aOut, pLine->GetOutWidth() );
807  break;
808  }
809  bOk = true;
810  }
811  }
812  break;
813 
814  case RES_BREAK:
815  {
816  const SvxFormatBreakItem& rFormatBreak = dynamic_cast<const SvxFormatBreakItem&>(rItem);
817 
818  sal_uInt16 eEnum = 0;
819 
820  switch( nMemberId )
821  {
822  case MID_BREAK_BEFORE:
823  switch (rFormatBreak.GetBreak())
824  {
825  case SvxBreak::ColumnBefore:
826  eEnum = 1;
827  break;
828  case SvxBreak::PageBefore:
829  eEnum = 2;
830  break;
831  case SvxBreak::NONE:
832  eEnum = 0;
833  break;
834  default:
835  return false;
836  }
837  break;
838  case MID_BREAK_AFTER:
839  switch (rFormatBreak.GetBreak())
840  {
841  case SvxBreak::ColumnAfter:
842  eEnum = 1;
843  break;
844  case SvxBreak::PageAfter:
845  eEnum = 2;
846  break;
847  case SvxBreak::NONE:
848  eEnum = 0;
849  break;
850  default:
851  return false;
852  }
853  break;
854  }
855 
856  bOk = SvXMLUnitConverter::convertEnum( aOut, eEnum, psXML_BreakType );
857  }
858  break;
859 
860  case RES_KEEP:
861  {
862  const SvxFormatKeepItem* pFormatKeep = dynamic_cast<const SvxFormatKeepItem*>( &rItem );
863  assert(pFormatKeep && "Wrong Which-ID");
864  if (pFormatKeep)
865  {
866  aOut.append( pFormatKeep->GetValue()
868  : GetXMLToken( XML_AUTO ) );
869  bOk = true;
870  }
871  }
872  break;
873 
874  case RES_BACKGROUND:
875  {
876  const SvxBrushItem& rBrush = dynamic_cast<const SvxBrushItem&>(rItem);
877 
878  // note: the graphic is only exported if nMemberId equals
879  // MID_GRAPHIC...
880  // If not, only the color or transparency is exported
881 
882  switch( nMemberId )
883  {
884  case MID_BACK_COLOR:
885  if ( rBrush.GetColor().GetTransparency() )
886  aOut.append( GetXMLToken(XML_TRANSPARENT) );
887  else
888  {
890  rBrush.GetColor());
891  }
892  bOk = true;
893  break;
894 
896  switch (rBrush.GetGraphicPos())
897  {
898  case GPOS_LT:
899  case GPOS_MT:
900  case GPOS_RT:
901  aOut.append( GetXMLToken(XML_TOP) );
902  bOk = true;
903  break;
904  case GPOS_LM:
905  case GPOS_MM:
906  case GPOS_RM:
907  aOut.append( GetXMLToken(XML_CENTER) );
908  bOk = true;
909  break;
910  case GPOS_LB:
911  case GPOS_MB:
912  case GPOS_RB:
913  aOut.append( GetXMLToken(XML_BOTTOM) );
914  bOk = true;
915  break;
916  default:
917  ;
918  }
919 
920  if( bOk )
921  {
922  aOut.append( ' ' );
923 
924  switch (rBrush.GetGraphicPos())
925  {
926  case GPOS_LT:
927  case GPOS_LB:
928  case GPOS_LM:
929  aOut.append( GetXMLToken(XML_LEFT) );
930  break;
931  case GPOS_MT:
932  case GPOS_MM:
933  case GPOS_MB:
934  aOut.append( GetXMLToken(XML_CENTER) );
935  break;
936  case GPOS_RM:
937  case GPOS_RT:
938  case GPOS_RB:
939  aOut.append( GetXMLToken(XML_RIGHT) );
940  break;
941  default:
942  ;
943  }
944  }
945  break;
946 
947  case MID_GRAPHIC_REPEAT:
948  {
949  SvxGraphicPosition eGraphicPos = rBrush.GetGraphicPos();
950  if( GPOS_AREA == eGraphicPos )
951  {
952  aOut.append( GetXMLToken(XML_STRETCH) );
953  bOk = true;
954  }
955  else if( GPOS_NONE != eGraphicPos && GPOS_TILED != eGraphicPos )
956  {
957  aOut.append( GetXMLToken(XML_BACKGROUND_NO_REPEAT) );
958  bOk = true;
959  }
960  }
961  break;
962 
963  case MID_GRAPHIC_FILTER:
964  if (rBrush.GetGraphicPos() != GPOS_NONE &&
965  !rBrush.GetGraphicFilter().isEmpty())
966  {
967  aOut.append(rBrush.GetGraphicFilter());
968  bOk = true;
969  }
970  break;
971  }
972  }
973  break;
974 
975  case RES_PAGEDESC:
976  {
977  const SwFormatPageDesc& rPageDesc = dynamic_cast<const SwFormatPageDesc&>(rItem);
978 
979  if( MID_PAGEDESC_PAGENUMOFFSET==nMemberId )
980  {
981  ::std::optional<sal_uInt16> oNumOffset = rPageDesc.GetNumOffset();
982  if (oNumOffset && *oNumOffset > 0)
983  {
984  // #i114163# positiveInteger only!
985  sal_Int32 const number(*oNumOffset);
986  aOut.append(number);
987  }
988  else
989  {
990  aOut.append(GetXMLToken(XML_AUTO));
991  }
992  bOk = true;
993  }
994  }
995  break;
996 
997  case RES_LAYOUT_SPLIT:
998  case RES_ROW_SPLIT:
999  {
1000  const SfxBoolItem* pSplit = dynamic_cast<const SfxBoolItem*>( &rItem );
1001  assert(pSplit && "Wrong Which-ID");
1002  if (pSplit)
1003  {
1004  ::sax::Converter::convertBool( aOut, pSplit->GetValue() );
1005  bOk = true;
1006  }
1007  }
1008  break;
1009 
1010  case RES_HORI_ORIENT:
1011  {
1012  const SwFormatHoriOrient* pHoriOrient = dynamic_cast<const SwFormatHoriOrient*>( &rItem );
1013  assert(pHoriOrient && "Wrong Which-ID");
1014  if (pHoriOrient)
1015  {
1016  SvXMLUnitConverter::convertEnum( aOut, pHoriOrient->GetHoriOrient(),
1018  bOk = true;
1019  }
1020  }
1021  break;
1022 
1023  case RES_VERT_ORIENT:
1024  {
1025  const SwFormatVertOrient* pVertOrient = dynamic_cast<const SwFormatVertOrient*>( &rItem );
1026  assert(pVertOrient && "Wrong Which-ID");
1027 
1028  SvXMLUnitConverter::convertEnum( aOut, pVertOrient->GetVertOrient(),
1030  bOk = true;
1031  }
1032  break;
1033 
1034  case RES_FRM_SIZE:
1035  {
1036  const SwFormatFrameSize& rFrameSize = dynamic_cast<const SwFormatFrameSize&>(rItem);
1037 
1038  bool bOutHeight = false;
1039  switch( nMemberId )
1040  {
1041  case MID_FRMSIZE_REL_WIDTH:
1042  if (rFrameSize.GetWidthPercent())
1043  {
1045  aOut, rFrameSize.GetWidthPercent() );
1046  bOk = true;
1047  }
1048  break;
1050  if( SwFrameSize::Minimum == rFrameSize.GetHeightSizeType() )
1051  bOutHeight = true;
1052  break;
1054  if( SwFrameSize::Fixed == rFrameSize.GetHeightSizeType() )
1055  bOutHeight = true;
1056  break;
1057  }
1058 
1059  if( bOutHeight )
1060  {
1061  rUnitConverter.convertMeasureToXML(aOut, rFrameSize.GetHeight());
1062  bOk = true;
1063  }
1064  }
1065  break;
1066 
1067  case RES_FRAMEDIR:
1068  {
1069  Any aAny;
1070  bOk = rItem.QueryValue( aAny );
1071  if( bOk )
1072  {
1073  std::unique_ptr<XMLPropertyHandler> pWritingModeHandler =
1076  OUString sValue;
1077  bOk = pWritingModeHandler->exportXML( sValue, aAny,
1078  rUnitConverter );
1079  if( bOk )
1080  aOut.append( sValue );
1081  }
1082  }
1083  break;
1084 
1086  {
1087  const SfxBoolItem* pBorders = dynamic_cast<const SfxBoolItem*>( &rItem );
1088  assert(pBorders && "Wrong RES-ID");
1089  if (pBorders)
1090  {
1091  aOut.append( pBorders->GetValue()
1093  : GetXMLToken( XML_SEPARATING ) );
1094  bOk = true;
1095  }
1096  }
1097  break;
1098 
1099  default:
1100  OSL_FAIL("GetXMLValue not implemented for this item.");
1101  break;
1102  }
1103 
1104  if ( bOk )
1105  rValue = aOut.makeStringAndClear();
1106 
1107  return bOk;
1108 }
1109 
1110 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
long GetLeft() const
bool GetValue() const
constexpr sal_uInt16 XML_NAMESPACE_LO_EXT
constexpr TypedWhichId< SvxFrameDirectionItem > RES_FRAMEDIR(120)
constexpr TypedWhichId< SwFormatPageDesc > RES_PAGEDESC(93)
const ::std::optional< sal_uInt16 > & GetNumOffset() const
Definition: fmtpdsc.hxx:65
XML_BOTTOM
constexpr sal_uInt16 XML_NAMESPACE_STYLE
sal_Int32 nIndex
static bool convertEnum(EnumT &rEnum, const OUString &rValue, const SvXMLEnumMapEntry< EnumT > *pMap)
XML_DOUBLE_THIN
SvXMLExportItemMapper(SvXMLItemMapEntriesRef rMapEntries)
Definition: xmlexpit.cxx:279
Pagedescriptor Client of SwPageDesc that is "described" by the attribute.
Definition: fmtpdsc.hxx:35
sal_uInt16 GetLower() const
XML_WRITING_MODE
static bool convertBool(bool &rBool, const OUString &rString)
GPOS_RM
static bool convertMeasure(sal_Int32 &rValue, const OUString &rString, sal_Int16 nTargetUnit=css::util::MeasureUnit::MM_100TH, sal_Int32 nMin=SAL_MIN_INT32, sal_Int32 nMax=SAL_MAX_INT32)
virtual void handleElementItem(const SvXMLItemMapEntry &rEntry, const SfxPoolItem &rItem) const
this method is called for every item that has the MID_SW_FLAG_ELEMENT_EXPORT flag set ...
Definition: xmlexpit.cxx:322
XML_OUTSET
#define MID_FIRST_AUTO
const OUString & GetGraphicFilter() const
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
SvxBreak GetBreak() const
sal_uInt16 nWhichId
Definition: xmlitmap.hxx:43
sal_uInt16 getCount() const
Definition: xmlitmpr.cxx:71
#define MID_FRMSIZE_REL_WIDTH
Definition: unomid.h:72
sal_uInt8 GetTransparency() const
XML_DOUBLE
#define LEFT_BORDER_PADDING
XML_ALWAYS
#define MID_PAGEDESC_PAGENUMOFFSET
Definition: unomid.h:27
sal_uInt16 GetPropTextFirstLineOffset() const
sal_uInt16 GetDistance(SvxBoxItemLine nLine) const
constexpr TypedWhichId< SvxFormatBreakItem > RES_BREAK(94)
#define MID_BACK_COLOR
const editeng::SvxBorderLine * GetRight() const
virtual ~SvXMLExportItemMapper()
Definition: xmlexpit.cxx:284
sal_uInt16 GetPropLower() 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).
SvXMLItemMapEntry const & getByIndex(sal_uInt16 nIndex) const
Definition: xmlitmpr.cxx:66
XML_RIGHT
#define TOP_BORDER_LINE_WIDTH
constexpr TypedWhichId< SwFormatLayoutSplit > RES_LAYOUT_SPLIT(113)
#define ALL_BORDER_LINE_WIDTH
SvXMLAttributeList & GetAttrList()
constexpr TypedWhichId< SwFormatVertOrient > RES_VERT_ORIENT(102)
GPOS_TILED
SvxGraphicPosition GetGraphicPos() const
SvxShadowLocation GetLocation() const
#define XML_TYPE_TEXT_WRITING_MODE_WITH_DEFAULT
GPOS_LM
constexpr TypedWhichId< SwFormatHoriOrient > RES_HORI_ORIENT(103)
virtual bool QueryValue(css::uno::Any &rVal, sal_uInt8 nMemberId=0) const
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
XML_INSET
#define MID_SW_FLAG_MASK
Definition: xmlitmap.hxx:28
int nCount
#define MID_FRMSIZE_FIX_HEIGHT
Definition: unomid.h:80
#define MID_GRAPHIC_REPEAT
const char * sName
XML_SOLID
XMLTokenEnum
virtual void handleSpecialItem(SvXMLAttributeList &rAttrList, const SvXMLItemMapEntry &rEntry, const SfxPoolItem &rItem, const SvXMLUnitConverter &rUnitConverter, const SvXMLNamespaceMap &rNamespaceMap, const SfxItemSet *pSet) const
this method is called for every item that has the MID_SW_FLAG_SPECIAL_ITEM_EXPORT flag set ...
Definition: xmlexpit.cxx:310
constexpr TypedWhichId< SwFormatRowSplit > RES_ROW_SPLIT(122)
const struct SvXMLEnumMapEntry< sal_Int16 > aXMLTableAlignMap[]
Definition: xmlithlp.cxx:307
const Color & GetColor() const
sal_uInt16 GetPropRight() const
const Color & GetColor() const
XML_FINE_DASHED
#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
sal_uInt16 GetIndexByPrefix(const OUString &rPrefix) const
#define BOTTOM_BORDER_PADDING
XML_STRETCH
#define MID_SW_FLAG_ELEMENT_ITEM_EXPORT
Definition: xmlitmap.hxx:36
enum::xmloff::token::XMLTokenEnum const eLocalName
Definition: xmlitmap.hxx:45
XML_TOP
#define TOP_BORDER
sal_uInt16 GetPropLeft() const
#define MID_SW_FLAG_SPECIAL_ITEM_EXPORT
Definition: xmlitmap.hxx:33
virtual sal_Int16 SAL_CALL getLength() override
constexpr TypedWhichId< SfxBoolItem > RES_COLLAPSING_BORDERS(124)
GPOS_MT
SvxGraphicPosition
XML_BT_LR
static const SfxPoolItem * GetItem(const SfxItemSet &rSet, sal_uInt16 nWhichId)
returns the item with the given WhichId from the given ItemSet if its set
Definition: xmlexpit.cxx:262
SvXMLItemMapEntriesRef mrMapEntries
Definition: xmlexpit.hxx:37
sal_Int16 GetHoriOrient() const
Definition: fmtornt.hxx:87
#define TOP_BORDER_PADDING
GPOS_MM
static bool QueryXMLValue(const SfxPoolItem &rItem, OUString &rValue, sal_uInt16 nMemberId, const SvXMLUnitConverter &rUnitConverter)
Definition: xmlexpit.cxx:349
XML_CENTER
short GetTextFirstLineOffset() const
static bool lcl_isOdfDoubleLine(const SvxBorderLine *pLine)
Definition: xmlexpit.cxx:329
XML_GROOVE
XML_SEPARATING
#define MID_R_MARGIN
#define MID_GRAPHIC_POSITION
OUString sPrefix
OUString GetQNameByKey(sal_uInt16 nKey, const OUString &rLocalName, bool bCache=true) const
sal_uInt8 GetWidthPercent() const
Definition: fmtfsize.hxx:91
#define MID_SW_FLAG_NO_ITEM_EXPORT
Definition: xmlitmap.hxx:34
GPOS_AREA
XML_DASH_DOT_DOT
Frame cannot be moved in Var-direction.
XML_LEFT
const SvXMLNamespaceMap & GetNamespaceMap() const
XML_RIDGE
GPOS_MB
#define ALL_BORDER_PADDING
sal_uInt32 nMemberId
Definition: xmlitmap.hxx:48
void IgnorableWhitespace()
#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
void exportXML(const SvXMLExport &rExport, SvXMLAttributeList &rAttrList, const SfxItemSet &rSet, const SvXMLUnitConverter &rUnitConverter, const SvXMLNamespaceMap &rNamespaceMap, std::vector< sal_uInt16 > *pIndexArray) const
fills the given attribute list with the items in the given set
Definition: xmlexpit.cxx:63
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
static bool convertColor(sal_Int32 &rColor, const OUString &rValue)
const o3tl::enumarray< SvxAdjust, unsigned short > aSvxToUnoAdjust USHRT_MAX
Definition: unosett.cxx:253
void exportElementItems(SvXMLExport &rExport, const SfxItemSet &rSet, const std::vector< sal_uInt16 > &rIndexArray) const
Definition: xmlexpit.cxx:230
sal_uInt16 Add(const OUString &rPrefix, const OUString &rName, sal_uInt16 nKey=XML_NAMESPACE_UNKNOWN)
#define MID_LO_MARGIN
#define MID_GRAPHIC_FILTER
constexpr TypedWhichId< SvxLRSpaceItem > RES_LR_SPACE(91)
sal_Int16 GetVertOrient() const
Definition: fmtornt.hxx:54
XML_COLLAPSING
constexpr TypedWhichId< SvxBoxItem > RES_BOX(106)
XML_DASHED
const struct SvXMLEnumMapEntry< sal_uInt16 > psXML_BreakType[]
Definition: xmlithlp.cxx:297
long GetRight() const
XML_NONE
XML_DOTTED
sal_uInt16 nNameSpace
Definition: xmlitmap.hxx:41
#define ALL_BORDER
void AddAttribute(const OUString &sName, const OUString &sValue)
#define RIGHT_BORDER
GPOS_RB
const OUString & GetNameByIndex(sal_uInt16 nIdx) const
GPOS_LB
XML_BACKGROUND_NO_REPEAT
long GetHeight() const
GPOS_RT
#define MID_BREAK_BEFORE
XML_XMLNS
XML_AUTO
bool IsAutoFirst() const
const editeng::SvxBorderLine * GetBottom() const
constexpr TypedWhichId< SvxULSpaceItem > RES_UL_SPACE(92)
#define BOTTOM_BORDER_LINE_WIDTH
void convertMeasureToXML(OUStringBuffer &rBuffer, sal_Int32 nMeasure) const
sal_uInt16 Which() const
constexpr TypedWhichId< SvxShadowItem > RES_SHADOW(107)
const struct SvXMLEnumMapEntry< sal_uInt16 > aXML_KeepTogetherType[]
Definition: xmlithlp.cxx:326
sal_uInt16 GetUpper() const
static bool convertPercent(sal_Int32 &rValue, const OUString &rString)
XML_TRANSPARENT
SwFrameSize GetHeightSizeType() const
Definition: fmtfsize.hxx:80
sal_uInt16 GetWidth() const
sal_uInt16 GetPropUpper() const
XML_DASH_DOT
#define MID_UP_MARGIN