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 155 : static void lcl_frmitems_setXMLBorderStyle( table::BorderLine2 & rBorderLine, sal_uInt16 nStyle )
96 : {
97 155 : sal_Int16 eStyle = -1; // None
98 155 : if ( nStyle != API_LINE_NONE )
99 155 : eStyle = sal_Int16( nStyle );
100 :
101 155 : rBorderLine.LineStyle = eStyle;
102 155 : }
103 :
104 :
105 : ///////////////////////////////////////////////////////////////////////////////
106 : //
107 : // class XMLEscapementPropHdl
108 : //
109 :
110 1320 : XMLBorderWidthHdl::~XMLBorderWidthHdl()
111 : {
112 : // nothing to do
113 1320 : }
114 :
115 12 : sal_Bool XMLBorderWidthHdl::importXML( const OUString& rStrImpValue, uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const
116 : {
117 12 : SvXMLTokenEnumerator aTokenEnum( rStrImpValue );
118 :
119 : sal_Int32 nInWidth, nDistance, nOutWidth;
120 :
121 12 : OUString aToken;
122 12 : if( !aTokenEnum.getNextToken( aToken ) )
123 0 : return sal_False;
124 :
125 12 : if (!rUnitConverter.convertMeasureToCore( nInWidth, aToken, 0, 500 ))
126 0 : return sal_False;
127 :
128 12 : if( !aTokenEnum.getNextToken( aToken ) )
129 0 : return sal_False;
130 :
131 12 : if (!rUnitConverter.convertMeasureToCore( nDistance, aToken, 0, 500 ))
132 0 : return sal_False;
133 :
134 12 : if( !aTokenEnum.getNextToken( aToken ) )
135 0 : return sal_False;
136 :
137 12 : if (!rUnitConverter.convertMeasureToCore( nOutWidth, aToken, 0, 500 ))
138 0 : return sal_False;
139 :
140 12 : table::BorderLine2 aBorderLine;
141 12 : if(!(rValue >>= aBorderLine))
142 12 : aBorderLine.Color = 0;
143 :
144 12 : aBorderLine.InnerLineWidth = sal::static_int_cast< sal_Int16 >(nInWidth);
145 12 : aBorderLine.OuterLineWidth = sal::static_int_cast< sal_Int16 >(nOutWidth);
146 12 : aBorderLine.LineDistance = sal::static_int_cast< sal_Int16 >(nDistance);
147 :
148 12 : rValue <<= aBorderLine;
149 12 : return sal_True;
150 : }
151 :
152 4 : sal_Bool XMLBorderWidthHdl::exportXML( OUString& rStrExpValue, const uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const
153 : {
154 4 : OUStringBuffer aOut;
155 :
156 4 : table::BorderLine2 aBorderLine;
157 4 : if(!(rValue >>= aBorderLine))
158 0 : return sal_False;
159 :
160 4 : bool bDouble = false;
161 4 : 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 4 : break;
174 : }
175 :
176 4 : if( ( aBorderLine.LineDistance == 0 && aBorderLine.InnerLineWidth == 0 ) || !bDouble )
177 4 : 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 1320 : XMLBorderHdl::~XMLBorderHdl()
195 : {
196 : // nothing to do
197 1320 : }
198 :
199 235 : sal_Bool XMLBorderHdl::importXML( const OUString& rStrImpValue, uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const
200 : {
201 235 : OUString aToken;
202 235 : SvXMLTokenEnumerator aTokens( rStrImpValue );
203 :
204 235 : sal_Bool bHasStyle = sal_False;
205 235 : sal_Bool bHasWidth = sal_False;
206 235 : sal_Bool bHasColor = sal_False;
207 :
208 235 : sal_uInt16 nStyle = USHRT_MAX;
209 235 : sal_uInt16 nWidth = 0;
210 235 : sal_uInt16 nNamedWidth = USHRT_MAX;
211 235 : sal_Int32 nColor = 0;
212 :
213 : sal_Int32 nTemp;
214 1015 : while( aTokens.getNextToken( aToken ) && !aToken.isEmpty() )
215 : {
216 780 : if( !bHasWidth &&
217 : rUnitConverter.convertEnum( nNamedWidth, aToken,
218 235 : pXML_NamedBorderWidths ) )
219 : {
220 0 : bHasWidth = sal_True;
221 : }
222 935 : else if( !bHasStyle &&
223 : rUnitConverter.convertEnum( nStyle, aToken,
224 390 : pXML_BorderStyles ) )
225 : {
226 235 : bHasStyle = sal_True;
227 : }
228 310 : else if (!bHasColor && ::sax::Converter::convertColor(nColor, aToken))
229 : {
230 155 : bHasColor = sal_True;
231 : }
232 310 : else if( !bHasWidth &&
233 : rUnitConverter.convertMeasureToCore( nTemp, aToken, 0,
234 155 : USHRT_MAX ) )
235 : {
236 155 : nWidth = (sal_uInt16)nTemp;
237 155 : 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 235 : if( !bHasStyle || (API_LINE_NONE != nStyle && !bHasWidth) )
249 0 : return sal_False;
250 :
251 235 : table::BorderLine2 aBorderLine;
252 235 : if(!(rValue >>= aBorderLine))
253 : {
254 235 : aBorderLine.Color = 0;
255 235 : aBorderLine.InnerLineWidth = 0;
256 235 : aBorderLine.OuterLineWidth = 0;
257 235 : aBorderLine.LineDistance = 0;
258 235 : aBorderLine.LineWidth = 0;
259 : }
260 :
261 : // first of all, delete an empty line
262 235 : if( (bHasStyle && API_LINE_NONE == nStyle) ||
263 : (bHasWidth && USHRT_MAX == nNamedWidth && 0 == nWidth) )
264 : {
265 80 : aBorderLine.InnerLineWidth = 0;
266 80 : aBorderLine.OuterLineWidth = 0;
267 80 : aBorderLine.LineDistance = 0;
268 80 : aBorderLine.LineWidth = 0;
269 : }
270 155 : else if( bHasWidth )
271 : {
272 155 : if( USHRT_MAX != nNamedWidth )
273 : {
274 0 : aBorderLine.LineWidth = aBorderWidths[nNamedWidth];
275 : }
276 : else
277 : {
278 155 : aBorderLine.LineWidth = nWidth;
279 155 : 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 235 : if( bHasColor )
290 : {
291 155 : aBorderLine.Color = nColor;
292 : }
293 :
294 235 : rValue <<= aBorderLine;
295 235 : return sal_True;
296 : }
297 :
298 4 : sal_Bool XMLBorderHdl::exportXML( OUString& rStrExpValue, const uno::Any& rValue, const SvXMLUnitConverter& /* rUnitConverter */ ) const
299 : {
300 4 : OUStringBuffer aOut;
301 :
302 4 : table::BorderLine2 aBorderLine;
303 4 : if(!(rValue >>= aBorderLine))
304 0 : return sal_False;
305 :
306 4 : sal_Int32 nWidth = aBorderLine.LineWidth;
307 :
308 4 : if( nWidth == 0 )
309 : {
310 0 : aOut.append( GetXMLToken( XML_NONE ) );
311 : }
312 : else
313 : {
314 : ::sax::Converter::convertMeasure( aOut, nWidth,
315 4 : util::MeasureUnit::MM_100TH, util::MeasureUnit::POINT);
316 :
317 4 : aOut.append( sal_Unicode( ' ' ) );
318 :
319 4 : XMLTokenEnum eStyleToken = XML_SOLID;
320 4 : 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 4 : break;
352 : }
353 4 : aOut.append( GetXMLToken( eStyleToken ) );
354 :
355 4 : aOut.append( sal_Unicode( ' ' ) );
356 :
357 4 : ::sax::Converter::convertColor( aOut, aBorderLine.Color );
358 : }
359 :
360 4 : rStrExpValue = aOut.makeStringAndClear();
361 :
362 4 : return sal_True;
363 : }
364 :
365 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|