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