blob: b12656704097cd913908172110bd7744b993ac11 [file] [log] [blame]
/**************************************************************
*
* 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_sw.hxx"
#include "xmlithlp.hxx"
#include "hintids.hxx"
#include "unomid.h"
#include <svx/unomid.hxx>
#include <editeng/lrspitem.hxx>
#include <editeng/ulspitem.hxx>
#include <editeng/shaditem.hxx>
#include <editeng/boxitem.hxx>
#include <editeng/brkitem.hxx>
#include <editeng/keepitem.hxx>
#include <editeng/brshitem.hxx>
#include "fmtpdsc.hxx"
#include "fmtornt.hxx"
#include "fmtfsize.hxx"
#ifndef _FMTLSPLT_HXX
#include "fmtlsplt.hxx"
#endif
#include <xmloff/xmluconv.hxx>
using ::rtl::OUString;
using namespace ::xmloff::token;
using namespace ::com::sun::star;
#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
const struct SvXMLEnumMapEntry psXML_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 }
};
const struct SvXMLEnumMapEntry psXML_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
const sal_uInt16 aSBorderWidths[] =
{
SBORDER_ENTRY( 0 ), SBORDER_ENTRY( 5 ), SBORDER_ENTRY( 1 ),
SBORDER_ENTRY( 2 ), SBORDER_ENTRY( 3 ), SBORDER_ENTRY( 4 )
};
const sal_uInt16 aDBorderWidths[5*11] =
{
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 )
};
sal_Bool lcl_frmitems_parseXMLBorder( const OUString& rValue,
const SvXMLUnitConverter& rUnitConverter,
sal_Bool& rHasStyle, sal_uInt16& rStyle,
sal_Bool& rHasWidth, sal_uInt16& rWidth,
sal_uInt16& rNamedWidth,
sal_Bool& rHasColor, Color& rColor )
{
OUString aToken;
SvXMLTokenEnumerator aTokens( rValue );
rHasStyle = sal_False;
rHasWidth = sal_False;
rHasColor = sal_False;
rStyle = USHRT_MAX;
rWidth = 0;
rNamedWidth = USHRT_MAX;
sal_Int32 nTemp;
while( aTokens.getNextToken( aToken ) && aToken.getLength() != 0 )
{
if( !rHasWidth &&
rUnitConverter.convertEnum( rNamedWidth, aToken,
psXML_NamedBorderWidths ) )
{
rHasWidth = sal_True;
}
else if( !rHasStyle &&
rUnitConverter.convertEnum( rStyle, aToken,
psXML_BorderStyles ) )
{
rHasStyle = sal_True;
}
else if( !rHasColor && rUnitConverter.convertColor( rColor, aToken ) )
{
rHasColor = sal_True;
}
else if( !rHasWidth &&
rUnitConverter.convertMeasure( nTemp, aToken, 0, USHRT_MAX ) )
{
rWidth = (sal_uInt16)nTemp;
rHasWidth = sal_True;
}
else
{
// missformed
return sal_False;
}
}
return rHasStyle || rHasWidth || rHasColor;
}
void lcl_frmitems_setXMLBorderWidth( SvxBorderLine& rLine,
sal_uInt16 nOutWidth, sal_uInt16 nInWidth,
sal_uInt16 nDistance )
{
rLine.SetOutWidth( nOutWidth );
rLine.SetInWidth( nInWidth );
rLine.SetDistance( nDistance );
}
void lcl_frmitems_setXMLBorderWidth( SvxBorderLine& rLine,
sal_uInt16 nWidth, sal_Bool bDouble )
{
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) )
{
DBG_ASSERT( aWidths[i] >= aWidths[i-4], "line widths are unordered!" );
i -= 4;
}
rLine.SetOutWidth( aWidths[i+1] );
rLine.SetInWidth( aWidths[i+2] );
rLine.SetDistance( aWidths[i+3] );
}
sal_Bool lcl_frmitems_setXMLBorder( SvxBorderLine*& rpLine,
sal_Bool bHasStyle, sal_uInt16 nStyle,
sal_Bool bHasWidth, sal_uInt16 nWidth,
sal_uInt16 nNamedWidth,
sal_Bool bHasColor, const Color& rColor )
{
// first of all, delete an empty line
if( (bHasStyle && SVX_XML_BORDER_STYLE_NONE == nStyle) ||
(bHasWidth && USHRT_MAX == nNamedWidth && 0 == nWidth) )
{
sal_Bool bRet = 0 != rpLine;
if( rpLine )
{
delete rpLine;
rpLine = 0;
}
return bRet;
}
// if there is no line and no style and no with, there will never be a line
if( !rpLine && !(bHasStyle && bHasWidth) )
return sal_False;
// We now do know that there will be a line
if( !rpLine )
rpLine = new SvxBorderLine;
if( ( bHasWidth &&
(USHRT_MAX != nNamedWidth || (nWidth != rpLine->GetOutWidth() +
rpLine->GetInWidth() +
rpLine->GetDistance()) ) ) ||
( bHasStyle &&
((SVX_XML_BORDER_STYLE_SOLID == nStyle && rpLine->GetDistance()) ||
(SVX_XML_BORDER_STYLE_DOUBLE == nStyle && !rpLine->GetDistance())) ))
{
sal_Bool bDouble = (bHasWidth && SVX_XML_BORDER_STYLE_DOUBLE == nStyle ) ||
rpLine->GetDistance();
// The width has to be changed
if( bHasWidth && USHRT_MAX != nNamedWidth )
{
const sal_uInt16 *aWidths = bDouble ? aDBorderWidths :aSBorderWidths;
sal_uInt16 nNWidth = nNamedWidth * 4;
rpLine->SetOutWidth( aWidths[nNWidth+1] );
rpLine->SetInWidth( aWidths[nNWidth+2] );
rpLine->SetDistance( aWidths[nNWidth+3] );
}
else
{
if( !bHasWidth )
nWidth = rpLine->GetInWidth() + rpLine->GetDistance() +
rpLine->GetOutWidth();
lcl_frmitems_setXMLBorderWidth( *rpLine, nWidth, bDouble );
}
}
// set color
if( bHasColor )
rpLine->SetColor( rColor );
return sal_True;
}
void lcl_frmitems_setXMLBorder( SvxBorderLine*& rpLine,
sal_uInt16 nWidth, sal_uInt16 nOutWidth,
sal_uInt16 nInWidth, sal_uInt16 nDistance )
{
if( !rpLine )
rpLine = new SvxBorderLine;
if( nWidth > 0 )
lcl_frmitems_setXMLBorderWidth( *rpLine, nWidth, sal_True );
else
lcl_frmitems_setXMLBorderWidth( *rpLine, nOutWidth, nInWidth,
nDistance );
}
const struct SvXMLEnumMapEntry psXML_BrushRepeat[] =
{
{ XML_BACKGROUND_REPEAT, GPOS_TILED },
{ XML_BACKGROUND_NO_REPEAT, GPOS_MM },
{ XML_BACKGROUND_STRETCH, GPOS_AREA },
{ XML_TOKEN_INVALID, 0 }
};
const struct SvXMLEnumMapEntry psXML_BrushHoriPos[] =
{
{ XML_LEFT, GPOS_LM },
{ XML_RIGHT, GPOS_RM },
{ XML_TOKEN_INVALID, 0 }
};
const struct SvXMLEnumMapEntry psXML_BrushVertPos[] =
{
{ XML_TOP, GPOS_MT },
{ XML_BOTTOM, GPOS_MB },
{ XML_TOKEN_INVALID, 0 }
};
void lcl_frmitems_MergeXMLHoriPos( SvxGraphicPosition& ePos,
SvxGraphicPosition eHori )
{
DBG_ASSERT( GPOS_LM==eHori || GPOS_MM==eHori || GPOS_RM==eHori,
"lcl_frmitems_MergeXMLHoriPos: vertical pos must be middle" );
switch( ePos )
{
case GPOS_LT:
case GPOS_MT:
case GPOS_RT:
ePos = GPOS_LM==eHori ? GPOS_LT : (GPOS_MM==eHori ? GPOS_MT : GPOS_RT);
break;
case GPOS_LM:
case GPOS_MM:
case GPOS_RM:
ePos = eHori;
break;
case GPOS_LB:
case GPOS_MB:
case GPOS_RB:
ePos = GPOS_LM==eHori ? GPOS_LB : (GPOS_MM==eHori ? GPOS_MB : GPOS_RB);
break;
default:
;
}
}
void lcl_frmitems_MergeXMLVertPos( SvxGraphicPosition& ePos,
SvxGraphicPosition eVert )
{
DBG_ASSERT( GPOS_MT==eVert || GPOS_MM==eVert || GPOS_MB==eVert,
"lcl_frmitems_MergeXMLVertPos: horizontal pos must be middle" );
switch( ePos )
{
case GPOS_LT:
case GPOS_LM:
case GPOS_LB:
ePos = GPOS_MT==eVert ? GPOS_LT : (GPOS_MM==eVert ? GPOS_LM : GPOS_LB);
ePos = eVert;
break;
case GPOS_MT:
case GPOS_MM:
case GPOS_MB:
ePos = eVert;
break;
case GPOS_RT:
case GPOS_RM:
case GPOS_RB:
ePos = GPOS_MT==eVert ? GPOS_RT : (GPOS_MM==eVert ? GPOS_RM : GPOS_RB);
break;
default:
;
}
}
const struct SvXMLEnumMapEntry psXML_BreakType[] =
{
{ XML_AUTO, 0 },
{ XML_COLUMN, 1 },
{ XML_PAGE, 2 },
{ XML_EVEN_PAGE, 2 },
{ XML_ODD_PAGE, 2 },
{ XML_TOKEN_INVALID, 0}
};
const struct SvXMLEnumMapEntry aXMLTableAlignMap[] =
{
{ XML_LEFT, text::HoriOrientation::LEFT },
{ XML_LEFT, text::HoriOrientation::LEFT_AND_WIDTH },
{ XML_CENTER, text::HoriOrientation::CENTER },
{ XML_RIGHT, text::HoriOrientation::RIGHT },
{ XML_MARGINS, text::HoriOrientation::FULL },
{ XML_MARGINS, text::HoriOrientation::NONE },
{ XML_TOKEN_INVALID, 0 }
};
const struct SvXMLEnumMapEntry aXMLTableVAlignMap[] =
{
{ XML_TOP, text::VertOrientation::TOP },
{ XML_MIDDLE, text::VertOrientation::CENTER },
{ XML_BOTTOM, text::VertOrientation::BOTTOM },
{ XML_TOKEN_INVALID, 0 }
};
const struct SvXMLEnumMapEntry aXML_KeepTogetherType[] =
{
{ XML_ALWAYS, 0 },
{ XML_AUTO, 1 },
{ XML_TOKEN_INVALID, 0}
};