Update ooo320-m1
[ooovba.git] / xmloff / source / style / bordrhdl.cxx
blob86ec25c5b5f3ea8526b56933a4a94aca9181369c
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: bordrhdl.cxx,v $
10 * $Revision: 1.11 $
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>
43 #endif
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
106 // finished copy
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[] =
168 DBORDER_ENTRY( 0 ),
169 DBORDER_ENTRY( 7 ),
170 DBORDER_ENTRY( 1 ),
171 DBORDER_ENTRY( 8 ),
172 DBORDER_ENTRY( 4 ),
173 DBORDER_ENTRY( 9 ),
174 DBORDER_ENTRY( 3 ),
175 DBORDER_ENTRY( 10 ),
176 DBORDER_ENTRY( 2 ),
177 DBORDER_ENTRY( 6 ),
178 DBORDER_ENTRY( 5 )
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;
186 sal_uInt16 nSize;
187 if( !bDouble )
189 aWidths = aSBorderWidths;
190 nSize = sizeof( aSBorderWidths );
192 else
194 aWidths = aDBorderWidths;
195 nSize = sizeof( aDBorderWidths );
198 sal_uInt16 i = (nSize / sizeof(sal_uInt16)) - 4;
199 while( i>0 &&
200 nWidth <= ((aWidths[i] + aWidths[i-4]) / 2) )
202 i -= 4;
205 rBorderLine.OuterLineWidth = aWidths[i+1];
206 rBorderLine.InnerLineWidth = aWidths[i+2];
207 rBorderLine.LineDistance = aWidths[i+3];
208 #else
209 if( bDouble )
211 const sal_uInt16 *aWidths = aDBorderWidths;
212 sal_uInt16 nSize = sizeof( aDBorderWidths );
213 sal_uInt16 i = (nSize / sizeof(sal_uInt16)) - 4;
214 while( i>0 &&
215 nWidth <= ((aWidths[i] + aWidths[i-4]) / 2) )
217 i -= 4;
220 rBorderLine.OuterLineWidth = aWidths[i+1];
221 rBorderLine.InnerLineWidth = aWidths[i+2];
222 rBorderLine.LineDistance = aWidths[i+3];
224 else
226 rBorderLine.OuterLineWidth = 0 == nWidth ? DEF_LINE_WIDTH_0 : nWidth;
227 rBorderLine.InnerLineWidth = 0;
228 rBorderLine.LineDistance = 0;
231 #endif
235 ///////////////////////////////////////////////////////////////////////////////
237 // class XMLEscapementPropHdl
240 XMLBorderWidthHdl::~XMLBorderWidthHdl()
242 // nothing to do
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;
251 OUString aToken;
252 if( !aTokenEnum.getNextToken( aToken ) )
253 return sal_False;
255 if( !rUnitConverter.convertMeasure( nInWidth, aToken, 0, 500 ) )
256 return sal_False;
258 if( !aTokenEnum.getNextToken( aToken ) )
259 return sal_False;
261 if( !rUnitConverter.convertMeasure( nDistance, aToken, 0, 500 ) )
262 return sal_False;
264 if( !aTokenEnum.getNextToken( aToken ) )
265 return sal_False;
267 if( !rUnitConverter.convertMeasure( nOutWidth, aToken, 0, 500 ) )
268 return sal_False;
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 )
277 break;
280 sal_uInt16 nWidth = i < nSize ? 0 : nOutWidth + nInWidth + nDistance;
281 #endif
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;
292 return sal_True;
295 sal_Bool XMLBorderWidthHdl::exportXML( OUString& rStrExpValue, const uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const
297 OUStringBuffer aOut;
299 table::BorderLine aBorderLine;
300 if(!(rValue >>= aBorderLine))
301 return sal_False;
303 if( aBorderLine.LineDistance == 0 && aBorderLine.InnerLineWidth == 0)
304 return sal_False;
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();
313 return sal_True;
316 ///////////////////////////////////////////////////////////////////////////////
318 // class XMLEscapementHeightPropHdl
321 XMLBorderHdl::~XMLBorderHdl()
323 // nothing to do
326 sal_Bool XMLBorderHdl::importXML( const OUString& rStrImpValue, uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const
328 OUString aToken;
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;
338 Color aColor;
340 sal_Int32 nTemp;
341 while( aTokens.getNextToken( aToken ) && aToken.getLength() != 0 )
343 if( !bHasWidth &&
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,
361 USHRT_MAX ) )
363 nWidth = (sal_uInt16)nTemp;
364 bHasWidth = sal_True;
366 else
368 // missformed
369 return sal_False;
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) )
376 return sal_False;
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;
396 else if( bHasWidth )
398 if( USHRT_MAX != nNamedWidth )
400 const sal_uInt16 *aWidths = bDouble ? aDBorderWidths
401 : aSBorderWidths;
402 sal_uInt16 nNWidth = nNamedWidth * 4;
403 aBorderLine.OuterLineWidth = aWidths[nNWidth+1];
404 aBorderLine.InnerLineWidth = aWidths[nNWidth+2];
405 aBorderLine.LineDistance = aWidths[nNWidth+3];
407 else
409 lcl_frmitems_setXMLBorderWidth( aBorderLine, nWidth, bDouble );
412 else
414 lcl_frmitems_setXMLBorderWidth( aBorderLine, 0, bDouble );
417 // set color
418 if( bHasColor )
419 aBorderLine.Color = (sal_Int32)aColor.GetRGBColor();
421 rValue <<= aBorderLine;
422 return sal_True;
425 sal_Bool XMLBorderHdl::exportXML( OUString& rStrExpValue, const uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const
427 OUStringBuffer aOut;
429 table::BorderLine aBorderLine;
430 if(!(rValue >>= aBorderLine))
431 return sal_False;
433 sal_Int32 nWidth = aBorderLine.OuterLineWidth;
434 const sal_uInt16 nDistance = aBorderLine.LineDistance;
435 if( 0 != nDistance )
437 nWidth += nDistance;
438 nWidth += aBorderLine.InnerLineWidth;
441 if( nWidth == 0 )
443 aOut.append( GetXMLToken( XML_NONE ) );
445 else
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();
460 return sal_True;