LibreOffice Module sw (master)  1
xmlithlp.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 "xmlithlp.hxx"
21 #include <hintids.hxx>
22 #include <unomid.h>
23 #include <sax/tools/converter.hxx>
24 #include <svx/unomid.hxx>
25 #include <editeng/lrspitem.hxx>
26 #include <editeng/ulspitem.hxx>
27 #include <editeng/shaditem.hxx>
28 #include <editeng/boxitem.hxx>
30 #include <editeng/keepitem.hxx>
31 #include <editeng/brushitem.hxx>
32 #include <fmtpdsc.hxx>
33 #include <fmtornt.hxx>
34 #include <fmtfsize.hxx>
35 
36 #include <fmtlsplt.hxx>
37 #include <xmloff/xmluconv.hxx>
38 #include <osl/diagnose.h>
39 
40 using ::editeng::SvxBorderLine;
41 using namespace ::xmloff::token;
42 using namespace ::com::sun::star;
43 
44 #define SVX_XML_BORDER_WIDTH_THIN 0
45 #define SVX_XML_BORDER_WIDTH_MIDDLE 1
46 #define SVX_XML_BORDER_WIDTH_THICK 2
47 
48 const struct SvXMLEnumMapEntry<sal_uInt16> psXML_BorderStyles[] =
49 {
53  { XML_DOUBLE, table::BorderLineStyle::DOUBLE },
54  { XML_DOUBLE_THIN, table::BorderLineStyle::DOUBLE_THIN },
55  { XML_DOTTED, table::BorderLineStyle::DOTTED },
56  { XML_DASHED, table::BorderLineStyle::DASHED },
57  { XML_FINE_DASHED, table::BorderLineStyle::FINE_DASHED },
58  { XML_DASH_DOT, table::BorderLineStyle::DASH_DOT },
59  { XML_DASH_DOT_DOT, table::BorderLineStyle::DASH_DOT_DOT },
60  { XML_GROOVE, table::BorderLineStyle::ENGRAVED },
61  { XML_RIDGE, table::BorderLineStyle::EMBOSSED },
62  { XML_INSET, table::BorderLineStyle::INSET },
63  { XML_OUTSET, table::BorderLineStyle::OUTSET },
64  { XML_TOKEN_INVALID, 0 }
65 };
66 
67 const struct SvXMLEnumMapEntry<sal_uInt16> psXML_NamedBorderWidths[] =
68 {
72  { XML_TOKEN_INVALID, 0 }
73 };
74 // mapping tables to map external xml input to internal box line widths
75 
76 const sal_uInt16 aBorderWidths[] =
77 {
81 };
82 
83 bool sw_frmitems_parseXMLBorder( const OUString& rValue,
84  const SvXMLUnitConverter& rUnitConverter,
85  bool& rHasStyle, sal_uInt16& rStyle,
86  bool& rHasWidth, sal_uInt16& rWidth,
87  sal_uInt16& rNamedWidth,
88  bool& rHasColor, Color& rColor )
89 {
90  OUString aToken;
91  SvXMLTokenEnumerator aTokens( rValue );
92 
93  rHasStyle = false;
94  rHasWidth = false;
95  rHasColor = false;
96 
97  rStyle = USHRT_MAX;
98  rWidth = 0;
99  rNamedWidth = USHRT_MAX;
100 
101  sal_Int32 nTemp;
102  while( aTokens.getNextToken( aToken ) && !aToken.isEmpty() )
103  {
104  if( !rHasWidth &&
105  SvXMLUnitConverter::convertEnum( rNamedWidth, aToken,
106  psXML_NamedBorderWidths ) )
107  {
108  rHasWidth = true;
109  }
110  else if( !rHasStyle &&
111  SvXMLUnitConverter::convertEnum( rStyle, aToken,
112  psXML_BorderStyles ) )
113  {
114  rHasStyle = true;
115  }
116  else if (!rHasColor && ::sax::Converter::convertColor(rColor, aToken))
117  {
118  rHasColor = true;
119  }
120  else if( !rHasWidth &&
121  rUnitConverter.convertMeasureToCore(nTemp, aToken, 0, USHRT_MAX))
122  {
123  rWidth = static_cast<sal_uInt16>(nTemp);
124  rHasWidth = true;
125  }
126  else
127  {
128  // misformed
129  return false;
130  }
131  }
132 
133  return rHasStyle || rHasWidth || rHasColor;
134 }
135 
136 static void sw_frmitems_setXMLBorderStyle( SvxBorderLine& rLine, sal_uInt16 nStyle )
137 {
138  SvxBorderLineStyle eStyle = SvxBorderLineStyle::NONE;
139  if ( nStyle != table::BorderLineStyle::NONE )
140  eStyle = SvxBorderLineStyle( nStyle );
141  rLine.SetBorderLineStyle(eStyle);
142 }
143 
144 bool sw_frmitems_setXMLBorder( std::unique_ptr<SvxBorderLine>& rpLine,
145  bool bHasStyle, sal_uInt16 nStyle,
146  bool bHasWidth, sal_uInt16 nWidth,
147  sal_uInt16 nNamedWidth,
148  bool bHasColor, const Color& rColor )
149 {
150  // first of all, delete an empty line
151  if( (bHasStyle && table::BorderLineStyle::NONE == nStyle) ||
152  (bHasWidth && USHRT_MAX == nNamedWidth && 0 == nWidth) )
153  {
154  bool bRet = nullptr != rpLine;
155  rpLine.reset();
156  return bRet;
157  }
158 
159  // if there is no line and no style and no with, there will never be a line
160  if( !rpLine && !(bHasStyle && bHasWidth) )
161  return false;
162 
163  // We now do know that there will be a line
164  if( !rpLine )
165  rpLine.reset(new SvxBorderLine);
166 
167  if( ( bHasWidth &&
168  (USHRT_MAX != nNamedWidth || (nWidth != rpLine->GetWidth() ) ) ) ||
169  ( bHasStyle &&
170  ((table::BorderLineStyle::SOLID == nStyle && rpLine->GetDistance()) ||
171  (table::BorderLineStyle::DOUBLE == nStyle && !rpLine->GetDistance())) ) )
172  {
173  bool bDouble = (bHasWidth && table::BorderLineStyle::DOUBLE == nStyle ) ||
174  rpLine->GetDistance();
175 
176  // fdo#38542: for double borders, do not override the width
177  // set via style:border-line-width{,-left,-right,-top,-bottom}
178  if (!bDouble || !rpLine->GetWidth())
179  {
180  // The width has to be changed
181  if (bHasWidth && USHRT_MAX != nNamedWidth)
182  {
183  if (bDouble)
184  {
185  rpLine->SetBorderLineStyle( SvxBorderLineStyle::DOUBLE );
186  }
187  rpLine->SetWidth( aBorderWidths[nNamedWidth] );
188  }
189  else
190  {
191  if (!bHasWidth)
192  nWidth = rpLine->GetScaledWidth();
193 
194  rpLine->SetWidth( nWidth );
195  }
196  }
197  sw_frmitems_setXMLBorderStyle( *rpLine, nStyle );
198  }
199 
200  // set color
201  if( bHasColor )
202  rpLine->SetColor( rColor );
203 
204  return true;
205 }
206 
207 void sw_frmitems_setXMLBorder( std::unique_ptr<SvxBorderLine>& rpLine,
208  sal_uInt16 nWidth, sal_uInt16 nOutWidth,
209  sal_uInt16 nInWidth, sal_uInt16 nDistance )
210 {
211  if( !rpLine )
212  rpLine.reset(new SvxBorderLine);
213 
214  if( nWidth > 0 )
215  rpLine->SetWidth( nWidth );
216  else
217  rpLine->GuessLinesWidths(SvxBorderLineStyle::DOUBLE,
218  nOutWidth, nInWidth, nDistance);
219 }
220 
222 {
227 };
228 
230 {
231  { XML_LEFT, GPOS_LM },
232  { XML_RIGHT, GPOS_RM },
234 };
235 
237 {
238  { XML_TOP, GPOS_MT },
239  { XML_BOTTOM, GPOS_MB },
241 };
242 
244  SvxGraphicPosition eHori )
245 {
246  OSL_ENSURE( GPOS_LM==eHori || GPOS_MM==eHori || GPOS_RM==eHori,
247  "sw_frmitems_MergeXMLHoriPos: vertical pos must be middle" );
248 
249  switch( ePos )
250  {
251  case GPOS_LT:
252  case GPOS_MT:
253  case GPOS_RT:
254  ePos = GPOS_LM==eHori ? GPOS_LT : (GPOS_MM==eHori ? GPOS_MT : GPOS_RT);
255  break;
256 
257  case GPOS_LM:
258  case GPOS_MM:
259  case GPOS_RM:
260  ePos = eHori;
261  break;
262 
263  case GPOS_LB:
264  case GPOS_MB:
265  case GPOS_RB:
266  ePos = GPOS_LM==eHori ? GPOS_LB : (GPOS_MM==eHori ? GPOS_MB : GPOS_RB);
267  break;
268  default:
269  ;
270  }
271 }
272 
274  SvxGraphicPosition eVert )
275 {
276  OSL_ENSURE( GPOS_MT==eVert || GPOS_MM==eVert || GPOS_MB==eVert,
277  "sw_frmitems_MergeXMLVertPos: horizontal pos must be middle" );
278 
279  switch( ePos )
280  {
281  case GPOS_LT:
282  case GPOS_LM:
283  case GPOS_LB:
284  ePos = GPOS_MT==eVert ? GPOS_LT : (GPOS_MM==eVert ? GPOS_LM : GPOS_LB);
285  break;
286 
287  case GPOS_MT:
288  case GPOS_MM:
289  case GPOS_MB:
290  ePos = eVert;
291  break;
292 
293  case GPOS_RT:
294  case GPOS_RM:
295  case GPOS_RB:
296  ePos = GPOS_MT==eVert ? GPOS_RT : (GPOS_MM==eVert ? GPOS_RM : GPOS_RB);
297  break;
298  default:
299  ;
300  }
301 }
302 
303 const struct SvXMLEnumMapEntry<sal_uInt16> psXML_BreakType[] =
304 {
305  { XML_AUTO, 0 },
306  { XML_COLUMN, 1 },
307  { XML_PAGE, 2 },
308  { XML_EVEN_PAGE, 2 },
309  { XML_ODD_PAGE, 2 },
310  { XML_TOKEN_INVALID, 0}
311 };
312 
313 const struct SvXMLEnumMapEntry<sal_Int16> aXMLTableAlignMap[] =
314 {
316  { XML_LEFT, text::HoriOrientation::LEFT_AND_WIDTH },
317  { XML_CENTER, text::HoriOrientation::CENTER },
319  { XML_MARGINS, text::HoriOrientation::FULL },
321  { XML_TOKEN_INVALID, 0 }
322 };
323 
324 const struct SvXMLEnumMapEntry<sal_Int16> aXMLTableVAlignMap[] =
325 {
327  { XML_MIDDLE, text::VertOrientation::CENTER },
329  { XML_TOKEN_INVALID, 0 }
330 };
331 
332 const struct SvXMLEnumMapEntry<sal_uInt16> aXML_KeepTogetherType[] =
333 {
334  { XML_ALWAYS, 0 },
335  { XML_AUTO, 1 },
336  { XML_TOKEN_INVALID, 0}
337 };
338 
339 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
XML_BOTTOM
static bool convertEnum(EnumT &rEnum, const OUString &rValue, const SvXMLEnumMapEntry< EnumT > *pMap)
XML_DOUBLE_THIN
GPOS_RM
static void sw_frmitems_setXMLBorderStyle(SvxBorderLine &rLine, sal_uInt16 nStyle)
Definition: xmlithlp.cxx:136
bool sw_frmitems_parseXMLBorder(const OUString &rValue, const SvXMLUnitConverter &rUnitConverter, bool &rHasStyle, sal_uInt16 &rStyle, bool &rHasWidth, sal_uInt16 &rWidth, sal_uInt16 &rNamedWidth, bool &rHasColor, Color &rColor)
Define various helper variables and functions for xmlimpit.cxx and xmlexpit.cxx.
Definition: xmlithlp.cxx:83
void sw_frmitems_MergeXMLHoriPos(SvxGraphicPosition &ePos, SvxGraphicPosition eHori)
Definition: xmlithlp.cxx:243
XML_OUTSET
XML_COLUMN
GPOS_LT
XML_DOUBLE
#define SVX_XML_BORDER_WIDTH_MIDDLE
Definition: xmlithlp.cxx:45
XML_ALWAYS
XML_MIDDLE
bool getNextToken(OUString &rToken)
const struct SvXMLEnumMapEntry< sal_uInt16 > psXML_BorderStyles[]
Definition: xmlithlp.cxx:48
const struct SvXMLEnumMapEntry< sal_Int16 > aXMLTableVAlignMap[]
Definition: xmlithlp.cxx:324
#define DEF_LINE_WIDTH_1
XML_RIGHT
const struct SvXMLEnumMapEntry< SvxGraphicPosition > psXML_BrushVertPos[]
Definition: xmlithlp.cxx:236
SvxBorderLineStyle
GPOS_TILED
bool convertMeasureToCore(sal_Int32 &rValue, const OUString &rString, sal_Int32 nMin=SAL_MIN_INT32, sal_Int32 nMax=SAL_MAX_INT32) const
GPOS_LM
XML_HIDDEN
XML_INSET
XML_BACKGROUND_STRETCH
XML_SOLID
XML_ODD_PAGE
const struct SvXMLEnumMapEntry< sal_Int16 > aXMLTableAlignMap[]
Definition: xmlithlp.cxx:313
XML_FINE_DASHED
XML_THIN
XML_TOP
XML_EVEN_PAGE
GPOS_MT
SvxGraphicPosition
XML_TOKEN_INVALID
GPOS_MM
XML_CENTER
XML_GROOVE
#define SVX_XML_BORDER_WIDTH_THIN
Definition: xmlithlp.cxx:44
GPOS_AREA
bool sw_frmitems_setXMLBorder(std::unique_ptr< SvxBorderLine > &rpLine, bool bHasStyle, sal_uInt16 nStyle, bool bHasWidth, sal_uInt16 nWidth, sal_uInt16 nNamedWidth, bool bHasColor, const Color &rColor)
Definition: xmlithlp.cxx:144
XML_DASH_DOT_DOT
XML_LEFT
XML_RIDGE
XML_THICK
GPOS_MB
const struct SvXMLEnumMapEntry< sal_uInt16 > psXML_NamedBorderWidths[]
Definition: xmlithlp.cxx:67
XML_BACKGROUND_REPEAT
static bool convertColor(sal_Int32 &rColor, const OUString &rValue)
const o3tl::enumarray< SvxAdjust, unsigned short > aSvxToUnoAdjust USHRT_MAX
Definition: unosett.cxx:260
const struct SvXMLEnumMapEntry< SvxGraphicPosition > psXML_BrushHoriPos[]
Definition: xmlithlp.cxx:229
#define SVX_XML_BORDER_WIDTH_THICK
Definition: xmlithlp.cxx:46
XML_MARGINS
void sw_frmitems_MergeXMLVertPos(SvxGraphicPosition &ePos, SvxGraphicPosition eVert)
Definition: xmlithlp.cxx:273
#define DEF_LINE_WIDTH_5
XML_PAGE
XML_DASHED
const struct SvXMLEnumMapEntry< sal_uInt16 > psXML_BreakType[]
Definition: xmlithlp.cxx:303
XML_NONE
XML_DOTTED
GPOS_RB
#define DEF_LINE_WIDTH_0
GPOS_LB
XML_BACKGROUND_NO_REPEAT
GPOS_RT
XML_AUTO
const sal_uInt16 aBorderWidths[]
Definition: xmlithlp.cxx:76
const struct SvXMLEnumMapEntry< sal_uInt16 > aXML_KeepTogetherType[]
Definition: xmlithlp.cxx:332
const struct SvXMLEnumMapEntry< SvxGraphicPosition > psXML_BrushRepeat[]
Definition: xmlithlp.cxx:221
XML_DASH_DOT