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