Line data Source code
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 :
21 : #include <bordrhdl.hxx>
22 : #include <sax/tools/converter.hxx>
23 : #include <xmloff/xmltoken.hxx>
24 : #include <xmloff/xmluconv.hxx>
25 : #include <rtl/ustrbuf.hxx>
26 : #include <com/sun/star/uno/Any.hxx>
27 : #include <com/sun/star/table/BorderLine2.hpp>
28 :
29 :
30 : using namespace ::com::sun::star;
31 : using namespace ::xmloff::token;
32 :
33 : const sal_uInt16 API_LINE_SOLID = 0;
34 : const sal_uInt16 API_LINE_DOTTED = 1;
35 : const sal_uInt16 API_LINE_DASHED = 2;
36 : const sal_uInt16 API_LINE_DOUBLE = 3;
37 : const sal_uInt16 API_LINE_THINTHICK_SMALLGAP = 4;
38 : const sal_uInt16 API_LINE_THINTHICK_MEDIUMGAP = 5;
39 : const sal_uInt16 API_LINE_THINTHICK_LARGEGAP = 6;
40 : const sal_uInt16 API_LINE_THICKTHIN_SMALLGAP = 7;
41 : const sal_uInt16 API_LINE_THICKTHIN_MEDIUMGAP = 8;
42 : const sal_uInt16 API_LINE_THICKTHIN_LARGEGAP = 9;
43 : const sal_uInt16 API_LINE_EMBOSSED = 10;
44 : const sal_uInt16 API_LINE_ENGRAVED = 11;
45 : const sal_uInt16 API_LINE_OUTSET = 12;
46 : const sal_uInt16 API_LINE_INSET = 13;
47 : const sal_uInt16 API_LINE_NONE = USHRT_MAX;
48 :
49 : #define DEF_LINE_WIDTH_0 1
50 : #define DEF_LINE_WIDTH_1 35
51 : #define DEF_LINE_WIDTH_2 88
52 :
53 : #define SVX_XML_BORDER_WIDTH_THIN 0
54 : #define SVX_XML_BORDER_WIDTH_MIDDLE 1
55 : #define SVX_XML_BORDER_WIDTH_THICK 2
56 :
57 : SvXMLEnumMapEntry pXML_BorderStyles[] =
58 : {
59 : { XML_NONE, API_LINE_NONE },
60 : { XML_HIDDEN, API_LINE_NONE },
61 : { XML_SOLID, API_LINE_SOLID },
62 : { XML_DOUBLE, API_LINE_DOUBLE },
63 : { XML_DOTTED, API_LINE_DOTTED },
64 : { XML_DASHED, API_LINE_DASHED },
65 : { XML_GROOVE, API_LINE_ENGRAVED },
66 : { XML_RIDGE, API_LINE_EMBOSSED },
67 : { XML_INSET, API_LINE_INSET },
68 : { XML_OUTSET, API_LINE_OUTSET },
69 : { XML_TOKEN_INVALID, 0 }
70 : };
71 :
72 : SvXMLEnumMapEntry pXML_NamedBorderWidths[] =
73 : {
74 : { XML_THIN, SVX_XML_BORDER_WIDTH_THIN },
75 : { XML_MIDDLE, SVX_XML_BORDER_WIDTH_MIDDLE },
76 : { XML_THICK, SVX_XML_BORDER_WIDTH_THICK },
77 : { XML_TOKEN_INVALID, 0 }
78 : };
79 : // mapping tables to map external xml input to intarnal box line widths
80 :
81 :
82 : static sal_uInt16 const aBorderWidths[] =
83 : {
84 : DEF_LINE_WIDTH_0,
85 : DEF_LINE_WIDTH_1,
86 : DEF_LINE_WIDTH_2
87 : };
88 :
89 399 : static void lcl_frmitems_setXMLBorderStyle( table::BorderLine2 & rBorderLine, sal_uInt16 nStyle )
90 : {
91 399 : sal_Int16 eStyle = -1; // None
92 399 : if ( nStyle != API_LINE_NONE )
93 399 : eStyle = sal_Int16( nStyle );
94 :
95 399 : rBorderLine.LineStyle = eStyle;
96 399 : }
97 :
98 :
99 : ///////////////////////////////////////////////////////////////////////////////
100 : //
101 : // class XMLEscapementPropHdl
102 : //
103 :
104 5208 : XMLBorderWidthHdl::~XMLBorderWidthHdl()
105 : {
106 : // nothing to do
107 5208 : }
108 :
109 13 : sal_Bool XMLBorderWidthHdl::importXML( const OUString& rStrImpValue, uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const
110 : {
111 13 : SvXMLTokenEnumerator aTokenEnum( rStrImpValue );
112 :
113 : sal_Int32 nInWidth, nDistance, nOutWidth;
114 :
115 13 : OUString aToken;
116 13 : if( !aTokenEnum.getNextToken( aToken ) )
117 0 : return sal_False;
118 :
119 13 : if (!rUnitConverter.convertMeasureToCore( nInWidth, aToken, 0, 500 ))
120 0 : return sal_False;
121 :
122 13 : if( !aTokenEnum.getNextToken( aToken ) )
123 0 : return sal_False;
124 :
125 13 : if (!rUnitConverter.convertMeasureToCore( nDistance, aToken, 0, 500 ))
126 0 : return sal_False;
127 :
128 13 : if( !aTokenEnum.getNextToken( aToken ) )
129 0 : return sal_False;
130 :
131 13 : if (!rUnitConverter.convertMeasureToCore( nOutWidth, aToken, 0, 500 ))
132 0 : return sal_False;
133 :
134 13 : table::BorderLine2 aBorderLine;
135 13 : if(!(rValue >>= aBorderLine))
136 13 : aBorderLine.Color = 0;
137 :
138 13 : aBorderLine.InnerLineWidth = sal::static_int_cast< sal_Int16 >(nInWidth);
139 13 : aBorderLine.OuterLineWidth = sal::static_int_cast< sal_Int16 >(nOutWidth);
140 13 : aBorderLine.LineDistance = sal::static_int_cast< sal_Int16 >(nDistance);
141 :
142 13 : rValue <<= aBorderLine;
143 13 : return sal_True;
144 : }
145 :
146 24 : sal_Bool XMLBorderWidthHdl::exportXML( OUString& rStrExpValue, const uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const
147 : {
148 24 : OUStringBuffer aOut;
149 :
150 24 : table::BorderLine2 aBorderLine;
151 24 : if(!(rValue >>= aBorderLine))
152 0 : return sal_False;
153 :
154 24 : bool bDouble = false;
155 24 : switch ( aBorderLine.LineStyle )
156 : {
157 : case API_LINE_DOUBLE:
158 : case API_LINE_THINTHICK_SMALLGAP:
159 : case API_LINE_THINTHICK_MEDIUMGAP:
160 : case API_LINE_THINTHICK_LARGEGAP:
161 : case API_LINE_THICKTHIN_SMALLGAP:
162 : case API_LINE_THICKTHIN_MEDIUMGAP:
163 : case API_LINE_THICKTHIN_LARGEGAP:
164 0 : bDouble = true;
165 0 : break;
166 : default:
167 24 : break;
168 : }
169 :
170 24 : if( ( aBorderLine.LineDistance == 0 && aBorderLine.InnerLineWidth == 0 ) || !bDouble )
171 24 : return sal_False;
172 :
173 0 : rUnitConverter.convertMeasureToXML( aOut, aBorderLine.InnerLineWidth );
174 0 : aOut.append( sal_Unicode( ' ' ) );
175 0 : rUnitConverter.convertMeasureToXML( aOut, aBorderLine.LineDistance );
176 0 : aOut.append( sal_Unicode( ' ' ) );
177 0 : rUnitConverter.convertMeasureToXML( aOut, aBorderLine.OuterLineWidth );
178 :
179 0 : rStrExpValue = aOut.makeStringAndClear();
180 0 : return sal_True;
181 : }
182 :
183 : ///////////////////////////////////////////////////////////////////////////////
184 : //
185 : // class XMLEscapementHeightPropHdl
186 : //
187 :
188 5208 : XMLBorderHdl::~XMLBorderHdl()
189 : {
190 : // nothing to do
191 5208 : }
192 :
193 558 : sal_Bool XMLBorderHdl::importXML( const OUString& rStrImpValue, uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const
194 : {
195 558 : OUString aToken;
196 558 : SvXMLTokenEnumerator aTokens( rStrImpValue );
197 :
198 558 : sal_Bool bHasStyle = sal_False;
199 558 : sal_Bool bHasWidth = sal_False;
200 558 : sal_Bool bHasColor = sal_False;
201 :
202 558 : sal_uInt16 nStyle = USHRT_MAX;
203 558 : sal_uInt16 nWidth = 0;
204 558 : sal_uInt16 nNamedWidth = USHRT_MAX;
205 558 : sal_Int32 nColor = 0;
206 :
207 : sal_Int32 nTemp;
208 2472 : while( aTokens.getNextToken( aToken ) && !aToken.isEmpty() )
209 : {
210 1914 : if( !bHasWidth &&
211 : rUnitConverter.convertEnum( nNamedWidth, aToken,
212 558 : pXML_NamedBorderWidths ) )
213 : {
214 0 : bHasWidth = sal_True;
215 : }
216 2313 : else if( !bHasStyle &&
217 : rUnitConverter.convertEnum( nStyle, aToken,
218 957 : pXML_BorderStyles ) )
219 : {
220 558 : bHasStyle = sal_True;
221 : }
222 798 : else if (!bHasColor && ::sax::Converter::convertColor(nColor, aToken))
223 : {
224 399 : bHasColor = sal_True;
225 : }
226 798 : else if( !bHasWidth &&
227 : rUnitConverter.convertMeasureToCore( nTemp, aToken, 0,
228 399 : USHRT_MAX ) )
229 : {
230 399 : nWidth = (sal_uInt16)nTemp;
231 399 : bHasWidth = sal_True;
232 : }
233 : else
234 : {
235 : // missformed
236 0 : return sal_False;
237 : }
238 : }
239 :
240 : // if there is no style or a different style than none but no width,
241 : // then the declaration is not valid.
242 558 : if( !bHasStyle || (API_LINE_NONE != nStyle && !bHasWidth) )
243 0 : return sal_False;
244 :
245 558 : table::BorderLine2 aBorderLine;
246 558 : if(!(rValue >>= aBorderLine))
247 : {
248 558 : aBorderLine.Color = 0;
249 558 : aBorderLine.InnerLineWidth = 0;
250 558 : aBorderLine.OuterLineWidth = 0;
251 558 : aBorderLine.LineDistance = 0;
252 558 : aBorderLine.LineWidth = 0;
253 : }
254 :
255 : // first of all, delete an empty line
256 558 : if( (bHasStyle && API_LINE_NONE == nStyle) ||
257 399 : (bHasWidth && USHRT_MAX == nNamedWidth && 0 == nWidth) )
258 : {
259 159 : aBorderLine.InnerLineWidth = 0;
260 159 : aBorderLine.OuterLineWidth = 0;
261 159 : aBorderLine.LineDistance = 0;
262 159 : aBorderLine.LineWidth = 0;
263 : }
264 399 : else if( bHasWidth )
265 : {
266 399 : if( USHRT_MAX != nNamedWidth )
267 : {
268 0 : aBorderLine.LineWidth = aBorderWidths[nNamedWidth];
269 : }
270 : else
271 : {
272 399 : aBorderLine.LineWidth = nWidth;
273 399 : lcl_frmitems_setXMLBorderStyle( aBorderLine, nStyle );
274 : }
275 : }
276 : else
277 : {
278 0 : aBorderLine.LineWidth = 0;
279 0 : lcl_frmitems_setXMLBorderStyle( aBorderLine, nStyle );
280 : }
281 :
282 : // set color
283 558 : if( bHasColor )
284 : {
285 399 : aBorderLine.Color = nColor;
286 : }
287 :
288 558 : rValue <<= aBorderLine;
289 558 : return sal_True;
290 : }
291 :
292 24 : sal_Bool XMLBorderHdl::exportXML( OUString& rStrExpValue, const uno::Any& rValue, const SvXMLUnitConverter& /* rUnitConverter */ ) const
293 : {
294 24 : OUStringBuffer aOut;
295 :
296 24 : table::BorderLine2 aBorderLine;
297 24 : if(!(rValue >>= aBorderLine))
298 0 : return sal_False;
299 :
300 24 : sal_Int32 nWidth = aBorderLine.LineWidth;
301 :
302 24 : if( nWidth == 0 )
303 : {
304 3 : aOut.append( GetXMLToken( XML_NONE ) );
305 : }
306 : else
307 : {
308 : ::sax::Converter::convertMeasure( aOut, nWidth,
309 21 : util::MeasureUnit::MM_100TH, util::MeasureUnit::POINT);
310 :
311 21 : aOut.append( sal_Unicode( ' ' ) );
312 :
313 21 : XMLTokenEnum eStyleToken = XML_SOLID;
314 21 : switch ( aBorderLine.LineStyle )
315 : {
316 : case API_LINE_DASHED:
317 0 : eStyleToken = XML_DASHED;
318 0 : break;
319 : case API_LINE_DOTTED:
320 0 : eStyleToken = XML_DOTTED;
321 0 : break;
322 : case API_LINE_DOUBLE:
323 : case API_LINE_THINTHICK_SMALLGAP:
324 : case API_LINE_THINTHICK_MEDIUMGAP:
325 : case API_LINE_THINTHICK_LARGEGAP:
326 : case API_LINE_THICKTHIN_SMALLGAP:
327 : case API_LINE_THICKTHIN_MEDIUMGAP:
328 : case API_LINE_THICKTHIN_LARGEGAP:
329 0 : eStyleToken = XML_DOUBLE;
330 0 : break;
331 : case API_LINE_EMBOSSED:
332 0 : eStyleToken = XML_RIDGE;
333 0 : break;
334 : case API_LINE_ENGRAVED:
335 0 : eStyleToken = XML_GROOVE;
336 0 : break;
337 : case API_LINE_OUTSET:
338 0 : eStyleToken = XML_OUTSET;
339 0 : break;
340 : case API_LINE_INSET:
341 0 : eStyleToken = XML_INSET;
342 0 : break;
343 : case API_LINE_SOLID:
344 : default:
345 21 : break;
346 : }
347 21 : aOut.append( GetXMLToken( eStyleToken ) );
348 :
349 21 : aOut.append( sal_Unicode( ' ' ) );
350 :
351 21 : ::sax::Converter::convertColor( aOut, aBorderLine.Color );
352 : }
353 :
354 24 : rStrExpValue = aOut.makeStringAndClear();
355 :
356 24 : return sal_True;
357 : }
358 :
359 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|