1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xmlithlp.cxx,v $
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"
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"
49 #include "fmtlsplt.hxx"
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] =
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
)
140 SvXMLTokenEnumerator
aTokens( rValue
);
142 rHasStyle
= sal_False
;
143 rHasWidth
= sal_False
;
144 rHasColor
= sal_False
;
148 rNamedWidth
= USHRT_MAX
;
151 while( aTokens
.getNextToken( aToken
) && aToken
.getLength() != 0 )
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
;
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
;
201 aWidths
= aSBorderWidths
;
202 nSize
= sizeof( aSBorderWidths
);
206 aWidths
= aDBorderWidths
;
207 nSize
= sizeof( aDBorderWidths
);
210 sal_uInt16 i
= (nSize
/ sizeof(sal_uInt16
)) - 4;
212 nWidth
<= ((aWidths
[i
] + aWidths
[i
-4]) / 2) )
214 DBG_ASSERT( aWidths
[i
] >= aWidths
[i
-4], "line widths are unordered!" );
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
;
243 // if there is no line and no style and no with, there will never be a line
244 if( !rpLine
&& !(bHasStyle
&& bHasWidth
) )
247 // We now do know that there will be a line
249 rpLine
= new SvxBorderLine
;
253 (USHRT_MAX
!= nNamedWidth
|| (nWidth
!= rpLine
->GetOutWidth() +
254 rpLine
->GetInWidth() +
255 rpLine
->GetDistance()) ) ) ||
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] );
277 nWidth
= rpLine
->GetInWidth() + rpLine
->GetDistance() +
278 rpLine
->GetOutWidth();
280 lcl_frmitems_setXMLBorderWidth( *rpLine
, nWidth
, bDouble
);
286 rpLine
->SetColor( rColor
);
291 void lcl_frmitems_setXMLBorder( SvxBorderLine
*& rpLine
,
292 sal_uInt16 nWidth
, sal_uInt16 nOutWidth
,
293 sal_uInt16 nInWidth
, sal_uInt16 nDistance
)
296 rpLine
= new SvxBorderLine
;
299 lcl_frmitems_setXMLBorderWidth( *rpLine
, nWidth
, sal_True
);
301 lcl_frmitems_setXMLBorderWidth( *rpLine
, nOutWidth
, nInWidth
,
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" );
338 ePos
= GPOS_LM
==eHori
? GPOS_LT
: (GPOS_MM
==eHori
? GPOS_MT
: GPOS_RT
);
350 ePos
= GPOS_LM
==eHori
? GPOS_LB
: (GPOS_MM
==eHori
? GPOS_MB
: GPOS_RB
);
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" );
368 ePos
= GPOS_MT
==eVert
? GPOS_LT
: (GPOS_MM
==eVert
? GPOS_LM
: GPOS_LB
);
381 ePos
= GPOS_MT
==eVert
? GPOS_RT
: (GPOS_MM
==eVert
? GPOS_RM
: GPOS_RB
);
389 const struct SvXMLEnumMapEntry psXML_BreakType
[] =
394 { XML_EVEN_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
[] =
422 { XML_TOKEN_INVALID
, 0}