merge the formfield patch from ooo-build
[ooovba.git] / sw / source / filter / xml / xmlithlp.cxx
blob2de4a4bed25b064ce12ff5a049bf7ad7d4b02688
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xmlithlp.cxx,v $
10 * $Revision: 1.10 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
33 #include "xmlithlp.hxx"
34 #include "hintids.hxx"
35 #include "unomid.h"
36 #include <svx/unomid.hxx>
37 #include <svx/lrspitem.hxx>
38 #include <svx/ulspitem.hxx>
39 #include <svx/shaditem.hxx>
40 #include <svx/boxitem.hxx>
41 #include <svx/brkitem.hxx>
42 #include <svx/keepitem.hxx>
43 #include <svx/brshitem.hxx>
44 #include "fmtpdsc.hxx"
45 #include "fmtornt.hxx"
46 #include "fmtfsize.hxx"
48 #ifndef _FMTLSPLT_HXX
49 #include "fmtlsplt.hxx"
50 #endif
51 #include <xmloff/xmluconv.hxx>
53 using ::rtl::OUString;
54 using namespace ::xmloff::token;
55 using namespace ::com::sun::star;
58 #define SVX_XML_BORDER_STYLE_NONE 0
59 #define SVX_XML_BORDER_STYLE_SOLID 1
60 #define SVX_XML_BORDER_STYLE_DOUBLE 2
62 #define SVX_XML_BORDER_WIDTH_THIN 0
63 #define SVX_XML_BORDER_WIDTH_MIDDLE 1
64 #define SVX_XML_BORDER_WIDTH_THICK 2
67 const struct SvXMLEnumMapEntry psXML_BorderStyles[] =
69 { XML_NONE, SVX_XML_BORDER_STYLE_NONE },
70 { XML_HIDDEN, SVX_XML_BORDER_STYLE_NONE },
71 { XML_SOLID, SVX_XML_BORDER_STYLE_SOLID },
72 { XML_DOUBLE, SVX_XML_BORDER_STYLE_DOUBLE },
73 { XML_DOTTED, SVX_XML_BORDER_STYLE_SOLID },
74 { XML_DASHED, SVX_XML_BORDER_STYLE_SOLID },
75 { XML_GROOVE, SVX_XML_BORDER_STYLE_SOLID },
76 { XML_RIDGE, SVX_XML_BORDER_STYLE_SOLID },
77 { XML_INSET, SVX_XML_BORDER_STYLE_SOLID },
78 { XML_OUTSET, SVX_XML_BORDER_STYLE_SOLID },
79 { XML_TOKEN_INVALID, 0 }
82 const struct SvXMLEnumMapEntry psXML_NamedBorderWidths[] =
84 { XML_THIN, SVX_XML_BORDER_WIDTH_THIN },
85 { XML_MIDDLE, SVX_XML_BORDER_WIDTH_MIDDLE },
86 { XML_THICK, SVX_XML_BORDER_WIDTH_THICK },
87 { XML_TOKEN_INVALID, 0 }
89 // mapping tables to map external xml input to intarnal box line widths
91 // Ein Eintrag besteht aus vier USHORTs. Der erste ist die Gesamtbreite,
92 // die anderen sind die 3 Einzelbreiten
94 #define SBORDER_ENTRY( n ) \
95 DEF_LINE_WIDTH_##n, DEF_LINE_WIDTH_##n, 0, 0
97 #define DBORDER_ENTRY( n ) \
98 DEF_DOUBLE_LINE##n##_OUT + DEF_DOUBLE_LINE##n##_IN + \
99 DEF_DOUBLE_LINE##n##_DIST, \
100 DEF_DOUBLE_LINE##n##_OUT, \
101 DEF_DOUBLE_LINE##n##_IN, \
102 DEF_DOUBLE_LINE##n##_DIST
104 #define TDBORDER_ENTRY( n ) \
105 DEF_DOUBLE_LINE##n##_OUT, \
106 DEF_DOUBLE_LINE##n##_OUT, \
107 DEF_DOUBLE_LINE##n##_IN, \
108 DEF_DOUBLE_LINE##n##_DIST
111 const sal_uInt16 aSBorderWidths[] =
113 SBORDER_ENTRY( 0 ), SBORDER_ENTRY( 5 ), SBORDER_ENTRY( 1 ),
114 SBORDER_ENTRY( 2 ), SBORDER_ENTRY( 3 ), SBORDER_ENTRY( 4 )
117 const sal_uInt16 aDBorderWidths[5*11] =
119 DBORDER_ENTRY( 0 ),
120 DBORDER_ENTRY( 7 ),
121 DBORDER_ENTRY( 1 ),
122 DBORDER_ENTRY( 8 ),
123 DBORDER_ENTRY( 4 ),
124 DBORDER_ENTRY( 9 ),
125 DBORDER_ENTRY( 3 ),
126 DBORDER_ENTRY( 10 ),
127 DBORDER_ENTRY( 2 ),
128 DBORDER_ENTRY( 6 ),
129 DBORDER_ENTRY( 5 )
132 sal_Bool lcl_frmitems_parseXMLBorder( const OUString& rValue,
133 const SvXMLUnitConverter& rUnitConverter,
134 sal_Bool& rHasStyle, sal_uInt16& rStyle,
135 sal_Bool& rHasWidth, sal_uInt16& rWidth,
136 sal_uInt16& rNamedWidth,
137 sal_Bool& rHasColor, Color& rColor )
139 OUString aToken;
140 SvXMLTokenEnumerator aTokens( rValue );
142 rHasStyle = sal_False;
143 rHasWidth = sal_False;
144 rHasColor = sal_False;
146 rStyle = USHRT_MAX;
147 rWidth = 0;
148 rNamedWidth = USHRT_MAX;
150 sal_Int32 nTemp;
151 while( aTokens.getNextToken( aToken ) && aToken.getLength() != 0 )
153 if( !rHasWidth &&
154 rUnitConverter.convertEnum( rNamedWidth, aToken,
155 psXML_NamedBorderWidths ) )
157 rHasWidth = sal_True;
159 else if( !rHasStyle &&
160 rUnitConverter.convertEnum( rStyle, aToken,
161 psXML_BorderStyles ) )
163 rHasStyle = sal_True;
165 else if( !rHasColor && rUnitConverter.convertColor( rColor, aToken ) )
167 rHasColor = sal_True;
169 else if( !rHasWidth &&
170 rUnitConverter.convertMeasure( nTemp, aToken, 0, USHRT_MAX ) )
172 rWidth = (sal_uInt16)nTemp;
173 rHasWidth = sal_True;
175 else
177 // missformed
178 return sal_False;
182 return rHasStyle || rHasWidth || rHasColor;
185 void lcl_frmitems_setXMLBorderWidth( SvxBorderLine& rLine,
186 sal_uInt16 nOutWidth, sal_uInt16 nInWidth,
187 sal_uInt16 nDistance )
189 rLine.SetOutWidth( nOutWidth );
190 rLine.SetInWidth( nInWidth );
191 rLine.SetDistance( nDistance );
194 void lcl_frmitems_setXMLBorderWidth( SvxBorderLine& rLine,
195 sal_uInt16 nWidth, sal_Bool bDouble )
197 const sal_uInt16 *aWidths;
198 sal_uInt16 nSize;
199 if( !bDouble )
201 aWidths = aSBorderWidths;
202 nSize = sizeof( aSBorderWidths );
204 else
206 aWidths = aDBorderWidths;
207 nSize = sizeof( aDBorderWidths );
210 sal_uInt16 i = (nSize / sizeof(sal_uInt16)) - 4;
211 while( i>0 &&
212 nWidth <= ((aWidths[i] + aWidths[i-4]) / 2) )
214 DBG_ASSERT( aWidths[i] >= aWidths[i-4], "line widths are unordered!" );
215 i -= 4;
218 rLine.SetOutWidth( aWidths[i+1] );
219 rLine.SetInWidth( aWidths[i+2] );
220 rLine.SetDistance( aWidths[i+3] );
223 sal_Bool lcl_frmitems_setXMLBorder( SvxBorderLine*& rpLine,
224 sal_Bool bHasStyle, sal_uInt16 nStyle,
225 sal_Bool bHasWidth, sal_uInt16 nWidth,
226 sal_uInt16 nNamedWidth,
227 sal_Bool bHasColor, const Color& rColor )
229 // first of all, delete an empty line
230 if( (bHasStyle && SVX_XML_BORDER_STYLE_NONE == nStyle) ||
231 (bHasWidth && USHRT_MAX == nNamedWidth && 0 == nWidth) )
233 sal_Bool bRet = 0 != rpLine;
234 if( rpLine )
236 delete rpLine;
237 rpLine = 0;
240 return bRet;
243 // if there is no line and no style and no with, there will never be a line
244 if( !rpLine && !(bHasStyle && bHasWidth) )
245 return sal_False;
247 // We now do know that there will be a line
248 if( !rpLine )
249 rpLine = new SvxBorderLine;
252 if( ( bHasWidth &&
253 (USHRT_MAX != nNamedWidth || (nWidth != rpLine->GetOutWidth() +
254 rpLine->GetInWidth() +
255 rpLine->GetDistance()) ) ) ||
256 ( bHasStyle &&
257 ((SVX_XML_BORDER_STYLE_SOLID == nStyle && rpLine->GetDistance()) ||
258 (SVX_XML_BORDER_STYLE_DOUBLE == nStyle && !rpLine->GetDistance())) ))
260 sal_Bool bDouble = (bHasWidth && SVX_XML_BORDER_STYLE_DOUBLE == nStyle ) ||
261 rpLine->GetDistance();
263 // The width has to be changed
264 if( bHasWidth && USHRT_MAX != nNamedWidth )
266 const sal_uInt16 *aWidths = bDouble ? aDBorderWidths :aSBorderWidths;
268 sal_uInt16 nNWidth = nNamedWidth * 4;
269 rpLine->SetOutWidth( aWidths[nNWidth+1] );
270 rpLine->SetInWidth( aWidths[nNWidth+2] );
271 rpLine->SetDistance( aWidths[nNWidth+3] );
274 else
276 if( !bHasWidth )
277 nWidth = rpLine->GetInWidth() + rpLine->GetDistance() +
278 rpLine->GetOutWidth();
280 lcl_frmitems_setXMLBorderWidth( *rpLine, nWidth, bDouble );
284 // set color
285 if( bHasColor )
286 rpLine->SetColor( rColor );
288 return sal_True;
291 void lcl_frmitems_setXMLBorder( SvxBorderLine*& rpLine,
292 sal_uInt16 nWidth, sal_uInt16 nOutWidth,
293 sal_uInt16 nInWidth, sal_uInt16 nDistance )
295 if( !rpLine )
296 rpLine = new SvxBorderLine;
298 if( nWidth > 0 )
299 lcl_frmitems_setXMLBorderWidth( *rpLine, nWidth, sal_True );
300 else
301 lcl_frmitems_setXMLBorderWidth( *rpLine, nOutWidth, nInWidth,
302 nDistance );
305 const struct SvXMLEnumMapEntry psXML_BrushRepeat[] =
307 { XML_BACKGROUND_REPEAT, GPOS_TILED },
308 { XML_BACKGROUND_NO_REPEAT, GPOS_MM },
309 { XML_BACKGROUND_STRETCH, GPOS_AREA },
310 { XML_TOKEN_INVALID, 0 }
313 const struct SvXMLEnumMapEntry psXML_BrushHoriPos[] =
315 { XML_LEFT, GPOS_LM },
316 { XML_RIGHT, GPOS_RM },
317 { XML_TOKEN_INVALID, 0 }
320 const struct SvXMLEnumMapEntry psXML_BrushVertPos[] =
322 { XML_TOP, GPOS_MT },
323 { XML_BOTTOM, GPOS_MB },
324 { XML_TOKEN_INVALID, 0 }
327 void lcl_frmitems_MergeXMLHoriPos( SvxGraphicPosition& ePos,
328 SvxGraphicPosition eHori )
330 DBG_ASSERT( GPOS_LM==eHori || GPOS_MM==eHori || GPOS_RM==eHori,
331 "lcl_frmitems_MergeXMLHoriPos: vertical pos must be middle" );
333 switch( ePos )
335 case GPOS_LT:
336 case GPOS_MT:
337 case GPOS_RT:
338 ePos = GPOS_LM==eHori ? GPOS_LT : (GPOS_MM==eHori ? GPOS_MT : GPOS_RT);
339 break;
341 case GPOS_LM:
342 case GPOS_MM:
343 case GPOS_RM:
344 ePos = eHori;
345 break;
347 case GPOS_LB:
348 case GPOS_MB:
349 case GPOS_RB:
350 ePos = GPOS_LM==eHori ? GPOS_LB : (GPOS_MM==eHori ? GPOS_MB : GPOS_RB);
351 break;
352 default:
357 void lcl_frmitems_MergeXMLVertPos( SvxGraphicPosition& ePos,
358 SvxGraphicPosition eVert )
360 DBG_ASSERT( GPOS_MT==eVert || GPOS_MM==eVert || GPOS_MB==eVert,
361 "lcl_frmitems_MergeXMLVertPos: horizontal pos must be middle" );
363 switch( ePos )
365 case GPOS_LT:
366 case GPOS_LM:
367 case GPOS_LB:
368 ePos = GPOS_MT==eVert ? GPOS_LT : (GPOS_MM==eVert ? GPOS_LM : GPOS_LB);
369 ePos = eVert;
370 break;
372 case GPOS_MT:
373 case GPOS_MM:
374 case GPOS_MB:
375 ePos = eVert;
376 break;
378 case GPOS_RT:
379 case GPOS_RM:
380 case GPOS_RB:
381 ePos = GPOS_MT==eVert ? GPOS_RT : (GPOS_MM==eVert ? GPOS_RM : GPOS_RB);
382 break;
383 default:
389 const struct SvXMLEnumMapEntry psXML_BreakType[] =
391 { XML_AUTO, 0 },
392 { XML_COLUMN, 1 },
393 { XML_PAGE, 2 },
394 { XML_EVEN_PAGE, 2 },
395 { XML_ODD_PAGE, 2 },
396 { XML_TOKEN_INVALID, 0}
399 const struct SvXMLEnumMapEntry aXMLTableAlignMap[] =
401 { XML_LEFT, text::HoriOrientation::LEFT },
402 { XML_LEFT, text::HoriOrientation::LEFT_AND_WIDTH },
403 { XML_CENTER, text::HoriOrientation::CENTER },
404 { XML_RIGHT, text::HoriOrientation::RIGHT },
405 { XML_MARGINS, text::HoriOrientation::FULL },
406 { XML_MARGINS, text::HoriOrientation::NONE },
407 { XML_TOKEN_INVALID, 0 }
410 const struct SvXMLEnumMapEntry aXMLTableVAlignMap[] =
412 { XML_TOP, text::VertOrientation::TOP },
413 { XML_MIDDLE, text::VertOrientation::CENTER },
414 { XML_BOTTOM, text::VertOrientation::BOTTOM },
415 { XML_TOKEN_INVALID, 0 }
418 const struct SvXMLEnumMapEntry aXML_KeepTogetherType[] =
420 { XML_ALWAYS, 0 },
421 { XML_AUTO, 1 },
422 { XML_TOKEN_INVALID, 0}