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