| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_xmloff.hxx" |
| |
| |
| #include <bordrhdl.hxx> |
| #include <xmloff/xmltoken.hxx> |
| #include <xmloff/xmluconv.hxx> |
| #include <rtl/ustrbuf.hxx> |
| #include <com/sun/star/uno/Any.hxx> |
| #include <com/sun/star/table/BorderLine.hpp> |
| |
| using ::rtl::OUString; |
| using ::rtl::OUStringBuffer; |
| |
| using namespace ::com::sun::star; |
| using namespace ::xmloff::token; |
| |
| // copied from svx/boxitem.hxx |
| #define DEF_LINE_WIDTH_0 1 |
| #define DEF_LINE_WIDTH_1 35 |
| #define DEF_LINE_WIDTH_2 88 |
| #define DEF_LINE_WIDTH_3 141 |
| #define DEF_LINE_WIDTH_4 176 |
| |
| #define DEF_MAX_LINE_WIDHT DEF_LINE_WIDTH_4 |
| #define DEF_MAX_LINE_DIST DEF_LINE_WIDTH_2 |
| |
| #define DEF_DOUBLE_LINE0_OUT DEF_LINE_WIDTH_0 |
| #define DEF_DOUBLE_LINE0_IN DEF_LINE_WIDTH_0 |
| #define DEF_DOUBLE_LINE0_DIST DEF_LINE_WIDTH_1 |
| |
| #define DEF_DOUBLE_LINE1_OUT DEF_LINE_WIDTH_1 |
| #define DEF_DOUBLE_LINE1_IN DEF_LINE_WIDTH_1 |
| #define DEF_DOUBLE_LINE1_DIST DEF_LINE_WIDTH_1 |
| |
| #define DEF_DOUBLE_LINE2_OUT DEF_LINE_WIDTH_2 |
| #define DEF_DOUBLE_LINE2_IN DEF_LINE_WIDTH_2 |
| #define DEF_DOUBLE_LINE2_DIST DEF_LINE_WIDTH_2 |
| |
| #define DEF_DOUBLE_LINE3_OUT DEF_LINE_WIDTH_2 |
| #define DEF_DOUBLE_LINE3_IN DEF_LINE_WIDTH_1 |
| #define DEF_DOUBLE_LINE3_DIST DEF_LINE_WIDTH_2 |
| |
| #define DEF_DOUBLE_LINE4_OUT DEF_LINE_WIDTH_1 |
| #define DEF_DOUBLE_LINE4_IN DEF_LINE_WIDTH_2 |
| #define DEF_DOUBLE_LINE4_DIST DEF_LINE_WIDTH_1 |
| |
| #define DEF_DOUBLE_LINE5_OUT DEF_LINE_WIDTH_3 |
| #define DEF_DOUBLE_LINE5_IN DEF_LINE_WIDTH_2 |
| #define DEF_DOUBLE_LINE5_DIST DEF_LINE_WIDTH_2 |
| |
| #define DEF_DOUBLE_LINE6_OUT DEF_LINE_WIDTH_2 |
| #define DEF_DOUBLE_LINE6_IN DEF_LINE_WIDTH_3 |
| #define DEF_DOUBLE_LINE6_DIST DEF_LINE_WIDTH_2 |
| |
| #define DEF_DOUBLE_LINE7_OUT DEF_LINE_WIDTH_0 |
| #define DEF_DOUBLE_LINE7_IN DEF_LINE_WIDTH_0 |
| #define DEF_DOUBLE_LINE7_DIST DEF_LINE_WIDTH_2 |
| |
| #define DEF_DOUBLE_LINE8_OUT DEF_LINE_WIDTH_1 |
| #define DEF_DOUBLE_LINE8_IN DEF_LINE_WIDTH_0 |
| #define DEF_DOUBLE_LINE8_DIST DEF_LINE_WIDTH_2 |
| |
| #define DEF_DOUBLE_LINE9_OUT DEF_LINE_WIDTH_2 |
| #define DEF_DOUBLE_LINE9_IN DEF_LINE_WIDTH_0 |
| #define DEF_DOUBLE_LINE9_DIST DEF_LINE_WIDTH_2 |
| |
| #define DEF_DOUBLE_LINE10_OUT DEF_LINE_WIDTH_3 |
| #define DEF_DOUBLE_LINE10_IN DEF_LINE_WIDTH_0 |
| #define DEF_DOUBLE_LINE10_DIST DEF_LINE_WIDTH_2 |
| |
| // finished copy |
| |
| #define SVX_XML_BORDER_STYLE_NONE 0 |
| #define SVX_XML_BORDER_STYLE_SOLID 1 |
| #define SVX_XML_BORDER_STYLE_DOUBLE 2 |
| |
| #define SVX_XML_BORDER_WIDTH_THIN 0 |
| #define SVX_XML_BORDER_WIDTH_MIDDLE 1 |
| #define SVX_XML_BORDER_WIDTH_THICK 2 |
| |
| SvXMLEnumMapEntry pXML_BorderStyles[] = |
| { |
| { XML_NONE, SVX_XML_BORDER_STYLE_NONE }, |
| { XML_HIDDEN, SVX_XML_BORDER_STYLE_NONE }, |
| { XML_SOLID, SVX_XML_BORDER_STYLE_SOLID }, |
| { XML_DOUBLE, SVX_XML_BORDER_STYLE_DOUBLE }, |
| { XML_DOTTED, SVX_XML_BORDER_STYLE_SOLID }, |
| { XML_DASHED, SVX_XML_BORDER_STYLE_SOLID }, |
| { XML_GROOVE, SVX_XML_BORDER_STYLE_SOLID }, |
| { XML_RIDGE, SVX_XML_BORDER_STYLE_SOLID }, |
| { XML_INSET, SVX_XML_BORDER_STYLE_SOLID }, |
| { XML_OUTSET, SVX_XML_BORDER_STYLE_SOLID }, |
| { XML_TOKEN_INVALID, 0 } |
| }; |
| |
| SvXMLEnumMapEntry pXML_NamedBorderWidths[] = |
| { |
| { XML_THIN, SVX_XML_BORDER_WIDTH_THIN }, |
| { XML_MIDDLE, SVX_XML_BORDER_WIDTH_MIDDLE }, |
| { XML_THICK, SVX_XML_BORDER_WIDTH_THICK }, |
| { XML_TOKEN_INVALID, 0 } |
| }; |
| // mapping tables to map external xml input to intarnal box line widths |
| |
| // Ein Eintrag besteht aus vier USHORTs. Der erste ist die Gesamtbreite, |
| // die anderen sind die 3 Einzelbreiten |
| |
| #define SBORDER_ENTRY( n ) \ |
| DEF_LINE_WIDTH_##n, DEF_LINE_WIDTH_##n, 0, 0 |
| |
| #define DBORDER_ENTRY( n ) \ |
| DEF_DOUBLE_LINE##n##_OUT + DEF_DOUBLE_LINE##n##_IN + \ |
| DEF_DOUBLE_LINE##n##_DIST, \ |
| DEF_DOUBLE_LINE##n##_OUT, \ |
| DEF_DOUBLE_LINE##n##_IN, \ |
| DEF_DOUBLE_LINE##n##_DIST |
| |
| #define TDBORDER_ENTRY( n ) \ |
| DEF_DOUBLE_LINE##n##_OUT, \ |
| DEF_DOUBLE_LINE##n##_OUT, \ |
| DEF_DOUBLE_LINE##n##_IN, \ |
| DEF_DOUBLE_LINE##n##_DIST |
| |
| |
| static sal_uInt16 __READONLY_DATA aSBorderWidths[] = |
| { |
| SBORDER_ENTRY( 0 ), SBORDER_ENTRY( 1 ), SBORDER_ENTRY( 2 ), |
| SBORDER_ENTRY( 3 ), SBORDER_ENTRY( 4 ) |
| }; |
| |
| static sal_uInt16 __READONLY_DATA aDBorderWidths[] = |
| { |
| DBORDER_ENTRY( 0 ), |
| DBORDER_ENTRY( 7 ), |
| DBORDER_ENTRY( 1 ), |
| DBORDER_ENTRY( 8 ), |
| DBORDER_ENTRY( 4 ), |
| DBORDER_ENTRY( 9 ), |
| DBORDER_ENTRY( 3 ), |
| DBORDER_ENTRY( 10 ), |
| DBORDER_ENTRY( 2 ), |
| DBORDER_ENTRY( 6 ), |
| DBORDER_ENTRY( 5 ) |
| }; |
| |
| void lcl_frmitems_setXMLBorderWidth( table::BorderLine &rBorderLine, |
| sal_uInt16 nWidth, sal_Bool bDouble ) |
| { |
| #ifdef XML_CHECK_UI_CONTSTRAINS |
| const sal_uInt16 *aWidths; |
| sal_uInt16 nSize; |
| if( !bDouble ) |
| { |
| aWidths = aSBorderWidths; |
| nSize = sizeof( aSBorderWidths ); |
| } |
| else |
| { |
| aWidths = aDBorderWidths; |
| nSize = sizeof( aDBorderWidths ); |
| } |
| |
| sal_uInt16 i = (nSize / sizeof(sal_uInt16)) - 4; |
| while( i>0 && |
| nWidth <= ((aWidths[i] + aWidths[i-4]) / 2) ) |
| { |
| i -= 4; |
| } |
| |
| rBorderLine.OuterLineWidth = aWidths[i+1]; |
| rBorderLine.InnerLineWidth = aWidths[i+2]; |
| rBorderLine.LineDistance = aWidths[i+3]; |
| #else |
| if( bDouble ) |
| { |
| const sal_uInt16 *aWidths = aDBorderWidths; |
| sal_uInt16 nSize = sizeof( aDBorderWidths ); |
| sal_uInt16 i = (nSize / sizeof(sal_uInt16)) - 4; |
| while( i>0 && |
| nWidth <= ((aWidths[i] + aWidths[i-4]) / 2) ) |
| { |
| i -= 4; |
| } |
| |
| rBorderLine.OuterLineWidth = aWidths[i+1]; |
| rBorderLine.InnerLineWidth = aWidths[i+2]; |
| rBorderLine.LineDistance = aWidths[i+3]; |
| } |
| else |
| { |
| rBorderLine.OuterLineWidth = 0 == nWidth ? DEF_LINE_WIDTH_0 : nWidth; |
| rBorderLine.InnerLineWidth = 0; |
| rBorderLine.LineDistance = 0; |
| |
| } |
| #endif |
| } |
| |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // |
| // class XMLEscapementPropHdl |
| // |
| |
| XMLBorderWidthHdl::~XMLBorderWidthHdl() |
| { |
| // nothing to do |
| } |
| |
| sal_Bool XMLBorderWidthHdl::importXML( const OUString& rStrImpValue, uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const |
| { |
| SvXMLTokenEnumerator aTokenEnum( rStrImpValue ); |
| |
| sal_Int32 nInWidth, nDistance, nOutWidth; |
| |
| OUString aToken; |
| if( !aTokenEnum.getNextToken( aToken ) ) |
| return sal_False; |
| |
| if( !rUnitConverter.convertMeasure( nInWidth, aToken, 0, 500 ) ) |
| return sal_False; |
| |
| if( !aTokenEnum.getNextToken( aToken ) ) |
| return sal_False; |
| |
| if( !rUnitConverter.convertMeasure( nDistance, aToken, 0, 500 ) ) |
| return sal_False; |
| |
| if( !aTokenEnum.getNextToken( aToken ) ) |
| return sal_False; |
| |
| if( !rUnitConverter.convertMeasure( nOutWidth, aToken, 0, 500 ) ) |
| return sal_False; |
| |
| #ifdef XML_CHECK_UI_CONSTRAINS |
| sal_uInt16 nSize = sizeof( aDBorderWidths ); |
| for( sal_uInt16 i=0; i < nSize; i += 4 ) |
| { |
| if( aDBorderWidths[i+1] == nOutWidth && |
| aDBorderWidths[i+2] == nInWidth && |
| aDBorderWidths[i+3] == nDistance ) |
| break; |
| } |
| |
| sal_uInt16 nWidth = i < nSize ? 0 : nOutWidth + nInWidth + nDistance; |
| #endif |
| |
| table::BorderLine aBorderLine; |
| if(!(rValue >>= aBorderLine)) |
| aBorderLine.Color = 0; |
| |
| aBorderLine.InnerLineWidth = sal::static_int_cast< sal_Int16 >(nInWidth); |
| aBorderLine.OuterLineWidth = sal::static_int_cast< sal_Int16 >(nOutWidth); |
| aBorderLine.LineDistance = sal::static_int_cast< sal_Int16 >(nDistance); |
| |
| rValue <<= aBorderLine; |
| return sal_True; |
| } |
| |
| sal_Bool XMLBorderWidthHdl::exportXML( OUString& rStrExpValue, const uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const |
| { |
| OUStringBuffer aOut; |
| |
| table::BorderLine aBorderLine; |
| if(!(rValue >>= aBorderLine)) |
| return sal_False; |
| |
| if( aBorderLine.LineDistance == 0 && aBorderLine.InnerLineWidth == 0) |
| return sal_False; |
| |
| rUnitConverter.convertMeasure( aOut, aBorderLine.InnerLineWidth ); |
| aOut.append( sal_Unicode( ' ' ) ); |
| rUnitConverter.convertMeasure( aOut, aBorderLine.LineDistance ); |
| aOut.append( sal_Unicode( ' ' ) ); |
| rUnitConverter.convertMeasure( aOut, aBorderLine.OuterLineWidth ); |
| |
| rStrExpValue = aOut.makeStringAndClear(); |
| return sal_True; |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // |
| // class XMLEscapementHeightPropHdl |
| // |
| |
| XMLBorderHdl::~XMLBorderHdl() |
| { |
| // nothing to do |
| } |
| |
| sal_Bool XMLBorderHdl::importXML( const OUString& rStrImpValue, uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const |
| { |
| OUString aToken; |
| SvXMLTokenEnumerator aTokens( rStrImpValue ); |
| |
| sal_Bool bHasStyle = sal_False; |
| sal_Bool bHasWidth = sal_False; |
| sal_Bool bHasColor = sal_False; |
| |
| sal_uInt16 nStyle = USHRT_MAX; |
| sal_uInt16 nWidth = 0; |
| sal_uInt16 nNamedWidth = USHRT_MAX; |
| Color aColor; |
| |
| sal_Int32 nTemp; |
| while( aTokens.getNextToken( aToken ) && aToken.getLength() != 0 ) |
| { |
| if( !bHasWidth && |
| rUnitConverter.convertEnum( nNamedWidth, aToken, |
| pXML_NamedBorderWidths ) ) |
| { |
| bHasWidth = sal_True; |
| } |
| else if( !bHasStyle && |
| rUnitConverter.convertEnum( nStyle, aToken, |
| pXML_BorderStyles ) ) |
| { |
| bHasStyle = sal_True; |
| } |
| else if( !bHasColor && rUnitConverter.convertColor( aColor, aToken ) ) |
| { |
| bHasColor = sal_True; |
| } |
| else if( !bHasWidth && |
| rUnitConverter.convertMeasure( nTemp, aToken, 0, |
| USHRT_MAX ) ) |
| { |
| nWidth = (sal_uInt16)nTemp; |
| bHasWidth = sal_True; |
| } |
| else |
| { |
| // missformed |
| return sal_False; |
| } |
| } |
| |
| // if there is no style or a different style than none but no width, |
| // then the declaration is not valid. |
| if( !bHasStyle || (SVX_XML_BORDER_STYLE_NONE != nStyle && !bHasWidth) ) |
| return sal_False; |
| |
| table::BorderLine aBorderLine; |
| if(!(rValue >>= aBorderLine)) |
| { |
| aBorderLine.Color = 0; |
| aBorderLine.InnerLineWidth = 0; |
| aBorderLine.OuterLineWidth = 0; |
| aBorderLine.LineDistance = 0; |
| } |
| |
| // first of all, delete an empty line |
| sal_Bool bDouble = SVX_XML_BORDER_STYLE_DOUBLE == nStyle; |
| if( (bHasStyle && SVX_XML_BORDER_STYLE_NONE == nStyle) || |
| (bHasWidth && USHRT_MAX == nNamedWidth && 0 == nWidth) ) |
| { |
| aBorderLine.InnerLineWidth = 0; |
| aBorderLine.OuterLineWidth = 0; |
| aBorderLine.LineDistance = 0; |
| } |
| else if( bHasWidth ) |
| { |
| if( USHRT_MAX != nNamedWidth ) |
| { |
| const sal_uInt16 *aWidths = bDouble ? aDBorderWidths |
| : aSBorderWidths; |
| sal_uInt16 nNWidth = nNamedWidth * 4; |
| aBorderLine.OuterLineWidth = aWidths[nNWidth+1]; |
| aBorderLine.InnerLineWidth = aWidths[nNWidth+2]; |
| aBorderLine.LineDistance = aWidths[nNWidth+3]; |
| } |
| else |
| { |
| lcl_frmitems_setXMLBorderWidth( aBorderLine, nWidth, bDouble ); |
| } |
| } |
| else |
| { |
| lcl_frmitems_setXMLBorderWidth( aBorderLine, 0, bDouble ); |
| } |
| |
| // set color |
| if( bHasColor ) |
| aBorderLine.Color = (sal_Int32)aColor.GetRGBColor(); |
| |
| rValue <<= aBorderLine; |
| return sal_True; |
| } |
| |
| sal_Bool XMLBorderHdl::exportXML( OUString& rStrExpValue, const uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const |
| { |
| OUStringBuffer aOut; |
| |
| table::BorderLine aBorderLine; |
| if(!(rValue >>= aBorderLine)) |
| return sal_False; |
| |
| sal_Int32 nWidth = aBorderLine.OuterLineWidth; |
| const sal_uInt16 nDistance = aBorderLine.LineDistance; |
| if( 0 != nDistance ) |
| { |
| nWidth += nDistance; |
| nWidth += aBorderLine.InnerLineWidth; |
| } |
| |
| if( nWidth == 0 ) |
| { |
| aOut.append( GetXMLToken( XML_NONE ) ); |
| } |
| else |
| { |
| rUnitConverter.convertMeasure( aOut, nWidth ); |
| |
| aOut.append( sal_Unicode( ' ' ) ); |
| |
| aOut.append( GetXMLToken((0 == nDistance) ? XML_SOLID : XML_DOUBLE) ); |
| |
| aOut.append( sal_Unicode( ' ' ) ); |
| |
| rUnitConverter.convertColor( aOut, aBorderLine.Color ); |
| } |
| |
| rStrExpValue = aOut.makeStringAndClear(); |
| |
| return sal_True; |
| } |