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: bordrhdl.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_xmloff.hxx"
35 #include <bordrhdl.hxx>
36 #include <xmloff/xmltoken.hxx>
37 #include <xmloff/xmluconv.hxx>
38 #include <rtl/ustrbuf.hxx>
39 #include <com/sun/star/uno/Any.hxx>
41 #ifndef _XMLOFF_XMLEMENT_HXX
42 #include <xmloff/xmlelement.hxx>
44 #include <com/sun/star/table/BorderLine.hpp>
46 using ::rtl::OUString
;
47 using ::rtl::OUStringBuffer
;
49 using namespace ::com::sun::star
;
50 using namespace ::xmloff::token
;
52 // copied from svx/boxitem.hxx
53 #define DEF_LINE_WIDTH_0 1
54 #define DEF_LINE_WIDTH_1 35
55 #define DEF_LINE_WIDTH_2 88
56 #define DEF_LINE_WIDTH_3 141
57 #define DEF_LINE_WIDTH_4 176
59 #define DEF_MAX_LINE_WIDHT DEF_LINE_WIDTH_4
60 #define DEF_MAX_LINE_DIST DEF_LINE_WIDTH_2
62 #define DEF_DOUBLE_LINE0_OUT DEF_LINE_WIDTH_0
63 #define DEF_DOUBLE_LINE0_IN DEF_LINE_WIDTH_0
64 #define DEF_DOUBLE_LINE0_DIST DEF_LINE_WIDTH_1
66 #define DEF_DOUBLE_LINE1_OUT DEF_LINE_WIDTH_1
67 #define DEF_DOUBLE_LINE1_IN DEF_LINE_WIDTH_1
68 #define DEF_DOUBLE_LINE1_DIST DEF_LINE_WIDTH_1
70 #define DEF_DOUBLE_LINE2_OUT DEF_LINE_WIDTH_2
71 #define DEF_DOUBLE_LINE2_IN DEF_LINE_WIDTH_2
72 #define DEF_DOUBLE_LINE2_DIST DEF_LINE_WIDTH_2
74 #define DEF_DOUBLE_LINE3_OUT DEF_LINE_WIDTH_2
75 #define DEF_DOUBLE_LINE3_IN DEF_LINE_WIDTH_1
76 #define DEF_DOUBLE_LINE3_DIST DEF_LINE_WIDTH_2
78 #define DEF_DOUBLE_LINE4_OUT DEF_LINE_WIDTH_1
79 #define DEF_DOUBLE_LINE4_IN DEF_LINE_WIDTH_2
80 #define DEF_DOUBLE_LINE4_DIST DEF_LINE_WIDTH_1
82 #define DEF_DOUBLE_LINE5_OUT DEF_LINE_WIDTH_3
83 #define DEF_DOUBLE_LINE5_IN DEF_LINE_WIDTH_2
84 #define DEF_DOUBLE_LINE5_DIST DEF_LINE_WIDTH_2
86 #define DEF_DOUBLE_LINE6_OUT DEF_LINE_WIDTH_2
87 #define DEF_DOUBLE_LINE6_IN DEF_LINE_WIDTH_3
88 #define DEF_DOUBLE_LINE6_DIST DEF_LINE_WIDTH_2
90 #define DEF_DOUBLE_LINE7_OUT DEF_LINE_WIDTH_0
91 #define DEF_DOUBLE_LINE7_IN DEF_LINE_WIDTH_0
92 #define DEF_DOUBLE_LINE7_DIST DEF_LINE_WIDTH_2
94 #define DEF_DOUBLE_LINE8_OUT DEF_LINE_WIDTH_1
95 #define DEF_DOUBLE_LINE8_IN DEF_LINE_WIDTH_0
96 #define DEF_DOUBLE_LINE8_DIST DEF_LINE_WIDTH_2
98 #define DEF_DOUBLE_LINE9_OUT DEF_LINE_WIDTH_2
99 #define DEF_DOUBLE_LINE9_IN DEF_LINE_WIDTH_0
100 #define DEF_DOUBLE_LINE9_DIST DEF_LINE_WIDTH_2
102 #define DEF_DOUBLE_LINE10_OUT DEF_LINE_WIDTH_3
103 #define DEF_DOUBLE_LINE10_IN DEF_LINE_WIDTH_0
104 #define DEF_DOUBLE_LINE10_DIST DEF_LINE_WIDTH_2
108 #define SVX_XML_BORDER_STYLE_NONE 0
109 #define SVX_XML_BORDER_STYLE_SOLID 1
110 #define SVX_XML_BORDER_STYLE_DOUBLE 2
112 #define SVX_XML_BORDER_WIDTH_THIN 0
113 #define SVX_XML_BORDER_WIDTH_MIDDLE 1
114 #define SVX_XML_BORDER_WIDTH_THICK 2
116 SvXMLEnumMapEntry pXML_BorderStyles
[] =
118 { XML_NONE
, SVX_XML_BORDER_STYLE_NONE
},
119 { XML_HIDDEN
, SVX_XML_BORDER_STYLE_NONE
},
120 { XML_SOLID
, SVX_XML_BORDER_STYLE_SOLID
},
121 { XML_DOUBLE
, SVX_XML_BORDER_STYLE_DOUBLE
},
122 { XML_DOTTED
, SVX_XML_BORDER_STYLE_SOLID
},
123 { XML_DASHED
, SVX_XML_BORDER_STYLE_SOLID
},
124 { XML_GROOVE
, SVX_XML_BORDER_STYLE_SOLID
},
125 { XML_RIDGE
, SVX_XML_BORDER_STYLE_SOLID
},
126 { XML_INSET
, SVX_XML_BORDER_STYLE_SOLID
},
127 { XML_OUTSET
, SVX_XML_BORDER_STYLE_SOLID
},
128 { XML_TOKEN_INVALID
, 0 }
131 SvXMLEnumMapEntry pXML_NamedBorderWidths
[] =
133 { XML_THIN
, SVX_XML_BORDER_WIDTH_THIN
},
134 { XML_MIDDLE
, SVX_XML_BORDER_WIDTH_MIDDLE
},
135 { XML_THICK
, SVX_XML_BORDER_WIDTH_THICK
},
136 { XML_TOKEN_INVALID
, 0 }
138 // mapping tables to map external xml input to intarnal box line widths
140 // Ein Eintrag besteht aus vier USHORTs. Der erste ist die Gesamtbreite,
141 // die anderen sind die 3 Einzelbreiten
143 #define SBORDER_ENTRY( n ) \
144 DEF_LINE_WIDTH_##n, DEF_LINE_WIDTH_##n, 0, 0
146 #define DBORDER_ENTRY( n ) \
147 DEF_DOUBLE_LINE##n##_OUT + DEF_DOUBLE_LINE##n##_IN + \
148 DEF_DOUBLE_LINE##n##_DIST, \
149 DEF_DOUBLE_LINE##n##_OUT, \
150 DEF_DOUBLE_LINE##n##_IN, \
151 DEF_DOUBLE_LINE##n##_DIST
153 #define TDBORDER_ENTRY( n ) \
154 DEF_DOUBLE_LINE##n##_OUT, \
155 DEF_DOUBLE_LINE##n##_OUT, \
156 DEF_DOUBLE_LINE##n##_IN, \
157 DEF_DOUBLE_LINE##n##_DIST
160 static sal_uInt16 __READONLY_DATA aSBorderWidths
[] =
162 SBORDER_ENTRY( 0 ), SBORDER_ENTRY( 1 ), SBORDER_ENTRY( 2 ),
163 SBORDER_ENTRY( 3 ), SBORDER_ENTRY( 4 )
166 static sal_uInt16 __READONLY_DATA aDBorderWidths
[] =
181 void lcl_frmitems_setXMLBorderWidth( table::BorderLine
&rBorderLine
,
182 sal_uInt16 nWidth
, sal_Bool bDouble
)
184 #ifdef XML_CHECK_UI_CONTSTRAINS
185 const sal_uInt16
*aWidths
;
189 aWidths
= aSBorderWidths
;
190 nSize
= sizeof( aSBorderWidths
);
194 aWidths
= aDBorderWidths
;
195 nSize
= sizeof( aDBorderWidths
);
198 sal_uInt16 i
= (nSize
/ sizeof(sal_uInt16
)) - 4;
200 nWidth
<= ((aWidths
[i
] + aWidths
[i
-4]) / 2) )
205 rBorderLine
.OuterLineWidth
= aWidths
[i
+1];
206 rBorderLine
.InnerLineWidth
= aWidths
[i
+2];
207 rBorderLine
.LineDistance
= aWidths
[i
+3];
211 const sal_uInt16
*aWidths
= aDBorderWidths
;
212 sal_uInt16 nSize
= sizeof( aDBorderWidths
);
213 sal_uInt16 i
= (nSize
/ sizeof(sal_uInt16
)) - 4;
215 nWidth
<= ((aWidths
[i
] + aWidths
[i
-4]) / 2) )
220 rBorderLine
.OuterLineWidth
= aWidths
[i
+1];
221 rBorderLine
.InnerLineWidth
= aWidths
[i
+2];
222 rBorderLine
.LineDistance
= aWidths
[i
+3];
226 rBorderLine
.OuterLineWidth
= 0 == nWidth
? DEF_LINE_WIDTH_0
: nWidth
;
227 rBorderLine
.InnerLineWidth
= 0;
228 rBorderLine
.LineDistance
= 0;
235 ///////////////////////////////////////////////////////////////////////////////
237 // class XMLEscapementPropHdl
240 XMLBorderWidthHdl::~XMLBorderWidthHdl()
245 sal_Bool
XMLBorderWidthHdl::importXML( const OUString
& rStrImpValue
, uno::Any
& rValue
, const SvXMLUnitConverter
& rUnitConverter
) const
247 SvXMLTokenEnumerator
aTokenEnum( rStrImpValue
);
249 sal_Int32 nInWidth
, nDistance
, nOutWidth
;
252 if( !aTokenEnum
.getNextToken( aToken
) )
255 if( !rUnitConverter
.convertMeasure( nInWidth
, aToken
, 0, 500 ) )
258 if( !aTokenEnum
.getNextToken( aToken
) )
261 if( !rUnitConverter
.convertMeasure( nDistance
, aToken
, 0, 500 ) )
264 if( !aTokenEnum
.getNextToken( aToken
) )
267 if( !rUnitConverter
.convertMeasure( nOutWidth
, aToken
, 0, 500 ) )
270 #ifdef XML_CHECK_UI_CONSTRAINS
271 sal_uInt16 nSize
= sizeof( aDBorderWidths
);
272 for( sal_uInt16 i
=0; i
< nSize
; i
+= 4 )
274 if( aDBorderWidths
[i
+1] == nOutWidth
&&
275 aDBorderWidths
[i
+2] == nInWidth
&&
276 aDBorderWidths
[i
+3] == nDistance
)
280 sal_uInt16 nWidth
= i
< nSize
? 0 : nOutWidth
+ nInWidth
+ nDistance
;
283 table::BorderLine aBorderLine
;
284 if(!(rValue
>>= aBorderLine
))
285 aBorderLine
.Color
= 0;
287 aBorderLine
.InnerLineWidth
= sal::static_int_cast
< sal_Int16
>(nInWidth
);
288 aBorderLine
.OuterLineWidth
= sal::static_int_cast
< sal_Int16
>(nOutWidth
);
289 aBorderLine
.LineDistance
= sal::static_int_cast
< sal_Int16
>(nDistance
);
291 rValue
<<= aBorderLine
;
295 sal_Bool
XMLBorderWidthHdl::exportXML( OUString
& rStrExpValue
, const uno::Any
& rValue
, const SvXMLUnitConverter
& rUnitConverter
) const
299 table::BorderLine aBorderLine
;
300 if(!(rValue
>>= aBorderLine
))
303 if( aBorderLine
.LineDistance
== 0 && aBorderLine
.InnerLineWidth
== 0)
306 rUnitConverter
.convertMeasure( aOut
, aBorderLine
.InnerLineWidth
);
307 aOut
.append( sal_Unicode( ' ' ) );
308 rUnitConverter
.convertMeasure( aOut
, aBorderLine
.LineDistance
);
309 aOut
.append( sal_Unicode( ' ' ) );
310 rUnitConverter
.convertMeasure( aOut
, aBorderLine
.OuterLineWidth
);
312 rStrExpValue
= aOut
.makeStringAndClear();
316 ///////////////////////////////////////////////////////////////////////////////
318 // class XMLEscapementHeightPropHdl
321 XMLBorderHdl::~XMLBorderHdl()
326 sal_Bool
XMLBorderHdl::importXML( const OUString
& rStrImpValue
, uno::Any
& rValue
, const SvXMLUnitConverter
& rUnitConverter
) const
329 SvXMLTokenEnumerator
aTokens( rStrImpValue
);
331 sal_Bool bHasStyle
= sal_False
;
332 sal_Bool bHasWidth
= sal_False
;
333 sal_Bool bHasColor
= sal_False
;
335 sal_uInt16 nStyle
= USHRT_MAX
;
336 sal_uInt16 nWidth
= 0;
337 sal_uInt16 nNamedWidth
= USHRT_MAX
;
341 while( aTokens
.getNextToken( aToken
) && aToken
.getLength() != 0 )
344 rUnitConverter
.convertEnum( nNamedWidth
, aToken
,
345 pXML_NamedBorderWidths
) )
347 bHasWidth
= sal_True
;
349 else if( !bHasStyle
&&
350 rUnitConverter
.convertEnum( nStyle
, aToken
,
351 pXML_BorderStyles
) )
353 bHasStyle
= sal_True
;
355 else if( !bHasColor
&& rUnitConverter
.convertColor( aColor
, aToken
) )
357 bHasColor
= sal_True
;
359 else if( !bHasWidth
&&
360 rUnitConverter
.convertMeasure( nTemp
, aToken
, 0,
363 nWidth
= (sal_uInt16
)nTemp
;
364 bHasWidth
= sal_True
;
373 // if there is no style or a different style than none but no width,
374 // then the declaration is not valid.
375 if( !bHasStyle
|| (SVX_XML_BORDER_STYLE_NONE
!= nStyle
&& !bHasWidth
) )
378 table::BorderLine aBorderLine
;
379 if(!(rValue
>>= aBorderLine
))
381 aBorderLine
.Color
= 0;
382 aBorderLine
.InnerLineWidth
= 0;
383 aBorderLine
.OuterLineWidth
= 0;
384 aBorderLine
.LineDistance
= 0;
387 // first of all, delete an empty line
388 sal_Bool bDouble
= SVX_XML_BORDER_STYLE_DOUBLE
== nStyle
;
389 if( (bHasStyle
&& SVX_XML_BORDER_STYLE_NONE
== nStyle
) ||
390 (bHasWidth
&& USHRT_MAX
== nNamedWidth
&& 0 == nWidth
) )
392 aBorderLine
.InnerLineWidth
= 0;
393 aBorderLine
.OuterLineWidth
= 0;
394 aBorderLine
.LineDistance
= 0;
398 if( USHRT_MAX
!= nNamedWidth
)
400 const sal_uInt16
*aWidths
= bDouble
? aDBorderWidths
402 sal_uInt16 nNWidth
= nNamedWidth
* 4;
403 aBorderLine
.OuterLineWidth
= aWidths
[nNWidth
+1];
404 aBorderLine
.InnerLineWidth
= aWidths
[nNWidth
+2];
405 aBorderLine
.LineDistance
= aWidths
[nNWidth
+3];
409 lcl_frmitems_setXMLBorderWidth( aBorderLine
, nWidth
, bDouble
);
414 lcl_frmitems_setXMLBorderWidth( aBorderLine
, 0, bDouble
);
419 aBorderLine
.Color
= (sal_Int32
)aColor
.GetRGBColor();
421 rValue
<<= aBorderLine
;
425 sal_Bool
XMLBorderHdl::exportXML( OUString
& rStrExpValue
, const uno::Any
& rValue
, const SvXMLUnitConverter
& rUnitConverter
) const
429 table::BorderLine aBorderLine
;
430 if(!(rValue
>>= aBorderLine
))
433 sal_Int32 nWidth
= aBorderLine
.OuterLineWidth
;
434 const sal_uInt16 nDistance
= aBorderLine
.LineDistance
;
438 nWidth
+= aBorderLine
.InnerLineWidth
;
443 aOut
.append( GetXMLToken( XML_NONE
) );
447 rUnitConverter
.convertMeasure( aOut
, nWidth
);
449 aOut
.append( sal_Unicode( ' ' ) );
451 aOut
.append( GetXMLToken((0 == nDistance
) ? XML_SOLID
: XML_DOUBLE
) );
453 aOut
.append( sal_Unicode( ' ' ) );
455 rUnitConverter
.convertColor( aOut
, aBorderLine
.Color
);
458 rStrExpValue
= aOut
.makeStringAndClear();