diff options
Diffstat (limited to 'writerfilter/source/dmapper')
62 files changed, 23122 insertions, 0 deletions
diff --git a/writerfilter/source/dmapper/BorderHandler.cxx b/writerfilter/source/dmapper/BorderHandler.cxx new file mode 100644 index 000000000000..85fe714c25e3 --- /dev/null +++ b/writerfilter/source/dmapper/BorderHandler.cxx @@ -0,0 +1,168 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include <BorderHandler.hxx> +#include <PropertyMap.hxx> +#include <resourcemodel/QNameToString.hxx> +#include <doctok/resourceids.hxx> +#include <ConversionHelper.hxx> +#include <com/sun/star/table/BorderLine2.hpp> +#include <ooxml/resourceids.hxx> +#include <dmapperLoggers.hxx> + +namespace writerfilter { + +namespace dmapper { + +using namespace ::com::sun::star; + + +BorderHandler::BorderHandler( bool bOOXML ) : +LoggedProperties(dmapper_logger, "BorderHandler"), +m_nCurrentBorderPosition( BORDER_TOP ), +m_nLineWidth(0), +m_nLineType(0), +m_nLineColor(0), +m_nLineDistance(0), +m_bOOXML( bOOXML ) +{ + const int nBorderCount(BORDER_COUNT); + std::fill_n(m_aFilledLines, nBorderCount, false); + std::fill_n(m_aBorderLines, nBorderCount, table::BorderLine2()); +} + +BorderHandler::~BorderHandler() +{ +} + +void BorderHandler::lcl_attribute(Id rName, Value & rVal) +{ + sal_Int32 nIntValue = rVal.getInt(); + switch( rName ) + { + case NS_rtf::LN_rgbrc: + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rVal.getProperties(); + if( pProperties.get()) + { + pProperties->resolve(*this); + ConversionHelper::MakeBorderLine( m_nLineWidth, m_nLineType, m_nLineColor, + m_aBorderLines[m_nCurrentBorderPosition], m_bOOXML ); + OSL_ENSURE(m_nCurrentBorderPosition < BORDER_COUNT, "too many border values"); + ++m_nCurrentBorderPosition; + } + } + break; + case NS_rtf::LN_DPTLINEWIDTH: // 0x2871 + // width of a single line in 1/8 pt, max of 32 pt -> twip * 5 / 2. + m_nLineWidth = ConversionHelper::convertTwipToMM100( nIntValue * 5 / 2 ); + break; + case NS_rtf::LN_BRCTYPE: // 0x2872 + m_nLineType = nIntValue; + break; + case NS_ooxml::LN_CT_Border_color: + case NS_rtf::LN_ICO: // 0x2873 + m_nLineColor = nIntValue; + break; + case NS_rtf::LN_DPTSPACE: // border distance in points + m_nLineDistance = ConversionHelper::convertTwipToMM100( nIntValue * 20 ); + break; + case NS_rtf::LN_FSHADOW: // 0x2875 + //if 1 then line has shadow - unsupported + case NS_rtf::LN_FFRAME: // 0x2876 + case NS_rtf::LN_UNUSED2_15: // 0x2877 + // ignored + break; + case NS_ooxml::LN_CT_Border_themeTint: break; + case NS_ooxml::LN_CT_Border_themeColor: break; + default: + OSL_FAIL( "unknown attribute"); + } +} + +void BorderHandler::lcl_sprm(Sprm & rSprm) +{ + switch( rSprm.getId()) + { + case NS_ooxml::LN_CT_TblBorders_top: + case NS_ooxml::LN_CT_TblBorders_left: + case NS_ooxml::LN_CT_TblBorders_bottom: + case NS_ooxml::LN_CT_TblBorders_right: + case NS_ooxml::LN_CT_TblBorders_insideH: + case NS_ooxml::LN_CT_TblBorders_insideV: + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + pProperties->resolve(*this); + ConversionHelper::MakeBorderLine( m_nLineWidth, m_nLineType, m_nLineColor, + m_aBorderLines[rSprm.getId() - NS_ooxml::LN_CT_TblBorders_top], m_bOOXML ); + + m_aFilledLines[ rSprm.getId( ) - NS_ooxml::LN_CT_TblBorders_top] = true; + } + break; + default:; + } +} + +PropertyMapPtr BorderHandler::getProperties() +{ + static const PropertyIds aPropNames[BORDER_COUNT] = + { + PROP_TOP_BORDER, + PROP_LEFT_BORDER, + PROP_BOTTOM_BORDER, + PROP_RIGHT_BORDER, + META_PROP_HORIZONTAL_BORDER, + META_PROP_VERTICAL_BORDER + }; + PropertyMapPtr pPropertyMap(new PropertyMap); + // don't fill in default properties + if( m_bOOXML || m_nCurrentBorderPosition ) + { + for( sal_Int32 nProp = 0; nProp < BORDER_COUNT; ++nProp) + { + if ( m_aFilledLines[nProp] ) { + pPropertyMap->Insert( aPropNames[nProp], false, uno::makeAny( m_aBorderLines[nProp] ) ); + } + } + } + return pPropertyMap; +} +/*------------------------------------------------------------------------- + used only in OOXML import + -----------------------------------------------------------------------*/ +table::BorderLine2 BorderHandler::getBorderLine() +{ + table::BorderLine2 aBorderLine; + ConversionHelper::MakeBorderLine( m_nLineWidth, m_nLineType, m_nLineColor, aBorderLine, m_bOOXML ); + return aBorderLine; +} + +} //namespace dmapper +} //namespace writerfilter + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/BorderHandler.hxx b/writerfilter/source/dmapper/BorderHandler.hxx new file mode 100644 index 000000000000..6d23f123c2aa --- /dev/null +++ b/writerfilter/source/dmapper/BorderHandler.hxx @@ -0,0 +1,84 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef INCLUDED_BORDERHANDLER_HXX +#define INCLUDED_BORDERHANDLER_HXX + +#include <WriterFilterDllApi.hxx> +#include <resourcemodel/LoggedResources.hxx> +#include <boost/shared_ptr.hpp> +#include <com/sun/star/table/BorderLine2.hpp> + +namespace writerfilter { +namespace dmapper +{ +class PropertyMap; +class WRITERFILTER_DLLPRIVATE BorderHandler : public LoggedProperties +{ +public: + //todo: order is a guess + enum BorderPosition + { + BORDER_TOP, + BORDER_LEFT, + BORDER_BOTTOM, + BORDER_RIGHT, + BORDER_HORIZONTAL, + BORDER_VERTICAL, + BORDER_COUNT + }; + +private: + sal_Int8 m_nCurrentBorderPosition; + //values of the current border + sal_Int32 m_nLineWidth; + sal_Int32 m_nLineType; + sal_Int32 m_nLineColor; + sal_Int32 m_nLineDistance; + bool m_bOOXML; + + bool m_aFilledLines[BORDER_COUNT]; + ::com::sun::star::table::BorderLine2 m_aBorderLines[BORDER_COUNT]; + + // Properties + virtual void lcl_attribute(Id Name, Value & val); + virtual void lcl_sprm(Sprm & sprm); + +public: + BorderHandler( bool bOOXML ); + virtual ~BorderHandler(); + + ::boost::shared_ptr<PropertyMap> getProperties(); + ::com::sun::star::table::BorderLine2 getBorderLine(); + sal_Int32 getLineDistance() const { return m_nLineDistance;} +}; +typedef boost::shared_ptr< BorderHandler > BorderHandlerPtr; +}} + +#endif // + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/CellColorHandler.cxx b/writerfilter/source/dmapper/CellColorHandler.cxx new file mode 100644 index 000000000000..8b087e7bd3eb --- /dev/null +++ b/writerfilter/source/dmapper/CellColorHandler.cxx @@ -0,0 +1,211 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include <CellColorHandler.hxx> +#include <PropertyMap.hxx> +#include <doctok/resourceids.hxx> +#include <ConversionHelper.hxx> +#include <ooxml/resourceids.hxx> +#include <sal/macros.h> +#include "dmapperLoggers.hxx" + +#define OOXML_COLOR_AUTO 0x0a //todo: AutoColor needs symbol + +namespace writerfilter { +namespace dmapper { + +using namespace ::com::sun::star; +using namespace ::writerfilter; + + +CellColorHandler::CellColorHandler() : +LoggedProperties(dmapper_logger, "CellColorHandler"), +m_nShadowType( 0 ), +m_nColor( 0xffffffff ), +m_nFillColor( 0xffffffff ), + m_OutputFormat( Form ) +{ +} + +CellColorHandler::~CellColorHandler() +{ +} + +void CellColorHandler::lcl_attribute(Id rName, Value & rVal) +{ + sal_Int32 nIntValue = rVal.getInt(); + switch( rName ) + { + case NS_rtf::LN_cellTopColor: + case NS_rtf::LN_cellLeftColor: + case NS_rtf::LN_cellBottomColor: + case NS_rtf::LN_cellRightColor: + // nIntValue contains the color, directly + break; + case NS_ooxml::LN_CT_Shd_val: + { + //might be clear, pct5...90, some hatch types + //TODO: The values need symbolic names! + m_nShadowType = nIntValue; //clear == 0, solid: 1, pct5: 2, pct50:8, pct95: x3c, horzStripe:0x0e, thinVertStripe: 0x15 + } + break; + case NS_ooxml::LN_CT_Shd_fill: + if( nIntValue == OOXML_COLOR_AUTO ) + nIntValue = 0xffffff; //fill color auto means white + m_nFillColor = nIntValue; + break; + case NS_ooxml::LN_CT_Shd_color: + if( nIntValue == OOXML_COLOR_AUTO ) + nIntValue = 0; //shading color auto means black + //color of the shading + m_nColor = nIntValue; + break; + case NS_ooxml::LN_CT_Shd_themeFill: + case NS_ooxml::LN_CT_Shd_themeFillTint: + case NS_ooxml::LN_CT_Shd_themeFillShade: + // ignored + break; + default: + OSL_FAIL( "unknown attribute"); + } +} + +void CellColorHandler::lcl_sprm(Sprm & rSprm) +{ + (void)rSprm; +} + +TablePropertyMapPtr CellColorHandler::getProperties() +{ + TablePropertyMapPtr pPropertyMap(new TablePropertyMap); +//code from binary word filter + static const sal_Int32 eMSGrayScale[] = + { + // Nul-Brush + 0, // 0 + // Solid-Brush + 1000, // 1 + // percent values + 50, // 2 + 100, // 3 + 200, // 4 + 250, // 5 + 300, // 6 + 400, // 7 + 500, // 8 + 600, // 9 + 700, // 10 + 750, // 11 + 800, // 12 + 900, // 13 + 333, // 14 Dark Horizontal + 333, // 15 Dark Vertical + 333, // 16 Dark Forward Diagonal + 333, // 17 Dark Backward Diagonal + 333, // 18 Dark Cross + 333, // 19 Dark Diagonal Cross + 333, // 20 Horizontal + 333, // 21 Vertical + 333, // 22 Forward Diagonal + 333, // 23 Backward Diagonal + 333, // 24 Cross + 333, // 25 Diagonal Cross + // some undefined values + 500, // 26 + 500, // 27 + 500, // 28 + 500, // 29 + 500, // 30 + 500, // 31 + 500, // 32 + 500, // 33 + 500, // 34 + // different shading types + 25, // 35 + 75, // 36 + 125, // 37 + 150, // 38 + 175, // 39 + 225, // 40 + 275, // 41 + 325, // 42 + 350, // 43 + 375, // 44 + 425, // 45 + 450, // 46 + 475, // 47 + 525, // 48 + 550, // 49 + 575, // 50 + 625, // 51 + 650, // 52 + 675, // 53 + 725, // 54 + 775, // 55 + 825, // 56 + 850, // 57 + 875, // 58 + 925, // 59 + 950, // 60 + 975, // 61 + // und zu guter Letzt: + 970 + };// 62 + if( m_nShadowType >= (sal_Int32)SAL_N_ELEMENTS( eMSGrayScale ) ) + m_nShadowType = 0; + + sal_Int32 nWW8BrushStyle = eMSGrayScale[m_nShadowType]; + sal_Int32 nApplyColor = 0; + if( !nWW8BrushStyle ) + { + // Null-Brush + nApplyColor = m_nFillColor; + } + else + { + sal_Int32 nFore = m_nColor; + sal_Int32 nBack = m_nFillColor; + + sal_uInt32 nRed = ((nFore & 0xff0000)>>0x10) * nWW8BrushStyle; + sal_uInt32 nGreen = ((nFore & 0xff00)>>0x8) * nWW8BrushStyle; + sal_uInt32 nBlue = (nFore & 0xff) * nWW8BrushStyle; + nRed += ((nBack & 0xff0000)>>0x10) * (1000L - nWW8BrushStyle); + nGreen += ((nBack & 0xff00)>>0x8)* (1000L - nWW8BrushStyle); + nBlue += (nBack & 0xff) * (1000L - nWW8BrushStyle); + + nApplyColor = ( (nRed/1000) << 0x10 ) + ((nGreen/1000) << 8) + nBlue/1000; + } + + pPropertyMap->Insert( m_OutputFormat == Form ? PROP_BACK_COLOR + : m_OutputFormat == Paragraph ? PROP_PARA_BACK_COLOR + : PROP_CHAR_BACK_COLOR, false, uno::makeAny( nApplyColor )); + return pPropertyMap; +} +} //namespace dmapper +} //namespace writerfilter + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/CellColorHandler.hxx b/writerfilter/source/dmapper/CellColorHandler.hxx new file mode 100644 index 000000000000..a745b8fcf73e --- /dev/null +++ b/writerfilter/source/dmapper/CellColorHandler.hxx @@ -0,0 +1,66 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef INCLUDED_CELLCOLORHANDLER_HXX +#define INCLUDED_CELLCOLORHANDLER_HXX + +#include <WriterFilterDllApi.hxx> +#include <resourcemodel/LoggedResources.hxx> +#include <boost/shared_ptr.hpp> + +namespace writerfilter { +namespace dmapper +{ +class TablePropertyMap; +class WRITERFILTER_DLLPRIVATE CellColorHandler : public LoggedProperties +{ +public: + enum OutputFormat { Form, Paragraph, Character }; // for what part of the document +private: + sal_Int32 m_nShadowType; + sal_Int32 m_nColor; + sal_Int32 m_nFillColor; + OutputFormat m_OutputFormat; + + // Properties + virtual void lcl_attribute(Id Name, Value & val); + virtual void lcl_sprm(Sprm & sprm); + +public: + CellColorHandler( ); + virtual ~CellColorHandler(); + + ::boost::shared_ptr<TablePropertyMap> getProperties(); + + void setOutputFormat( OutputFormat format ) { m_OutputFormat = format; } +}; +typedef boost::shared_ptr< CellColorHandler > CellColorHandlerPtr; +}} + +#endif // + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/CellMarginHandler.cxx b/writerfilter/source/dmapper/CellMarginHandler.cxx new file mode 100644 index 000000000000..25c2530c1b4a --- /dev/null +++ b/writerfilter/source/dmapper/CellMarginHandler.cxx @@ -0,0 +1,110 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include <CellMarginHandler.hxx> +#include <PropertyMap.hxx> +#include <doctok/resourceids.hxx> +#include <ConversionHelper.hxx> +#include <ooxml/resourceids.hxx> +#include "dmapperLoggers.hxx" + +namespace writerfilter { +namespace dmapper { + +using namespace ::com::sun::star; +using namespace ::writerfilter; + +CellMarginHandler::CellMarginHandler() : +LoggedProperties(dmapper_logger, "CellMarginHandler"), +m_nValue( 0 ), +m_nLeftMargin( 0 ), +m_bLeftMarginValid( false ), +m_nRightMargin( 0 ), +m_bRightMarginValid( false ), +m_nTopMargin( 0 ), +m_bTopMarginValid( false ), +m_nBottomMargin( 0 ), +m_bBottomMarginValid( false ) +{ +} + +CellMarginHandler::~CellMarginHandler() +{ +} + +void CellMarginHandler::lcl_attribute(Id rName, Value & rVal) +{ + sal_Int32 nIntValue = rVal.getInt(); + (void)nIntValue; + (void)rName; + switch( rName ) + { + case NS_ooxml::LN_CT_TblWidth_w: + m_nValue = ConversionHelper::convertTwipToMM100( nIntValue ); + break; + case NS_ooxml::LN_CT_TblWidth_type: + OSL_ENSURE( NS_ooxml::LN_Value_ST_TblWidth_dxa == sal::static_int_cast<Id>(nIntValue), "cell margins work for absolute values, only"); + break; + default: + OSL_FAIL( "unknown attribute"); + } +} + +void CellMarginHandler::lcl_sprm(Sprm & rSprm) +{ + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + { + pProperties.get()->resolve( *this ); + switch( rSprm.getId() ) + { + case NS_ooxml::LN_CT_TblCellMar_top: + m_nTopMargin = m_nValue; + m_bTopMarginValid = true; + break; + case NS_ooxml::LN_CT_TblCellMar_left: + m_nLeftMargin = m_nValue; + m_bLeftMarginValid = true; + break; + case NS_ooxml::LN_CT_TblCellMar_bottom: + m_nBottomMargin = m_nValue; + m_bBottomMarginValid = true; + break; + case NS_ooxml::LN_CT_TblCellMar_right: + m_nRightMargin = m_nValue; + m_bRightMarginValid = true; + break; + default: + OSL_FAIL( "unknown attribute"); + } + } + m_nValue = 0; +} +} //namespace dmapper +} //namespace writerfilter + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/CellMarginHandler.hxx b/writerfilter/source/dmapper/CellMarginHandler.hxx new file mode 100644 index 000000000000..7a36458a72c2 --- /dev/null +++ b/writerfilter/source/dmapper/CellMarginHandler.hxx @@ -0,0 +1,70 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef INCLUDED_CELLMARGINHANDLER_HXX +#define INCLUDED_CELLMARGINHANDLER_HXX + +#include <WriterFilterDllApi.hxx> +#include <resourcemodel/LoggedResources.hxx> +#include <boost/shared_ptr.hpp> + +namespace writerfilter { +namespace dmapper +{ +class TablePropertyMap; +class WRITERFILTER_DLLPRIVATE CellMarginHandler : public LoggedProperties +{ +private: + sal_Int32 m_nValue; + + // Properties + virtual void lcl_attribute(Id Name, Value & val); + virtual void lcl_sprm(Sprm & sprm); + +public: + sal_Int32 m_nLeftMargin; + bool m_bLeftMarginValid; + sal_Int32 m_nRightMargin; + bool m_bRightMarginValid; + sal_Int32 m_nTopMargin; + bool m_bTopMarginValid; + sal_Int32 m_nBottomMargin; + bool m_bBottomMarginValid; + +public: + CellMarginHandler( ); + virtual ~CellMarginHandler(); + + ::boost::shared_ptr<TablePropertyMap> getProperties(); + +}; +typedef boost::shared_ptr< CellMarginHandler > CellMarginHandlerPtr; +}} + +#endif // + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/ConversionHelper.cxx b/writerfilter/source/dmapper/ConversionHelper.cxx new file mode 100644 index 000000000000..a1ebac530a46 --- /dev/null +++ b/writerfilter/source/dmapper/ConversionHelper.cxx @@ -0,0 +1,536 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include <ConversionHelper.hxx> +#include <com/sun/star/table/BorderLine2.hpp> +#include <com/sun/star/table/BorderLineStyle.hpp> +#include <com/sun/star/lang/Locale.hpp> +#include <com/sun/star/text/HoriOrientation.hpp> +#include <com/sun/star/style/NumberingType.hpp> +#include <ooxml/resourceids.hxx> +#include <tools/color.hxx> +#include <rtl/ustrbuf.hxx> +#include <algorithm> +#include <functional> + +using namespace com::sun::star; +using namespace com::sun::star::table::BorderLineStyle; + +namespace writerfilter { +namespace dmapper{ +namespace ConversionHelper{ + +const sal_Int16 API_LINE_SOLID = 0; +const sal_Int16 API_LINE_DOTTED = 1; +const sal_Int16 API_LINE_DASHED = 2; + +#define TWIP_TO_MM100(TWIP) ((TWIP) >= 0 ? (((TWIP)*127L+36L)/72L) : (((TWIP)*127L-36L)/72L)) + +//line definitions in 1/100 mm +#define LINE_WIDTH_0 2 +#define LINE_WIDTH_1 36 +#define LINE_WIDTH_2 89 +#define LINE_WIDTH_3 142 +#define LINE_WIDTH_4 177 +#define LINE_WIDTH_5 18 + +#define DOUBLE_LINE0_OUT LINE_WIDTH_0 +#define DOUBLE_LINE0_IN LINE_WIDTH_0 +#define DOUBLE_LINE0_DIST LINE_WIDTH_1 + +#define DOUBLE_LINE1_OUT LINE_WIDTH_1 +#define DOUBLE_LINE1_IN LINE_WIDTH_1 +#define DOUBLE_LINE1_DIST LINE_WIDTH_1 + +#define DOUBLE_LINE2_OUT LINE_WIDTH_2 +#define DOUBLE_LINE2_IN LINE_WIDTH_2 +#define DOUBLE_LINE2_DIST LINE_WIDTH_2 + +#define DOUBLE_LINE3_OUT LINE_WIDTH_2 +#define DOUBLE_LINE3_IN LINE_WIDTH_1 +#define DOUBLE_LINE3_DIST LINE_WIDTH_2 + +#define DOUBLE_LINE4_OUT LINE_WIDTH_1 +#define DOUBLE_LINE4_IN LINE_WIDTH_2 +#define DOUBLE_LINE4_DIST LINE_WIDTH_1 + +#define DOUBLE_LINE5_OUT LINE_WIDTH_3 +#define DOUBLE_LINE5_IN LINE_WIDTH_2 +#define DOUBLE_LINE5_DIST LINE_WIDTH_2 + +#define DOUBLE_LINE6_OUT LINE_WIDTH_2 +#define DOUBLE_LINE6_IN LINE_WIDTH_3 +#define DOUBLE_LINE6_DIST LINE_WIDTH_2 + +#define DOUBLE_LINE7_OUT LINE_WIDTH_0 +#define DOUBLE_LINE7_IN LINE_WIDTH_0 +#define DOUBLE_LINE7_DIST LINE_WIDTH_2 + +#define DOUBLE_LINE8_OUT LINE_WIDTH_1 +#define DOUBLE_LINE8_IN LINE_WIDTH_0 +#define DOUBLE_LINE8_DIST LINE_WIDTH_2 + +#define DOUBLE_LINE9_OUT LINE_WIDTH_2 +#define DOUBLE_LINE9_IN LINE_WIDTH_0 +#define DOUBLE_LINE9_DIST LINE_WIDTH_2 + +#define DOUBLE_LINE10_OUT LINE_WIDTH_3 +#define DOUBLE_LINE10_IN LINE_WIDTH_0 +#define DOUBLE_LINE10_DIST LINE_WIDTH_2 + +sal_Int32 MakeBorderLine( sal_Int32 nSprmValue, table::BorderLine2& rToFill ) +{ + //TODO: Lines are always solid + //Border + //borders are defined as: + // 0x XX XX XX XX + // || || || || + // || || || ---- Line width in 1/8 pt + // || || || + // || || ------- Line type: 0 - none 1 - single ... 25 - engrave 3D and 64 - 230 page borders + // || || + // || ---------- Line color + // || + // ------------- seven bits line space + // -------------- first bit: with shading + sal_Int16 nLineThicknessTwip = (sal_Int16)((nSprmValue & 0xff) * 20)/8L ; + sal_Int32 nLineType = ((nSprmValue & 0xff00) >> 8); + sal_Int32 nLineColor = (nSprmValue & 0xff0000)>>16; + sal_Int32 nLineDistance = (((nSprmValue & 0x3f000000)>>24) * 2540 + 36)/72L; + sal_Int32 nLineThickness = TWIP_TO_MM100(nLineThicknessTwip); + MakeBorderLine( nLineThickness, nLineType, nLineColor, rToFill, false); + return nLineDistance; +} +void MakeBorderLine( sal_Int32 nLineThickness, sal_Int32 nLineType, + sal_Int32 nLineColor, + table::BorderLine2& rToFill, bool bIsOOXML ) +{ + static const sal_Int32 aBorderDefColor[] = + { + COL_AUTO, COL_BLACK, COL_LIGHTBLUE, COL_LIGHTCYAN, COL_LIGHTGREEN, + COL_LIGHTMAGENTA, COL_LIGHTRED, COL_YELLOW, COL_WHITE, COL_BLUE, + COL_CYAN, COL_GREEN, COL_MAGENTA, COL_RED, COL_BROWN, COL_GRAY, + COL_LIGHTGRAY + }; + //no auto color for borders + if(!nLineColor) + ++nLineColor; + if(!bIsOOXML && sal::static_int_cast<sal_uInt32>(nLineColor) < SAL_N_ELEMENTS(aBorderDefColor)) + nLineColor = aBorderDefColor[nLineColor]; + + sal_Int16 nLineStyle = NONE; + // Map to our border types, we should use of one equal line + // thickness, or one of smaller thickness. If too small we + // can make the defecit up in additional white space or + // object size + switch(nLineType) + { + // First the single lines + case 1: + case 2: + case 5: + nLineStyle = SOLID; + break; + // Dotted and dashed lines + case 6: + nLineStyle = DOTTED; + break; + case 7: + case 22: + nLineStyle = DASHED; + break; + // and the unsupported special cases which we map to a single line + case 8: + case 9: + case 20: + nLineStyle = SOLID; + break; + // Double line + case 3: + case 10: //Don't have tripple so use double + case 21: + case 23: + nLineStyle = DOUBLE; + break; + case 11: + case 13: //Don't have thin thick thin, so use thick thin + nLineStyle = THINTHICK_SMALLGAP; + break; + case 12: + nLineStyle = THICKTHIN_SMALLGAP; + break; + case 14: + nLineStyle = THINTHICK_MEDIUMGAP; + break; + case 15: + case 16: //Don't have thin thick thin, so use thick thin + nLineStyle = THICKTHIN_MEDIUMGAP; + break; + case 17: + nLineStyle = THINTHICK_LARGEGAP; + break; + case 18: + case 19: //Don't have thin thick thin, so use thick thin + nLineStyle = THICKTHIN_LARGEGAP; + break; + // Embossed and engraved lines + case 24: + nLineStyle = EMBOSSED; + break; + case 25: + nLineStyle = ENGRAVED; + break; + case 0: + case 255: + default: + break; + } + + rToFill.LineStyle = nLineStyle; + rToFill.LineWidth = sal_uInt32( nLineThickness ); + rToFill.Color = nLineColor; +} + +void lcl_SwapQuotesInField(::rtl::OUString &rFmt) +{ + //Swap unescaped " and ' with ' and " + sal_Int32 nLen = rFmt.getLength(); + ::rtl::OUStringBuffer aBuffer( rFmt.getStr() ); + const sal_Unicode* pFmt = rFmt.getStr(); + for (sal_Int32 nI = 0; nI < nLen; ++nI) + { + if ((pFmt[nI] == '\"') && (!nI || pFmt[nI-1] != '\\')) + aBuffer.setCharAt(nI, '\''); + else if ((pFmt[nI] == '\'') && (!nI || pFmt[nI-1] != '\\')) + aBuffer.setCharAt(nI, '\"'); + } + rFmt = aBuffer.makeStringAndClear(); +} +bool lcl_IsNotAM(::rtl::OUString& rFmt, sal_Int32 nPos) +{ + return ( + (nPos == rFmt.getLength() - 1) || + ( + (rFmt.getStr()[nPos+1] != 'M') && + (rFmt.getStr()[nPos+1] != 'm') + ) + ); +} + +::rtl::OUString ConvertMSFormatStringToSO( + const ::rtl::OUString& rFormat, lang::Locale& rLocale, bool bHijri) +{ + ::rtl::OUString sFormat(rFormat); + lcl_SwapQuotesInField(sFormat); + + //#102782#, #102815#, #108341# & #111944# have to work at the same time :-) + bool bForceJapanese(false); + bool bForceNatNum(false); + sal_Int32 nLen = sFormat.getLength(); + sal_Int32 nI = 0; +// const sal_Unicode* pFormat = sFormat.getStr(); + ::rtl::OUStringBuffer aNewFormat( sFormat.getStr() ); + while (nI < nLen) + { + if (aNewFormat.charAt(nI) == '\\') + nI++; + else if (aNewFormat.charAt(nI) == '\"') + { + ++nI; + //While not at the end and not at an unescaped end quote + while ((nI < nLen) && (!(aNewFormat.charAt(nI) == '\"') && (aNewFormat.charAt(nI-1) != '\\'))) + ++nI; + } + else //normal unquoted section + { + sal_Unicode nChar = aNewFormat.charAt(nI); + if (nChar == 'O') + { + aNewFormat.setCharAt(nI, 'M'); + bForceNatNum = true; + } + else if (nChar == 'o') + { + aNewFormat.setCharAt(nI, 'm'); + bForceNatNum = true; + } + else if ((nChar == 'A') && lcl_IsNotAM(sFormat, nI)) + { + aNewFormat.setCharAt(nI, 'D'); + bForceNatNum = true; + } + else if ((nChar == 'g') || (nChar == 'G')) + bForceJapanese = true; + else if ((nChar == 'a') && lcl_IsNotAM(sFormat, nI)) + bForceJapanese = true; + else if (nChar == 'E') + { + if ((nI != nLen-1) && (aNewFormat.charAt(nI+1) == 'E')) + { + //todo: this cannot be the right way to replace a part of the string! + aNewFormat.setCharAt( nI, 'Y' ); + aNewFormat.setCharAt( nI + 1, 'Y' ); + aNewFormat.insert(nI + 2, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("YY"))); + nLen+=2; + nI+=3; + } + bForceJapanese = true; + } + else if (nChar == 'e') + { + if ((nI != nLen-1) && (aNewFormat.charAt(nI+1) == 'e')) + { + //todo: this cannot be the right way to replace a part of the string! + aNewFormat.setCharAt( nI, 'y' ); + aNewFormat.setCharAt( nI + 1, 'y' ); + aNewFormat.insert(nI + 2, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("yy"))); + nLen+=2; + nI+=3; + } + bForceJapanese = true; + } + else if (nChar == '/') + { + // MM We have to escape '/' in case it's used as a char + //todo: this cannot be the right way to replace a part of the string! + aNewFormat.setCharAt( nI, '\\' ); + aNewFormat.insert(nI + 1, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"))); + nI++; + nLen++; + } + } + ++nI; + } + + if (bForceNatNum) + bForceJapanese = true; + + if (bForceJapanese) + { + rLocale.Language = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ja")); + rLocale.Country = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JP")); + } + + if (bForceNatNum) + { + aNewFormat.insert( 0, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("[NatNum1][$-411]"))); + } + + if (bHijri) + { + aNewFormat.insert( 0, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("[~hijri]"))); + } + return aNewFormat.makeStringAndClear(); + +} + + +sal_Int32 convertTwipToMM100(sal_Int32 _t) +{ + return TWIP_TO_MM100( _t ); +} + + +sal_Int32 convertEMUToMM100(sal_Int32 _t) +{ + return _t / 360; +} + +/*------------------------------------------------------------------------- + contains a color from 0xTTRRGGBB to 0xTTRRGGBB + -----------------------------------------------------------------------*/ +sal_Int32 ConvertColor(sal_Int32 nWordColor) +{ + sal_uInt8 + r(static_cast<sal_uInt8>(nWordColor&0xFF)), + g(static_cast<sal_uInt8>(((nWordColor)>>8)&0xFF)), + b(static_cast<sal_uInt8>((nWordColor>>16)&0xFF)), + t(static_cast<sal_uInt8>((nWordColor>>24)&0xFF)); + sal_Int32 nRet = (t<<24) + (r<<16) + (g<<8) + b; + return nRet; +} + + +sal_Int16 convertTableJustification( sal_Int32 nIntValue ) +{ + sal_Int16 nOrient = text::HoriOrientation::LEFT_AND_WIDTH; + switch( nIntValue ) + { + case 1 : nOrient = text::HoriOrientation::CENTER; break; + case 2 : nOrient = text::HoriOrientation::RIGHT; break; + case 0 : + //no break + default:; + + } + return nOrient; +} + +sal_Int16 ConvertNumberingType(sal_Int32 nNFC) +{ + sal_Int16 nRet; + switch(nNFC) + { + case NS_ooxml::LN_Value_ST_NumberFormat_decimal: + case 0: + nRet = style::NumberingType::ARABIC; + break; + case NS_ooxml::LN_Value_ST_NumberFormat_upperRoman: + case 1: + nRet = style::NumberingType::ROMAN_UPPER; + break; + case NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman: + case 2: + nRet = style::NumberingType::ROMAN_LOWER; + break; + case 3: + nRet = style::NumberingType::CHARS_UPPER_LETTER_N; + break; + case 4: + nRet = style::NumberingType::CHARS_LOWER_LETTER_N; + break; + case 5: + nRet = style::NumberingType::ARABIC; + break;//ORDINAL + case NS_ooxml::LN_Value_ST_NumberFormat_bullet: + case 23: + case 25: + nRet = style::NumberingType::CHAR_SPECIAL; + break; + case NS_ooxml::LN_Value_ST_NumberFormat_none: + case 255: + nRet = style::NumberingType::NUMBER_NONE; + break; + case NS_ooxml::LN_Value_ST_NumberFormat_upperLetter: + nRet = style::NumberingType::CHARS_UPPER_LETTER; + break; + case NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter: + nRet = style::NumberingType::CHARS_LOWER_LETTER; + break; + case NS_ooxml::LN_Value_ST_NumberFormat_iroha: + nRet = style::NumberingType::IROHA_HALFWIDTH_JA; + break; + case NS_ooxml::LN_Value_ST_NumberFormat_irohaFullWidth: + nRet = style::NumberingType::IROHA_FULLWIDTH_JA; + break; + case NS_ooxml::LN_Value_ST_NumberFormat_aiueo: + nRet = style::NumberingType::AIU_HALFWIDTH_JA; + break; + case NS_ooxml::LN_Value_ST_NumberFormat_aiueoFullWidth: + nRet = style::NumberingType::AIU_FULLWIDTH_JA; + break; + case NS_ooxml::LN_Value_ST_NumberFormat_hebrew2: + nRet = style::NumberingType::CHARS_HEBREW; + break; + case NS_ooxml::LN_Value_ST_NumberFormat_thaiLetters: + nRet = style::NumberingType::CHARS_THAI; + break; + case NS_ooxml::LN_Value_ST_NumberFormat_russianLower: + nRet = style::NumberingType::CHARS_CYRILLIC_LOWER_LETTER_RU; + break; + case NS_ooxml::LN_Value_ST_NumberFormat_russianUpper: + nRet = style::NumberingType::CHARS_CYRILLIC_UPPER_LETTER_RU; + break; + case NS_ooxml::LN_Value_ST_NumberFormat_decimalEnclosedCircleChinese: + case NS_ooxml::LN_Value_ST_NumberFormat_ideographEnclosedCircle: + nRet = style::NumberingType::CIRCLE_NUMBER; + break; + case NS_ooxml::LN_Value_ST_NumberFormat_ideographTraditional: + nRet = style::NumberingType::TIAN_GAN_ZH; + break; + case NS_ooxml::LN_Value_ST_NumberFormat_ideographZodiac: + nRet = style::NumberingType::DI_ZI_ZH; + break; + case NS_ooxml::LN_Value_ST_NumberFormat_ganada: + nRet = style::NumberingType::HANGUL_SYLLABLE_KO; + break; + case NS_ooxml::LN_Value_ST_NumberFormat_chosung: + nRet = style::NumberingType::HANGUL_JAMO_KO; + break; + case NS_ooxml::LN_Value_ST_NumberFormat_koreanDigital: + case NS_ooxml::LN_Value_ST_NumberFormat_koreanCounting: + case NS_ooxml::LN_Value_ST_NumberFormat_koreanDigital2: + nRet = style::NumberingType::NUMBER_HANGUL_KO; + break; + case NS_ooxml::LN_Value_ST_NumberFormat_ideographLegalTraditional: + nRet = style::NumberingType::NUMBER_UPPER_ZH_TW; + break; + case NS_ooxml::LN_Value_ST_NumberFormat_arabicAlpha: + nRet = style::NumberingType::CHARS_ARABIC; + break; + case NS_ooxml::LN_Value_ST_NumberFormat_hindiVowels: + nRet = style::NumberingType::CHARS_NEPALI; + break; + case NS_ooxml::LN_Value_ST_NumberFormat_japaneseLegal: + nRet = style::NumberingType::NUMBER_TRADITIONAL_JA; + break; + case NS_ooxml::LN_Value_ST_NumberFormat_chineseCounting: + case NS_ooxml::LN_Value_ST_NumberFormat_japaneseCounting: + case NS_ooxml::LN_Value_ST_NumberFormat_taiwaneseCounting: + case NS_ooxml::LN_Value_ST_NumberFormat_ideographDigital: + nRet = style::NumberingType::NUMBER_LOWER_ZH; + break; + default: nRet = style::NumberingType::ARABIC; + } +/* TODO: Lots of additional values are available - some are supported in the I18 framework + NS_ooxml::LN_Value_ST_NumberFormat_ordinal = 91682; + NS_ooxml::LN_Value_ST_NumberFormat_cardinalText = 91683; + NS_ooxml::LN_Value_ST_NumberFormat_ordinalText = 91684; + NS_ooxml::LN_Value_ST_NumberFormat_hex = 91685; + NS_ooxml::LN_Value_ST_NumberFormat_chicago = 91686; + NS_ooxml::LN_Value_ST_NumberFormat_decimalFullWidth = 91691; + NS_ooxml::LN_Value_ST_NumberFormat_decimalHalfWidth = 91692; + NS_ooxml::LN_Value_ST_NumberFormat_japaneseDigitalTenThousand = 91694; + NS_ooxml::LN_Value_ST_NumberFormat_decimalEnclosedCircle = 91695; + NS_ooxml::LN_Value_ST_NumberFormat_decimalFullWidth2 = 91696; + NS_ooxml::LN_Value_ST_NumberFormat_decimalZero = 91699; + NS_ooxml::LN_Value_ST_NumberFormat_decimalEnclosedFullstop = 91703; + NS_ooxml::LN_Value_ST_NumberFormat_decimalEnclosedParen = 91704; + NS_ooxml::LN_Value_ST_NumberFormat_ideographZodiacTraditional = 91709; + NS_ooxml::LN_Value_ST_NumberFormat_taiwaneseCountingThousand = 91712; + NS_ooxml::LN_Value_ST_NumberFormat_taiwaneseDigital = 91713; + NS_ooxml::LN_Value_ST_NumberFormat_chineseLegalSimplified = 91715; + NS_ooxml::LN_Value_ST_NumberFormat_chineseCountingThousand = 91716; + NS_ooxml::LN_Value_ST_NumberFormat_koreanLegal = 91719; + NS_ooxml::LN_Value_ST_NumberFormat_vietnameseCounting = 91721; + NS_ooxml::LN_Value_ST_NumberFormat_numberInDash = 91725; + NS_ooxml::LN_Value_ST_NumberFormat_arabicAbjad: + NS_ooxml::LN_Value_ST_NumberFormat_hebrew1 = 91726; + NS_ooxml::LN_Value_ST_NumberFormat_hindiConsonants = 91731; + NS_ooxml::LN_Value_ST_NumberFormat_hindiNumbers = 91732; + NS_ooxml::LN_Value_ST_NumberFormat_hindiCounting = 91733; + NS_ooxml::LN_Value_ST_NumberFormat_thaiNumbers = 91735; + NS_ooxml::LN_Value_ST_NumberFormat_thaiCounting = 91736;*/ + return nRet; +} + + +} // namespace ConversionHelper +} //namespace dmapper +} //namespace writerfilter + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/ConversionHelper.hxx b/writerfilter/source/dmapper/ConversionHelper.hxx new file mode 100644 index 000000000000..d25e62a58f97 --- /dev/null +++ b/writerfilter/source/dmapper/ConversionHelper.hxx @@ -0,0 +1,67 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef INCLUDED_DMAPPER_CONVERSIONHELPER_HXX +#define INCLUDED_DMAPPER_CONVERSIONHELPER_HXX + +#include <sal/types.h> +#include <rtl/ustring.hxx> +#include <com/sun/star/util/DateTime.hpp> +#include <com/sun/star/table/BorderLine2.hpp> +namespace com{ namespace sun{ namespace star{ + namespace lang{ + struct Locale; + } + namespace table{ + struct BorderLine2; +}}}} + +namespace writerfilter { +namespace dmapper{ +namespace ConversionHelper{ + + // create a border line and return the distance value + sal_Int32 MakeBorderLine( sal_Int32 nSprmValue, ::com::sun::star::table::BorderLine2& rToFill ); + void MakeBorderLine( sal_Int32 nLineThickness, sal_Int32 nLineType, + sal_Int32 nLineColor, + ::com::sun::star::table::BorderLine2& rToFill, bool bIsOOXML ); + //convert the number format string form MS format to SO format + ::rtl::OUString ConvertMSFormatStringToSO( + const ::rtl::OUString& rFormat, ::com::sun::star::lang::Locale& rLocale, bool bHijri); + sal_Int32 convertTwipToMM100(sal_Int32 _t); + // probably the most useless unit in the world - English Metric Units (EMU) 360 000 EMU == 1cm + sal_Int32 convertEMUToMM100(sal_Int32 _t); + sal_Int32 ConvertColor(sal_Int32 nWordColor ); + sal_Int16 convertTableJustification( sal_Int32 nIntValue ); + sal_Int16 ConvertNumberingType(sal_Int32 nNFC); + +} // namespace ConversionHelper +} //namespace dmapper +} // namespace writerfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx new file mode 100644 index 000000000000..97131a48cfe4 --- /dev/null +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -0,0 +1,3695 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include "PageBordersHandler.hxx" + +#include <dmapper/DomainMapper.hxx> +#include <resourcemodel/ResourceModelHelper.hxx> +#include <DomainMapper_Impl.hxx> +#include <ConversionHelper.hxx> +#include <NumberingManager.hxx> +#include <ThemeTable.hxx> +#include <ModelEventListener.hxx> +#include <MeasureHandler.hxx> +#include <OLEHandler.hxx> +#include <i18npool/mslangid.hxx> +#include <i18npool/paper.hxx> +#include <ooxml/OOXMLFastTokens.hxx> +#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> +#include <com/sun/star/document/XOOXMLDocumentPropertiesImporter.hpp> +#include <com/sun/star/text/HoriOrientation.hpp> +#include <com/sun/star/text/RelOrientation.hpp> +#include <com/sun/star/text/VertOrientation.hpp> +#include <com/sun/star/text/WrapTextMode.hpp> +#include <com/sun/star/text/SizeType.hpp> +#include <com/sun/star/text/XEndnotesSupplier.hpp> +#include <com/sun/star/text/XFootnotesSupplier.hpp> +#include <com/sun/star/text/XLineNumberingProperties.hpp> +#include <com/sun/star/text/XTextDocument.hpp> +#include <com/sun/star/text/XTextCursor.hpp> +#include <com/sun/star/text/XTextPortionAppend.hpp> +#include <com/sun/star/text/XParagraphAppend.hpp> +#include <com/sun/star/text/FontEmphasis.hpp> +#include <com/sun/star/awt/FontRelief.hpp> +#include <com/sun/star/awt/FontWeight.hpp> +#include <com/sun/star/awt/FontUnderline.hpp> +#include <com/sun/star/awt/FontStrikeout.hpp> +#include <com/sun/star/awt/FontSlant.hpp> +#include <com/sun/star/container/XIndexReplace.hpp> +#include <com/sun/star/drawing/XShape.hpp> +#include <com/sun/star/document/XEventBroadcaster.hpp> +#include <com/sun/star/style/ParagraphAdjust.hpp> +#include <com/sun/star/style/BreakType.hpp> +#include <com/sun/star/style/CaseMap.hpp> +#include <com/sun/star/style/LineSpacing.hpp> +#include <com/sun/star/style/LineSpacingMode.hpp> +#include <com/sun/star/table/BorderLine2.hpp> +#include <com/sun/star/text/TextGridMode.hpp> +#include <com/sun/star/text/XDocumentIndexesSupplier.hpp> +#include <com/sun/star/text/WritingMode.hpp> +#include <com/sun/star/text/WritingMode2.hpp> +#include <com/sun/star/text/XFootnote.hpp> +#include <com/sun/star/style/NumberingType.hpp> +#include <comphelper/types.hxx> +#include <comphelper/storagehelper.hxx> + +#include <rtl/ustrbuf.hxx> +#include <boost/shared_ptr.hpp> +#include <com/sun/star/uno/Any.hxx> +#include <tools/color.hxx> +#include <BorderHandler.hxx> +#include <CellColorHandler.hxx> +#include <SectionColumnHandler.hxx> +#include <vector> +#include <iostream> + +#if OSL_DEBUG_LEVEL > 0 +#include <resourcemodel/QNameToString.hxx> +#endif + +#include <resourcemodel/TagLogger.hxx> + +using namespace ::com::sun::star; +using namespace ::rtl; + +namespace writerfilter { + +using resourcemodel::resolveSprmProps; +using resourcemodel::resolveAttributeProperties; + +namespace dmapper{ + +TagLogger::Pointer_t dmapper_logger(TagLogger::getInstance("DOMAINMAPPER")); + +struct _PageSz +{ + sal_Int32 code; + sal_Int32 h; + bool orient; + sal_Int32 w; +} CT_PageSz; + + +DomainMapper::DomainMapper( const uno::Reference< uno::XComponentContext >& xContext, + uno::Reference< io::XInputStream > xInputStream, + uno::Reference< lang::XComponent > xModel, + SourceDocumentType eDocumentType) : +LoggedProperties(dmapper_logger, "DomainMapper"), +LoggedTable(dmapper_logger, "DomainMapper"), +LoggedStream(dmapper_logger, "DomainMapper"), + m_pImpl( new DomainMapper_Impl( *this, xContext, xModel, eDocumentType )), + mnBackgroundColor(0), mbIsHighlightSet(false) +{ + // #i24363# tab stops relative to indent + m_pImpl->SetDocumentSettingsProperty( + PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_TABS_RELATIVE_TO_INDENT ), + uno::makeAny( false ) ); + + m_pImpl->SetDocumentSettingsProperty( + PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_ADD_PARA_TABLE_SPACING ), + uno::makeAny( false ) ); + + //import document properties + + try + { + uno::Reference< lang::XMultiServiceFactory > xFactory(xContext->getServiceManager(), uno::UNO_QUERY_THROW); + uno::Reference< embed::XStorage > xDocumentStorage = + (comphelper::OStorageHelper::GetStorageOfFormatFromInputStream(OFOPXML_STORAGE_FORMAT_STRING, xInputStream)); + + uno::Reference< uno::XInterface > xTemp = xContext->getServiceManager()->createInstanceWithContext( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.OOXMLDocumentPropertiesImporter")), + xContext); + + uno::Reference< document::XOOXMLDocumentPropertiesImporter > xImporter( xTemp, uno::UNO_QUERY_THROW ); + uno::Reference< document::XDocumentPropertiesSupplier > xPropSupplier( xModel, uno::UNO_QUERY_THROW); + xImporter->importProperties( xDocumentStorage, xPropSupplier->getDocumentProperties() ); + } + catch( const uno::Exception& rEx ) + { + (void)rEx; + } +} + +DomainMapper::~DomainMapper() +{ + try + { + uno::Reference< text::XDocumentIndexesSupplier> xIndexesSupplier( m_pImpl->GetTextDocument(), uno::UNO_QUERY ); + uno::Reference< container::XIndexAccess > xIndexes = xIndexesSupplier->getDocumentIndexes(); + sal_Int32 nIndexes = xIndexes->getCount(); + if( nIndexes ) + { + //index update has to wait until first view is created + uno::Reference< document::XEventBroadcaster > xBroadcaster(xIndexesSupplier, uno::UNO_QUERY); + xBroadcaster->addEventListener(uno::Reference< document::XEventListener >(new ModelEventListener)); + } + + + // Apply the document settings after everything else + m_pImpl->GetSettingsTable()->ApplyProperties( m_pImpl->GetTextDocument( ) ); + } + catch( const uno::Exception& rEx ) + { + (void)rEx; + } + + delete m_pImpl; +} + +void DomainMapper::lcl_attribute(Id nName, Value & val) +{ + static ::rtl::OUString sLocalBookmarkName; + sal_Int32 nIntValue = val.getInt(); + rtl::OUString sStringValue = val.getString(); + + SectionPropertyMap * pSectionContext = m_pImpl->GetSectionContext(); + + if( nName >= NS_rtf::LN_WIDENT && nName <= NS_rtf::LN_LCBSTTBFUSSR ) + m_pImpl->GetFIB().SetData( nName, nIntValue ); + else + { + + + switch( nName ) + { + /* attributes to be ignored */ + case NS_rtf::LN_UNUSED1_3: + case NS_rtf::LN_UNUSED1_7: + case NS_rtf::LN_UNUSED8_3: + case NS_rtf::LN_FWRITERESERVATION: + case NS_rtf::LN_FLOADOVERRIDE: + case NS_rtf::LN_FFAREAST: + case NS_rtf::LN_FCRYPTO: + case NS_rtf::LN_NFIBBACK: + case NS_rtf::LN_LKEY: + case NS_rtf::LN_ENVR: + case NS_rtf::LN_FMAC: + case NS_rtf::LN_FWORD97SAVED: + case NS_rtf::LN_FCMAC: + case NS_rtf::LN_PNFBPCHPFIRST_W6: + case NS_rtf::LN_PNCHPFIRST_W6: + case NS_rtf::LN_CPNBTECHP_W6: + case NS_rtf::LN_PNFBPPAPFIRST_W6: + case NS_rtf::LN_PNPAPFIRST_W6: + case NS_rtf::LN_CPNBTEPAP_W6: + case NS_rtf::LN_PNFBPLVCFIRST_W6: + case NS_rtf::LN_PNLVCFIRST_W6: + case NS_rtf::LN_CPNBTELVC_W6: + case NS_rtf::LN_CBMAC: + case NS_rtf::LN_LPRODUCTCREATED: + case NS_rtf::LN_LPRODUCTREVISED: + case NS_rtf::LN_CCPMCR: + case NS_rtf::LN_PNFBPCHPFIRST: + case NS_rtf::LN_PNFBPPAPFIRST: + case NS_rtf::LN_PNFBPLVCFIRST: + case NS_rtf::LN_FCISLANDFIRST: + case NS_rtf::LN_FCISLANDLIM: + case NS_rtf::LN_FCSTSHFORIG: + case NS_rtf::LN_LCBSTSHFORIG: + case NS_rtf::LN_FCPLCFPAD: + case NS_rtf::LN_LCBPLCFPAD: + case NS_rtf::LN_FCSTTBFGLSY: + case NS_rtf::LN_LCBSTTBFGLSY: + case NS_rtf::LN_FCPLCFGLSY: + case NS_rtf::LN_LCBPLCFGLSY: + case NS_rtf::LN_FCPLCFSEA: + case NS_rtf::LN_LCBPLCFSEA: + case NS_rtf::LN_FCPLCFFLDMCR: + case NS_rtf::LN_LCBPLCFFLDMCR: + case NS_rtf::LN_FCCMDS: + case NS_rtf::LN_LCBCMDS: + case NS_rtf::LN_FCPLCMCR: + case NS_rtf::LN_LCBPLCMCR: + case NS_rtf::LN_FCSTTBFMCR: + case NS_rtf::LN_LCBSTTBFMCR: + case NS_rtf::LN_FCPRDRVR: + case NS_rtf::LN_LCBPRDRVR: + case NS_rtf::LN_FCPRENVPORT: + case NS_rtf::LN_LCBPRENVPORT: + case NS_rtf::LN_FCPRENVLAND: + case NS_rtf::LN_LCBPRENVLAND: + case NS_rtf::LN_FCWSS: + case NS_rtf::LN_LCBWSS: + case NS_rtf::LN_FCPLCFPGDFTN: + case NS_rtf::LN_LCBPLCFPGDFTN: + case NS_rtf::LN_FCAUTOSAVESOURCE: + case NS_rtf::LN_LCBAUTOSAVESOURCE: + case NS_rtf::LN_FCPLCDOAMOM: + case NS_rtf::LN_LCBPLCDOAMOM: + case NS_rtf::LN_FCPLCDOAHDR: + case NS_rtf::LN_LCBPLCDOAHDR: + case NS_rtf::LN_FCPMS: + case NS_rtf::LN_LCBPMS: + case NS_rtf::LN_FCPLCFPGDEDN: + case NS_rtf::LN_LCBPLCFPGDEDN: + case NS_rtf::LN_FCPLCFWKB: + case NS_rtf::LN_LCBPLCFWKB: + case NS_rtf::LN_FCPLCFSPL: + case NS_rtf::LN_LCBPLCFSPL: + case NS_rtf::LN_FCSTWUSER: + case NS_rtf::LN_LCBSTWUSER: + case NS_rtf::LN_FCUNUSED: + case NS_rtf::LN_LCBUNUSED: + case NS_rtf::LN_FCSTTBFINTLFLD: + case NS_rtf::LN_LCBSTTBFINTLFLD: + case NS_rtf::LN_FCROUTESLIP: + case NS_rtf::LN_LCBROUTESLIP: + case NS_rtf::LN_FCSTTBSAVEDBY: + case NS_rtf::LN_LCBSTTBSAVEDBY: + case NS_rtf::LN_FCSTTBFNM: + case NS_rtf::LN_LCBSTTBFNM: + case NS_rtf::LN_FCDOCUNDO: + case NS_rtf::LN_LCBDOCUNDO: + case NS_rtf::LN_FCRGBUSE: + case NS_rtf::LN_LCBRGBUSE: + case NS_rtf::LN_FCUSP: + case NS_rtf::LN_LCBUSP: + case NS_rtf::LN_FCUSKF: + case NS_rtf::LN_LCBUSKF: + case NS_rtf::LN_FCPLCUPCRGBUSE: + case NS_rtf::LN_LCBPLCUPCRGBUSE: + case NS_rtf::LN_FCPLCUPCUSP: + case NS_rtf::LN_LCBPLCUPCUSP: + case NS_rtf::LN_FCPLGOSL: + case NS_rtf::LN_LCBPLGOSL: + case NS_rtf::LN_FCPLCOCX: + case NS_rtf::LN_LCBPLCOCX: + case NS_rtf::LN_DWLOWDATETIME: + case NS_rtf::LN_DWHIGHDATETIME: + case NS_rtf::LN_FCPLCASUMY: + case NS_rtf::LN_LCBPLCASUMY: + case NS_rtf::LN_FCPLCFGRAM: + case NS_rtf::LN_LCBPLCFGRAM: + case NS_rtf::LN_FCSTTBFUSSR: + break; + + case NS_rtf::LN_ISTD: //index of applied style + { + //search for the style with the given id and apply it + //as CharStyleName or ParaStyleName + //if the style is a user defined style then it must have an ISTD - built-in styles might not have it + StyleSheetTablePtr pStyleSheets = m_pImpl->GetStyleSheetTable(); + ::rtl::OUString sValue = ::rtl::OUString::valueOf(nIntValue, 16); + const StyleSheetEntryPtr pEntry = pStyleSheets->FindStyleSheetByISTD(sValue); + if( pEntry.get( ) ) + { + bool bParaStyle = (pEntry->nStyleTypeCode == STYLE_TYPE_PARA); + if(bParaStyle) + m_pImpl->SetCurrentParaStyleId(::rtl::OUString::valueOf(static_cast<sal_Int32>(nIntValue), 16)); + if (m_pImpl->GetTopContext() && m_pImpl->GetTopContextType() != CONTEXT_SECTION) + m_pImpl->GetTopContext()->Insert( + bParaStyle ? + PROP_PARA_STYLE_NAME : PROP_CHAR_STYLE_NAME, + true, + uno::makeAny( + m_pImpl->GetStyleSheetTable()->ConvertStyleName( pEntry->sStyleName ) ) ); + } + } + break; + case NS_rtf::LN_ISTARTAT: + break; + case NS_rtf::LN_NFC: + break; + case NS_rtf::LN_FLEGAL: + break; + case NS_rtf::LN_FNORESTART: + break; + case NS_rtf::LN_FIDENTSAV: + break; + case NS_rtf::LN_FCONVERTED: + break; + case NS_rtf::LN_FTENTATIVE: + break; + case NS_rtf::LN_RGBXCHNUMS: + break; + case NS_rtf::LN_IXCHFOLLOW: + break; + case NS_rtf::LN_DXASPACE: + break; + case NS_rtf::LN_DXAINDENT: + break; + case NS_rtf::LN_CBGRPPRLCHPX: + break; + case NS_rtf::LN_CBGRPPRLPAPX: + break; + case NS_rtf::LN_LSID: + break; + case NS_rtf::LN_TPLC: + break; + case NS_rtf::LN_RGISTD: + break; + case NS_rtf::LN_FSIMPLELIST: + break; + case NS_rtf::LN_fAutoNum: + break; + case NS_rtf::LN_fHybrid: + break; + case NS_rtf::LN_ILVL: + break; + case NS_rtf::LN_FSTARTAT: + break; + case NS_rtf::LN_FFORMATTING: + break; + case NS_rtf::LN_UNSIGNED4_6: + break; + case NS_rtf::LN_clfolvl: + break; + case NS_rtf::LN_CBFFNM1: + break; + case NS_rtf::LN_PRQ: + break; + case NS_rtf::LN_FTRUETYPE: + break; + case NS_rtf::LN_FF: + break; + case NS_rtf::LN_WWEIGHT: + break; + case NS_rtf::LN_CHS: + + { + m_pImpl->GetFIB().SetLNCHS( nIntValue ); + } + break; + case NS_rtf::LN_IXCHSZALT: + break; + case NS_rtf::LN_PANOSE: + break; + case NS_rtf::LN_FS: + break; + case NS_rtf::LN_STI: + break; + case NS_rtf::LN_FSCRATCH: + break; + case NS_rtf::LN_FINVALHEIGHT: + break; + case NS_rtf::LN_FHASUPE: + break; + case NS_rtf::LN_FMASSCOPY: + break; + case NS_rtf::LN_SGC: + break; + case NS_rtf::LN_ISTDBASE: + break; + case NS_rtf::LN_CUPX: + break; + case NS_rtf::LN_ISTDNEXT: + break; + case NS_rtf::LN_BCHUPE: + break; + case NS_rtf::LN_FAUTOREDEF: + break; + case NS_rtf::LN_FHIDDEN: + break; + case NS_rtf::LN_CSTD: + break; + case NS_rtf::LN_CBSTDBASEINFILE: + break; + case NS_rtf::LN_FSTDSTYLENAMESWRITTEN: + break; + case NS_rtf::LN_UNUSED4_2: + break; + case NS_rtf::LN_STIMAXWHENSAVED: + break; + case NS_rtf::LN_ISTDMAXFIXEDWHENSAVED: + break; + case NS_rtf::LN_NVERBUILTINNAMESWHENSAVED: + break; + case NS_rtf::LN_RGFTCSTANDARDCHPSTSH: + break; + case NS_rtf::LN_WIDENT: + + case NS_rtf::LN_NFIB: + + case NS_rtf::LN_NPRODUCT: + case NS_rtf::LN_LID: + case NS_rtf::LN_PNNEXT: + case NS_rtf::LN_FDOT: + case NS_rtf::LN_FGLSY: + case NS_rtf::LN_FCOMPLEX: + case NS_rtf::LN_FHASPIC: + case NS_rtf::LN_CQUICKSAVES: + case NS_rtf::LN_FENCRYPTED: + case NS_rtf::LN_FWHICHTBLSTM: + case NS_rtf::LN_FREADONLYRECOMMENDED: + case NS_rtf::LN_FEXTCHAR: + case NS_rtf::LN_FEMPTYSPECIAL: + case NS_rtf::LN_FLOADOVERRIDEPAGE: + case NS_rtf::LN_FFUTURESAVEDUNDO: + case NS_rtf::LN_FSPARE0: + case NS_rtf::LN_CHSTABLES: + case NS_rtf::LN_FCMIN: + case NS_rtf::LN_CSW: + case NS_rtf::LN_WMAGICCREATED: + case NS_rtf::LN_WMAGICREVISED: + case NS_rtf::LN_WMAGICCREATEDPRIVATE: + case NS_rtf::LN_WMAGICREVISEDPRIVATE: + case NS_rtf::LN_LIDFE: + case NS_rtf::LN_CLW: + case NS_rtf::LN_CCPTEXT: + case NS_rtf::LN_CCPFTN: + case NS_rtf::LN_CCPHDD: + case NS_rtf::LN_CCPATN: + case NS_rtf::LN_CCPEDN: + case NS_rtf::LN_CCPTXBX: + case NS_rtf::LN_CCPHDRTXBX: + case NS_rtf::LN_PNCHPFIRST: + case NS_rtf::LN_CPNBTECHP: + case NS_rtf::LN_PNPAPFIRST: + case NS_rtf::LN_CPNBTEPAP: + case NS_rtf::LN_PNLVCFIRST: + case NS_rtf::LN_CPNBTELVC: + case NS_rtf::LN_CFCLCB: + case NS_rtf::LN_FCSTSHF: + case NS_rtf::LN_LCBSTSHF: + case NS_rtf::LN_FCPLCFFNDREF: + case NS_rtf::LN_LCBPLCFFNDREF: + case NS_rtf::LN_FCPLCFFNDTXT: + case NS_rtf::LN_LCBPLCFFNDTXT: + case NS_rtf::LN_FCPLCFANDREF: + case NS_rtf::LN_LCBPLCFANDREF: + case NS_rtf::LN_FCPLCFANDTXT: + case NS_rtf::LN_LCBPLCFANDTXT: + case NS_rtf::LN_FCPLCFSED: + case NS_rtf::LN_LCBPLCFSED: + case NS_rtf::LN_FCPLCFPHE: + case NS_rtf::LN_LCBPLCFPHE: + case NS_rtf::LN_FCPLCFHDD: + case NS_rtf::LN_LCBPLCFHDD: + case NS_rtf::LN_FCPLCFBTECHPX: + case NS_rtf::LN_LCBPLCFBTECHPX: + case NS_rtf::LN_FCPLCFBTEPAPX: + case NS_rtf::LN_LCBPLCFBTEPAPX: + case NS_rtf::LN_FCSTTBFFFN: + case NS_rtf::LN_LCBSTTBFFFN: + case NS_rtf::LN_FCPLCFFLDMOM: + case NS_rtf::LN_LCBPLCFFLDMOM: + case NS_rtf::LN_FCPLCFFLDHDR: + case NS_rtf::LN_LCBPLCFFLDHDR: + case NS_rtf::LN_FCPLCFFLDFTN: + case NS_rtf::LN_LCBPLCFFLDFTN: + case NS_rtf::LN_FCPLCFFLDATN: + case NS_rtf::LN_LCBPLCFFLDATN: + case NS_rtf::LN_FCSTTBFBKMK: + case NS_rtf::LN_LCBSTTBFBKMK: + case NS_rtf::LN_FCPLCFBKF: + case NS_rtf::LN_LCBPLCFBKF: + case NS_rtf::LN_FCPLCFBKL: + case NS_rtf::LN_LCBPLCFBKL: + case NS_rtf::LN_FCDOP: + case NS_rtf::LN_LCBDOP: + case NS_rtf::LN_FCSTTBFASSOC: + case NS_rtf::LN_LCBSTTBFASSOC: + case NS_rtf::LN_FCCLX: + case NS_rtf::LN_LCBCLX: + case NS_rtf::LN_FCGRPXSTATNOWNERS: + case NS_rtf::LN_LCBGRPXSTATNOWNERS: + case NS_rtf::LN_FCSTTBFATNBKMK: + case NS_rtf::LN_LCBSTTBFATNBKMK: + case NS_rtf::LN_FCPLCSPAMOM: + case NS_rtf::LN_LCBPLCSPAMOM: + case NS_rtf::LN_FCPLCSPAHDR: + case NS_rtf::LN_LCBPLCSPAHDR: + case NS_rtf::LN_FCPLCFATNBKF: + case NS_rtf::LN_LCBPLCFATNBKF: + case NS_rtf::LN_FCPLCFATNBKL: + case NS_rtf::LN_LCBPLCFATNBKL: + case NS_rtf::LN_FCFORMFLDSTTBF: + case NS_rtf::LN_LCBFORMFLDSTTBF: + case NS_rtf::LN_FCPLCFENDREF: + case NS_rtf::LN_LCBPLCFENDREF: + case NS_rtf::LN_FCPLCFENDTXT: + case NS_rtf::LN_LCBPLCFENDTXT: + case NS_rtf::LN_FCPLCFFLDEDN: + case NS_rtf::LN_LCBPLCFFLDEDN: + case NS_rtf::LN_FCDGGINFO: + case NS_rtf::LN_LCBDGGINFO: + case NS_rtf::LN_FCSTTBFRMARK: + case NS_rtf::LN_LCBSTTBFRMARK: + case NS_rtf::LN_FCSTTBFCAPTION: + case NS_rtf::LN_LCBSTTBFCAPTION: + case NS_rtf::LN_FCSTTBFAUTOCAPTION: + case NS_rtf::LN_LCBSTTBFAUTOCAPTION: + case NS_rtf::LN_LCBPLCFTXBXTXT: + case NS_rtf::LN_FCPLCFFLDTXBX: + case NS_rtf::LN_LCBPLCFFLDTXBX: + case NS_rtf::LN_FCPLCFHDRTXBXTXT: + case NS_rtf::LN_LCBPLCFHDRTXBXTXT: + case NS_rtf::LN_FCPLCFFLDHDRTXBX: + case NS_rtf::LN_LCBPLCFFLDHDRTXBX: + case NS_rtf::LN_FCSTTBTTMBD: + case NS_rtf::LN_LCBSTTBTTMBD: + case NS_rtf::LN_FCPGDMOTHER: + case NS_rtf::LN_LCBPGDMOTHER: + case NS_rtf::LN_FCBKDMOTHER: + case NS_rtf::LN_LCBBKDMOTHER: + case NS_rtf::LN_FCPGDFTN: + case NS_rtf::LN_LCBPGDFTN: + case NS_rtf::LN_FCBKDFTN: + case NS_rtf::LN_LCBBKDFTN: + case NS_rtf::LN_FCPGDEDN: + case NS_rtf::LN_LCBPGDEDN: + case NS_rtf::LN_FCBKDEDN: + case NS_rtf::LN_LCBBKDEDN: + case NS_rtf::LN_FCPLCFLST: + case NS_rtf::LN_LCBPLCFLST: + case NS_rtf::LN_FCPLFLFO: + case NS_rtf::LN_LCBPLFLFO: + case NS_rtf::LN_FCPLCFTXBXBKD: + case NS_rtf::LN_LCBPLCFTXBXBKD: + case NS_rtf::LN_FCPLCFTXBXHDRBKD: + case NS_rtf::LN_LCBPLCFTXBXHDRBKD: + case NS_rtf::LN_FCSTTBGLSYSTYLE: + case NS_rtf::LN_LCBSTTBGLSYSTYLE: + case NS_rtf::LN_FCPLCFBTELVC: + case NS_rtf::LN_LCBPLCFBTELVC: + case NS_rtf::LN_FCPLCFLVC: + case NS_rtf::LN_LCBPLCFLVC: + case NS_rtf::LN_FCSTTBLISTNAMES: + case NS_rtf::LN_LCBSTTBLISTNAMES: + case NS_rtf::LN_LCBSTTBFUSSR: + { + m_pImpl->GetFIB().SetData( nName, nIntValue ); + } + break; + case NS_rtf::LN_FN: + case NS_rtf::LN_FCSEPX: + case NS_rtf::LN_FNMPR: + case NS_rtf::LN_FCMPR: + + //section descriptor, unused or internally used + break; + case NS_rtf::LN_ICOFORE: + break; + case NS_rtf::LN_ICOBACK: + break; + case NS_rtf::LN_IPAT: + break; + case NS_rtf::LN_SHDFORECOLOR: + break; + case NS_rtf::LN_SHDBACKCOLOR: + break; + case NS_rtf::LN_SHDPATTERN: + break; + case NS_rtf::LN_DPTLINEWIDTH: + break; + case NS_rtf::LN_BRCTYPE: + break; + case NS_rtf::LN_ICO: + break; + case NS_rtf::LN_DPTSPACE: + break; + case NS_rtf::LN_FSHADOW: + break; + case NS_rtf::LN_FFRAME: + break; + case NS_rtf::LN_UNUSED2_15: + break; + case NS_rtf::LN_FFIRSTMERGED: + break; + case NS_rtf::LN_FMERGED: + break; + case NS_rtf::LN_FVERTICAL: + break; + case NS_rtf::LN_FBACKWARD: + break; + case NS_rtf::LN_FROTATEFONT: + break; + case NS_rtf::LN_FVERTMERGE: + break; + case NS_rtf::LN_FVERTRESTART: + break; + case NS_rtf::LN_VERTALIGN: + break; + case NS_rtf::LN_FUNUSED: + break; + case NS_rtf::LN_BRCTOP: + case NS_rtf::LN_BRCLEFT: + case NS_rtf::LN_BRCBOTTOM: + case NS_rtf::LN_BRCRIGHT: + { + table::BorderLine2 aBorderLine; + sal_Int32 nLineDistance = ConversionHelper::MakeBorderLine( nIntValue, aBorderLine ); + (void)nLineDistance; + PropertyIds eBorderId = PROP_LEFT_BORDER; + PropertyIds eBorderDistId = PROP_LEFT_BORDER_DISTANCE ; + switch( nName ) + { + case NS_rtf::LN_BRCTOP: + eBorderId = PROP_TOP_BORDER ; + eBorderDistId = PROP_TOP_BORDER_DISTANCE; + break; + case NS_rtf::LN_BRCLEFT: + break; + case NS_rtf::LN_BRCBOTTOM: + eBorderId = PROP_BOTTOM_BORDER ; + eBorderDistId = PROP_BOTTOM_BORDER_DISTANCE; + break; + case NS_rtf::LN_BRCRIGHT: + eBorderId = PROP_RIGHT_BORDER ; + eBorderDistId = PROP_RIGHT_BORDER_DISTANCE ; + break; + default:; + } + //todo: where to put the border properties + //rContext->Insert(eBorderId, uno::makeAny( aBorderLine )); + //rContext->Insert(eBorderDistId, uno::makeAny( nLineDistance )); + (void)eBorderId; + (void)eBorderDistId; + } + break; + case NS_rtf::LN_ITCFIRST: + break; + case NS_rtf::LN_FPUB: + break; + case NS_rtf::LN_ITCLIM: + break; + case NS_rtf::LN_FCOL: + break; + case NS_rtf::LN_LINECOLOR: + break; + case NS_rtf::LN_LINEWIDTH: + break; + case NS_rtf::LN_LINETYPE: + break; + case NS_rtf::LN_MM: + break; + case NS_rtf::LN_XEXT: + break; + case NS_rtf::LN_YEXT: + break; + case NS_rtf::LN_HMF: + break; + case NS_rtf::LN_LCB: + break; + case NS_rtf::LN_CBHEADER: + break; + case NS_rtf::LN_MFP: + break; + case NS_rtf::LN_BM_RCWINMF: + break; + case NS_rtf::LN_DXAGOAL: + break; + case NS_rtf::LN_DYAGOAL: + break; + case NS_rtf::LN_MX: + break; + case NS_rtf::LN_MY: + break; + case NS_rtf::LN_DXACROPLEFT: + break; + case NS_rtf::LN_DYACROPTOP: + break; + case NS_rtf::LN_DXACROPRIGHT: + break; + case NS_rtf::LN_DYACROPBOTTOM: + break; + case NS_rtf::LN_BRCL: + break; + case NS_rtf::LN_FFRAMEEMPTY: + break; + case NS_rtf::LN_FBITMAP: + break; + case NS_rtf::LN_FDRAWHATCH: + break; + case NS_rtf::LN_FERROR: + break; + case NS_rtf::LN_BPP: + break; + case NS_rtf::LN_DXAORIGIN: + break; + case NS_rtf::LN_DYAORIGIN: + break; + case NS_rtf::LN_CPROPS: + break; + case NS_rtf::LN_LINEPROPSTOP: + break; + case NS_rtf::LN_LINEPROPSLEFT: + break; + case NS_rtf::LN_LINEPROPSBOTTOM: + break; + case NS_rtf::LN_LINEPROPSRIGHT: + break; + case NS_rtf::LN_LINEPROPSHORIZONTAL: + break; + case NS_rtf::LN_LINEPROPSVERTICAL: + break; + case NS_rtf::LN_headerr: + break; + case NS_rtf::LN_footerr: + break; + case NS_rtf::LN_endnote: + break; + case NS_rtf::LN_BOOKMARKNAME: + // sStringValue contains the bookmark name + sLocalBookmarkName = sStringValue; + break; + case NS_rtf::LN_IBKL: + //contains the bookmark identifier - has to be added to the bookmark name imported before + //if it is already available then the bookmark should be inserted + m_pImpl->AddBookmark( sLocalBookmarkName, sStringValue ); + sLocalBookmarkName = ::rtl::OUString(); + break; + case NS_rtf::LN_LISTLEVEL: + break; + case NS_rtf::LN_LFOData: + break; + case NS_rtf::LN_F: + break; + case NS_rtf::LN_ALTFONTNAME: + break; + case NS_rtf::LN_XSZFFN: + break; + case NS_rtf::LN_XSTZNAME: + break; + case NS_rtf::LN_XSTZNAME1: + break; + case NS_rtf::LN_UPXSTART: + break; + case NS_rtf::LN_UPX: + break; + case NS_rtf::LN_sed: + //section properties + resolveAttributeProperties(*this, val); + break; + case NS_rtf::LN_tbdAdd: + // + { + writerfilter::Reference<Properties>::Pointer_t pProperties = val.getProperties(); + if( pProperties.get()) + { + pProperties->resolve(*this); + //increment to the next tab stop + m_pImpl->NextTabStop(); + } + } + break; + case NS_rtf::LN_dxaDel: + //deleted tab + case NS_rtf::LN_dxaAdd: + //set tab + case NS_rtf::LN_TLC: + //tab leading characters - for decimal tabs + case NS_rtf::LN_JC: + //tab justification + m_pImpl->ModifyCurrentTabStop(nName, nIntValue); + break; + case NS_rtf::LN_UNUSED0_6: + // really unused + break; + case NS_rtf::LN_rgbrc: + break; + case NS_rtf::LN_shd: + break; + case NS_rtf::LN_cellShd: + break; + case NS_rtf::LN_cellTopColor: + case NS_rtf::LN_cellLeftColor: + case NS_rtf::LN_cellBottomColor: + case NS_rtf::LN_cellRightColor: + OSL_FAIL("handled by DomainMapperTableManager"); + break; + + case NS_rtf::LN_LISTTABLE: + break; + case NS_rtf::LN_LFOTABLE: + break; + case NS_rtf::LN_FONTTABLE: + break; + case NS_rtf::LN_STYLESHEET: + break; + + case NS_rtf::LN_fcEastAsianLayout: + /* it seems that the value is following: + ???? XX YYYY ZZ + where + XX seems to be the run id + ZZ is the length of the function that is normally 6 + Lower byte of YYYY determines whether it is + vertical text flow (0x01), or + two lines in one layout (0x02). + For 0x01, if the higher byte of YYYY is zero, the text is not scaled to fit the line height, + in oposite case, it is to be scaled. + For 0x02, the higher byte of YYYY is determinig the prefix and suffix of the run: + no brackets (0x00) , + () round brackets (0x01), + [] square backets (0x02), + <> angle brackets (0x03) and + {} curly brackets (0x04). + ???? is different and we do not know its signification + */ + + if ((nIntValue & 0x000000FF) == 6) + { + switch ((nIntValue & 0x0000FF00) >> 8) + { + case 1: // vertical text + if (m_pImpl->GetTopContext()) + { + m_pImpl->GetTopContext()->Insert(PROP_CHAR_ROTATION, true, uno::makeAny ( sal_Int16(900) )); + m_pImpl->GetTopContext()->Insert(PROP_CHAR_ROTATION_IS_FIT_TO_LINE, true, uno::makeAny (((nIntValue & 0x00FF0000) >> 16) != 0)); + } + break; + case 2: // two lines in one + if (m_pImpl->GetTopContext()) + { + m_pImpl->GetTopContext()->Insert(PROP_CHAR_COMBINE_IS_ON, true, uno::makeAny ( true )); + m_pImpl->GetTopContext()->Insert(PROP_CHAR_COMBINE_PREFIX, true, uno::makeAny ( getBracketStringFromEnum((nIntValue & 0x00FF0000) >> 16))); + m_pImpl->GetTopContext()->Insert(PROP_CHAR_COMBINE_SUFFIX, true, uno::makeAny ( getBracketStringFromEnum((nIntValue & 0x00FF0000) >> 16, false))); + } + break; + default: + break; + } + } + break; + case NS_rtf::LN_FRD : + //footnote reference descriptor, if nIntValue > 0 then automatic, custom otherwise + //ignored + break; + case NS_rtf::LN_FONT: //font of footnote symbol + if (m_pImpl->GetTopContext()) + m_pImpl->GetTopContext()->SetFootnoteFontId( nIntValue ); + break; + case NS_ooxml::LN_CT_Sym_char: + if( m_pImpl->GetTopContext() && m_pImpl->GetTopContext()->GetFootnote().is()) + { + m_pImpl->GetTopContext()->GetFootnote()->setLabel(::rtl::OUString( sal_Unicode(nIntValue))); + break; + } + else //it's a _real_ symbol + { + utext( reinterpret_cast < const sal_uInt8 * >( &nIntValue ), 1 ); + } + break; + case NS_rtf::LN_CHAR: //footnote symbol character + if (m_pImpl->GetTopContext()) + m_pImpl->GetTopContext()->SetFootnoteSymbol( sal_Unicode(nIntValue)); + break; + case NS_ooxml::LN_CT_Sym_font: + //the footnote symbol and font are provided after the footnote is already inserted + if( m_pImpl->GetTopContext() && m_pImpl->GetTopContext()->GetFootnote().is()) + { + uno::Reference< beans::XPropertySet > xAnchorProps( m_pImpl->GetTopContext()->GetFootnote()->getAnchor(), uno::UNO_QUERY ); + xAnchorProps->setPropertyValue( + PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_CHAR_FONT_NAME), + uno::makeAny( sStringValue )); + } + else //a real symbol + if (m_pImpl->GetTopContext()) + m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME, true, uno::makeAny( sStringValue )); + break; + case NS_ooxml::LN_CT_Underline_val: + handleUnderlineType(nIntValue, m_pImpl->GetTopContext()); + break; + case NS_ooxml::LN_CT_Color_val: + if (m_pImpl->GetTopContext()) + m_pImpl->GetTopContext()->Insert(PROP_CHAR_COLOR, true, uno::makeAny( nIntValue ) ); + break; + case NS_ooxml::LN_CT_Underline_color: + if (m_pImpl->GetTopContext()) + { + m_pImpl->GetTopContext()->Insert(PROP_CHAR_UNDERLINE_HAS_COLOR, true, uno::makeAny( true ) ); + m_pImpl->GetTopContext()->Insert(PROP_CHAR_UNDERLINE_COLOR, true, uno::makeAny( nIntValue ) ); + } + break; + + case NS_ooxml::LN_CT_TabStop_val: + if (sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_ST_TabJc_clear) + { + m_pImpl->m_aCurrentTabStop.bDeleted = true; + } + else + { + m_pImpl->m_aCurrentTabStop.bDeleted = false; + m_pImpl->m_aCurrentTabStop.Alignment = getTabAlignFromValue(nIntValue); + } + break; + case NS_ooxml::LN_CT_TabStop_leader: + m_pImpl->m_aCurrentTabStop.FillChar = getFillCharFromValue(nIntValue); + break; + case NS_ooxml::LN_CT_TabStop_pos: + m_pImpl->m_aCurrentTabStop.Position = ConversionHelper::convertTwipToMM100(nIntValue); + break; + + case NS_ooxml::LN_CT_Fonts_ascii: + if (m_pImpl->GetTopContext()) + m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME, true, uno::makeAny( sStringValue )); + break; + case NS_ooxml::LN_CT_Fonts_asciiTheme: + if (m_pImpl->GetTopContext()) + m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME, true, uno::makeAny( m_pImpl->GetThemeTable()->getFontNameForTheme(nIntValue) )); + break; + case NS_ooxml::LN_CT_Fonts_hAnsi: + break;//unsupported + case NS_ooxml::LN_CT_Fonts_hAnsiTheme: + break; //unsupported + case NS_ooxml::LN_CT_Fonts_eastAsia: + if (m_pImpl->GetTopContext()) + m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_ASIAN, true, uno::makeAny( sStringValue )); + break; + case NS_ooxml::LN_CT_Fonts_eastAsiaTheme: + if (m_pImpl->GetTopContext()) + m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_COMPLEX, true, uno::makeAny( m_pImpl->GetThemeTable()->getFontNameForTheme(nIntValue) ) ); + break; + case NS_ooxml::LN_CT_Fonts_cs: + if (m_pImpl->GetTopContext()) + m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_COMPLEX, true, uno::makeAny( sStringValue )); + break; + case NS_ooxml::LN_CT_Fonts_cstheme: + if (m_pImpl->GetTopContext()) + m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_COMPLEX, true, uno::makeAny( m_pImpl->GetThemeTable()->getFontNameForTheme(nIntValue) )); + break; + case NS_ooxml::LN_CT_Spacing_before: + if (m_pImpl->GetTopContext()) + m_pImpl->GetTopContext()->Insert(PROP_PARA_TOP_MARGIN, true, uno::makeAny( ConversionHelper::convertTwipToMM100( nIntValue ) )); + break; + case NS_ooxml::LN_CT_Spacing_beforeLines: + break; + case NS_ooxml::LN_CT_Spacing_after: + if (m_pImpl->GetTopContext()) + m_pImpl->GetTopContext()->Insert(PROP_PARA_BOTTOM_MARGIN, true, uno::makeAny( ConversionHelper::convertTwipToMM100( nIntValue ) )); + break; + case NS_ooxml::LN_CT_Spacing_afterLines: + break; + case NS_ooxml::LN_CT_Spacing_line: //91434 + case NS_ooxml::LN_CT_Spacing_lineRule: //91435 + { +#define SINGLE_LINE_SPACING 240 + style::LineSpacing aSpacing; + PropertyMapPtr pTopContext = m_pImpl->GetTopContext(); + PropertyMap::iterator aLineSpacingIter = pTopContext->find(PropertyDefinition( PROP_PARA_LINE_SPACING, true ) ); + if( aLineSpacingIter != pTopContext->end()) + { + aLineSpacingIter->second >>= aSpacing; + } + else + { + //default to single line spacing + aSpacing.Mode = style::LineSpacingMode::FIX; + aSpacing.Height = sal_Int16(ConversionHelper::convertTwipToMM100( SINGLE_LINE_SPACING )); + } + if( nName == NS_ooxml::LN_CT_Spacing_line ) + { + //now set the value depending on the Mode + if( aSpacing.Mode == style::LineSpacingMode::PROP ) + aSpacing.Height = sal_Int16(sal_Int32(nIntValue) * 100 / SINGLE_LINE_SPACING ); + else + aSpacing.Height = sal_Int16(ConversionHelper::convertTwipToMM100( nIntValue )); + } + else //NS_ooxml::LN_CT_Spacing_lineRule: + { + // exactly, atLeast, auto + if( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_wordprocessingml_ST_LineSpacingRule_auto) + { + aSpacing.Mode = style::LineSpacingMode::PROP; + //reinterpret the already set value + aSpacing.Height = sal_Int16( aSpacing.Height * 100 / ConversionHelper::convertTwipToMM100( SINGLE_LINE_SPACING )); + } + else if( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_wordprocessingml_ST_LineSpacingRule_atLeast) + aSpacing.Mode = style::LineSpacingMode::MINIMUM; + else // NS_ooxml::LN_Value_wordprocessingml_ST_LineSpacingRule_exact + aSpacing.Mode = style::LineSpacingMode::FIX; + } + pTopContext->Insert(PROP_PARA_LINE_SPACING, true, uno::makeAny( aSpacing )); + } + break; + case NS_ooxml::LN_CT_Ind_start: + case NS_ooxml::LN_CT_Ind_left: + if (m_pImpl->GetTopContext()) + m_pImpl->GetTopContext()->Insert( + PROP_PARA_LEFT_MARGIN, true, uno::makeAny( ConversionHelper::convertTwipToMM100(nIntValue ) )); + break; + case NS_ooxml::LN_CT_Ind_end: + case NS_ooxml::LN_CT_Ind_right: + if (m_pImpl->GetTopContext()) + m_pImpl->GetTopContext()->Insert( + PROP_PARA_RIGHT_MARGIN, true, uno::makeAny( ConversionHelper::convertTwipToMM100(nIntValue ) )); + break; + case NS_ooxml::LN_CT_Ind_hanging: + if (m_pImpl->GetTopContext()) + { + sal_Int32 nValue = ConversionHelper::convertTwipToMM100( nIntValue ); + m_pImpl->GetTopContext()->Insert( + PROP_PARA_FIRST_LINE_INDENT, true, uno::makeAny( - nValue )); + } + break; + case NS_ooxml::LN_CT_Ind_firstLine: + if (m_pImpl->GetTopContext()) + m_pImpl->GetTopContext()->Insert( + PROP_PARA_FIRST_LINE_INDENT, true, uno::makeAny( ConversionHelper::convertTwipToMM100(nIntValue ) )); + break; + + case NS_ooxml::LN_CT_EastAsianLayout_id: + break; + case NS_ooxml::LN_CT_EastAsianLayout_combine: + if (m_pImpl->GetTopContext()) + m_pImpl->GetTopContext()->Insert(PROP_CHAR_COMBINE_IS_ON, true, uno::makeAny ( nIntValue ? true : false )); + break; + case NS_ooxml::LN_CT_EastAsianLayout_combineBrackets: + if (m_pImpl->GetTopContext()) + { + rtl::OUString sCombinePrefix = getBracketStringFromEnum(nIntValue); + rtl::OUString sCombineSuffix = getBracketStringFromEnum(nIntValue, false); + m_pImpl->GetTopContext()->Insert(PROP_CHAR_COMBINE_PREFIX, true, uno::makeAny ( sCombinePrefix )); + m_pImpl->GetTopContext()->Insert(PROP_CHAR_COMBINE_SUFFIX, true, uno::makeAny ( sCombineSuffix )); + } + break; + case NS_ooxml::LN_CT_EastAsianLayout_vert: + if (m_pImpl->GetTopContext()) + { + sal_Int16 nRotationAngle = (nIntValue ? 900 : 0); + m_pImpl->GetTopContext()->Insert(PROP_CHAR_ROTATION, true, uno::makeAny ( nRotationAngle )); + } + break; + case NS_ooxml::LN_CT_EastAsianLayout_vertCompress: + if (m_pImpl->GetTopContext()) + m_pImpl->GetTopContext()->Insert(PROP_CHAR_ROTATION_IS_FIT_TO_LINE, true, uno::makeAny ( nIntValue ? true : false)); + break; + + case NS_ooxml::LN_CT_PageSz_code: + CT_PageSz.code = nIntValue; + break; + case NS_ooxml::LN_CT_PageSz_h: + { + sal_Int32 nHeight = ConversionHelper::convertTwipToMM100(nIntValue); + CT_PageSz.h = PaperInfo::sloppyFitPageDimension(nHeight); + } + break; + case NS_ooxml::LN_CT_PageSz_orient: + CT_PageSz.orient = (nIntValue != 0); + break; + case NS_ooxml::LN_CT_PageSz_w: + { + sal_Int32 nWidth = ConversionHelper::convertTwipToMM100(nIntValue); + CT_PageSz.w = PaperInfo::sloppyFitPageDimension(nWidth); + } + break; + + case NS_ooxml::LN_CT_PageMar_top: + m_pImpl->SetPageMarginTwip( PAGE_MAR_TOP, nIntValue ); + break; + case NS_ooxml::LN_CT_PageMar_right: + m_pImpl->SetPageMarginTwip( PAGE_MAR_RIGHT, nIntValue ); + break; + case NS_ooxml::LN_CT_PageMar_bottom: + m_pImpl->SetPageMarginTwip( PAGE_MAR_BOTTOM, nIntValue ); + break; + case NS_ooxml::LN_CT_PageMar_left: + m_pImpl->SetPageMarginTwip( PAGE_MAR_LEFT, nIntValue ); + break; + case NS_ooxml::LN_CT_PageMar_header: + m_pImpl->SetPageMarginTwip( PAGE_MAR_HEADER, nIntValue ); + break; + case NS_ooxml::LN_CT_PageMar_footer: + m_pImpl->SetPageMarginTwip( PAGE_MAR_FOOTER, nIntValue ); + break; + case NS_ooxml::LN_CT_PageMar_gutter: + m_pImpl->SetPageMarginTwip( PAGE_MAR_GUTTER, nIntValue ); + break; + case NS_ooxml::LN_CT_Language_val: //90314 + case NS_ooxml::LN_CT_Language_eastAsia: //90315 + case NS_ooxml::LN_CT_Language_bidi: //90316 + { + LanguageType eLang = MsLangId::convertIsoStringToLanguage( sStringValue ); + lang::Locale aLocale = MsLangId::convertLanguageToLocale( eLang ); + if (m_pImpl->GetTopContext()) + m_pImpl->GetTopContext()->Insert(NS_ooxml::LN_CT_Language_val== nName ? PROP_CHAR_LOCALE : + NS_ooxml::LN_CT_Language_eastAsia == nName ? PROP_CHAR_LOCALE_ASIAN : PROP_CHAR_LOCALE_COMPLEX, + true, + uno::makeAny( aLocale ) ); + } + break; +#define AUTO_PARA_SPACING sal_Int32(49) + case NS_ooxml::LN_CT_Spacing_beforeAutospacing: + //TODO: autospacing depends on some document property (called fDontUseHTMLAutoSpacing in old ww8 filter) 100 or 280 twip + //and should be set to 0 on start of page + m_pImpl->GetTopContext()->Insert( PROP_PARA_TOP_MARGIN, false, uno::makeAny( AUTO_PARA_SPACING ) ); + break; + case NS_ooxml::LN_CT_Spacing_afterAutospacing: + //TODO: autospacing depends on some document property (called fDontUseHTMLAutoSpacing in old ww8 filter) 100 or 280 twip + m_pImpl->GetTopContext()->Insert( PROP_PARA_BOTTOM_MARGIN, false, uno::makeAny( AUTO_PARA_SPACING ) ); + break; + case NS_ooxml::LN_CT_SmartTagRun_uri: + case NS_ooxml::LN_CT_SmartTagRun_element: + //TODO: add handling of SmartTags + break; + case NS_ooxml::LN_CT_Br_type : + //TODO: attributes for break (0x12) are not supported + break; + case NS_ooxml::LN_CT_Fonts_hint : + /* assigns script type to ambigous characters, values can be: + NS_ooxml::LN_Value_ST_Hint_default + NS_ooxml::LN_Value_ST_Hint_eastAsia + NS_ooxml::LN_Value_ST_Hint_cs + */ + //TODO: unsupported? + break; + case NS_ooxml::LN_CT_TblCellMar_right: // 92375; + case NS_ooxml::LN_CT_TblBorders_top: // 92377; + case NS_ooxml::LN_CT_TblBorders_left: // 92378; + case NS_ooxml::LN_CT_TblBorders_bottom: // 92379; + //todo: handle cell mar + break; + case NS_rtf::LN_blip: // contains the binary graphic + case NS_ooxml::LN_shape: + { + //looks a bit like a hack - and it is. The graphic import is split into the inline_inline part and + //afterwards the adding of the binary data. + m_pImpl->GetGraphicImport( IMPORT_AS_DETECTED_INLINE )->attribute(nName, val); + m_pImpl->ImportGraphic( val.getProperties(), IMPORT_AS_DETECTED_INLINE ); + } + break; + case NS_ooxml::LN_CT_FramePr_dropCap: + case NS_ooxml::LN_CT_FramePr_lines: + case NS_ooxml::LN_CT_FramePr_hAnchor: + case NS_ooxml::LN_CT_FramePr_vAnchor: + case NS_ooxml::LN_CT_FramePr_x: + case NS_ooxml::LN_CT_FramePr_xAlign: + case NS_ooxml::LN_CT_FramePr_y: + case NS_ooxml::LN_CT_FramePr_yAlign: + case NS_ooxml::LN_CT_FramePr_hRule: + case NS_sprm::LN_PWr: + case NS_sprm::LN_PDxaWidth: + case NS_sprm::LN_PWHeightAbs: + case NS_sprm::LN_PDxaFromText: + case NS_sprm::LN_PDyaFromText: + { + ParagraphProperties* pParaProperties = dynamic_cast< ParagraphProperties*>(m_pImpl->GetTopContext().get()); + if( pParaProperties ) + { + switch( nName ) + { + case NS_ooxml::LN_CT_FramePr_dropCap: + pParaProperties->SetDropCap( nIntValue ); + break; + case NS_ooxml::LN_CT_FramePr_lines: + pParaProperties->SetLines( nIntValue ); + break; + case NS_ooxml::LN_CT_FramePr_hAnchor: + switch(nIntValue) + { + case NS_ooxml::LN_Value_wordprocessingml_ST_HAnchor_text: //relative to column + nIntValue = text::RelOrientation::FRAME; break; + case NS_ooxml::LN_Value_wordprocessingml_ST_HAnchor_margin: nIntValue = text::RelOrientation::PAGE_PRINT_AREA; break; + case NS_ooxml::LN_Value_wordprocessingml_ST_HAnchor_page: nIntValue = text::RelOrientation::PAGE_FRAME; break; + default:; + } + pParaProperties->SethAnchor( nIntValue ); + break; + case NS_ooxml::LN_CT_FramePr_vAnchor: + switch(nIntValue) + { + case NS_ooxml::LN_Value_wordprocessingml_ST_VAnchor_text: //relative to paragraph + nIntValue = text::RelOrientation::FRAME; break; + case NS_ooxml::LN_Value_wordprocessingml_ST_VAnchor_margin:nIntValue = text::RelOrientation::PAGE_PRINT_AREA ; break; + case NS_ooxml::LN_Value_wordprocessingml_ST_VAnchor_page: nIntValue = text::RelOrientation::PAGE_FRAME; break; + default:; + } + pParaProperties->SetvAnchor( nIntValue ); + break; + case NS_ooxml::LN_CT_FramePr_x: + pParaProperties->Setx( ConversionHelper::convertTwipToMM100(nIntValue )); + break; + case NS_ooxml::LN_CT_FramePr_xAlign: + switch( nIntValue ) + { + case NS_ooxml::LN_Value_wordprocessingml_ST_XAlign_center : nIntValue = text::HoriOrientation::CENTER; break; + case NS_ooxml::LN_Value_wordprocessingml_ST_XAlign_right : nIntValue = text::HoriOrientation::RIGHT; break; + case NS_ooxml::LN_Value_wordprocessingml_ST_XAlign_inside : nIntValue = text::HoriOrientation::INSIDE; break; + case NS_ooxml::LN_Value_wordprocessingml_ST_XAlign_outside : nIntValue = text::HoriOrientation::OUTSIDE; break; + case NS_ooxml::LN_Value_wordprocessingml_ST_XAlign_left : nIntValue = text::HoriOrientation::LEFT; break; + default: nIntValue = text::HoriOrientation::NONE; + } + pParaProperties->SetxAlign( nIntValue ); + break; + case NS_ooxml::LN_CT_FramePr_y: + pParaProperties->Sety( ConversionHelper::convertTwipToMM100(nIntValue )); + break; + case NS_ooxml::LN_CT_FramePr_yAlign: + switch( nIntValue ) + { + case NS_ooxml::LN_Value_wordprocessingml_ST_YAlign_top : + case NS_ooxml::LN_Value_wordprocessingml_ST_YAlign_inside :nIntValue = text::VertOrientation::TOP; break; + case NS_ooxml::LN_Value_wordprocessingml_ST_YAlign_center :nIntValue = text::VertOrientation::CENTER;break; + case NS_ooxml::LN_Value_wordprocessingml_ST_YAlign_bottom : + case NS_ooxml::LN_Value_wordprocessingml_ST_YAlign_outside :nIntValue = text::VertOrientation::BOTTOM;break; + case NS_ooxml::LN_Value_wordprocessingml_ST_YAlign_inline ://todo: what to do with inline - no avail. in WW97 and WW2007 + //no break; + default:nIntValue = text::VertOrientation::NONE; + } + pParaProperties->SetyAlign( nIntValue ); + break; + case NS_ooxml::LN_CT_FramePr_hRule: + switch( nIntValue ) + { + case NS_ooxml::LN_Value_wordprocessingml_ST_HeightRule_exact: + nIntValue = text::SizeType::FIX; + break; + case NS_ooxml::LN_Value_wordprocessingml_ST_HeightRule_atLeast: + nIntValue = text::SizeType::MIN; + break; + case NS_ooxml::LN_Value_wordprocessingml_ST_HeightRule_auto: + //no break; + default:; + nIntValue = text::SizeType::VARIABLE; + } + pParaProperties->SethRule( nIntValue ); + break; + case NS_sprm::LN_PWr: + { + //should be either LN_Value_wordprocessingml_ST_Wrap_notBeside or LN_Value_wordprocessingml_ST_Wrap_around + OSL_ENSURE( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_wordprocessingml_ST_Wrap_around || + sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_wordprocessingml_ST_Wrap_notBeside, + "wrap not around or not_Beside?"); + pParaProperties->SetWrap(sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_wordprocessingml_ST_Wrap_around ? + text::WrapTextMode_DYNAMIC : text::WrapTextMode_NONE ); + } + break; + case NS_sprm::LN_PDxaWidth: + pParaProperties->Setw(ConversionHelper::convertTwipToMM100(nIntValue)); + break; + case NS_sprm::LN_PWHeightAbs: + pParaProperties->Seth(ConversionHelper::convertTwipToMM100(nIntValue)); + break; + case NS_sprm::LN_PDxaFromText: + pParaProperties->SethSpace( ConversionHelper::convertTwipToMM100(nIntValue )); + break; + case NS_sprm::LN_PDyaFromText: + pParaProperties->SetvSpace( ConversionHelper::convertTwipToMM100(nIntValue )); + break; + default:; + } + } + else + { + //TODO: how to handle frame properties at styles + } + } + break; + case NS_ooxml::LN_CT_LineNumber_start: + case NS_ooxml::LN_CT_LineNumber_distance: + case NS_ooxml::LN_CT_TrackChange_author: + m_pImpl->SetCurrentRedlineAuthor( sStringValue ); + break; + case NS_ooxml::LN_CT_TrackChange_date: + m_pImpl->SetCurrentRedlineDate( sStringValue ); + break; + case NS_ooxml::LN_CT_Markup_id: + m_pImpl->SetCurrentRedlineId( nIntValue ); + break; + case NS_ooxml::LN_token: + m_pImpl->SetCurrentRedlineToken( nIntValue ); + break; + case NS_ooxml::LN_CT_LineNumber_countBy: + case NS_ooxml::LN_CT_LineNumber_restart: + { + //line numbering in Writer is a global document setting + //in Word is a section setting + //if line numbering is switched on anywhere in the document it's set at the global settings + LineNumberSettings aSettings = m_pImpl->GetLineNumberSettings(); + switch( nName ) + { + case NS_ooxml::LN_CT_LineNumber_countBy: + aSettings.nInterval = nIntValue; + break; + case NS_ooxml::LN_CT_LineNumber_start: + aSettings.nStartValue = nIntValue; // todo: has to be set at (each) first paragraph + break; + case NS_ooxml::LN_CT_LineNumber_distance: + aSettings.nDistance = ConversionHelper::convertTwipToMM100( nIntValue ); + break; + case NS_ooxml::LN_CT_LineNumber_restart: + //page:empty, probably 0,section:1,continuous:2; + aSettings.bRestartAtEachPage = nIntValue < 1; + break; + default:; + } + m_pImpl->SetLineNumberSettings( aSettings ); + } + break; + case NS_ooxml::LN_CT_FtnEdnRef_customMarkFollows: + m_pImpl->SetCustomFtnMark( true ); + break; + case NS_ooxml::LN_CT_FtnEdnRef_id: + // footnote or endnote reference id - not needed + case NS_ooxml::LN_CT_Color_themeColor: + case NS_ooxml::LN_CT_Color_themeTint: + case NS_ooxml::LN_CT_Color_themeShade: + //unsupported + break; + case NS_ooxml::LN_endtrackchange: + m_pImpl->RemoveCurrentRedline( ); + break; + case NS_ooxml::LN_CT_DocGrid_linePitch: + { + //see SwWW8ImplReader::SetDocumentGrid + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + { + pSectionContext->SetGridLinePitch( ConversionHelper::convertTwipToMM100( nIntValue ) ); + } + } + break; + case NS_ooxml::LN_CT_DocGrid_charSpace: + { + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + { + pSectionContext->SetDxtCharSpace( nIntValue ); + } + } + break; + case NS_ooxml::LN_CT_DocGrid_type: + { + if (pSectionContext != NULL) + { + pSectionContext->SetGridType(nIntValue); + } + } + break; + default: + { +#if OSL_DEBUG_LEVEL > 0 + ::rtl::OString sMessage( "DomainMapper::attribute() - Id: "); + sMessage += ::rtl::OString::valueOf( sal_Int32( nName ), 10 ); + sMessage += ::rtl::OString(" / 0x"); + sMessage += ::rtl::OString::valueOf( sal_Int32( nName ), 16 ); + sMessage += ::rtl::OString(" value: "); + sMessage += ::rtl::OString::valueOf( sal_Int32( nIntValue ), 10 ); + sMessage += ::rtl::OString(" / 0x"); + sMessage += ::rtl::OString::valueOf( sal_Int32( nIntValue ), 16 ); + OSL_FAIL( sMessage.getStr()); // +#endif + } + } + } +} + +void DomainMapper::lcl_sprm(Sprm & rSprm) +{ + if( !m_pImpl->getTableManager().sprm(rSprm)) + sprmWithProps( rSprm, m_pImpl->GetTopContext() ); +} + +void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext, SprmType eSprmType ) +{ + OSL_ENSURE(rContext.get(), "PropertyMap has to be valid!"); + if(!rContext.get()) + return ; + + sal_uInt32 nSprmId = rSprm.getId(); + //needed for page properties + SectionPropertyMap * pSectionContext = m_pImpl->GetSectionContext(); + + //TODO: In rtl-paragraphs the meaning of left/right are to be exchanged + bool bExchangeLeftRight = false; + Value::Pointer_t pValue = rSprm.getValue(); + sal_Int32 nIntValue = pValue->getInt(); + rtl::OUString sStringValue = pValue->getString(); + + switch(nSprmId) + { + case 2: // sprmPIstd + case 0x4600: + break; // sprmPIstd - style code + case 3: // "sprmPIstdPermute + case NS_sprm::LN_PIstdPermute: + break; // sprmPIstdPermute + case NS_sprm::LN_PIncLvl: + break; // sprmPIncLvl + case NS_sprm::LN_PJcExtra: // sprmPJc Asian (undocumented) + case NS_sprm::LN_PJc: // sprmPJc + handleParaJustification(nIntValue, rContext, bExchangeLeftRight); + break; + case NS_sprm::LN_PFSideBySide: + break; // sprmPFSideBySide + + case NS_sprm::LN_PFKeep: // sprmPFKeep + rContext->Insert(PROP_PARA_SPLIT, true, uno::makeAny(nIntValue ? false : true)); + break; + case NS_sprm::LN_PFKeepFollow: // sprmPFKeepFollow + rContext->Insert(PROP_PARA_KEEP_TOGETHER, true, uno::makeAny( nIntValue ? true : false) ); + break; + case NS_sprm::LN_PFPageBreakBefore: + rContext->Insert(PROP_BREAK_TYPE, true, uno::makeAny( com::sun::star::style::BreakType_PAGE_BEFORE ) ); + break; // sprmPFPageBreakBefore + case NS_sprm::LN_PBrcl: + break; // sprmPBrcl + case NS_sprm::LN_PBrcp: + break; // sprmPBrcp + case NS_sprm::LN_PIlvl: // sprmPIlvl + //todo: Numbering level will be implemented in the near future (OOo 3.0?) + if( m_pImpl->IsStyleSheetImport() ) + { + //style sheets cannot have a numbering rule attached + StyleSheetPropertyMap* pStyleSheetPropertyMap = dynamic_cast< StyleSheetPropertyMap* >( rContext.get() ); + pStyleSheetPropertyMap->SetListLevel( (sal_Int16)nIntValue ); + } + else + rContext->Insert( PROP_NUMBERING_LEVEL, true, uno::makeAny( (sal_Int16)nIntValue )); + break; + case NS_sprm::LN_PIlfo: // sprmPIlfo + { + //convert the ListTable entry to a NumberingRules propery and apply it + ListsManager::Pointer pListTable = m_pImpl->GetListTable(); + ListDef::Pointer pList = pListTable->GetList( nIntValue ); + if( pList.get( ) ) + { + if( m_pImpl->IsStyleSheetImport() ) + { + //style sheets cannot have a numbering rule attached + StyleSheetPropertyMap* pStyleSheetPropertyMap = dynamic_cast< StyleSheetPropertyMap* >( rContext.get() ); + pStyleSheetPropertyMap->SetListId( nIntValue ); + } + else + { + uno::Any aRules = uno::makeAny( pList->GetNumberingRules( ) ); + rContext->Insert( PROP_NUMBERING_RULES, true, aRules ); + } + } + else if ( !m_pImpl->IsStyleSheetImport( ) ) + { + rtl::OUString sNone; + rContext->Insert( PROP_NUMBERING_STYLE_NAME, true, uno::makeAny( sNone ) ); + } + } + break; + case NS_sprm::LN_PFNoLineNumb: // sprmPFNoLineNumb + rContext->Insert(PROP_PARA_LINE_NUMBER_COUNT, true, uno::makeAny( nIntValue ? false : true) ); + break; + case NS_sprm::LN_PChgTabsPapx: // sprmPChgTabsPapx + { + // Initialize tab stop vector from style sheet + uno::Any aValue = m_pImpl->GetPropertyFromStyleSheet(PROP_PARA_TAB_STOPS); + uno::Sequence< style::TabStop > aStyleTabStops; + if(aValue >>= aStyleTabStops) + { + m_pImpl->InitTabStopFromStyle( aStyleTabStops ); + } + + //create a new tab stop property - this is done with the contained properties + resolveSprmProps(*this, rSprm); + //add this property + rContext->Insert(PROP_PARA_TAB_STOPS, true, uno::makeAny( m_pImpl->GetCurrentTabStopAndClear())); + } + break; + case 0x845d: //right margin Asian - undocumented + case 0x845e: //left margin Asian - undocumented + case 16: // sprmPDxaRight - right margin + case NS_sprm::LN_PDxaRight: // sprmPDxaRight - right margin + case 17: + case NS_sprm::LN_PDxaLeft: // sprmPDxaLeft + if( NS_sprm::LN_PDxaLeft == nSprmId || 0x17 == nSprmId|| (bExchangeLeftRight && nSprmId == 0x845d) || ( !bExchangeLeftRight && nSprmId == 0x845e)) + rContext->Insert( + eSprmType == SPRM_DEFAULT ? PROP_PARA_LEFT_MARGIN : PROP_LEFT_MARGIN, + true, + uno::makeAny( ConversionHelper::convertTwipToMM100( nIntValue ) )); + else if(eSprmType == SPRM_DEFAULT) + rContext->Insert( + PROP_PARA_RIGHT_MARGIN, true, + uno::makeAny( ConversionHelper::convertTwipToMM100(nIntValue ) )); + //TODO: what happens to the right margins in numberings? + break; + case 18: // sprmPNest + case NS_sprm::LN_PNest: // sprmPNest + //not handled in the old WW8 filter + break; + case NS_sprm::LN_PDxaLeft1: // sprmPDxaLeft1 + case 19: + case NS_sprm::LN_PDxaLeft180: // sprmPDxaLeft180 + rContext->Insert( + eSprmType == SPRM_DEFAULT ? PROP_PARA_FIRST_LINE_INDENT : PROP_FIRST_LINE_OFFSET, + true, + uno::makeAny( ConversionHelper::convertTwipToMM100(nIntValue ) )); + break; + case 20 : // sprmPDyaLine + case NS_sprm::LN_PDyaLine: // sprmPDyaLine + { + style::LineSpacing aSpacing; + sal_Int16 nDistance = sal_Int16(nIntValue & 0xffff); + if(nIntValue & 0xffff0000) + { + // single line in Writer is 100, in Word it is 240 + aSpacing.Mode = style::LineSpacingMode::PROP; + aSpacing.Height = sal_Int16(sal_Int32(nDistance) * 100 /240); + } + else + { + if(nDistance < 0) + { + aSpacing.Mode = style::LineSpacingMode::FIX; + aSpacing.Height = sal_Int16(ConversionHelper::convertTwipToMM100(-nDistance)); + } + else if(nDistance >0) + { + aSpacing.Mode = style::LineSpacingMode::MINIMUM; + aSpacing.Height = sal_Int16(ConversionHelper::convertTwipToMM100(nDistance)); + } + } + rContext->Insert(PROP_PARA_LINE_SPACING, true, uno::makeAny( aSpacing )); + } + break; + case 21 : // legacy version + case NS_sprm::LN_PDyaBefore: // sprmPDyaBefore + rContext->Insert(PROP_PARA_TOP_MARGIN, true, uno::makeAny( ConversionHelper::convertTwipToMM100( nIntValue ) )); + break; + case 22 : + case NS_sprm::LN_PDyaAfter: // sprmPDyaAfter + rContext->Insert(PROP_PARA_BOTTOM_MARGIN, true, uno::makeAny( ConversionHelper::convertTwipToMM100( nIntValue ) )); + break; + + case 23: //sprmPChgTabs + case NS_sprm::LN_PChgTabs: // sprmPChgTabs + OSL_FAIL( "unhandled"); + //tabs of list level? + break; + case 24: // "sprmPFInTable" + case NS_sprm::LN_PFInTable: + break; // sprmPFInTable + case NS_sprm::LN_PTableDepth: //sprmPTableDepth + //not handled via sprm but via text( 0x07 ) + break; + case 25: // "sprmPTtp" pap.fTtp + case NS_sprm::LN_PFTtp: // sprmPFTtp was: Read_TabRowEnd + break; + case 26: // "sprmPDxaAbs + case NS_sprm::LN_PDxaAbs: + break; // sprmPDxaAbs + case 27: //sprmPDyaAbs + case NS_sprm::LN_PDyaAbs: + break; // sprmPDyaAbs + case NS_sprm::LN_PDxaWidth: + break; // sprmPDxaWidth + case NS_sprm::LN_PPc: + break; // sprmPPc + case NS_sprm::LN_PBrcTop10: + break; // sprmPBrcTop10 + case NS_sprm::LN_PBrcLeft10: + break; // sprmPBrcLeft10 + case NS_sprm::LN_PBrcBottom10: + break; // sprmPBrcBottom10 + case NS_sprm::LN_PBrcRight10: + break; // sprmPBrcRight10 + case NS_sprm::LN_PBrcBetween10: + break; // sprmPBrcBetween10 + case NS_sprm::LN_PBrcBar10: + break; // sprmPBrcBar10 + case NS_sprm::LN_PDxaFromText10: + break; // sprmPDxaFromText10 + case NS_sprm::LN_PWr: + break; // sprmPWr + + case NS_ooxml::LN_CT_PrBase_pBdr: //paragraph border + resolveSprmProps(*this, rSprm); + break; + case NS_sprm::LN_PBrcTop: // sprmPBrcTop + case NS_sprm::LN_PBrcLeft: // sprmPBrcLeft + case NS_sprm::LN_PBrcBottom: // sprmPBrcBottom + case NS_sprm::LN_PBrcRight: // sprmPBrcRight + case NS_sprm::LN_PBrcBetween: // sprmPBrcBetween + { + //in binary format the borders are directly provided in OOXML they are inside of properties + if( IsOOXMLImport() ) + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + { + BorderHandlerPtr pBorderHandler( new BorderHandler( true ) ); + pProperties->resolve(*pBorderHandler); + PropertyIds eBorderId = PropertyIds( 0 ); + PropertyIds eBorderDistId = PropertyIds( 0 ); + switch( nSprmId ) + { + case NS_sprm::LN_PBrcTop: + eBorderId = PROP_TOP_BORDER; + eBorderDistId = PROP_TOP_BORDER_DISTANCE; + break; + case NS_sprm::LN_PBrcLeft: + eBorderId = PROP_LEFT_BORDER; + eBorderDistId = PROP_LEFT_BORDER_DISTANCE; + break; + case NS_sprm::LN_PBrcBottom: + eBorderId = PROP_BOTTOM_BORDER ; + eBorderDistId = PROP_BOTTOM_BORDER_DISTANCE; + break; + case NS_sprm::LN_PBrcRight: + eBorderId = PROP_RIGHT_BORDER; + eBorderDistId = PROP_RIGHT_BORDER_DISTANCE ; + break; + case NS_sprm::LN_PBrcBetween: + //not supported + break; + default:; + } + if( eBorderId ) + rContext->Insert( eBorderId, true, uno::makeAny( pBorderHandler->getBorderLine()) , true); + if(eBorderDistId) + rContext->Insert(eBorderDistId, true, uno::makeAny( pBorderHandler->getLineDistance()), true); + } + } + else + { + table::BorderLine2 aBorderLine; + sal_Int32 nLineDistance = ConversionHelper::MakeBorderLine( nIntValue, aBorderLine ); + PropertyIds eBorderId = PROP_LEFT_BORDER; + PropertyIds eBorderDistId = PROP_LEFT_BORDER_DISTANCE ; + switch( nSprmId ) + { + case NS_sprm::LN_PBrcBetween: // sprmPBrcBetween + OSL_FAIL( "TODO: inner border is not handled"); + break; + case NS_sprm::LN_PBrcLeft: // sprmPBrcLeft + eBorderId = PROP_LEFT_BORDER; + eBorderDistId = PROP_LEFT_BORDER_DISTANCE ; + break; + case NS_sprm::LN_PBrcRight: // sprmPBrcRight + eBorderId = PROP_RIGHT_BORDER ; + eBorderDistId = PROP_RIGHT_BORDER_DISTANCE ; + break; + case NS_sprm::LN_PBrcTop: // sprmPBrcTop + eBorderId = PROP_TOP_BORDER ; + eBorderDistId = PROP_TOP_BORDER_DISTANCE; + break; + case NS_sprm::LN_PBrcBottom: // sprmPBrcBottom + default: + eBorderId = PROP_BOTTOM_BORDER ; + eBorderDistId = PROP_BOTTOM_BORDER_DISTANCE; + } + rContext->Insert(eBorderId, true, uno::makeAny( aBorderLine )); + rContext->Insert(eBorderDistId, true, uno::makeAny( nLineDistance )); + } + } + break; + case NS_sprm::LN_PBorderTop: + case NS_sprm::LN_PBorderLeft: + case NS_sprm::LN_PBorderBottom: + case NS_sprm::LN_PBorderRight: + OSL_FAIL( "TODO: border color definition"); + break; + case NS_sprm::LN_PBrcBar: + break; // sprmPBrcBar + case NS_sprm::LN_PFNoAutoHyph: // sprmPFNoAutoHyph + rContext->Insert(PROP_PARA_IS_HYPHENATION, true, uno::makeAny( nIntValue ? false : true )); + break; + case NS_sprm::LN_PWHeightAbs: + break; // sprmPWHeightAbs + case NS_sprm::LN_PDcs: + break; // sprmPDcs + + case NS_sprm::LN_PShd: // sprmPShd + { + //contains fore color, back color and shadow percentage, results in a brush + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + { + CellColorHandlerPtr pCellColorHandler( new CellColorHandler ); + pCellColorHandler->setOutputFormat( CellColorHandler::Paragraph ); + pProperties->resolve(*pCellColorHandler); + rContext->insert( pCellColorHandler->getProperties(), true ); + } + } + break; + case NS_sprm::LN_PDyaFromText: + break; // sprmPDyaFromText + case NS_sprm::LN_PDxaFromText: + break; // sprmPDxaFromText + case NS_sprm::LN_PFLocked: + break; // sprmPFLocked + case NS_sprm::LN_PFWidowControl: + case NS_ooxml::LN_CT_PPrBase_widowControl: + { + uno::Any aVal( uno::makeAny( sal_Int8(nIntValue ? 2 : 0 ))); + rContext->Insert( PROP_PARA_WIDOWS, true, aVal ); + rContext->Insert( PROP_PARA_ORPHANS, true, aVal ); + } + break; // sprmPFWidowControl + case NS_sprm::LN_PRuler: + break; // sprmPRuler + case NS_sprm::LN_PFKinsoku: + break; // sprmPFKinsoku + case NS_sprm::LN_PFWordWrap: + break; // sprmPFWordWrap + case NS_sprm::LN_PFOverflowPunct: ; // sprmPFOverflowPunct - hanging punctuation + rContext->Insert(PROP_PARA_IS_HANGING_PUNCTUATION, true, uno::makeAny( nIntValue ? false : true )); + break; + case NS_sprm::LN_PFTopLinePunct: + break; // sprmPFTopLinePunct + case NS_sprm::LN_PFAutoSpaceDE: + break; // sprmPFAutoSpaceDE + case NS_sprm::LN_PFAutoSpaceDN: + break; // sprmPFAutoSpaceDN + case NS_sprm::LN_PWAlignFont: + break; // sprmPWAlignFont + case NS_sprm::LN_PFrameTextFlow: + break; // sprmPFrameTextFlow + case NS_sprm::LN_PISnapBaseLine: + break; // sprmPISnapBaseLine + case NS_sprm::LN_PAnld: + break; // sprmPAnld + case NS_sprm::LN_PPropRMark: + break; // sprmPPropRMark + case NS_sprm::LN_POutLvl: + { + if( m_pImpl->IsStyleSheetImport() ) + { + sal_Int16 nLvl = static_cast< sal_Int16 >( nIntValue ); + + StyleSheetPropertyMap* pStyleSheetPropertyMap = dynamic_cast< StyleSheetPropertyMap* >( rContext.get() ); + pStyleSheetPropertyMap->SetOutlineLevel( nLvl ); + } + } + break; // sprmPOutLvl + case NS_sprm::LN_PFBiDi: + rContext->Insert(PROP_WRITING_MODE, false, uno::makeAny( text::WritingMode2::RL_TB )); + rContext->Insert(PROP_PARA_ADJUST, false, uno::makeAny( style::ParagraphAdjust_RIGHT )); + + break; // sprmPFBiDi + case NS_ooxml::LN_EG_SectPrContents_bidi: + if (pSectionContext != NULL) + pSectionContext->Insert(PROP_WRITING_MODE,false, uno::makeAny( text::WritingMode2::RL_TB)); + break; + case NS_sprm::LN_PFNumRMIns: + break; // sprmPFNumRMIns + case NS_sprm::LN_PCrLf: + break; // sprmPCrLf + case NS_sprm::LN_PNumRM: + break; // sprmPNumRM + case NS_sprm::LN_PHugePapx: + break; // sprmPHugePapx + case NS_sprm::LN_PFUsePgsuSettings: + break; // sprmPFUsePgsuSettings + case NS_sprm::LN_PFAdjustRight: + break; // sprmPFAdjustRight + case NS_sprm::LN_CFRMarkDel: + break; // sprmCFRMarkDel + case NS_sprm::LN_CFRMark: + break; // sprmCFRMark + case NS_sprm::LN_CFFldVanish: + break; // sprmCFFldVanish + case NS_sprm::LN_CFSpec: // sprmCFSpec + break; + case NS_sprm::LN_CPicLocation: // sprmCPicLocation + //is being resolved on the tokenizer side + break; + case NS_sprm::LN_CIbstRMark: + break; // sprmCIbstRMark + case NS_sprm::LN_CDttmRMark: + break; // sprmCDttmRMark + case NS_sprm::LN_CFData: + break; // sprmCFData + case NS_sprm::LN_CIdslRMark: + break; // sprmCIdslRMark + case NS_sprm::LN_CChs: + break; // sprmCChs + case NS_sprm::LN_CSymbol: // sprmCSymbol + resolveSprmProps(*this, rSprm); //resolves LN_FONT and LN_CHAR + break; + case NS_sprm::LN_CFOle2: + break; // sprmCFOle2 + case NS_sprm::LN_CIdCharType: + break; // sprmCIdCharType + case NS_sprm::LN_CHighlight: + { + sal_Int32 nColor = 0; + if(true ==( mbIsHighlightSet = getColorFromIndex(nIntValue, nColor))) + rContext->Insert(PROP_CHAR_BACK_COLOR, true, uno::makeAny( nColor )); + else if (mnBackgroundColor) + rContext->Insert(PROP_CHAR_BACK_COLOR, true, uno::makeAny( mnBackgroundColor )); + } + break; // sprmCHighlight + case NS_sprm::LN_CObjLocation: + break; // sprmCObjLocation + case NS_sprm::LN_CFFtcAsciSymb: + break; // sprmCFFtcAsciSymb + case NS_sprm::LN_CIstd: + break; // sprmCIstd + case NS_sprm::LN_CIstdPermute: + break; // sprmCIstdPermute + case NS_sprm::LN_CDefault: + break; // sprmCDefault + case NS_sprm::LN_CPlain: + break; // sprmCPlain + case NS_sprm::LN_CKcd: + rContext->Insert(PROP_CHAR_EMPHASIS, true, uno::makeAny ( getEmphasisValue (nIntValue))); + break; // sprmCKcd + case NS_sprm::LN_CFEmboss:// sprmCFEmboss + case 60:// sprmCFBold + case NS_sprm::LN_CFBoldBi:// sprmCFBoldBi (offset 0x27 to normal bold) + case NS_sprm::LN_CFItalicBi:// sprmCFItalicBi (offset 0x27 to normal italic) + case NS_sprm::LN_CFBold: //sprmCFBold + case 61: /*sprmCFItalic*/ + case NS_sprm::LN_CFItalic: //sprmCFItalic + case NS_sprm::LN_CFStrike: //sprmCFStrike + case NS_sprm::LN_CFOutline: //sprmCFOutline + case NS_sprm::LN_CFShadow: //sprmCFShadow + case NS_sprm::LN_CFSmallCaps: //sprmCFSmallCaps + case NS_sprm::LN_CFCaps: //sprmCFCaps + case NS_sprm::LN_CFVanish: //sprmCFVanish + case NS_sprm::LN_CFDStrike: // sprmCFDStrike + { + PropertyIds ePropertyId = PROP_CHAR_WEIGHT; //initialized to prevent warning! + switch( nSprmId ) + { + case 60:// sprmCFBold + case NS_sprm::LN_CFBoldBi: // sprmCFBoldBi + case NS_sprm::LN_CFBold: /*sprmCFBold*/ + ePropertyId = nSprmId != NS_sprm::LN_CFBoldBi ? PROP_CHAR_WEIGHT : PROP_CHAR_WEIGHT_COMPLEX; + break; + case 61: /*sprmCFItalic*/ + case NS_sprm::LN_CFItalicBi: // sprmCFItalicBi + case NS_sprm::LN_CFItalic: /*sprmCFItalic*/ + ePropertyId = nSprmId == 0x836 ? PROP_CHAR_POSTURE : PROP_CHAR_POSTURE_COMPLEX; + break; + case NS_sprm::LN_CFStrike: /*sprmCFStrike*/ + case NS_sprm::LN_CFDStrike : /*sprmCFDStrike double strike through*/ + ePropertyId = PROP_CHAR_STRIKEOUT; + break; + case NS_sprm::LN_CFOutline: /*sprmCFOutline*/ + ePropertyId = PROP_CHAR_CONTOURED; + break; + case NS_sprm::LN_CFShadow: /*sprmCFShadow*/ + ePropertyId = PROP_CHAR_SHADOWED; + break; + case NS_sprm::LN_CFSmallCaps: /*sprmCFSmallCaps*/ + case NS_sprm::LN_CFCaps: /*sprmCFCaps*/ + ePropertyId = PROP_CHAR_CASE_MAP; + break; + case NS_sprm::LN_CFVanish: /*sprmCFVanish*/ + ePropertyId = PROP_CHAR_HIDDEN; + break; + case NS_sprm::LN_CFEmboss: /*sprmCFEmboss*/ + ePropertyId = PROP_CHAR_RELIEF; + break; + } + //expected: 0,1,128,129 + if(nIntValue != 128) //inherited from paragraph - ignore + { + if( nIntValue == 129) //inverted style sheet value + { + //get value from style sheet and invert it + sal_Int16 nStyleValue = 0; + double fDoubleValue; + uno::Any aStyleVal = m_pImpl->GetPropertyFromStyleSheet(ePropertyId); + if( !aStyleVal.hasValue() ) + { + nIntValue = 0x83a == nSprmId ? + 4 : 1; + } + else if(aStyleVal.getValueTypeClass() == uno::TypeClass_FLOAT ) + { + //only in case of awt::FontWeight + aStyleVal >>= fDoubleValue; + nIntValue = fDoubleValue > 100. ? 0 : 1; + } + else if((aStyleVal >>= nStyleValue) || + (nStyleValue = (sal_Int16)comphelper::getEnumAsINT32(aStyleVal)) >= 0 ) + { + nIntValue = 0x83a == nSprmId ? + nStyleValue ? 0 : 4 : + nStyleValue ? 0 : 1; + } + else + { + OSL_FAIL( "what type was it"); + } + } + + switch( nSprmId ) + { + case 60:/*sprmCFBold*/ + case NS_sprm::LN_CFBold: /*sprmCFBold*/ + case NS_sprm::LN_CFBoldBi: // sprmCFBoldBi + { + uno::Any aBold( uno::makeAny( nIntValue ? awt::FontWeight::BOLD : awt::FontWeight::NORMAL ) ); + + rContext->Insert(ePropertyId, true, aBold ); + if( nSprmId != NS_sprm::LN_CFBoldBi ) // sprmCFBoldBi + rContext->Insert(PROP_CHAR_WEIGHT_ASIAN, true, aBold ); + } + break; + case 61: /*sprmCFItalic*/ + case NS_sprm::LN_CFItalic: /*sprmCFItalic*/ + case NS_sprm::LN_CFItalicBi: // sprmCFItalicBi + { + uno::Any aPosture( uno::makeAny( nIntValue ? awt::FontSlant_ITALIC : awt::FontSlant_NONE ) ); + rContext->Insert( ePropertyId, true, aPosture ); + if( nSprmId != NS_sprm::LN_CFItalicBi ) // sprmCFItalicBi + rContext->Insert(PROP_CHAR_POSTURE_ASIAN, true, aPosture ); + } + break; + case NS_sprm::LN_CFStrike: /*sprmCFStrike*/ + rContext->Insert(ePropertyId, true, + uno::makeAny( nIntValue ? awt::FontStrikeout::SINGLE : awt::FontStrikeout::NONE ) ); + break; + case NS_sprm::LN_CFDStrike : /*sprmCFDStrike double strike through*/ + rContext->Insert(ePropertyId, true, + uno::makeAny( awt::FontStrikeout::DOUBLE ) ); + break; + case NS_sprm::LN_CFOutline: /*sprmCFOutline*/ + case NS_sprm::LN_CFShadow: /*sprmCFShadow*/ + case NS_sprm::LN_CFVanish: /*sprmCFVanish*/ + rContext->Insert(ePropertyId, true, uno::makeAny( nIntValue ? true : false )); + break; + case NS_sprm::LN_CFSmallCaps: /*sprmCFSmallCaps*/ + rContext->Insert(ePropertyId, true, + uno::makeAny( nIntValue ? style::CaseMap::SMALLCAPS : style::CaseMap::NONE)); + break; + case NS_sprm::LN_CFCaps: /*sprmCFCaps*/ + rContext->Insert(ePropertyId, true, + uno::makeAny( nIntValue ? style::CaseMap::UPPERCASE : style::CaseMap::NONE)); + break; + case NS_sprm::LN_CFEmboss: /*sprmCFEmboss*/ + rContext->Insert(ePropertyId, true, + uno::makeAny( nIntValue ? awt::FontRelief::EMBOSSED : awt::FontRelief::NONE )); + break; + + } + } + } + break; + case NS_sprm::LN_CFtcDefault: + break; // sprmCFtcDefault + case NS_sprm::LN_CKul: // sprmCKul + { + // Parameter: 0 = none, 1 = single, 2 = by Word, + // 3 = double, 4 = dotted, 5 = hidden + // 6 = thick, 7 = dash, 8 = dot(not used) + // 9 = dotdash 10 = dotdotdash 11 = wave + handleUnderlineType(nIntValue, rContext); + } + break; + case NS_sprm::LN_CSizePos: + break; // sprmCSizePos + case NS_sprm::LN_CLid: + break; // sprmCLid + case NS_sprm::LN_CIco: + { + sal_Int32 nColor = 0; + if (getColorFromIndex(nIntValue, nColor)) + rContext->Insert(PROP_CHAR_COLOR, true, uno::makeAny( nColor ) ); + } + break; // sprmCIco + case NS_sprm::LN_CHpsBi: // sprmCHpsBi + case NS_sprm::LN_CHps: // sprmCHps + { + //multiples of half points (12pt == 24) + double fVal = double(nIntValue) / 2.; + uno::Any aVal = uno::makeAny( fVal ); + if( NS_sprm::LN_CHpsBi == nSprmId ) + rContext->Insert( PROP_CHAR_HEIGHT_COMPLEX, true, aVal ); + else + { + //Asian get the same value as Western + rContext->Insert( PROP_CHAR_HEIGHT, true, aVal ); + rContext->Insert( PROP_CHAR_HEIGHT_ASIAN, true, aVal ); + } + } + break; + case NS_sprm::LN_CHpsInc: + break; // sprmCHpsInc + case NS_sprm::LN_CHpsPos: + { + // FIXME: ww8 filter in ww8par6.cxx has a Read_SubSuperProp function + // that counts the escapement from this value and font size. So it will be + // on our TODO list + sal_Int16 nEscapement = 0; + sal_Int8 nProp = 100; + if (nIntValue < 0) + nEscapement = -58; + else if (nIntValue > 0) + nEscapement = 58; + else /* (nIntValue == 0) */ + nProp = 0; + rContext->Insert(PROP_CHAR_ESCAPEMENT, true, uno::makeAny( nEscapement ) ); + rContext->Insert(PROP_CHAR_ESCAPEMENT_HEIGHT, true, uno::makeAny( nProp ) ); + } + break; // sprmCHpsPos + case NS_sprm::LN_CHpsPosAdj: + break; // sprmCHpsPosAdj + case NS_sprm::LN_CMajority: + break; // sprmCMajority + case NS_sprm::LN_CIss: // sprmCIss + { + //sub/super script 1: super, 2: sub, 0: normal + sal_Int16 nEscapement = 0; + sal_Int8 nProp = 58; + switch(nIntValue) + { + case 1: //super + nEscapement = 101; + break; + case 2: //sub + nEscapement = -101; + break; + case 0: nProp = 0;break; //none + } + rContext->Insert(PROP_CHAR_ESCAPEMENT, true, uno::makeAny( nEscapement ) ); + rContext->Insert(PROP_CHAR_ESCAPEMENT_HEIGHT, true, uno::makeAny( nProp ) ); + } + break; + case NS_sprm::LN_CHpsNew50: + break; // sprmCHpsNew50 + case NS_sprm::LN_CHpsInc1: + break; // sprmCHpsInc1 + case 71 : //"sprmCDxaSpace" + case 96 : //"sprmCDxaSpace" + case NS_sprm::LN_CDxaSpace: // sprmCDxaSpace + //Kerning half point values + //TODO: there are two kerning values - + // in ww8par6.cxx NS_sprm::LN_CHpsKern is used as boolean AutoKerning + rContext->Insert(PROP_CHAR_CHAR_KERNING, true, uno::makeAny( sal_Int16(ConversionHelper::convertTwipToMM100(sal_Int16(nIntValue))) ) ); + break; + case NS_sprm::LN_CHpsKern: // sprmCHpsKern auto kerning is bound to a minimum font size in Word - but not in Writer :-( + rContext->Insert(PROP_CHAR_AUTO_KERNING, true, uno::makeAny( true ) ); + break; + case NS_sprm::LN_CMajority50: + break; // sprmCMajority50 + case NS_sprm::LN_CHpsMul: + break; // sprmCHpsMul + case NS_sprm::LN_CYsri: + break; // sprmCYsri + case NS_sprm::LN_CRgFtc0: // sprmCRgFtc0 //ascii font index + case NS_sprm::LN_CRgFtc1: // sprmCRgFtc1 //Asian font index + case NS_sprm::LN_CRgFtc2: // sprmCRgFtc2 //CTL font index + case NS_sprm::LN_CFtcBi: // sprmCFtcBi //font index of a CTL font + { + FontTablePtr pFontTable = m_pImpl->GetFontTable(); + if(nIntValue >= 0 && pFontTable->size() > sal_uInt32(nIntValue)) + { + PropertyIds eFontName = PROP_CHAR_FONT_NAME; + PropertyIds eFontStyle = PROP_CHAR_FONT_STYLE; + PropertyIds eFontFamily = PROP_CHAR_FONT_FAMILY; + PropertyIds eFontCharSet = PROP_CHAR_FONT_CHAR_SET; + PropertyIds eFontPitch = PROP_CHAR_FONT_PITCH; + switch(nSprmId) + { + case NS_sprm::LN_CRgFtc0: + //already initialized + break; + case NS_sprm::LN_CRgFtc1: + eFontName = PROP_CHAR_FONT_NAME_ASIAN; + eFontStyle = PROP_CHAR_FONT_STYLE_ASIAN; + eFontFamily = PROP_CHAR_FONT_FAMILY_ASIAN; + eFontCharSet = PROP_CHAR_FONT_CHAR_SET_ASIAN; + eFontPitch = PROP_CHAR_FONT_PITCH_ASIAN; + break; + case NS_sprm::LN_CRgFtc2: + case NS_sprm::LN_CFtcBi: + eFontName = PROP_CHAR_FONT_NAME_COMPLEX; + eFontStyle = PROP_CHAR_FONT_STYLE_COMPLEX; + eFontFamily = PROP_CHAR_FONT_FAMILY_COMPLEX; + eFontCharSet = PROP_CHAR_FONT_CHAR_SET_COMPLEX; + eFontPitch = PROP_CHAR_FONT_PITCH_COMPLEX; + break; + } + (void)eFontFamily; + (void)eFontStyle; + const FontEntry::Pointer_t pFontEntry(pFontTable->getFontEntry(sal_uInt32(nIntValue))); + rContext->Insert(eFontName, true, uno::makeAny( pFontEntry->sFontName )); + rContext->Insert(eFontCharSet, true, uno::makeAny( (sal_Int16)pFontEntry->nTextEncoding )); + rContext->Insert(eFontPitch, true, uno::makeAny( pFontEntry->nPitchRequest )); + } + } + break; + case NS_sprm::LN_CCharScale: // sprmCCharScale + rContext->Insert(PROP_CHAR_SCALE_WIDTH, true, + uno::makeAny( sal_Int16(nIntValue) )); + break; + case NS_sprm::LN_CFImprint: // sprmCFImprint 1 or 0 + // FontRelief: NONE, EMBOSSED, ENGRAVED + rContext->Insert(PROP_CHAR_RELIEF, true, + uno::makeAny( nIntValue ? awt::FontRelief::ENGRAVED : awt::FontRelief::NONE )); + break; + case NS_sprm::LN_CFObj: + break; // sprmCFObj + case NS_sprm::LN_CPropRMark: + break; // sprmCPropRMark + case NS_sprm::LN_CSfxText: + // The file-format has many character animations. We have only + // one, so we use it always. Suboptimal solution though. + if (nIntValue) + rContext->Insert(PROP_CHAR_FLASH, true, uno::makeAny( true )); + else + rContext->Insert(PROP_CHAR_FLASH, true, uno::makeAny( false )); + break; // sprmCSfxText + case NS_sprm::LN_CFBiDi: + break; // sprmCFBiDi + case NS_sprm::LN_CFDiacColor: + break; // sprmCFDiacColor + case NS_sprm::LN_CIcoBi: + break; // sprmCIcoBi + case NS_sprm::LN_CDispFldRMark: + break; // sprmCDispFldRMark + case NS_sprm::LN_CIbstRMarkDel: + break; // sprmCIbstRMarkDel + case NS_sprm::LN_CDttmRMarkDel: + break; // sprmCDttmRMarkDel + case NS_sprm::LN_CBrc: + break; // sprmCBrc + case NS_sprm::LN_CShd: + { + //contains fore color, back color and shadow percentage, results in a brush + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + { + CellColorHandlerPtr pCellColorHandler( new CellColorHandler ); + pCellColorHandler->setOutputFormat( CellColorHandler::Character ); + pProperties->resolve(*pCellColorHandler); + rContext->insert( pCellColorHandler->getProperties(), true ); + } + break; + } + case NS_sprm::LN_CIdslRMarkDel: + break; // sprmCIdslRMarkDel + case NS_sprm::LN_CFUsePgsuSettings: + break; // sprmCFUsePgsuSettings + case NS_sprm::LN_CCpg: + break; // sprmCCpg + case NS_sprm::LN_CLidBi: // sprmCLidBi language complex + case NS_sprm::LN_CRgLid0_80: // sprmCRgLid0_80 older language Western + case NS_sprm::LN_CRgLid0: // sprmCRgLid0 language Western + case NS_sprm::LN_CRgLid1: // sprmCRgLid1 language Asian + case NS_sprm::LN_CRgLid1_80: // sprmCRgLid1_80 older language Asian + { + lang::Locale aLocale; + MsLangId::convertLanguageToLocale( (LanguageType)nIntValue, aLocale ); + + PropertyIds aPropId; + switch (nSprmId) + { + case NS_sprm::LN_CRgLid0: + case NS_sprm::LN_CRgLid0_80: + aPropId = PROP_CHAR_LOCALE; + break; + case NS_sprm::LN_CRgLid1: + case NS_sprm::LN_CRgLid1_80: + aPropId = PROP_CHAR_LOCALE_ASIAN; + break; + default: + aPropId = PROP_CHAR_LOCALE_COMPLEX; + break; + } + + rContext->Insert(aPropId, true, uno::makeAny( aLocale ) ); + } + break; + + case NS_sprm::LN_CIdctHint: // sprmCIdctHint + //list table - text offset??? + break; + case NS_sprm::LN_PicBrcl: + break; // sprmPicBrcl + case NS_sprm::LN_PicScale: + break; // sprmPicScale + case NS_sprm::LN_PicBrcTop: + break; // sprmPicBrcTop + case NS_sprm::LN_PicBrcLeft: + break; // sprmPicBrcLeft + case NS_sprm::LN_PicBrcBottom: + break; // sprmPicBrcBoConversionHelper::convertTwipToMM100ttom + case NS_sprm::LN_PicBrcRight: + break; // sprmPicBrcRight + case NS_sprm::LN_ScnsPgn: + break; // sprmScnsPgn + case NS_sprm::LN_SiHeadingPgn: + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + pSectionContext->SetEvenlySpaced( nIntValue > 0 ); + + break; // sprmSiHeadingPgn + case NS_sprm::LN_SOlstAnm: + break; // sprmSOlstAnm + case 136: + case NS_sprm::LN_SDxaColWidth: // sprmSDxaColWidth + // contains the twip width of the column as 3-byte-code + // the lowet byte contains the index + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + pSectionContext->AppendColumnWidth( ConversionHelper::convertTwipToMM100( (nIntValue & 0xffff00) >> 8 )); + break; + case NS_sprm::LN_SDxaColSpacing: // sprmSDxaColSpacing + // the lowet byte contains the index + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + pSectionContext->AppendColumnSpacing( ConversionHelper::convertTwipToMM100( (nIntValue & 0xffff00) >> 8 )); + break; + case 138: + case NS_sprm::LN_SFEvenlySpaced: + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + pSectionContext->SetEvenlySpaced( nIntValue > 0 ); + break; // sprmSFEvenlySpaced + case NS_sprm::LN_SFProtected: // sprmSFProtected + //todo: missing feature - unlocked sections in protected documents + break; + case NS_sprm::LN_SDmBinFirst: // sprmSDmBinFirst + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + pSectionContext->SetFirstPaperBin(nIntValue); + break; + case NS_sprm::LN_SDmBinOther: // sprmSDmBinOther + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + pSectionContext->SetPaperBin( nIntValue ); + break; + case NS_sprm::LN_SBkc: // sprmSBkc + /* break type + 0 - No break + 1 - New Colunn + 2 - New page + 3 - Even page + 4 - odd page + */ + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + pSectionContext->SetBreakType( nIntValue ); + break; + case 143: + case NS_sprm::LN_SFTitlePage: // sprmSFTitlePage + case NS_ooxml::LN_EG_SectPrContents_titlePg: + { + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + pSectionContext->SetTitlePage( nIntValue > 0 ? true : false );//section has title page + } + break; + case 144: + case NS_sprm::LN_SCcolumns: // sprmSCcolumns + //no of columns - 1 + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + pSectionContext->SetColumnCount( (sal_Int16) nIntValue ); + break; + case 145: + case NS_sprm::LN_SDxaColumns: // sprmSDxaColumns + //column distance - default 708 twip + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + pSectionContext->SetColumnDistance( ConversionHelper::convertTwipToMM100( nIntValue ) ); + break; + case NS_sprm::LN_SFAutoPgn: + break; // sprmSFAutoPgn + case 147: + case NS_sprm::LN_SNfcPgn: // sprmSNfcPgn + //page numbering 0 - Arab, 1 - ROMAN, 2 - roman, 3 - ABC, 4 abc + sal_Int16 nNumbering; + switch( nIntValue ) + { + case 1: nNumbering = style::NumberingType::ROMAN_UPPER; + case 2: nNumbering = style::NumberingType::ROMAN_LOWER; + case 3: nNumbering = style::NumberingType::CHARS_UPPER_LETTER; + case 4: nNumbering = style::NumberingType::CHARS_LOWER_LETTER; + case 0: + default: + nNumbering = style::NumberingType::ARABIC; + } + rContext->Insert( PROP_NUMBERING_TYPE, false, uno::makeAny( nNumbering ) ); + break; + case NS_sprm::LN_SDyaPgn: + break; // sprmSDyaPgn + case NS_sprm::LN_SDxaPgn: + break; // sprmSDxaPgn + case 150: + case NS_sprm::LN_SFPgnRestart: // sprmSFPgnRestart + { + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + pSectionContext->SetPageNoRestart( nIntValue > 0 ); + } + break; + case NS_sprm::LN_SFEndnote: + break; // sprmSFEndnote + case 154: + case NS_sprm::LN_SNLnnMod:// sprmSNLnnMod + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if( pSectionContext ) + pSectionContext->SetLnnMod( nIntValue ); + break; + case 155: + case NS_sprm::LN_SDxaLnn: // sprmSDxaLnn + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if( pSectionContext ) + pSectionContext->SetdxaLnn( nIntValue ); + break; + case 152: + case NS_sprm::LN_SLnc:// sprmSLnc + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if( pSectionContext ) + pSectionContext->SetLnc( nIntValue ); + break; + case 160: + case NS_sprm::LN_SLnnMin: // sprmSLnnMin + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if( pSectionContext ) + pSectionContext->SetLnnMin( nIntValue ); + break; + + case NS_sprm::LN_SGprfIhdt: + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + //flags about header/footer sharing and footnotes? + /* ww8scan.hxx: + * WW8_HEADER_EVEN = 0x01, WW8_HEADER_ODD = 0x02, WW8_FOOTER_EVEN = 0x04, + * WW8_FOOTER_ODD = 0x08, WW8_HEADER_FIRST = 0x10, WW8_FOOTER_FIRST = 0x20 + */ + + break; // sprmSGprfIhdt + case NS_sprm::LN_SDyaHdrTop: // sprmSDyaHdrTop + // default 720 twip + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + pSectionContext->SetHeaderTop( ConversionHelper::convertTwipToMM100( nIntValue )); + break; + case NS_sprm::LN_SDyaHdrBottom: // sprmSDyaHdrBottom + // default 720 twip + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + pSectionContext->SetHeaderBottom( ConversionHelper::convertTwipToMM100( nIntValue ) ); + break; + case 158: + case NS_sprm::LN_SLBetween: // sprmSLBetween + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + pSectionContext->SetSeparatorLine( nIntValue > 0 ); + break; + case NS_sprm::LN_SVjc: + break; // sprmSVjc + case 161: + case NS_sprm::LN_SPgnStart: // sprmSPgnStart + //page number + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + pSectionContext->SetPageNumber( nIntValue ); + break; + case 162: + case NS_sprm::LN_SBOrientation: + //todo: the old filter assumed that a value of 2 points to double-pages layout + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + pSectionContext->SetLandscape( nIntValue > 0 ); + rContext->Insert( PROP_IS_LANDSCAPE , false, uno::makeAny( nIntValue > 0 )); + break; // sprmSBOrientation + case NS_sprm::LN_SBCustomize: + break; // sprmSBCustomize + case 165: + case NS_sprm::LN_SYaPage: // sprmSYaPage + { + //page height, rounded to default values, default: 0x3dc0 twip + sal_Int32 nHeight = ConversionHelper::convertTwipToMM100( nIntValue ); + rContext->Insert( PROP_HEIGHT, false, uno::makeAny( PaperInfo::sloppyFitPageDimension( nHeight ) ) ); + } + break; + case NS_sprm::LN_SXaPage: // sprmSXaPage + { + //page width, rounded to default values, default 0x2fd0 twip + sal_Int32 nWidth = ConversionHelper::convertTwipToMM100( nIntValue ); + rContext->Insert( PROP_WIDTH, false, uno::makeAny( PaperInfo::sloppyFitPageDimension( nWidth ) ) ); + } + break; + case 166: + case NS_sprm::LN_SDxaLeft: // sprmSDxaLeft + { + //left page margin default 0x708 twip + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + sal_Int32 nConverted = ConversionHelper::convertTwipToMM100( nIntValue ); + if(pSectionContext) + pSectionContext->SetLeftMargin( nConverted ); + rContext->Insert( PROP_LEFT_MARGIN, false, uno::makeAny( nConverted )); + } + break; + case 167: + case NS_sprm::LN_SDxaRight: // sprmSDxaRight + { + //right page margin default 0x708 twip + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + sal_Int32 nConverted = ConversionHelper::convertTwipToMM100( nIntValue ); + if(pSectionContext) + pSectionContext->SetRightMargin( nConverted ); + rContext->Insert( PROP_RIGHT_MARGIN, false, uno::makeAny( nConverted )); + } + break; + case 168: + case NS_sprm::LN_SDyaTop: // sprmSDyaTop + { + //top page margin default 1440 twip + //todo: check cast of SVBT16 + sal_Int32 nConverted = ConversionHelper::convertTwipToMM100( static_cast< sal_Int16 >( nIntValue ) ); + rContext->Insert( PROP_TOP_MARGIN, false, uno::makeAny( nConverted ) ); + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + pSectionContext->SetTopMargin( nConverted ); + } + break; + case 169: + case NS_sprm::LN_SDyaBottom: // sprmSDyaBottom + { + //bottom page margin default 1440 twip + //todo: check cast of SVBT16 + sal_Int32 nConverted = ConversionHelper::convertTwipToMM100( static_cast< sal_Int16 >( nIntValue ) ); + rContext->Insert( PROP_BOTTOM_MARGIN, false, uno::makeAny( nConverted) ); + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + pSectionContext->SetBottomMargin( nConverted ); + } + break; + case 170: + case NS_sprm::LN_SDzaGutter: // sprmSDzaGutter + { + // gutter is added to one of the margins of a section depending on RTL, can be placed on top either + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + { + pSectionContext->SetDzaGutter( ConversionHelper::convertTwipToMM100( nIntValue ) ); + } + } + break; + case NS_sprm::LN_SDmPaperReq: // sprmSDmPaperReq + //paper code - no handled in old filter + break; + case NS_sprm::LN_SPropRMark: + break; // sprmSPropRMark + case NS_sprm::LN_SFBiDi:// sprmSFBiDi + { + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + pSectionContext->SetSFBiDi( nIntValue > 0 ); + } + break; + case NS_sprm::LN_SFFacingCol: + break; // sprmSFFacingCol + case NS_sprm::LN_SFRTLGutter: // sprmSFRTLGutter + { + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + pSectionContext->SetGutterRTL( nIntValue > 0 ); + } + break; + case NS_sprm::LN_SBrcTop: // sprmSBrcTop + case NS_sprm::LN_SBrcLeft: // sprmSBrcLeft + case NS_sprm::LN_SBrcBottom: // sprmSBrcBottom + case NS_sprm::LN_SBrcRight: // sprmSBrcRight + { + table::BorderLine2 aBorderLine; + sal_Int32 nLineDistance = ConversionHelper::MakeBorderLine( nIntValue, aBorderLine ); + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + { + static const BorderPosition aPositions[4] = + { + BORDER_TOP, + BORDER_LEFT, + BORDER_BOTTOM, + BORDER_RIGHT + }; + pSectionContext->SetBorder( aPositions[nSprmId - NS_sprm::LN_SBrcTop], nLineDistance, aBorderLine ); + } + } + break; + + case NS_sprm::LN_SPgbProp: // sprmSPgbProp + { + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + { + pSectionContext->ApplyBorderToPageStyles( m_pImpl->GetPageStyles(), m_pImpl->GetTextFactory(), nIntValue ); + } + } + break; + case NS_sprm::LN_SDxtCharSpace: + { + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + { + pSectionContext->SetDxtCharSpace( nIntValue ); + } + } + break; // sprmSDxtCharSpace + case NS_sprm::LN_SDyaLinePitch: // sprmSDyaLinePitch + { + //see SwWW8ImplReader::SetDocumentGrid + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + { + pSectionContext->SetGridLinePitch( ConversionHelper::convertTwipToMM100( nIntValue ) ); + } + } + break; + case 0x703a: //undocumented, grid related? + OSL_FAIL( "TODO: not handled yet"); //nIntValue like 0x008a2373 ? + break; + case NS_sprm::LN_SClm: + { + sal_Int16 nGridType = text::TextGridMode::NONE; + switch( nIntValue ) + { + case 0: + nGridType = text::TextGridMode::NONE; + break; + case 3: + //Text snaps to char grid, this doesn't make a lot of sense to + //me. This is closer than LINES_CHARS + nGridType = text::TextGridMode::LINES; + break; + case 1: + nGridType = text::TextGridMode::LINES_AND_CHARS; + break; + case 2: + nGridType = text::TextGridMode::LINES; + break; + default:; + } + rContext->Insert( PROP_GRID_MODE, false, uno::makeAny( nGridType ) ); + + //Seems to force this behaviour in word ? + if(nGridType != text::TextGridMode::NONE) + m_pImpl->SetDocumentSettingsProperty( + PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_ADD_EXTERNAL_LEADING ), + uno::makeAny( true ) ); + } + break; // sprmSClm + case NS_sprm::LN_STextFlow: + case NS_ooxml::LN_EG_SectPrContents_textDirection: + { + /* 0 HoriLR 1 Vert TR 2 Vert TR 3 Vert TT 4 HoriLT + only 0 and 1 can be imported correctly + */ + sal_Int16 nDirection = text::WritingMode_LR_TB; + switch( nIntValue ) + { + case 0: + case 4: + nDirection = text::WritingMode_LR_TB; + break; + case 1: + case 2: + case 3: + nDirection = text::WritingMode_TB_RL; + break; + default:; + } + + PropertyMap * pTargetContext = rContext.get(); + + if (pSectionContext != NULL && + nSprmId == NS_ooxml::LN_EG_SectPrContents_textDirection) + { + pTargetContext = pSectionContext; + } + + pTargetContext->Insert(PROP_WRITING_MODE, false, uno::makeAny( nDirection ) ); + } + break; // sprmSTextFlow + case NS_sprm::LN_TJc: // sprmTJc + case NS_sprm::LN_TDxaLeft: + case NS_sprm::LN_TDxaGapHalf: + case NS_sprm::LN_TFCantSplit: + case NS_sprm::LN_TTableHeader: + case NS_sprm::LN_TTableBorders: // sprmTTableBorders + { + OSL_FAIL( "table propeties should be handled by the table manager"); + } + break; + case NS_sprm::LN_TDefTable10: + break; // sprmTDefTable10 + case NS_sprm::LN_TDyaRowHeight: + break; // sprmTDyaRowHeight + case NS_sprm::LN_TDefTable: + break; // sprmTDefTable + case NS_sprm::LN_TDefTableShd: + break; // sprmTDefTableShd + case NS_sprm::LN_TTlp: + break; // sprmTTlp + case NS_sprm::LN_TFBiDi: + break; // sprmTFBiDi + case NS_sprm::LN_THTMLProps: + break; // sprmTHTMLProps + case NS_sprm::LN_TSetBrc: + break; // sprmTSetBrc + case NS_sprm::LN_TInsert: + break; // sprmTInsert + case NS_sprm::LN_TDelete: + break; // sprmTDelete + case NS_sprm::LN_TDxaCol: + break; // sprmTDxaCol + case NS_sprm::LN_TMerge: + break; // sprmTMerge + case NS_sprm::LN_TSplit: + break; // sprmTSplit + case NS_sprm::LN_TSetBrc10: + break; // sprmTSetBrc10 + case 164: // sprmTSetShd + case NS_sprm::LN_TSetShd: + break; // sprmTSetShd + case NS_sprm::LN_TSetShdOdd: + break; // sprmTSetShdOdd + case NS_sprm::LN_TTextFlow: + break; // sprmTTextFlow + case NS_sprm::LN_TDiagLine: + break; // sprmTDiagLine + case NS_sprm::LN_TVertMerge: + break; // sprmTVertMerge + case NS_sprm::LN_TVertAlign: + break; // sprmTVertAlign + // the following are not part of the official documentation + case 0x6870: //TxtForeColor + { + //contains a color as 0xTTRRGGBB while SO uses 0xTTRRGGBB + sal_Int32 nColor = ConversionHelper::ConvertColor(nIntValue); + rContext->Insert(PROP_CHAR_COLOR, true, uno::makeAny( nColor ) ); + } + break; + case 0x6877: //underlining color + { + sal_Int32 nColor = ConversionHelper::ConvertColor(nIntValue); + rContext->Insert(PROP_CHAR_UNDERLINE_HAS_COLOR, true, uno::makeAny( true ) ); + rContext->Insert(PROP_CHAR_UNDERLINE_COLOR, true, uno::makeAny( nColor ) ); + } + break; + case 0x6815: + break; //undocumented + case NS_sprm::LN_CIndrsid: + break; //undocumented + case 0x6467: + break; //undocumented + case 0xF617: + break; //undocumented + case 0xd634: // sprmTNewSpacing - table spacing ( see WW8TabBandDesc::ProcessSpacing() ) + break; + case NS_sprm::LN_TTRLeft: + break; //undocumented + case 0x4888: + case 0x6887: + //properties of list levels - undocumented + break; + case 0xd234: + case 0xd235: + case 0xd236: + case 0xd237: + break;//undocumented section properties + case NS_sprm::LN_CEastAsianLayout: + resolveSprmProps(*this, rSprm); + break; + case NS_ooxml::LN_CT_Tabs_tab: + resolveSprmProps(*this, rSprm); + m_pImpl->IncorporateTabStop(m_pImpl->m_aCurrentTabStop); + m_pImpl->m_aCurrentTabStop = DeletableTabStop(); + break; + case NS_ooxml::LN_CT_PPrBase_tabs: + { + // Initialize tab stop vector from style sheet + if( !m_pImpl->IsStyleSheetImport() ) + { + uno::Any aValue = m_pImpl->GetPropertyFromStyleSheet(PROP_PARA_TAB_STOPS); + uno::Sequence< style::TabStop > aStyleTabStops; + if(aValue >>= aStyleTabStops) + { + m_pImpl->InitTabStopFromStyle( aStyleTabStops ); + } + } + resolveSprmProps(*this, rSprm); + rContext->Insert(PROP_PARA_TAB_STOPS, true, uno::makeAny( m_pImpl->GetCurrentTabStopAndClear())); + } + break; + + case NS_ooxml::LN_CT_DocDefaults_pPrDefault: + case NS_ooxml::LN_CT_DocDefaults_rPrDefault: + GetStyleSheetTable()->sprm( rSprm ); + break; + case NS_ooxml::LN_CT_PPr_sectPr: + case NS_ooxml::LN_EG_RPrBase_color: + case NS_ooxml::LN_EG_RPrBase_rFonts: + case NS_ooxml::LN_EG_RPrBase_bdr: + case NS_ooxml::LN_EG_RPrBase_eastAsianLayout: + case NS_ooxml::LN_EG_RPrBase_u: + case NS_ooxml::LN_EG_RPrBase_lang: + case NS_ooxml::LN_CT_PPrBase_spacing: + case NS_ooxml::LN_CT_PPrBase_ind: + case NS_ooxml::LN_CT_RPrDefault_rPr: + case NS_ooxml::LN_CT_PPrDefault_pPr: + case NS_ooxml::LN_CT_Style_pPr: + case NS_ooxml::LN_CT_Style_rPr: + case NS_ooxml::LN_CT_PPr_rPr: + case NS_ooxml::LN_CT_PPrBase_numPr: + resolveSprmProps(*this, rSprm); + break; + case NS_ooxml::LN_EG_SectPrContents_footnotePr: + case NS_ooxml::LN_EG_SectPrContents_endnotePr: + m_pImpl->SetInFootnoteProperties( NS_ooxml::LN_EG_SectPrContents_footnotePr == nSprmId ); + resolveSprmProps(*this, rSprm); + break; + case NS_ooxml::LN_EG_SectPrContents_lnNumType: + { + resolveSprmProps(*this, rSprm); + LineNumberSettings aSettings = m_pImpl->GetLineNumberSettings(); + aSettings.bIsOn = true; + m_pImpl->SetLineNumberSettings( aSettings ); + //apply settings at XLineNumberingProperties + try + { + uno::Reference< text::XLineNumberingProperties > xLineNumberingProperties( m_pImpl->GetTextDocument(), uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xLineNumberingPropSet = xLineNumberingProperties->getLineNumberingProperties(); + PropertyNameSupplier& rNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + xLineNumberingPropSet->setPropertyValue(rNameSupplier.GetName( PROP_IS_ON ), uno::makeAny(true) ); + if( aSettings.nInterval ) + xLineNumberingPropSet->setPropertyValue(rNameSupplier.GetName( PROP_INTERVAL ), uno::makeAny((sal_Int16)aSettings.nInterval) ); + if( aSettings.nDistance ) + xLineNumberingPropSet->setPropertyValue(rNameSupplier.GetName( PROP_DISTANCE ), uno::makeAny(aSettings.nDistance) ); + xLineNumberingPropSet->setPropertyValue(rNameSupplier.GetName( PROP_RESTART_AT_EACH_PAGE ), uno::makeAny(aSettings.bRestartAtEachPage) ); + } + catch( const uno::Exception& ) + { + } + + } + break; + case NS_ooxml::LN_CT_PPrBase_framePr: + { + PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH); + if( pContext.get() ) + { + ParagraphPropertyMap* pParaContext = dynamic_cast< ParagraphPropertyMap* >( pContext.get() ); + pParaContext->SetFrameMode(); + + } + else + { + //TODO: What about style sheet import of frame properties + } + resolveSprmProps(*this, rSprm); + } + break; + case NS_ooxml::LN_EG_SectPrContents_pgSz: + CT_PageSz.code = 0; + { + PaperInfo aLetter(PAPER_LETTER); + CT_PageSz.w = aLetter.getWidth(); + CT_PageSz.h = aLetter.getHeight(); + } + CT_PageSz.orient = false; + resolveSprmProps(*this, rSprm); + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + { + pSectionContext->Insert( PROP_HEIGHT, false, uno::makeAny( CT_PageSz.h ) ); + pSectionContext->Insert( PROP_IS_LANDSCAPE, false, uno::makeAny( CT_PageSz.orient )); + pSectionContext->Insert( PROP_WIDTH, false, uno::makeAny( CT_PageSz.w ) ); + pSectionContext->SetLandscape( CT_PageSz.orient ); + } + break; + + case NS_ooxml::LN_EG_SectPrContents_pgMar: + m_pImpl->InitPageMargins(); + resolveSprmProps(*this, rSprm); + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + { + const _PageMar& rPageMar = m_pImpl->GetPageMargins(); + pSectionContext->SetTopMargin( rPageMar.top ); + pSectionContext->SetRightMargin( rPageMar.right ); + pSectionContext->SetBottomMargin( rPageMar.bottom ); + pSectionContext->SetLeftMargin( rPageMar.left ); + pSectionContext->SetHeaderTop( rPageMar.header ); + pSectionContext->SetHeaderBottom( rPageMar.footer ); + } + break; + + case NS_ooxml::LN_EG_SectPrContents_cols: + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + { + + SectionColumnHandlerPtr pSectHdl( new SectionColumnHandler ); + pProperties->resolve(*pSectHdl); + if(pSectionContext) + { + if( pSectHdl->IsEqualWidth() ) + { + pSectionContext->SetEvenlySpaced( true ); + pSectionContext->SetColumnCount( (sal_Int16) (pSectHdl->GetNum() - 1) ); + pSectionContext->SetColumnDistance( pSectHdl->GetSpace() ); + pSectionContext->SetSeparatorLine( pSectHdl->IsSeparator() ); + } + else if( !pSectHdl->GetColumns().empty() ) + { + pSectionContext->SetEvenlySpaced( false ); + pSectionContext->SetColumnDistance( pSectHdl->GetSpace() ); + pSectionContext->SetColumnCount( (sal_Int16)(pSectHdl->GetColumns().size() -1)); + std::vector<_Column>::const_iterator tmpIter = pSectHdl->GetColumns().begin(); + for (; tmpIter != pSectHdl->GetColumns().end(); ++tmpIter) + { + pSectionContext->AppendColumnWidth( tmpIter->nWidth ); + if ((tmpIter != pSectHdl->GetColumns().end() - 1) || (tmpIter->nSpace > 0)) + pSectionContext->AppendColumnSpacing( tmpIter->nSpace ); + } + pSectionContext->SetSeparatorLine( pSectHdl->IsSeparator() ); + } + else if( pSectHdl->GetNum() > 0 ) + { + pSectionContext->SetColumnCount( (sal_Int16)pSectHdl->GetNum() - 1 ); + pSectionContext->SetColumnDistance( pSectHdl->GetSpace() ); + } + } + } + } + break; + case NS_ooxml::LN_EG_SectPrContents_docGrid: + resolveSprmProps(*this, rSprm); + break; + case NS_ooxml::LN_EG_SectPrContents_pgBorders: + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get( ) && pSectionContext ) + { + PageBordersHandlerPtr pHandler( new PageBordersHandler ); + pProperties->resolve( *pHandler ); + + // Set the borders to the context and apply them to the styles + pHandler->SetBorders( pSectionContext ); + pSectionContext->SetBorderParams( pHandler->GetDisplayOffset( ) ); + } + } + break; + + case NS_ooxml::LN_CT_PPrBase_pStyle: + { + m_pImpl->SetCurrentParaStyleId( sStringValue ); + StyleSheetTablePtr pStyleTable = m_pImpl->GetStyleSheetTable(); + const ::rtl::OUString sConvertedStyleName = pStyleTable->ConvertStyleName( sStringValue, true ); + if (m_pImpl->GetTopContext() && m_pImpl->GetTopContextType() != CONTEXT_SECTION) + m_pImpl->GetTopContext()->Insert( PROP_PARA_STYLE_NAME, true, uno::makeAny( sConvertedStyleName )); + const StyleSheetEntryPtr pEntry = pStyleTable->FindStyleSheetByISTD(sStringValue); + //apply numbering to paragraph if it was set at the style + OSL_ENSURE( pEntry.get(), "no style sheet found" ); + const StyleSheetPropertyMap* pStyleSheetProperties = dynamic_cast<const StyleSheetPropertyMap*>(pEntry ? pEntry->pProperties.get() : 0); + + if( pStyleSheetProperties && pStyleSheetProperties->GetListId() >= 0 ) + rContext->Insert( PROP_NUMBERING_STYLE_NAME, true, uno::makeAny( + ListDef::GetStyleName( pStyleSheetProperties->GetListId( ) ) ), false); + + if( pStyleSheetProperties && pStyleSheetProperties->GetListLevel() >= 0 ) + rContext->Insert( PROP_NUMBERING_LEVEL, true, uno::makeAny(pStyleSheetProperties->GetListLevel()), false); + } + break; + case NS_ooxml::LN_EG_RPrBase_rStyle: + { + rtl::OUString sConvertedName( m_pImpl->GetStyleSheetTable()->ConvertStyleName( sStringValue, true ) ); + // First check if the style exists in the document. + StyleSheetEntryPtr pEntry = m_pImpl->GetStyleSheetTable( )->FindStyleSheetByStyleName( sConvertedName ); + bool bExists = pEntry.get( ) && ( pEntry->nStyleTypeCode == STYLE_TYPE_CHAR ); + + // Add the property if the style exists + if ( bExists && m_pImpl->GetTopContext() ) + m_pImpl->GetTopContext()->Insert( PROP_CHAR_STYLE_NAME, true, uno::makeAny( sConvertedName ) ); + } + break; + case NS_ooxml::LN_CT_TblPrBase_tblCellMar: //cell margins + { + resolveSprmProps(*this, rSprm);//contains LN_CT_TblCellMar_top, LN_CT_TblCellMar_left, LN_CT_TblCellMar_bottom, LN_CT_TblCellMar_right + } + break; + case NS_ooxml::LN_CT_TblCellMar_top: + case NS_ooxml::LN_CT_TblCellMar_left: + case NS_ooxml::LN_CT_TblCellMar_bottom: + case NS_ooxml::LN_CT_TblCellMar_right: + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + { + MeasureHandlerPtr pMeasureHandler( new MeasureHandler ); + pProperties->resolve(*pMeasureHandler); + sal_Int32 nMeasureValue = pMeasureHandler->getMeasureValue(); + PropertyIds eId = META_PROP_CELL_MAR_TOP; + switch(nSprmId) + { + case NS_ooxml::LN_CT_TblCellMar_top: + break; + case NS_ooxml::LN_CT_TblCellMar_left: + eId = META_PROP_CELL_MAR_LEFT; + break; + case NS_ooxml::LN_CT_TblCellMar_bottom: + eId = META_PROP_CELL_MAR_BOTTOM; + break; + case NS_ooxml::LN_CT_TblCellMar_right: + eId = META_PROP_CELL_MAR_RIGHT; + break; + default:; + } + rContext->Insert( eId, false, uno::makeAny(nMeasureValue), false); + } + } + break; + case NS_sprm::LN_CFNoProof: //0x875 no grammar and spell checking, unsupported + break; + case NS_ooxml::LN_anchor_anchor: // at_character drawing + case NS_ooxml::LN_inline_inline: // as_character drawing + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + { + GraphicImportType eGraphicType = + (NS_ooxml::LN_anchor_anchor == + sal::static_int_cast<Id>(nSprmId)) ? + IMPORT_AS_DETECTED_ANCHOR : + IMPORT_AS_DETECTED_INLINE; + GraphicImportPtr pGraphicImport = + m_pImpl->GetGraphicImport(eGraphicType); + pProperties->resolve(*pGraphicImport); + m_pImpl->ImportGraphic(pProperties, eGraphicType); + if( !pGraphicImport->IsGraphic() ) + { + m_pImpl->ResetGraphicImport(); + // todo: It's a shape, now start shape import + } + } + } + break; + case NS_ooxml::LN_EG_RPrBase_vertAlign: + { + sal_Int16 nEscapement = 0; + sal_Int8 nProp = 58; + if( sStringValue.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "superscript" ) )) + nEscapement = 101; + else if( sStringValue.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "subscript" ) )) + nEscapement = -101; + else + nProp = 100; + + rContext->Insert(PROP_CHAR_ESCAPEMENT, true, uno::makeAny( nEscapement ) ); + rContext->Insert(PROP_CHAR_ESCAPEMENT_HEIGHT, true, uno::makeAny( nProp ) ); + } + break; + case NS_ooxml::LN_CT_FtnProps_pos: + //footnotes in word can be at page end or beneath text - writer supports only the first + //endnotes in word can be at section end or document end - writer supports only the latter + // -> so this property can be ignored + break; + case NS_ooxml::LN_EG_FtnEdnNumProps_numStart: + case NS_ooxml::LN_CT_FtnProps_numFmt: + case NS_ooxml::LN_CT_EdnProps_numFmt: + { + try + { + uno::Reference< beans::XPropertySet > xFtnEdnSettings; + if( m_pImpl->IsInFootnoteProperties() ) + { + uno::Reference< text::XFootnotesSupplier> xFootnotesSupplier( m_pImpl->GetTextDocument(), uno::UNO_QUERY ); + xFtnEdnSettings = xFootnotesSupplier->getFootnoteSettings(); + } + else + { + uno::Reference< text::XEndnotesSupplier> xEndnotesSupplier( m_pImpl->GetTextDocument(), uno::UNO_QUERY ); + xFtnEdnSettings = xEndnotesSupplier->getEndnoteSettings(); + } + if( NS_ooxml::LN_EG_FtnEdnNumProps_numStart == nSprmId ) + { + xFtnEdnSettings->setPropertyValue( + PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_START_AT), + uno::makeAny( sal_Int16( nIntValue - 1 ))); + } + else + { + sal_Int16 nNumType = ConversionHelper::ConvertNumberingType( nIntValue ); + xFtnEdnSettings->setPropertyValue( + PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_NUMBERING_TYPE), + uno::makeAny( nNumType )); + } + } + catch( const uno::Exception& ) + { + } + } + break; + case NS_ooxml::LN_paratrackchange: + m_pImpl->StartParaChange( ); + case NS_ooxml::LN_trackchange: + case NS_ooxml::LN_EG_RPrContent_rPrChange: + { + m_pImpl->AddNewRedline( ); + resolveSprmProps(*this, rSprm ); + // now the properties author, date and id should be available + sal_Int32 nToken = m_pImpl->GetCurrentRedlineToken(); + switch( nToken & 0xffff ) + { + case ooxml::OOXML_mod : + case ooxml::OOXML_ins : + case ooxml::OOXML_del : break; + default: OSL_FAIL( "redline token other than mod, ins or del" ); + } + m_pImpl->EndParaChange( ); + } + break; + case NS_ooxml::LN_CT_RPrChange_rPr: + break; + case NS_ooxml::LN_object: + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get( ) ) + { + OLEHandlerPtr pOLEHandler( new OLEHandler ); + pProperties->resolve(*pOLEHandler); + if ( pOLEHandler->isOLEObject( ) ) + { + ::rtl::OUString sStreamName = pOLEHandler->copyOLEOStream( m_pImpl->GetTextDocument() ); + if( sStreamName.getLength() ) + { + m_pImpl->appendOLE( sStreamName, pOLEHandler ); + } + } + } + } + break; + case NS_ooxml::LN_EG_HdrFtrReferences_headerReference: // header reference - not needed + case NS_ooxml::LN_EG_HdrFtrReferences_footerReference: // footer reference - not needed + break; + case NS_ooxml::LN_EG_RPrBase_snapToGrid: // "Use document grid settings for inter-paragraph spacing" + break; + case NS_sprm::LN_PContextualSpacing: + //TODO: determines whether top/bottom paragraph spacing is added if equal styles are following - unsupported + break; + case NS_ooxml::LN_EG_SectPrContents_formProt: //section protection, only form editing is enabled - unsupported + case NS_ooxml::LN_EG_SectPrContents_vAlign: + case NS_ooxml::LN_EG_RPrBase_fitText: + break; + case NS_ooxml::LN_ffdata: + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if (pProperties.get() != NULL) + { + FFDataHandler::Pointer_t pFFDataHandler(new FFDataHandler()); + + pProperties->resolve(*pFFDataHandler); + m_pImpl->SetFieldFFData(pFFDataHandler); + } + } + break; + default: + { +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->startElement("unhandled"); + dmapper_logger->attribute("id", nSprmId); + dmapper_logger->attribute("name", rSprm.getName()); + dmapper_logger->endElement(); +#endif + } + } +} + + +void DomainMapper::lcl_entry(int /*pos*/, + writerfilter::Reference<Properties>::Pointer_t ref) +{ + ref->resolve(*this); +} + +void DomainMapper::data(const sal_uInt8* /*buf*/, size_t /*len*/, + writerfilter::Reference<Properties>::Pointer_t /*ref*/) +{ +} + +void DomainMapper::lcl_startSectionGroup() +{ + m_pImpl->PushProperties(CONTEXT_SECTION); +} + +void DomainMapper::lcl_endSectionGroup() +{ + PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_SECTION); + SectionPropertyMap* pSectionContext = dynamic_cast< SectionPropertyMap* >( pContext.get() ); + OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); + if(pSectionContext) + pSectionContext->CloseSectionGroup( *m_pImpl ); + m_pImpl->PopProperties(CONTEXT_SECTION); +} + +void DomainMapper::lcl_startParagraphGroup() +{ + m_pImpl->getTableManager().startParagraphGroup(); + m_pImpl->PushProperties(CONTEXT_PARAGRAPH); + static ::rtl::OUString sDefault(RTL_CONSTASCII_USTRINGPARAM("Standard") ); + if (m_pImpl->GetTopContext()) + { + m_pImpl->GetTopContext()->Insert( PROP_PARA_STYLE_NAME, true, uno::makeAny( sDefault ) ); + if (m_pImpl->isBreakDeferred(PAGE_BREAK)) + m_pImpl->GetTopContext()->Insert( PROP_BREAK_TYPE, true, uno::makeAny( com::sun::star::style::BreakType_PAGE_BEFORE) ); + else if (m_pImpl->isBreakDeferred(COLUMN_BREAK)) + m_pImpl->GetTopContext()->Insert( PROP_BREAK_TYPE, true, uno::makeAny( com::sun::star::style::BreakType_COLUMN_BEFORE) ); + } + m_pImpl->clearDeferredBreaks(); +} + +void DomainMapper::lcl_endParagraphGroup() +{ + m_pImpl->PopProperties(CONTEXT_PARAGRAPH); + m_pImpl->getTableManager().endParagraphGroup(); + //frame conversion has to be executed after table conversion + m_pImpl->ExecuteFrameConversion(); +} + +void DomainMapper::markLastParagraphInSection( ) +{ + m_pImpl->SetIsLastParagraphInSection( true ); +} + +void DomainMapper::lcl_startShape( uno::Reference< drawing::XShape > xShape ) +{ + m_pImpl->PushShapeContext( xShape ); +} + +void DomainMapper::lcl_endShape( ) +{ + m_pImpl->PopShapeContext( ); +} + +void DomainMapper::PushStyleSheetProperties( PropertyMapPtr pStyleProperties, bool bAffectTableMngr ) +{ + m_pImpl->PushStyleProperties( pStyleProperties ); + if ( bAffectTableMngr ) + m_pImpl->getTableManager( ).SetStyleProperties( pStyleProperties ); +} + +void DomainMapper::PopStyleSheetProperties( bool bAffectTableMngr ) +{ + m_pImpl->PopProperties( CONTEXT_STYLESHEET ); + if ( bAffectTableMngr ) + { + PropertyMapPtr emptyPtr; + m_pImpl->getTableManager( ).SetStyleProperties( emptyPtr ); + } +} + +void DomainMapper::PushListProperties( ::boost::shared_ptr<PropertyMap> pListProperties ) +{ + m_pImpl->PushListProperties( pListProperties ); +} + +void DomainMapper::PopListProperties() +{ + m_pImpl->PopProperties( CONTEXT_LIST ); +} + +void DomainMapper::lcl_startCharacterGroup() +{ + m_pImpl->PushProperties(CONTEXT_CHARACTER); + DomainMapperTableManager& rTableManager = m_pImpl->getTableManager(); + if( rTableManager.getTableStyleName().getLength() ) + { + PropertyMapPtr pTopContext = m_pImpl->GetTopContext(); + rTableManager.CopyTextProperties(pTopContext, m_pImpl->GetStyleSheetTable()); + } +} + +void DomainMapper::lcl_endCharacterGroup() +{ + m_pImpl->PopProperties(CONTEXT_CHARACTER); +} + +void DomainMapper::lcl_text(const sal_uInt8 * data_, size_t len) +{ + //TODO: Determine the right text encoding (FIB?) + ::rtl::OUString sText( (const sal_Char*) data_, len, RTL_TEXTENCODING_MS_1252 ); +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->startElement("text"); + dmapper_logger->chars(sText); + dmapper_logger->endElement(); +#endif + + try + { + if(len == 1) + { + switch(*data_) + { + case 0x02: return; //footnote character + case 0x0c: //page break + m_pImpl->deferBreak(PAGE_BREAK); + return; + case 0x0e: //column break + m_pImpl->deferBreak(COLUMN_BREAK); + return; + case 0x07: + m_pImpl->getTableManager().text(data_, len); + case 0x0d: + m_pImpl->finishParagraph(m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)); + return; + case 0x13: + m_pImpl->PushFieldContext(); + return; + case 0x14: + // delimiter not necessarily available + // appears only if field contains further content + m_pImpl->CloseFieldCommand(); + return; + case 0x15: /* end of field */ + m_pImpl->PopFieldContext(); + return; + default: + break; + } + } + + PropertyMapPtr pContext = m_pImpl->GetTopContext(); + if ( pContext && !pContext->GetFootnote().is() ) + { + if (m_pImpl->isBreakDeferred(PAGE_BREAK)) + m_pImpl->GetTopContext()->Insert( PROP_BREAK_TYPE, true, uno::makeAny( com::sun::star::style::BreakType_PAGE_BEFORE) ); + else if (m_pImpl->isBreakDeferred(COLUMN_BREAK)) + m_pImpl->GetTopContext()->Insert( PROP_BREAK_TYPE, true, uno::makeAny( com::sun::star::style::BreakType_COLUMN_BEFORE) ); + m_pImpl->clearDeferredBreaks(); + } + + if( pContext->GetFootnote().is() && m_pImpl->IsCustomFtnMark() ) + { + pContext->GetFootnote()->setLabel( sText ); + m_pImpl->SetCustomFtnMark( false ); + //otherwise ignore sText + } + else if( m_pImpl->IsOpenFieldCommand() ) + m_pImpl->AppendFieldCommand(sText); + else if( m_pImpl->IsOpenField() && m_pImpl->IsFieldResultAsString()) + /*depending on the success of the field insert operation this result will be + set at the field or directly inserted into the text*/ + m_pImpl->SetFieldResult( sText ); + else + { + if (pContext == NULL) + pContext.reset(new PropertyMap()); + + m_pImpl->appendTextPortion( sText, pContext ); + } + } + catch( const uno::RuntimeException& ) + { + std::clog << __FILE__ << "(l" << __LINE__ << ")" << std::endl; + } +} + +void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len) +{ + OUString sText; + OUStringBuffer aBuffer = OUStringBuffer(len); + aBuffer.append( (const sal_Unicode *) data_, len); + sText = aBuffer.makeStringAndClear(); + + try + { + m_pImpl->getTableManager().utext(data_, len); + + if(len == 1 && ((*data_) == 0x0d || (*data_) == 0x07)) + m_pImpl->finishParagraph(m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)); + else + { + + PropertyMapPtr pContext = m_pImpl->GetTopContext(); + if ( pContext && !pContext->GetFootnote().is() ) + { + if (m_pImpl->isBreakDeferred(PAGE_BREAK)) + m_pImpl->GetTopContext()->Insert( PROP_BREAK_TYPE, true, uno::makeAny( com::sun::star::style::BreakType_PAGE_BEFORE) ); + else if (m_pImpl->isBreakDeferred(COLUMN_BREAK)) + m_pImpl->GetTopContext()->Insert( PROP_BREAK_TYPE, true, uno::makeAny( com::sun::star::style::BreakType_COLUMN_BEFORE) ); + m_pImpl->clearDeferredBreaks(); + } + + if( pContext && pContext->GetFootnote().is() ) + { + if( !pContext->GetFootnoteSymbol() ) + pContext->GetFootnote()->setLabel( sText ); + //otherwise ignore sText + } + else if( m_pImpl->IsOpenFieldCommand() ) + m_pImpl->AppendFieldCommand(sText); + else if( m_pImpl->IsOpenField() && m_pImpl->IsFieldResultAsString()) + /*depending on the success of the field insert operation this result will be + set at the field or directly inserted into the text*/ + m_pImpl->SetFieldResult( sText ); + else + { + if (pContext == NULL) + pContext.reset(new PropertyMap()); + + m_pImpl->appendTextPortion( sText, pContext ); + } + + } + } + catch( const uno::RuntimeException& ) + { + } +} + +void DomainMapper::lcl_props(writerfilter::Reference<Properties>::Pointer_t ref) +{ + string sType = ref->getType(); + if( sType == "PICF" ) + { + m_pImpl->ImportGraphic(ref, IMPORT_AS_GRAPHIC); + } + else if( sType == "FSPA" ) + { + m_pImpl->ImportGraphic(ref, IMPORT_AS_SHAPE); + } + else + ref->resolve(*this); +} + +void DomainMapper::lcl_table(Id name, writerfilter::Reference<Table>::Pointer_t ref) +{ + m_pImpl->SetAnyTableImport(true); + switch(name) + { + case NS_rtf::LN_FONTTABLE: + + // create a font table object that listens to the attributes + // each entry call inserts a new font entry + ref->resolve( *m_pImpl->GetFontTable() ); + break; + case NS_rtf::LN_STYLESHEET: + //same as above to import style sheets + m_pImpl->SetStyleSheetImport( true ); + ref->resolve( *m_pImpl->GetStyleSheetTable() ); + m_pImpl->GetStyleSheetTable()->ApplyStyleSheets(m_pImpl->GetFontTable()); + m_pImpl->SetStyleSheetImport( false ); + break; + case NS_ooxml::LN_NUMBERING: + case NS_rtf::LN_LISTTABLE: + { + + //the same for list tables + ref->resolve( *m_pImpl->GetListTable() ); + m_pImpl->GetListTable( )->CreateNumberingRules( ); + } + break; + case NS_rtf::LN_LFOTABLE: + { + m_pImpl->GetListTable( )->SetLFOImport( true ); + ref->resolve( *m_pImpl->GetListTable() ); + m_pImpl->GetListTable( )->CreateNumberingRules( ); + m_pImpl->GetListTable( )->SetLFOImport( false ); + } + break; + case NS_ooxml::LN_THEMETABLE: + ref->resolve ( *m_pImpl->GetThemeTable() ); + break; + case NS_ooxml::LN_settings_settings: + ref->resolve ( *m_pImpl->GetSettingsTable() ); + m_pImpl->ApplySettingsTable(); + break; + default: + OSL_FAIL( "which table is to be filled here?"); + } + m_pImpl->SetAnyTableImport(false); +} + +void DomainMapper::lcl_substream(Id rName, ::writerfilter::Reference<Stream>::Pointer_t ref) +{ + m_pImpl->appendTableManager( ); + m_pImpl->getTableManager().startLevel(); + + //import of page header/footer + + switch( rName ) + { + case NS_rtf::LN_headerl: + + m_pImpl->PushPageHeader(SectionPropertyMap::PAGE_LEFT); + break; + case NS_rtf::LN_headerr: + + m_pImpl->PushPageHeader(SectionPropertyMap::PAGE_RIGHT); + break; + case NS_rtf::LN_headerf: + + m_pImpl->PushPageHeader(SectionPropertyMap::PAGE_FIRST); + break; + case NS_rtf::LN_footerl: + + m_pImpl->PushPageFooter(SectionPropertyMap::PAGE_LEFT); + break; + case NS_rtf::LN_footerr: + + m_pImpl->PushPageFooter(SectionPropertyMap::PAGE_RIGHT); + break; + case NS_rtf::LN_footerf: + + m_pImpl->PushPageFooter(SectionPropertyMap::PAGE_FIRST); + break; + case NS_rtf::LN_footnote: + case NS_rtf::LN_endnote: + m_pImpl->PushFootOrEndnote( NS_rtf::LN_footnote == rName ); + break; + case NS_rtf::LN_annotation : + m_pImpl->PushAnnotation(); + break; + } + ref->resolve(*this); + switch( rName ) + { + case NS_rtf::LN_headerl: + case NS_rtf::LN_headerr: + case NS_rtf::LN_headerf: + case NS_rtf::LN_footerl: + case NS_rtf::LN_footerr: + case NS_rtf::LN_footerf: + m_pImpl->PopPageHeaderFooter(); + break; + case NS_rtf::LN_footnote: + case NS_rtf::LN_endnote: + m_pImpl->PopFootOrEndnote(); + break; + case NS_rtf::LN_annotation : + m_pImpl->PopAnnotation(); + break; + } + + m_pImpl->getTableManager().endLevel(); + m_pImpl->popTableManager( ); +} + +void DomainMapper::lcl_info(const string & /*info_*/) +{ +} + +void DomainMapper::handleUnderlineType(const sal_Int32 nIntValue, const ::boost::shared_ptr<PropertyMap> pContext) +{ + sal_Int16 eUnderline = awt::FontUnderline::NONE; + + switch(nIntValue) + { + case 0: eUnderline = awt::FontUnderline::NONE; break; + case 2: pContext->Insert(PROP_CHAR_WORD_MODE, true, uno::makeAny( true ) ); // TODO: how to get rid of it? + case 1: eUnderline = awt::FontUnderline::SINGLE; break; + case 3: eUnderline = awt::FontUnderline::DOUBLE; break; + case 4: eUnderline = awt::FontUnderline::DOTTED; break; + case 7: eUnderline = awt::FontUnderline::DASH; break; + case 9: eUnderline = awt::FontUnderline::DASHDOT; break; + case 10:eUnderline = awt::FontUnderline::DASHDOTDOT; break; + case 6: eUnderline = awt::FontUnderline::BOLD; break; + case 11:eUnderline = awt::FontUnderline::WAVE; break; + case 20:eUnderline = awt::FontUnderline::BOLDDOTTED; break; + case 23:eUnderline = awt::FontUnderline::BOLDDASH; break; + case 39:eUnderline = awt::FontUnderline::LONGDASH; break; + case 55:eUnderline = awt::FontUnderline::BOLDLONGDASH; break; + case 25:eUnderline = awt::FontUnderline::BOLDDASHDOT; break; + case 26:eUnderline = awt::FontUnderline::BOLDDASHDOTDOT;break; + case 27:eUnderline = awt::FontUnderline::BOLDWAVE; break; + case 43:eUnderline = awt::FontUnderline::DOUBLEWAVE; break; + default: ; + } + pContext->Insert(PROP_CHAR_UNDERLINE, true, uno::makeAny( eUnderline ) ); +} + +void DomainMapper::handleParaJustification(const sal_Int32 nIntValue, const ::boost::shared_ptr<PropertyMap> pContext, const bool bExchangeLeftRight) +{ + sal_Int16 nAdjust = 0; + sal_Int16 nLastLineAdjust = 0; + switch(nIntValue) + { + case 1: + nAdjust = style::ParagraphAdjust_CENTER; + break; + case 2: + nAdjust = static_cast< sal_Int16 > (bExchangeLeftRight ? style::ParagraphAdjust_LEFT : style::ParagraphAdjust_RIGHT); + break; + case 4: + nLastLineAdjust = style::ParagraphAdjust_BLOCK; + //no break; + case 3: + nAdjust = style::ParagraphAdjust_BLOCK; + break; + case 0: + default: + nAdjust = static_cast< sal_Int16 > (bExchangeLeftRight ? style::ParagraphAdjust_RIGHT : style::ParagraphAdjust_LEFT); + break; + } + pContext->Insert( PROP_PARA_ADJUST, true, uno::makeAny( nAdjust ) ); + pContext->Insert( PROP_PARA_LAST_LINE_ADJUST, true, uno::makeAny( nLastLineAdjust ) ); +} + +bool DomainMapper::getColorFromIndex(const sal_Int32 nIndex, sal_Int32 &nColor) +{ + nColor = 0; + if ((nIndex < 1) || (nIndex > 16)) + return false; + + switch (nIndex) + { + case 1: nColor=0x000000; break; //black + case 2: nColor=0x0000ff; break; //blue + case 3: nColor=0x00ffff; break; //cyan + case 4: nColor=0x00ff00; break; //green + case 5: nColor=0xff00ff; break; //magenta + case 6: nColor=0xff0000; break; //red + case 7: nColor=0xffff00; break; //yellow + case 8: nColor=0xffffff; break; //white + case 9: nColor=0x000080; break;//dark blue + case 10: nColor=0x008080; break; //dark cyan + case 11: nColor=0x008000; break; //dark green + case 12: nColor=0x800080; break; //dark magenta + case 13: nColor=0x800000; break; //dark red + case 14: nColor=0x808000; break; //dark yellow + case 15: nColor=0x808080; break; //dark gray + case 16: nColor=0xC0C0C0; break; //light gray + default: + return false; + } + return true; +} + +sal_Int16 DomainMapper::getEmphasisValue(const sal_Int32 nIntValue) +{ + switch (nIntValue) + { + case 1: + return com::sun::star::text::FontEmphasis::DOT_ABOVE; + case 2: + return com::sun::star::text::FontEmphasis::ACCENT_ABOVE; + case 3: + return com::sun::star::text::FontEmphasis::CIRCLE_ABOVE; + case 4: + return com::sun::star::text::FontEmphasis::DOT_BELOW; + default: + return com::sun::star::text::FontEmphasis::NONE; + } +} + +rtl::OUString DomainMapper::getBracketStringFromEnum(const sal_Int32 nIntValue, const bool bIsPrefix) +{ + switch(nIntValue) + { + case 1: + if (bIsPrefix) + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "(" )); + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( ")" )); + + case 2: + if (bIsPrefix) + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "[" )); + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "]" )); + + case 3: + if (bIsPrefix) + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "<" )); + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( ">" )); + + case 4: + if (bIsPrefix) + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "{" )); + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "}" )); + + case 0: + default: + return rtl::OUString(); + } +} + +com::sun::star::style::TabAlign DomainMapper::getTabAlignFromValue(const sal_Int32 nIntValue) +{ + switch (nIntValue) + { + case 0: + case 4: // bar not supported + case 5: // num not supported + return com::sun::star::style::TabAlign_LEFT; + case 1: + return com::sun::star::style::TabAlign_CENTER; + case 2: + return com::sun::star::style::TabAlign_RIGHT; + case 3: + return com::sun::star::style::TabAlign_DECIMAL; + } + return com::sun::star::style::TabAlign_LEFT; +} + +sal_Unicode DomainMapper::getFillCharFromValue(const sal_Int32 nIntValue) +{ + switch (nIntValue) + { + case 1: // dot + return sal_Unicode(0x002e); + case 2: // hyphen + return sal_Unicode(0x002d); + case 3: // underscore + case 4: // heavy FIXME ??? + return sal_Unicode(0x005f); + case NS_ooxml::LN_Value_ST_TabTlc_middleDot: // middleDot + return sal_Unicode(0x00b7); + case 0: // none + default: + return sal_Unicode(0x0020); // blank space + } +} + +bool DomainMapper::IsOOXMLImport() const +{ + return m_pImpl->IsOOXMLImport(); +} + +uno::Reference < lang::XMultiServiceFactory > DomainMapper::GetTextFactory() const +{ + return m_pImpl->GetTextFactory(); +} + +uno::Reference< text::XTextRange > DomainMapper::GetCurrentTextRange() +{ + return m_pImpl->GetTopTextAppend()->getEnd(); +} + +::rtl::OUString DomainMapper::getOrCreateCharStyle( PropertyValueVector_t& rCharProperties ) +{ + StyleSheetTablePtr pStyleSheets = m_pImpl->GetStyleSheetTable(); + return pStyleSheets->getOrCreateCharStyle( rCharProperties ); +} + +StyleSheetTablePtr DomainMapper::GetStyleSheetTable( ) +{ + return m_pImpl->GetStyleSheetTable( ); +} + +} //namespace dmapper +} //namespace writerfilter + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx new file mode 100644 index 000000000000..ebe7d41665f5 --- /dev/null +++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx @@ -0,0 +1,819 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include <DomainMapperTableHandler.hxx> +#include <DomainMapper_Impl.hxx> +#include <StyleSheetTable.hxx> +#include <com/sun/star/table/TableBorderDistances.hpp> +#include <com/sun/star/table/TableBorder.hpp> +#include <com/sun/star/table/BorderLine2.hpp> +#include <com/sun/star/text/HoriOrientation.hpp> +#include <dmapperLoggers.hxx> + +#ifdef DEBUG_DMAPPER_TABLE_HANDLER +#include <PropertyMapHelper.hxx> +#endif + +#if OSL_DEBUG_LEVEL > 1 +#include <stdio.h> +#endif + +namespace writerfilter { +namespace dmapper { + +using namespace ::com::sun::star; +using namespace ::std; + +#define DEF_BORDER_DIST 190 //0,19cm +#define DEFAULT_CELL_MARGIN 108 //default cell margin, not documented + +#ifdef DEBUG_DMAPPER_TABLE_HANDLER +static void lcl_printProperties( PropertyMapPtr pProps ) +{ + if( pProps.get() ) + { + dmapper_logger->startElement("properties"); + + PropertyMap::const_iterator aMapIter = pProps->begin(); + PropertyMap::const_iterator aEndIter = pProps->end(); + PropertyNameSupplier& rPropSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + for( ; aMapIter != aEndIter; ++aMapIter ) + { + rtl::OUString aOUStr = rPropSupplier.GetName( aMapIter->first.eId ); + rtl::OString aOStr(aOUStr.getStr(), aOUStr.getLength(), RTL_TEXTENCODING_ASCII_US ); + clog << aOStr.getStr(); + + table::BorderLine2 aLine; + sal_Int32 nColor; + if ( aMapIter->second >>= aLine ) + { + dmapper_logger->startElement("borderline"); + dmapper_logger->attribute("color", aLine.Color); + dmapper_logger->attribute("inner", aLine.InnerLineWidth); + dmapper_logger->attribute("outer", aLine.OuterLineWidth); + dmapper_logger->endElement(); + } + else if ( aMapIter->second >>= nColor ) + { + dmapper_logger->startElement("color"); + dmapper_logger->attribute("number", nColor); + dmapper_logger->endElement(); + } + } + + dmapper_logger->endElement(); + } +} +#endif + +DomainMapperTableHandler::DomainMapperTableHandler(TextReference_t xText, DomainMapper_Impl& rDMapper_Impl) + : m_xText(xText), + m_rDMapper_Impl( rDMapper_Impl ), + m_nCellIndex(0), + m_nRowIndex(0) +{ +} + +DomainMapperTableHandler::~DomainMapperTableHandler() +{ +} + +void DomainMapperTableHandler::startTable(unsigned int nRows, + unsigned int /*nDepth*/, + TablePropertyMapPtr pProps) +{ + m_aTableProperties = pProps; + m_pTableSeq = TableSequencePointer_t(new TableSequence_t(nRows)); + m_nRowIndex = 0; + +#ifdef DEBUG_DMAPPER_TABLE_HANDLER + dmapper_logger->startElement("tablehandler.table"); + dmapper_logger->attribute("rows", nRows); + + if (pProps.get() != NULL) + pProps->dumpXml( dmapper_logger ); +#endif +} + + + +PropertyMapPtr lcl_SearchParentStyleSheetAndMergeProperties(const StyleSheetEntryPtr pStyleSheet, StyleSheetTablePtr pStyleSheetTable) +{ + PropertyMapPtr pRet; + if( pStyleSheet->sBaseStyleIdentifier.getLength()) + { + const StyleSheetEntryPtr pParentStyleSheet = pStyleSheetTable->FindStyleSheetByISTD( pStyleSheet->sBaseStyleIdentifier ); + pRet = lcl_SearchParentStyleSheetAndMergeProperties( pParentStyleSheet, pStyleSheetTable ); + } + else + { + pRet.reset( new PropertyMap ); + } + + pRet->insert( pStyleSheet->pProperties, true ); + + return pRet; +} + +void lcl_mergeBorder( PropertyIds nId, PropertyMapPtr pOrig, PropertyMapPtr pDest ) +{ + PropertyDefinition aDef( nId, false ); + PropertyMap::iterator pOrigIt = pOrig->find( aDef ); + + if ( pOrigIt != pOrig->end( ) ) + { + pDest->Insert( nId, false, pOrigIt->second, false ); + } +} + +void lcl_computeCellBorders( PropertyMapPtr pTableBorders, PropertyMapPtr pCellProps, + sal_Int32 nCell, sal_Int32 nRow, bool bIsEndCol, bool bIsEndRow ) +{ + PropertyDefinition aVertPDef( META_PROP_VERTICAL_BORDER, false ); + PropertyDefinition aHorizPDef( META_PROP_HORIZONTAL_BORDER, false ); + + PropertyMap::iterator aVerticalIter = pCellProps->find( aVertPDef ); + PropertyMap::iterator aHorizontalIter = pCellProps->find( aHorizPDef ); + + // Handle the vertical and horizontal borders + bool bHasVert = ( aVerticalIter != pCellProps->end( ) ); + uno::Any aVertProp; + if ( !bHasVert ) + { + aVerticalIter = pTableBorders->find( aVertPDef ); + bHasVert = ( aVerticalIter != pTableBorders->end( ) ); + if ( bHasVert ) + aVertProp = aVerticalIter->second; + } + else + { + aVertProp = aVerticalIter->second; + pCellProps->erase( aVerticalIter ); + } + + bool bHasHoriz = ( aHorizontalIter != pCellProps->end( ) ); + uno::Any aHorizProp; + if ( !bHasHoriz ) + { + aHorizontalIter = pTableBorders->find( aHorizPDef ); + bHasHoriz = ( aHorizontalIter != pTableBorders->end( ) ); + if ( bHasHoriz ) + aHorizProp = aHorizontalIter->second; + } + else + { + aHorizProp = aHorizontalIter->second; + pCellProps->erase( aHorizontalIter ); + } + + if ( nCell == 0 ) + { + lcl_mergeBorder( PROP_LEFT_BORDER, pTableBorders, pCellProps ); + if ( bHasVert ) + pCellProps->Insert( PROP_RIGHT_BORDER, false, aVertProp, false ); + } + + if ( bIsEndCol ) + { + lcl_mergeBorder( PROP_RIGHT_BORDER, pTableBorders, pCellProps ); + if ( bHasVert ) + pCellProps->Insert( PROP_LEFT_BORDER, false, aVertProp, false ); + } + + if ( nCell > 0 && !bIsEndCol ) + { + if ( bHasVert ) + { + pCellProps->Insert( PROP_RIGHT_BORDER, false, aVertProp, false ); + pCellProps->Insert( PROP_LEFT_BORDER, false, aVertProp, false ); + } + } + + if ( nRow == 0 ) + { + lcl_mergeBorder( PROP_TOP_BORDER, pTableBorders, pCellProps ); + if ( bHasHoriz ) + pCellProps->Insert( PROP_BOTTOM_BORDER, false, aHorizProp, false ); + } + + if ( bIsEndRow ) + { + lcl_mergeBorder( PROP_BOTTOM_BORDER, pTableBorders, pCellProps ); + if ( bHasHoriz ) + pCellProps->Insert( PROP_TOP_BORDER, false, aHorizProp, false ); + } + + if ( nRow > 0 && !bIsEndRow ) + { + if ( bHasHoriz ) + { + pCellProps->Insert( PROP_TOP_BORDER, false, aHorizProp, false ); + pCellProps->Insert( PROP_BOTTOM_BORDER, false, aHorizProp, false ); + } + } +} + +#ifdef DEBUG_DMAPPER_TABLE_HANDLER + +void lcl_debug_BorderLine(table::BorderLine & rLine) +{ + dmapper_logger->startElement("BorderLine"); + dmapper_logger->attribute("Color", rLine.Color); + dmapper_logger->attribute("InnerLineWidth", rLine.InnerLineWidth); + dmapper_logger->attribute("OuterLineWidth", rLine.OuterLineWidth); + dmapper_logger->attribute("LineDistance", rLine.LineDistance); + dmapper_logger->endElement(); +} + +void lcl_debug_TableBorder(table::TableBorder & rBorder) +{ + dmapper_logger->startElement("TableBorder"); + lcl_debug_BorderLine(rBorder.TopLine); + dmapper_logger->attribute("IsTopLineValid", rBorder.IsTopLineValid); + lcl_debug_BorderLine(rBorder.BottomLine); + dmapper_logger->attribute("IsBottomLineValid", rBorder.IsBottomLineValid); + lcl_debug_BorderLine(rBorder.LeftLine); + dmapper_logger->attribute("IsLeftLineValid", rBorder.IsLeftLineValid); + lcl_debug_BorderLine(rBorder.RightLine); + dmapper_logger->attribute("IsRightLineValid", rBorder.IsRightLineValid); + lcl_debug_BorderLine(rBorder.VerticalLine); + dmapper_logger->attribute("IsVerticalLineValid", rBorder.IsVerticalLineValid); + lcl_debug_BorderLine(rBorder.HorizontalLine); + dmapper_logger->attribute("IsHorizontalLineValid", rBorder.IsHorizontalLineValid); + dmapper_logger->attribute("Distance", rBorder.Distance); + dmapper_logger->attribute("IsDistanceValid", rBorder.IsDistanceValid); + dmapper_logger->endElement(); +} +#endif + +struct WRITERFILTER_DLLPRIVATE TableInfo +{ + sal_Int32 nLeftBorderDistance; + sal_Int32 nRightBorderDistance; + sal_Int32 nTopBorderDistance; + sal_Int32 nBottomBorderDistance; + PropertyMapPtr pTableDefaults; + PropertyMapPtr pTableBorders; + TableStyleSheetEntry* pTableStyle; + TablePropertyValues_t aTableProperties; + + TableInfo() + : nLeftBorderDistance(DEF_BORDER_DIST) + , nRightBorderDistance(DEF_BORDER_DIST) + , nTopBorderDistance(0) + , nBottomBorderDistance(0) + , pTableDefaults(new PropertyMap) + , pTableBorders(new PropertyMap) + , pTableStyle(NULL) + { + } + +}; + +namespace +{ + +bool lcl_extractTableBorderProperty(PropertyMapPtr pTableProperties, const PropertyIds nId, TableInfo& rInfo, table::BorderLine2& rLine) +{ + PropertyMap::iterator aTblBorderIter = pTableProperties->find( PropertyDefinition(nId, false) ); + if( aTblBorderIter != pTableProperties->end() ) + { + OSL_VERIFY(aTblBorderIter->second >>= rLine); + + rInfo.pTableBorders->Insert( nId, false, uno::makeAny( rLine ) ); + PropertyMap::iterator pIt = rInfo.pTableDefaults->find( PropertyDefinition( nId, false ) ); + if ( pIt != rInfo.pTableDefaults->end( ) ) + rInfo.pTableDefaults->erase( pIt ); + + return true; + } + + return false; +} + +} + +TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo & rInfo) +{ + // will receive the table style if any + TableStyleSheetEntry* pTableStyle = NULL; + + if( m_aTableProperties.get() ) + { + //create properties from the table attributes + //...pPropMap->Insert( PROP_LEFT_MARGIN, false, uno::makeAny( m_nLeftMargin - m_nGapHalf )); + //pPropMap->Insert( PROP_HORI_ORIENT, false, uno::makeAny( text::HoriOrientation::RIGHT )); + sal_Int32 nGapHalf = 0; + sal_Int32 nLeftMargin = 0; + sal_Int32 nTableWidth = 0; + + PropertyMap::iterator aTableStyleIter = + m_aTableProperties->find( PropertyDefinition( META_PROP_TABLE_STYLE_NAME, false ) ); + if(aTableStyleIter != m_aTableProperties->end()) + { + // Apply table style properties recursively + ::rtl::OUString sTableStyleName; + aTableStyleIter->second >>= sTableStyleName; + StyleSheetTablePtr pStyleSheetTable = m_rDMapper_Impl.GetStyleSheetTable(); + const StyleSheetEntryPtr pStyleSheet = pStyleSheetTable->FindStyleSheetByISTD( sTableStyleName ); + pTableStyle = dynamic_cast<TableStyleSheetEntry*>( pStyleSheet.get( ) ); + m_aTableProperties->erase( aTableStyleIter ); + + if( pStyleSheet ) + { + // First get the style properties, then the table ones + PropertyMapPtr pTableProps( m_aTableProperties ); + TablePropertyMapPtr pEmptyProps( new TablePropertyMap ); + + m_aTableProperties = pEmptyProps; + + PropertyMapPtr pMergedProperties = lcl_SearchParentStyleSheetAndMergeProperties(pStyleSheet, pStyleSheetTable); + +#ifdef DEBUG_DMAPPER_TABLE_HANDLER + dmapper_logger->startElement("mergedProps"); + pMergedProperties->dumpXml( dmapper_logger ); + dmapper_logger->endElement(); +#endif + + m_aTableProperties->insert( pMergedProperties ); + m_aTableProperties->insert( pTableProps ); + +#ifdef DEBUG_DMAPPER_TABLE_HANDLER + dmapper_logger->startElement("TableProperties"); + m_aTableProperties->dumpXml( dmapper_logger ); + dmapper_logger->endElement(); +#endif + } + } + + // Set the table default attributes for the cells + rInfo.pTableDefaults->insert( m_aTableProperties ); + +#ifdef DEBUG_DMAPPER_TABLE_HANDLER + dmapper_logger->startElement("TableDefaults"); + rInfo.pTableDefaults->dumpXml( dmapper_logger ); + dmapper_logger->endElement(); +#endif + + m_aTableProperties->getValue( TablePropertyMap::GAP_HALF, nGapHalf ); + m_aTableProperties->getValue( TablePropertyMap::LEFT_MARGIN, nLeftMargin ); + + m_aTableProperties->getValue( TablePropertyMap::CELL_MAR_LEFT, + rInfo.nLeftBorderDistance ); + m_aTableProperties->getValue( TablePropertyMap::CELL_MAR_RIGHT, + rInfo.nRightBorderDistance ); + m_aTableProperties->getValue( TablePropertyMap::CELL_MAR_TOP, + rInfo.nTopBorderDistance ); + m_aTableProperties->getValue( TablePropertyMap::CELL_MAR_BOTTOM, + rInfo.nBottomBorderDistance ); + + table::TableBorderDistances aDistances; + aDistances.IsTopDistanceValid = + aDistances.IsBottomDistanceValid = + aDistances.IsLeftDistanceValid = + aDistances.IsRightDistanceValid = sal_True; + aDistances.TopDistance = static_cast<sal_Int16>( rInfo.nTopBorderDistance ); + aDistances.BottomDistance = static_cast<sal_Int16>( rInfo.nBottomBorderDistance ); + aDistances.LeftDistance = static_cast<sal_Int16>( rInfo.nLeftBorderDistance ); + aDistances.RightDistance = static_cast<sal_Int16>( rInfo.nRightBorderDistance ); + + m_aTableProperties->Insert( PROP_TABLE_BORDER_DISTANCES, false, uno::makeAny( aDistances ) ); + + //table border settings + table::TableBorder aTableBorder; + table::BorderLine2 aBorderLine; + + if (lcl_extractTableBorderProperty(m_aTableProperties, PROP_TOP_BORDER, rInfo, aBorderLine)) + { + aTableBorder.TopLine = aBorderLine; + aTableBorder.IsTopLineValid = sal_True; + } + if (lcl_extractTableBorderProperty(m_aTableProperties, PROP_BOTTOM_BORDER, rInfo, aBorderLine)) + { + aTableBorder.BottomLine = aBorderLine; + aTableBorder.IsBottomLineValid = sal_True; + } + if (lcl_extractTableBorderProperty(m_aTableProperties, PROP_LEFT_BORDER, rInfo, aBorderLine)) + { + aTableBorder.LeftLine = aBorderLine; + aTableBorder.IsLeftLineValid = sal_True; + } + if (lcl_extractTableBorderProperty(m_aTableProperties, PROP_RIGHT_BORDER, rInfo, aBorderLine)) + { + aTableBorder.RightLine = aBorderLine; + aTableBorder.IsRightLineValid = sal_True; + } + if (lcl_extractTableBorderProperty(m_aTableProperties, META_PROP_HORIZONTAL_BORDER, rInfo, aBorderLine)) + { + aTableBorder.HorizontalLine = aBorderLine; + aTableBorder.IsHorizontalLineValid = sal_True; + } + if (lcl_extractTableBorderProperty(m_aTableProperties, META_PROP_VERTICAL_BORDER, rInfo, aBorderLine)) + { + aTableBorder.VerticalLine = aBorderLine; + aTableBorder.IsVerticalLineValid = sal_True; + } + + aTableBorder.Distance = 0; + aTableBorder.IsDistanceValid = sal_False; + + m_aTableProperties->Insert( PROP_TABLE_BORDER, false, uno::makeAny( aTableBorder ) ); + +#ifdef DEBUG_DMAPPER_TABLE_HANDLER + lcl_debug_TableBorder(aTableBorder); +#endif + + m_aTableProperties->Insert( PROP_LEFT_MARGIN, false, uno::makeAny( nLeftMargin - nGapHalf - rInfo.nLeftBorderDistance)); + + m_aTableProperties->getValue( TablePropertyMap::TABLE_WIDTH, nTableWidth ); + if( nTableWidth > 0 ) + m_aTableProperties->Insert( PROP_WIDTH, false, uno::makeAny( nTableWidth )); + + sal_Int32 nHoriOrient = text::HoriOrientation::LEFT_AND_WIDTH; + m_aTableProperties->getValue( TablePropertyMap::HORI_ORIENT, nHoriOrient ) ; + m_aTableProperties->Insert( PROP_HORI_ORIENT, false, uno::makeAny( sal_Int16(nHoriOrient) ) ); + + //fill default value - if not available + const PropertyMap::const_iterator aRepeatIter = + m_aTableProperties->find( PropertyDefinition( PROP_HEADER_ROW_COUNT, false ) ); + if( aRepeatIter == m_aTableProperties->end() ) + m_aTableProperties->Insert( PROP_HEADER_ROW_COUNT, false, uno::makeAny( (sal_Int32)0 )); + + rInfo.aTableProperties = m_aTableProperties->GetPropertyValues(); + +#ifdef DEBUG_DMAPPER_TABLE_HANDLER + dmapper_logger->startElement("debug.tableprops"); + m_aTableProperties->dumpXml( dmapper_logger ); + dmapper_logger->endElement(); +#endif + + } + + return pTableStyle; +} + +CellPropertyValuesSeq_t DomainMapperTableHandler::endTableGetCellProperties(TableInfo & rInfo) +{ +#ifdef DEBUG_DMAPPER_TABLE_HANDLER + dmapper_logger->startElement("getCellProperties"); +#endif + + CellPropertyValuesSeq_t aCellProperties( m_aCellProperties.size() ); + + if ( !m_aCellProperties.size() ) + { + #ifdef DEBUG_DOMAINMAPPER + dmapper_logger->endElement(); + #endif + return aCellProperties; + } + // std::vector< std::vector<PropertyMapPtr> > m_aCellProperties + PropertyMapVector2::const_iterator aRowOfCellsIterator = m_aCellProperties.begin(); + PropertyMapVector2::const_iterator aRowOfCellsIteratorEnd = m_aCellProperties.end(); + PropertyMapVector2::const_iterator aLastRowIterator = m_aCellProperties.end() - 1; + sal_Int32 nRow = 0; + + //it's a uno::Sequence< beans::PropertyValues >* + RowPropertyValuesSeq_t* pCellProperties = aCellProperties.getArray(); + while( aRowOfCellsIterator != aRowOfCellsIteratorEnd ) + { + //aRowOfCellsIterator points to a vector of PropertyMapPtr + PropertyMapVector1::const_iterator aCellIterator = aRowOfCellsIterator->begin(); + PropertyMapVector1::const_iterator aCellIteratorEnd = aRowOfCellsIterator->end(); + PropertyMapVector1::const_iterator aLastCellIterator = aRowOfCellsIterator->end() - 1; + + // Get the row style properties + sal_Int32 nRowStyleMask = sal_Int32( 0 ); + PropertyMapPtr pRowProps = m_aRowProperties[nRow]; + if ( pRowProps.get( ) ) + { + PropertyMap::iterator pTcCnfStyleIt = pRowProps->find( PropertyDefinition( PROP_CNF_STYLE, true ) ); + if ( pTcCnfStyleIt != pRowProps->end( ) ) + { + if ( rInfo.pTableStyle ) + { + rtl::OUString sMask; + pTcCnfStyleIt->second >>= sMask; + nRowStyleMask = sMask.toInt32( 2 ); + } + pRowProps->erase( pTcCnfStyleIt ); + } + } + + sal_Int32 nCell = 0; + pCellProperties[nRow].realloc( aRowOfCellsIterator->size() ); + beans::PropertyValues* pSingleCellProperties = pCellProperties[nRow].getArray(); + while( aCellIterator != aCellIteratorEnd ) + { + PropertyMapPtr pAllCellProps( new PropertyMap ); + + bool bIsEndCol = aCellIterator == aLastCellIterator; + bool bIsEndRow = aRowOfCellsIterator == aLastRowIterator; + + //aCellIterator points to a PropertyMapPtr; + if( aCellIterator->get() ) + { + if ( rInfo.pTableDefaults->size( ) ) + pAllCellProps->insert( rInfo.pTableDefaults ); + + // Fill the cell properties with the ones of the style + sal_Int32 nCellStyleMask = 0; + const PropertyMap::iterator aCnfStyleIter = + aCellIterator->get()->find( PropertyDefinition( PROP_CNF_STYLE, false ) ); + if ( aCnfStyleIter != aCellIterator->get( )->end( ) ) + { + if ( rInfo.pTableStyle ) { + rtl::OUString sMask; + aCnfStyleIter->second >>= sMask; + nCellStyleMask = sMask.toInt32( 2 ); + } + aCellIterator->get( )->erase( aCnfStyleIter ); + } + + if ( rInfo.pTableStyle ) + { + PropertyMapPtr pStyleProps = rInfo.pTableStyle->GetProperties( nCellStyleMask + nRowStyleMask ); + pAllCellProps->insert( pStyleProps ); + } + + // Remove properties from style/row that aren't allowed in cells + const PropertyMap::iterator aDefaultRepeatIt = + pAllCellProps->find( + PropertyDefinition( PROP_HEADER_ROW_COUNT, false ) ); + if ( aDefaultRepeatIt != pAllCellProps->end( ) ) + pAllCellProps->erase( aDefaultRepeatIt ); + + // Then add the cell properties + pAllCellProps->insert( *aCellIterator ); + aCellIterator->get( )->swap( *pAllCellProps.get( ) ); + +#ifdef DEBUG_DMAPPER_TABLE_HANDLER + dmapper_logger->startElement("cell"); + dmapper_logger->attribute("cell", nCell); + dmapper_logger->attribute("row", nRow); +#endif + + lcl_computeCellBorders( rInfo.pTableBorders, *aCellIterator, nCell, nRow, bIsEndCol, bIsEndRow ); + + //now set the default left+right border distance TODO: there's an sprm containing the default distance! + const PropertyMap::const_iterator aLeftDistanceIter = + aCellIterator->get()->find( PropertyDefinition(PROP_LEFT_BORDER_DISTANCE, false) ); + if( aLeftDistanceIter == aCellIterator->get()->end() ) + aCellIterator->get()->Insert( PROP_LEFT_BORDER_DISTANCE, false, + uno::makeAny(rInfo.nLeftBorderDistance ) ); + const PropertyMap::const_iterator aRightDistanceIter = + aCellIterator->get()->find( PropertyDefinition(PROP_RIGHT_BORDER_DISTANCE, false) ); + if( aRightDistanceIter == aCellIterator->get()->end() ) + aCellIterator->get()->Insert( PROP_RIGHT_BORDER_DISTANCE, false, + uno::makeAny((sal_Int32) rInfo.nRightBorderDistance ) ); + + const PropertyMap::const_iterator aTopDistanceIter = + aCellIterator->get()->find( PropertyDefinition(PROP_TOP_BORDER_DISTANCE, false) ); + if( aTopDistanceIter == aCellIterator->get()->end() ) + aCellIterator->get()->Insert( PROP_TOP_BORDER_DISTANCE, false, + uno::makeAny((sal_Int32) rInfo.nTopBorderDistance ) ); + + const PropertyMap::const_iterator aBottomDistanceIter = + aCellIterator->get()->find( PropertyDefinition(PROP_BOTTOM_BORDER_DISTANCE, false) ); + if( aBottomDistanceIter == aCellIterator->get()->end() ) + aCellIterator->get()->Insert( PROP_BOTTOM_BORDER_DISTANCE, false, + uno::makeAny((sal_Int32) rInfo.nBottomBorderDistance ) ); + + pSingleCellProperties[nCell] = aCellIterator->get()->GetPropertyValues(); +#ifdef DEBUG_DMAPPER_TABLE_HANDLER + dmapper_logger->endElement(); +#endif + } + ++nCell; + ++aCellIterator; + } +#ifdef DEBUG_DMAPPER_TABLE_HANDLER + //-->debug cell properties + { + ::rtl::OUString sNames; + const uno::Sequence< beans::PropertyValues > aDebugCurrentRow = aCellProperties[nRow]; + sal_Int32 nDebugCells = aDebugCurrentRow.getLength(); + (void) nDebugCells; + for( sal_Int32 nDebugCell = 0; nDebugCell < nDebugCells; ++nDebugCell) + { + const uno::Sequence< beans::PropertyValue >& aDebugCellProperties = aDebugCurrentRow[nDebugCell]; + sal_Int32 nDebugCellProperties = aDebugCellProperties.getLength(); + for( sal_Int32 nDebugProperty = 0; nDebugProperty < nDebugCellProperties; ++nDebugProperty) + { + const ::rtl::OUString sName = aDebugCellProperties[nDebugProperty].Name; + sNames += sName; + sNames += ::rtl::OUString('-'); + } + sNames += ::rtl::OUString('\n'); + } + (void)sNames; + } + //--< +#endif + ++nRow; + ++aRowOfCellsIterator; + } + +#ifdef DEBUG_DMAPPER_TABLE_HANDLER + dmapper_logger->endElement(); +#endif + + return aCellProperties; +} + +RowPropertyValuesSeq_t DomainMapperTableHandler::endTableGetRowProperties() +{ +#ifdef DEBUG_DMAPPER_TABLE_HANDLER + dmapper_logger->startElement("getRowProperties"); +#endif + + RowPropertyValuesSeq_t aRowProperties( m_aRowProperties.size() ); + PropertyMapVector1::const_iterator aRowIter = m_aRowProperties.begin(); + PropertyMapVector1::const_iterator aRowIterEnd = m_aRowProperties.end(); + sal_Int32 nRow = 0; + while( aRowIter != aRowIterEnd ) + { +#ifdef DEBUG_DMAPPER_TABLE_HANDLER + dmapper_logger->startElement("rowProps.row"); +#endif + if( aRowIter->get() ) + { + //set default to 'break across pages" + if( aRowIter->get()->find( PropertyDefinition( PROP_IS_SPLIT_ALLOWED, false )) == aRowIter->get()->end()) + aRowIter->get()->Insert( PROP_IS_SPLIT_ALLOWED, false, uno::makeAny(sal_True ) ); + + aRowProperties[nRow] = (*aRowIter)->GetPropertyValues(); +#ifdef DEBUG_DMAPPER_TABLE_HANDLER + ((*aRowIter)->dumpXml( dmapper_logger )); + lcl_DumpPropertyValues(dmapper_logger, aRowProperties[nRow]); +#endif + } + ++nRow; + ++aRowIter; +#ifdef DEBUG_DMAPPER_TABLE_HANDLER + dmapper_logger->endElement(); +#endif + } + +#ifdef DEBUG_DMAPPER_TABLE_HANDLER + dmapper_logger->endElement(); +#endif + + return aRowProperties; +} + +void DomainMapperTableHandler::endTable() +{ +#ifdef DEBUG_DMAPPER_TABLE_HANDLER + dmapper_logger->startElement("tablehandler.endTable"); +#endif + + TableInfo aTableInfo; + aTableInfo.pTableStyle = endTableGetTableStyle(aTableInfo); + // expands to uno::Sequence< Sequence< beans::PropertyValues > > + + CellPropertyValuesSeq_t aCellProperties = endTableGetCellProperties(aTableInfo); + + RowPropertyValuesSeq_t aRowProperties = endTableGetRowProperties(); + +#ifdef DEBUG_DMAPPER_TABLE_HANDLER + lcl_DumpPropertyValueSeq(dmapper_logger, aRowProperties); +#endif + + if (m_pTableSeq->getLength() > 0) + { + try + { + uno::Reference<text::XTextTable> xTable = m_xText->convertToTable(*m_pTableSeq, + aCellProperties, + aRowProperties, + aTableInfo.aTableProperties); + + m_xTableRange = xTable->getAnchor( ); + } + catch (lang::IllegalArgumentException e) + { +#ifdef DEBUG_DMAPPER_TABLE_HANDLER + dmapper_logger->chars("failed to import table!"); +#endif + } + catch ( uno::Exception e ) + { +#ifdef DEBUG_DMAPPER_TABLE_HANDLER + dmapper_logger->startElement("exception"); + dmapper_logger->chars(rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_UTF8 ).getStr( )); + dmapper_logger->endElement(); +#endif + } + } + + m_aTableProperties.reset(); + m_aCellProperties.clear(); + m_aRowProperties.clear(); + +#ifdef DEBUG_DMAPPER_TABLE_HANDLER + dmapper_logger->endElement(); + dmapper_logger->endElement(); +#endif +} + +void DomainMapperTableHandler::startRow(unsigned int nCells, + TablePropertyMapPtr pProps) +{ + m_aRowProperties.push_back( pProps ); + m_aCellProperties.push_back( PropertyMapVector1() ); + +#if DEBUG_DMAPPER_TABLE_HANDLER + dmapper_logger->startElement("table.row"); + dmapper_logger->attribute("cells", nCells); + if (pProps != NULL) + pProps->dumpXml(dmapper_logger); +#endif + + m_pRowSeq = RowSequencePointer_t(new RowSequence_t(nCells)); + m_nCellIndex = 0; +} + +void DomainMapperTableHandler::endRow() +{ + (*m_pTableSeq)[m_nRowIndex] = *m_pRowSeq; + ++m_nRowIndex; + m_nCellIndex = 0; +#ifdef DEBUG_DMAPPER_TABLE_HANDLER + dmapper_logger->endElement(); +#endif +} + +void DomainMapperTableHandler::startCell(const Handle_t & start, + TablePropertyMapPtr pProps ) +{ + sal_uInt32 nRow = m_aRowProperties.size(); + if ( pProps.get( ) ) + m_aCellProperties[nRow - 1].push_back( pProps ); + else + { + // Adding an empty cell properties map to be able to get + // the table defaults properties + TablePropertyMapPtr pEmptyProps( new TablePropertyMap( ) ); + m_aCellProperties[nRow - 1].push_back( pEmptyProps ); + } + +#if DEBUG_DMAPPER_TABLE_HANDLER + dmapper_logger->startElement("table.cell"); + dmapper_logger->startElement("table.cell.start"); + dmapper_logger->chars(toString(start)); + dmapper_logger->endElement(); + lcl_printProperties( pProps ); +#endif + + //add a new 'row' of properties + m_pCellSeq = CellSequencePointer_t(new CellSequence_t(2)); + if (!start.get()) + return; + (*m_pCellSeq)[0] = start->getStart(); +} + +void DomainMapperTableHandler::endCell(const Handle_t & end) +{ +#ifdef DEBUG_DMAPPER_TABLE_HANDLER + dmapper_logger->startElement("table.cell.end"); + dmapper_logger->chars(toString(end)); + dmapper_logger->endElement(); + dmapper_logger->endElement(); + clog << "</table.cell>" << endl; +#endif + + if (!end.get()) + return; + (*m_pCellSeq)[1] = end->getEnd(); + (*m_pRowSeq)[m_nCellIndex] = *m_pCellSeq; + ++m_nCellIndex; +} + +}} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.hxx b/writerfilter/source/dmapper/DomainMapperTableHandler.hxx new file mode 100644 index 000000000000..e4e770cfd1d1 --- /dev/null +++ b/writerfilter/source/dmapper/DomainMapperTableHandler.hxx @@ -0,0 +1,106 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef INCLUDED_DOMAIN_MAPPER_TABLE_HANDLER_HXX +#define INCLUDED_DOMAIN_MAPPER_TABLE_HANDLER_HXX + +#include <resourcemodel/TableManager.hxx> +#include <PropertyMap.hxx> + +#include <com/sun/star/text/XTextAppendAndConvert.hpp> + +namespace writerfilter { +namespace dmapper { + +typedef ::com::sun::star::text::XTextRange TextRange_t; +typedef ::com::sun::star::uno::Reference< TextRange_t > Handle_t; +typedef ::com::sun::star::uno::Sequence< Handle_t> CellSequence_t; +typedef boost::shared_ptr<CellSequence_t> CellSequencePointer_t; +typedef ::com::sun::star::uno::Sequence< CellSequence_t > RowSequence_t; +typedef boost::shared_ptr<RowSequence_t> RowSequencePointer_t; +typedef ::com::sun::star::uno::Sequence< RowSequence_t> TableSequence_t; +typedef boost::shared_ptr<TableSequence_t> TableSequencePointer_t; +typedef ::com::sun::star::text::XTextAppendAndConvert Text_t; +typedef ::com::sun::star::uno::Reference<Text_t> TextReference_t; + +typedef ::com::sun::star::beans::PropertyValues TablePropertyValues_t; +typedef ::com::sun::star::uno::Sequence< TablePropertyValues_t > RowPropertyValuesSeq_t; +typedef ::com::sun::star::uno::Sequence< RowPropertyValuesSeq_t> CellPropertyValuesSeq_t; + +typedef std::vector<PropertyMapPtr> PropertyMapVector1; +typedef std::vector<PropertyMapVector1> PropertyMapVector2; + +class DomainMapper_Impl; +class TableStyleSheetEntry; +struct TableInfo; +class WRITERFILTER_DLLPRIVATE DomainMapperTableHandler : public TableDataHandler<Handle_t , TablePropertyMapPtr > +{ + TextReference_t m_xText; + DomainMapper_Impl& m_rDMapper_Impl; + CellSequencePointer_t m_pCellSeq; + RowSequencePointer_t m_pRowSeq; + TableSequencePointer_t m_pTableSeq; + + Handle_t m_xTableRange; + + // properties + PropertyMapVector2 m_aCellProperties; + PropertyMapVector1 m_aRowProperties; + TablePropertyMapPtr m_aTableProperties; + + sal_Int32 m_nCellIndex; + sal_Int32 m_nRowIndex; + + TableStyleSheetEntry * endTableGetTableStyle(TableInfo & rInfo); + CellPropertyValuesSeq_t endTableGetCellProperties(TableInfo & rInfo); + RowPropertyValuesSeq_t endTableGetRowProperties(); + +public: + typedef boost::shared_ptr<DomainMapperTableHandler> Pointer_t; + + DomainMapperTableHandler(TextReference_t xText, DomainMapper_Impl& rDMapper_Impl); + virtual ~DomainMapperTableHandler(); + + virtual void startTable(unsigned int nRows, unsigned int nDepth, + TablePropertyMapPtr pProps); + virtual void endTable(); + virtual void startRow(unsigned int nCells, TablePropertyMapPtr pProps); + virtual void endRow(); + virtual void startCell(const Handle_t & start, TablePropertyMapPtr pProps); + virtual void endCell(const Handle_t & end); + + virtual Handle_t* getTable( ) + { + return &m_xTableRange; + }; +}; + +}} + +#endif // INCLUDED_DOMAIN_MAPPER_TABLE_HANDLER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/DomainMapperTableManager.cxx b/writerfilter/source/dmapper/DomainMapperTableManager.cxx new file mode 100644 index 000000000000..b4b8278987bc --- /dev/null +++ b/writerfilter/source/dmapper/DomainMapperTableManager.cxx @@ -0,0 +1,538 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include <DomainMapperTableManager.hxx> +#include <resourcemodel/WW8ResourceModel.hxx> +#include <BorderHandler.hxx> +#include <CellColorHandler.hxx> +#include <CellMarginHandler.hxx> +#include <ConversionHelper.hxx> +#include <MeasureHandler.hxx> +#include <TDefTableHandler.hxx> +#include <com/sun/star/text/HoriOrientation.hpp> +#include <com/sun/star/text/SizeType.hpp> +#include <com/sun/star/text/TableColumnSeparator.hpp> +#include <com/sun/star/text/VertOrientation.hpp> +#include <ooxml/resourceids.hxx> +#include <doctok/sprmids.hxx> +#include <dmapperLoggers.hxx> + +namespace writerfilter { +namespace dmapper { + +using namespace ::com::sun::star; +using namespace ::std; + + +DomainMapperTableManager::DomainMapperTableManager(bool bOOXML) : + m_nRow(0), + m_nCell(0), + m_nGridSpan(1), + m_nCellBorderIndex(0), + m_nHeaderRepeat(0), + m_nTableWidth(0), + m_bOOXML( bOOXML ), + m_pTablePropsHandler( new TablePropertiesHandler( bOOXML ) ) +{ + m_pTablePropsHandler->SetTableManager( this ); + +#ifdef DEBUG_DOMAINMAPPER +#ifdef DEBUG_TABLE + setTagLogger(dmapper_logger); +#endif +#endif +} + + +DomainMapperTableManager::~DomainMapperTableManager() +{ + if ( m_pTablePropsHandler ) + delete m_pTablePropsHandler, m_pTablePropsHandler = NULL; +} + + +bool DomainMapperTableManager::sprm(Sprm & rSprm) +{ +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->startElement("tablemanager.sprm"); + string sSprm = rSprm.toString(); + dmapper_logger->chars(sSprm); + dmapper_logger->endElement(); +#endif + bool bRet = DomainMapperTableManager_Base_t::sprm(rSprm); + if( !bRet ) + { + bRet = m_pTablePropsHandler->sprm( rSprm ); + } + + if ( !bRet ) + { + bRet = true; + sal_uInt32 nSprmId = rSprm.getId(); + Value::Pointer_t pValue = rSprm.getValue(); + sal_Int32 nIntValue = ((pValue.get() != NULL) ? pValue->getInt() : 0); + switch ( nSprmId ) + { + case 0xf661: //sprmTTRLeft left table indent + case 0xf614: // sprmTTPreferredWidth - preferred table width + case NS_ooxml::LN_CT_TblPrBase_tblW: //90722; + case NS_ooxml::LN_CT_TblPrBase_tblInd: //90725 + { + //contains unit and value + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + { //contains attributes x2902 (LN_unit) and x17e2 (LN_trleft) + MeasureHandlerPtr pMeasureHandler( new MeasureHandler ); + pProperties->resolve(*pMeasureHandler); + TablePropertyMapPtr pPropMap( new TablePropertyMap ); + if( nSprmId == 0xf661 || nSprmId == sal_uInt32(NS_ooxml::LN_CT_TblPrBase_tblInd )) + { + pPropMap->setValue( TablePropertyMap::LEFT_MARGIN, pMeasureHandler->getMeasureValue() ); + } + else + { + m_nTableWidth = pMeasureHandler->getMeasureValue(); + if( m_nTableWidth ) + pPropMap->setValue( TablePropertyMap::TABLE_WIDTH, m_nTableWidth ); + } +#ifdef DEBUG_DOMAINMAPPER + pPropMap->dumpXml( dmapper_logger ); +#endif + insertTableProps(pPropMap); + } + } + break; + case 0x3404:// sprmTTableHeader + case NS_ooxml::LN_CT_TrPrBase_tblHeader: //90704 + // if nIntValue == 1 then the row is a repeated header line + // to prevent later rows from increasing the repeating m_nHeaderRepeat is set to NULL when repeating stops + if( nIntValue > 0 && m_nHeaderRepeat >= 0 ) + { + ++m_nHeaderRepeat; + TablePropertyMapPtr pPropMap( new TablePropertyMap ); + pPropMap->Insert( PROP_HEADER_ROW_COUNT, false, uno::makeAny( m_nHeaderRepeat )); + insertTableProps(pPropMap); + } + else + m_nHeaderRepeat = -1; + break; + case 0xd608: // TDefTable + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + { + TDefTableHandlerPtr pTDefTableHandler( new TDefTableHandler(m_bOOXML) ); + pProperties->resolve( *pTDefTableHandler ); + + TablePropertyMapPtr pRowPropMap( new TablePropertyMap ); + pRowPropMap->insert( pTDefTableHandler->getRowProperties() ); + insertRowProps( pRowPropMap ); + if( !m_nTableWidth ) + { + m_nTableWidth= pTDefTableHandler->getTableWidth(); + if( m_nTableWidth ) + { + TablePropertyMapPtr pPropMap( new TablePropertyMap ); + pPropMap->setValue( TablePropertyMap::TABLE_WIDTH, m_nTableWidth ); + insertTableProps(pPropMap); + } + } + for( size_t nCell = 0; nCell < pTDefTableHandler->getCellCount(); ++nCell ) + { + TablePropertyMapPtr pCellPropMap( new TablePropertyMap ); + pTDefTableHandler->fillCellProperties( nCell, pCellPropMap ); + cellPropsByCell( nCell, pCellPropMap ); + } + } + } + break; + case 0xD605: // sprmTTableBorders + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + { + BorderHandlerPtr pBorderHandler( new BorderHandler(m_bOOXML) ); + pProperties->resolve(*pBorderHandler); + TablePropertyMapPtr pCellPropMap( new TablePropertyMap() ); + pCellPropMap->insert( pBorderHandler->getProperties() ); + cellPropsByCell( m_nCellBorderIndex, pCellPropMap ); + ++m_nCellBorderIndex; + } + } + break; + case 0xd632 : //sprmTNewSpacing + case 0xd634 : //sprmTNewSpacing + //TODO: sprms contain default (TNew) and actual border spacing of cells - not resolvable yet + break; + case 0xd613: //sprmTGridLineProps + // TODO: needs a handler + /*contains: + GridLineProps"> + rtf:LINEPROPSTOP + rtf:LINEPROPSLEFT + rtf:LINEPROPSBOTTOM + rtf:LINEPROPSRIGHT + rtf:LINEPROPSHORIZONTAL + rtf:LINEPROPSVERTICAL + rtf:LINECOLOR + rtf:LINEWIDTH + rtf:LINETYPE + + */ + break; + case 0x740a : //sprmTTlp + //TODO: Table look specifier + break; + case 0x6816 : //unknown + case 0x3466 : //unknown + case 0x3615 : //unknown + case 0x646b : //unknown - expandable sprm - see ww8scan.cxx + case 0x7479 : //unknown + case 0xf617 : //unknown + case 0xf618 : //unknown + bRet = false; + break; + case NS_ooxml::LN_CT_TblPrBase_tblStyle: //table style name + { + m_sTableStyleName = pValue->getString(); + TablePropertyMapPtr pPropMap( new TablePropertyMap ); + pPropMap->Insert( META_PROP_TABLE_STYLE_NAME, false, uno::makeAny( m_sTableStyleName )); + insertTableProps(pPropMap); + } + break; + case NS_ooxml::LN_CT_TblGridBase_gridCol: + { + getCurrentGrid()->push_back( ConversionHelper::convertTwipToMM100( nIntValue ) ); + } + break; + case NS_ooxml::LN_CT_TcPrBase_vMerge : //vertical merge + { + // values can be: LN_Value_ST_Merge_restart, LN_Value_ST_Merge_continue, in reality the second one is a 0 + TablePropertyMapPtr pMergeProps( new TablePropertyMap ); + pMergeProps->Insert( PROP_VERTICAL_MERGE, false, uno::makeAny( bool( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_ST_Merge_restart )) ); + cellProps( pMergeProps); + } + break; + case NS_ooxml::LN_CT_TcPrBase_gridSpan: //number of grid positions spanned by this cell + { +#if DEBUG_DOMAINMAPPER + dmapper_logger->startElement("tablemanager.GridSpan"); + dmapper_logger->attribute("gridSpan", nIntValue); + dmapper_logger->endElement(); +#endif + m_nGridSpan = nIntValue; + } + break; + case NS_ooxml::LN_CT_TblPrBase_tblLook: + break; //todo: table look specifier + case NS_ooxml::LN_CT_TcPrBase_textDirection: + { + TablePropertyMapPtr pPropMap( new TablePropertyMap ); + const sal_Int16 HORI_LEFT_TOP = 0; + const sal_Int16 VERT_TOP_RIGHT = 2; + bool bInsertCellProps = true; + switch ( nIntValue ) + { + case 1: // tbRl + // Binary filter takes BiDirection into account ( but I have no idea about that here ) + // or even what it is. But... here's where to handle it if it becomes an issue + pPropMap->Insert( PROP_FRM_DIRECTION, false, uno::makeAny( VERT_TOP_RIGHT )); + OSL_TRACE("Have inserted textDirection %d", nIntValue ); + break; + case 3: // btLr + // We have to fake this text direction + pPropMap->Insert( PROP_FRM_DIRECTION, false, uno::makeAny( HORI_LEFT_TOP )); + pPropMap->Insert( PROP_CHAR_ROTATION, false, uno::makeAny( sal_Int16( 900 ) )); + OSL_TRACE("Have inserted textDirection %d", nIntValue ); + break; + case 4: // lrTbV + pPropMap->Insert( PROP_FRM_DIRECTION, false, uno::makeAny( HORI_LEFT_TOP )); + break; + case 5: // tbRlV + pPropMap->Insert( PROP_FRM_DIRECTION, false, uno::makeAny( VERT_TOP_RIGHT )); + break; + case 0: // lrTb + case NS_ooxml::LN_Value_ST_TextDirection_tbLrV: + default: + // Ignore - we can't handle these + bInsertCellProps = false; + break; + } + if ( bInsertCellProps ) + cellProps( pPropMap ); + break; + } + case NS_ooxml::LN_CT_TcPrBase_tcW: + break; //fixed column width is not supported + case NS_ooxml::LN_CT_TrPrBase_cnfStyle: + { + TablePropertyMapPtr pProps( new TablePropertyMap ); + pProps->Insert( PROP_CNF_STYLE, true, uno::makeAny( pValue->getString( ) ) ); + insertRowProps( pProps ); + } + break; + case NS_ooxml::LN_CT_PPrBase_cnfStyle: + // TODO cnfStyle on a paragraph + break; + case NS_ooxml::LN_CT_TcPrBase_cnfStyle: + { + TablePropertyMapPtr pProps( new TablePropertyMap ); + pProps->Insert( PROP_CNF_STYLE, true, uno::makeAny( pValue->getString( ) ) ); + cellProps( pProps ); + } + break; + default: + bRet = false; + +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->element("unhandled"); +#endif + } + } + return bRet; +} + +boost::shared_ptr< vector<sal_Int32> > DomainMapperTableManager::getCurrentGrid( ) +{ + return m_aTableGrid.back( ); +} + +boost::shared_ptr< vector< sal_Int32 > > DomainMapperTableManager::getCurrentSpans( ) +{ + return m_aGridSpans.back( ); +} + +void DomainMapperTableManager::startLevel( ) +{ + DomainMapperTableManager_Base_t::startLevel( ); + + IntVectorPtr pNewGrid( new vector<sal_Int32> ); + IntVectorPtr pNewSpans( new vector<sal_Int32> ); + m_aTableGrid.push_back( pNewGrid ); + m_aGridSpans.push_back( pNewSpans ); + m_nTableWidth = 0; +} + +void DomainMapperTableManager::endLevel( ) +{ + m_aTableGrid.pop_back( ); + m_aGridSpans.pop_back( ); + m_nTableWidth = 0; + + DomainMapperTableManager_Base_t::endLevel( ); +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->startElement("dmappertablemanager.endLevel"); + PropertyMapPtr pProps = getTableProps(); + if (pProps.get() != NULL) + getTableProps()->dumpXml( dmapper_logger ); + + dmapper_logger->endElement(); +#endif +} + + + +void DomainMapperTableManager::endOfCellAction() +{ +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->element("endOFCellAction"); +#endif + + getCurrentSpans()->push_back(m_nGridSpan); + m_nGridSpan = 1; + ++m_nCell; +} + + +void DomainMapperTableManager::endOfRowAction() +{ +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->startElement("endOfRowAction"); +#endif + + IntVectorPtr pTableGrid = getCurrentGrid( ); + if(!m_nTableWidth && pTableGrid->size()) + { + ::std::vector<sal_Int32>::const_iterator aCellIter = pTableGrid->begin(); + +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->startElement("tableWidth"); +#endif + + while( aCellIter != pTableGrid->end() ) + { +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->startElement("col"); + dmapper_logger->attribute("width", *aCellIter); + dmapper_logger->endElement(); +#endif + + m_nTableWidth += *aCellIter++; + } + + if( m_nTableWidth > 0) + { + TablePropertyMapPtr pPropMap( new TablePropertyMap ); + pPropMap->setValue( TablePropertyMap::TABLE_WIDTH, m_nTableWidth ); + insertTableProps(pPropMap); + } + +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->endElement(); +#endif + } + + IntVectorPtr pCurrentSpans = getCurrentSpans( ); + if( pCurrentSpans->size() < m_nCell) + { + //fill missing elements with '1' + pCurrentSpans->insert( pCurrentSpans->end( ), m_nCell - pCurrentSpans->size(), 1 ); + } + +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->startElement("gridSpans"); + { + ::std::vector<sal_Int32>::const_iterator aGridSpanIter = pCurrentSpans->begin(); + ::std::vector<sal_Int32>::const_iterator aGridSpanIterEnd = pCurrentSpans->end(); + + while (aGridSpanIter != aGridSpanIterEnd) + { + dmapper_logger->startElement("gridSpan"); + dmapper_logger->attribute("span", *aGridSpanIter); + dmapper_logger->endElement(); + + aGridSpanIter++; + } + } + dmapper_logger->endElement(); +#endif + + //calculate number of used grids - it has to match the size of m_aTableGrid + size_t nGrids = 0; + ::std::vector<sal_Int32>::const_iterator aGridSpanIter = pCurrentSpans->begin(); + for( ; aGridSpanIter != pCurrentSpans->end(); ++aGridSpanIter) + nGrids += *aGridSpanIter; + + if( pTableGrid->size() == nGrids ) + { + //determine table width + double nFullWidth = m_nTableWidth; + //the positions have to be distibuted in a range of 10000 + const double nFullWidthRelative = 10000.; + uno::Sequence< text::TableColumnSeparator > aSeparators( m_nCell - 1 ); + text::TableColumnSeparator* pSeparators = aSeparators.getArray(); + sal_Int16 nLastRelPos = 0; + sal_uInt32 nBorderGridIndex = 0; + + ::std::vector< sal_Int32 >::const_iterator aSpansIter = pCurrentSpans->begin( ); + for( sal_uInt32 nBorder = 0; nBorder < m_nCell - 1; ++nBorder ) + { + sal_Int32 nGridCount = *aSpansIter; + double fGridWidth = 0.; + do + { + fGridWidth += (*pTableGrid.get())[nBorderGridIndex++]; + }while( --nGridCount ); + + sal_Int16 nRelPos = + sal::static_int_cast< sal_Int16 >(fGridWidth * nFullWidthRelative / nFullWidth ); + + pSeparators[nBorder].Position = nRelPos + nLastRelPos; + pSeparators[nBorder].IsVisible = sal_True; + nLastRelPos = nLastRelPos + nRelPos; + aSpansIter++; + } + TablePropertyMapPtr pPropMap( new TablePropertyMap ); + pPropMap->Insert( PROP_TABLE_COLUMN_SEPARATORS, false, uno::makeAny( aSeparators ) ); + +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->startElement("rowProperties"); + pPropMap->dumpXml( dmapper_logger ); + dmapper_logger->endElement(); +#endif + insertRowProps(pPropMap); + } + + ++m_nRow; + m_nCell = 0; + m_nCellBorderIndex = 0; + pCurrentSpans->clear(); + +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->endElement(); +#endif +} + + +void DomainMapperTableManager::clearData() +{ + m_nRow = m_nCell = m_nCellBorderIndex = m_nHeaderRepeat = m_nTableWidth = 0; + m_sTableStyleName = ::rtl::OUString(); + m_pTableStyleTextProperies.reset(); +} + + +void lcl_CopyTextProperties(PropertyMapPtr pToFill, + const StyleSheetEntry* pStyleSheetEntry, StyleSheetTablePtr pStyleSheetTable) +{ + if( !pStyleSheetEntry ) + return; + //fill base style properties first, recursively + if( pStyleSheetEntry->sBaseStyleIdentifier.getLength()) + { + const StyleSheetEntryPtr pParentStyleSheet = + pStyleSheetTable->FindStyleSheetByISTD(pStyleSheetEntry->sBaseStyleIdentifier); + OSL_ENSURE( pParentStyleSheet, "table style not found" ); + lcl_CopyTextProperties( pToFill, pParentStyleSheet.get( ), pStyleSheetTable); + } + + PropertyMap::const_iterator aPropIter = pStyleSheetEntry->pProperties->begin(); + while(aPropIter != pStyleSheetEntry->pProperties->end()) + { + //copy all text properties form the table style to the current run attributes + if( aPropIter->first.bIsTextProperty ) + pToFill->insert(*aPropIter); + ++aPropIter; + } +} +void DomainMapperTableManager::CopyTextProperties(PropertyMapPtr pContext, StyleSheetTablePtr pStyleSheetTable) +{ + if( !m_pTableStyleTextProperies.get()) + { + m_pTableStyleTextProperies.reset( new PropertyMap ); + const StyleSheetEntryPtr pStyleSheetEntry = pStyleSheetTable->FindStyleSheetByISTD( + m_sTableStyleName); + OSL_ENSURE( pStyleSheetEntry, "table style not found" ); + lcl_CopyTextProperties(m_pTableStyleTextProperies, pStyleSheetEntry.get( ), pStyleSheetTable); + } + pContext->insert( m_pTableStyleTextProperies ); +} + + +}} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/DomainMapperTableManager.hxx b/writerfilter/source/dmapper/DomainMapperTableManager.hxx new file mode 100644 index 000000000000..6b20f026b725 --- /dev/null +++ b/writerfilter/source/dmapper/DomainMapperTableManager.hxx @@ -0,0 +1,126 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef INCLUDED_DOMAIN_MAPPER_TABLE_MANAGER_HXX +#define INCLUDED_DOMAIN_MAPPER_TABLE_MANAGER_HXX + +#include "TablePropertiesHandler.hxx" + +#include <resourcemodel/TableManager.hxx> +#include <PropertyMap.hxx> +#include <StyleSheetTable.hxx> +#include <com/sun/star/text/XTextRange.hpp> +#include <vector> + +namespace writerfilter { +namespace dmapper { + +class DomainMapperTableManager : public DomainMapperTableManager_Base_t +{ + typedef boost::shared_ptr< std::vector<sal_Int32> > IntVectorPtr; + + sal_uInt32 m_nRow; + sal_uInt32 m_nCell; + sal_uInt32 m_nGridSpan; + sal_uInt32 m_nCellBorderIndex; //borders are provided for all cells and need counting + sal_Int32 m_nHeaderRepeat; //counter of repeated headers - if == -1 then the repeating stops + sal_Int32 m_nTableWidth; //might be set directly or has to be calculated from the column positions + bool m_bOOXML; + ::rtl::OUString m_sTableStyleName; + PropertyMapPtr m_pTableStyleTextProperies; + + ::std::vector< IntVectorPtr > m_aTableGrid; + ::std::vector< IntVectorPtr > m_aGridSpans; + + TablePropertiesHandler *m_pTablePropsHandler; + PropertyMapPtr m_pStyleProps; + + virtual void clearData(); + +public: + + DomainMapperTableManager(bool bOOXML); + virtual ~DomainMapperTableManager(); + + // use this method to avoid adding the properties for the table + // but in the provided properties map. + inline void SetStyleProperties( PropertyMapPtr pProperties ) { m_pStyleProps = pProperties; }; + + virtual bool sprm(Sprm & rSprm); + + virtual void startLevel( ); + virtual void endLevel( ); + + virtual void endOfCellAction(); + virtual void endOfRowAction(); + + IntVectorPtr getCurrentGrid( ); + IntVectorPtr getCurrentSpans( ); + + const ::rtl::OUString& getTableStyleName() const { return m_sTableStyleName; } + /// copy the text properties of the table style and its parent into pContext + void CopyTextProperties(PropertyMapPtr pContext, StyleSheetTablePtr pStyleSheetTable); + + inline virtual void cellProps(TablePropertyMapPtr pProps) + { + if ( m_pStyleProps.get( ) ) + m_pStyleProps->insert( pProps, true ); + else + DomainMapperTableManager_Base_t::cellProps( pProps ); + }; + + inline virtual void cellPropsByCell(unsigned int i, TablePropertyMapPtr pProps) + { + if ( m_pStyleProps.get( ) ) + m_pStyleProps->insert( pProps, true ); + else + DomainMapperTableManager_Base_t::cellPropsByCell( i, pProps ); + }; + + inline virtual void insertRowProps(TablePropertyMapPtr pProps) + { + if ( m_pStyleProps.get( ) ) + m_pStyleProps->insert( pProps, true ); + else + DomainMapperTableManager_Base_t::insertRowProps( pProps ); + }; + + inline virtual void insertTableProps(TablePropertyMapPtr pProps) + { + if ( m_pStyleProps.get( ) ) + m_pStyleProps->insert( pProps, true ); + else + DomainMapperTableManager_Base_t::insertTableProps( pProps ); + }; + +}; + +}} + +#endif // INCLUDED_DOMAIN_MAPPER_TABLE_MANAGER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx new file mode 100644 index 000000000000..57bbba26fcac --- /dev/null +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -0,0 +1,3273 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include <DomainMapper_Impl.hxx> +#include <ConversionHelper.hxx> +#include <DomainMapperTableHandler.hxx> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/graphic/XGraphic.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XPropertyState.hpp> +#include <com/sun/star/container/XIndexReplace.hpp> +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/drawing/XDrawPageSupplier.hpp> +#include <com/sun/star/drawing/XShapes.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/style/XStyleFamiliesSupplier.hpp> +#include <com/sun/star/style/LineNumberPosition.hpp> +#include <com/sun/star/style/NumberingType.hpp> +#include <com/sun/star/drawing/XShape.hpp> +#include <com/sun/star/table/BorderLine2.hpp> +#include <com/sun/star/text/ChapterFormat.hpp> +#include <com/sun/star/text/FilenameDisplayFormat.hpp> +#include <com/sun/star/text/UserDataPart.hpp> +#include <com/sun/star/text/SetVariableType.hpp> +#include <com/sun/star/text/XFootnote.hpp> +#include <com/sun/star/text/XLineNumberingProperties.hpp> +#include <com/sun/star/text/PageNumberType.hpp> +#include <com/sun/star/text/RelOrientation.hpp> +#include <com/sun/star/text/HoriOrientation.hpp> +#include <com/sun/star/text/VertOrientation.hpp> +#include <com/sun/star/text/ReferenceFieldPart.hpp> +#include <com/sun/star/text/ReferenceFieldSource.hpp> +#include <com/sun/star/text/SizeType.hpp> +#include <com/sun/star/text/TextContentAnchorType.hpp> +#include <com/sun/star/text/WrapTextMode.hpp> +#include <com/sun/star/text/XDependentTextField.hpp> +#include <com/sun/star/text/XParagraphCursor.hpp> +#include <com/sun/star/text/XRedline.hpp> +#include <com/sun/star/text/XTextAppendAndConvert.hpp> +#include <com/sun/star/text/XTextCopy.hpp> +#include <com/sun/star/text/XTextField.hpp> +#include <com/sun/star/text/XTextFieldsSupplier.hpp> +#include <com/sun/star/text/XFormField.hpp> +#include <com/sun/star/style/DropCapFormat.hpp> +#include <com/sun/star/util/DateTime.hpp> +#include <com/sun/star/util/XNumberFormatsSupplier.hpp> +#include <com/sun/star/util/XNumberFormats.hpp> +#include <rtl/ustrbuf.hxx> +#include <rtl/string.h> +#include "FieldTypes.hxx" + +#include <tools/string.hxx> +#ifdef DEBUG_DOMAINMAPPER +#include <resourcemodel/QNameToString.hxx> +#include <resourcemodel/util.hxx> +#include <dmapperLoggers.hxx> +#endif +#include <ooxml/OOXMLFastTokens.hxx> + +#if DEBUG +#include <stdio.h> +#include <com/sun/star/style/TabStop.hpp> +#endif + +#include <map> + +#include <comphelper/configurationhelper.hxx> +#include <comphelper/stlunosequence.hxx> + +using namespace ::com::sun::star; +using namespace ::rtl; +namespace writerfilter { +namespace dmapper{ + +sal_Bool lcl_IsUsingEnhancedFields( const uno::Reference< lang::XMultiServiceFactory >& rFac ) +{ + bool bResult(sal_False); + try + { + rtl::OUString writerConfig = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.Office.Common")); + + uno::Reference< uno::XInterface > xCfgAccess = ::comphelper::ConfigurationHelper::openConfig( rFac, writerConfig, ::comphelper::ConfigurationHelper::E_READONLY ); + ::comphelper::ConfigurationHelper::readRelativeKey( xCfgAccess, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Filter/Microsoft/Import" ) ), rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ImportWWFieldsAsEnhancedFields" ) ) ) >>= bResult; + + } + catch( uno::Exception& e) + { + } + return bResult; +} + +// Populate Dropdown Field properties from FFData structure +void lcl_handleDropdownField( const uno::Reference< beans::XPropertySet >& rxFieldProps, FFDataHandler::Pointer_t pFFDataHandler ) +{ + if ( rxFieldProps.is() ) + { + if ( pFFDataHandler->getName().getLength() ) + rxFieldProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Name") ), uno::makeAny( pFFDataHandler->getName() ) ); + + const FFDataHandler::DropDownEntries_t& rEntries = pFFDataHandler->getDropDownEntries(); + uno::Sequence< rtl::OUString > sItems( rEntries.size() ); + ::std::copy( rEntries.begin(), rEntries.end(), ::comphelper::stl_begin(sItems)); + if ( sItems.getLength() ) + rxFieldProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Items") ), uno::makeAny( sItems ) ); + + sal_Int32 nResult = pFFDataHandler->getDropDownResult().toInt32(); + if ( nResult ) + rxFieldProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SelectedItem") ), uno::makeAny( sItems[ nResult ] ) ); + if ( pFFDataHandler->getHelpText().getLength() ) + rxFieldProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Help") ), uno::makeAny( pFFDataHandler->getHelpText() ) ); + } +} + +void lcl_handleTextField( const uno::Reference< beans::XPropertySet >& rxFieldProps, FFDataHandler::Pointer_t pFFDataHandler, PropertyNameSupplier& rPropNameSupplier ) +{ + if ( rxFieldProps.is() && pFFDataHandler ) + { + rxFieldProps->setPropertyValue + (rPropNameSupplier.GetName(PROP_HINT), + uno::makeAny(pFFDataHandler->getStatusText())); + rxFieldProps->setPropertyValue + (rPropNameSupplier.GetName(PROP_HELP), + uno::makeAny(pFFDataHandler->getHelpText())); + rxFieldProps->setPropertyValue + (rPropNameSupplier.GetName(PROP_CONTENT), + uno::makeAny(pFFDataHandler->getTextDefault())); + } +} + +struct FieldConversion +{ + ::rtl::OUString sWordCommand; + const sal_Char* cFieldServiceName; + const sal_Char* cFieldMasterServiceName; + FieldId eFieldId; +}; + +typedef ::std::map< ::rtl::OUString, FieldConversion> + FieldConversionMap_t; + + + +sal_Int32 FIB::GetData( Id nName ) +{ + if( nName >= NS_rtf::LN_WIDENT && nName <= NS_rtf::LN_LCBSTTBFUSSR) + return aFIBData[nName - NS_rtf::LN_WIDENT]; + OSL_FAIL( "invalid index in FIB"); + return -1; +} + + +void FIB::SetData( Id nName, sal_Int32 nValue ) +{ + OSL_ENSURE( nName >= NS_rtf::LN_WIDENT && nName <= NS_rtf::LN_LCBSTTBFUSSR, "invalid index in FIB"); + if( nName >= NS_rtf::LN_WIDENT && nName <= NS_rtf::LN_LCBSTTBFUSSR) + aFIBData[nName - NS_rtf::LN_WIDENT] = nValue; +} + + +DomainMapper_Impl::DomainMapper_Impl( + DomainMapper& rDMapper, + uno::Reference < uno::XComponentContext > xContext, + uno::Reference< lang::XComponent > xModel, + SourceDocumentType eDocumentType) : + m_eDocumentType( eDocumentType ), + m_rDMapper( rDMapper ), + m_xTextDocument( xModel, uno::UNO_QUERY ), + m_xTextFactory( xModel, uno::UNO_QUERY ), + m_xComponentContext( xContext ), + m_bFieldMode( false ), + m_bSetUserFieldContent( false ), + m_bIsFirstSection( true ), + m_bIsColumnBreakDeferred( false ), + m_bIsPageBreakDeferred( false ), + m_bIsInShape( false ), + m_bShapeContextAdded( false ), + m_pLastSectionContext( ), + m_nCurrentTabStopIndex( 0 ), + m_sCurrentParaStyleId(), + m_bInStyleSheetImport( false ), + m_bInAnyTableImport( false ), + m_bLineNumberingSet( false ), + m_bIsInFootnoteProperties( true ), + m_bIsCustomFtnMark( false ), + m_bIsParaChange( false ), + m_bParaChanged( false ), + m_bIsLastParaInSection( false ) +{ + appendTableManager( ); + GetBodyText(); + uno::Reference< text::XTextAppend > xBodyTextAppend = uno::Reference< text::XTextAppend >( m_xBodyText, uno::UNO_QUERY ); + m_aTextAppendStack.push(xBodyTextAppend); + + //todo: does it make sense to set the body text as static text interface? + uno::Reference< text::XTextAppendAndConvert > xBodyTextAppendAndConvert( m_xBodyText, uno::UNO_QUERY ); + TableDataHandler_t::Pointer_t pTableHandler + (new DomainMapperTableHandler(xBodyTextAppendAndConvert, *this)); + getTableManager( ).setHandler(pTableHandler); + + getTableManager( ).startLevel(); + m_bUsingEnhancedFields = lcl_IsUsingEnhancedFields( uno::Reference< lang::XMultiServiceFactory >( m_xComponentContext->getServiceManager(), uno::UNO_QUERY ) ); + +} + + +DomainMapper_Impl::~DomainMapper_Impl() +{ + RemoveLastParagraph( ); + getTableManager( ).endLevel(); + popTableManager( ); +} + + +uno::Reference< container::XNameContainer > DomainMapper_Impl::GetPageStyles() +{ + if(!m_xPageStyles.is()) + { + uno::Reference< style::XStyleFamiliesSupplier > xSupplier( m_xTextDocument, uno::UNO_QUERY ); + xSupplier->getStyleFamilies()->getByName(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PageStyles"))) >>= m_xPageStyles; + } + return m_xPageStyles; +} + + +uno::Reference< text::XText > DomainMapper_Impl::GetBodyText() +{ + if(!m_xBodyText.is() && m_xTextDocument.is()) + { + m_xBodyText = m_xTextDocument->getText(); + } + return m_xBodyText; +} + + +uno::Reference< beans::XPropertySet > DomainMapper_Impl::GetDocumentSettings() +{ + if( !m_xDocumentSettings.is() ) + { + m_xDocumentSettings = uno::Reference< beans::XPropertySet >( + m_xTextFactory->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.Settings"))), uno::UNO_QUERY ); + } + return m_xDocumentSettings; +} + + +void DomainMapper_Impl::SetDocumentSettingsProperty( const ::rtl::OUString& rPropName, const uno::Any& rValue ) +{ + uno::Reference< beans::XPropertySet > xSettings = GetDocumentSettings(); + if( xSettings.is() ) + { + try + { + xSettings->setPropertyValue( rPropName, rValue ); + } + catch( const uno::Exception& ) + { + } + } +} + +void DomainMapper_Impl::RemoveLastParagraph( ) +{ + uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; + try + { + uno::Reference< text::XTextCursor > xCursor = xTextAppend->createTextCursor(); + xCursor->gotoEnd(false); + xCursor->goLeft( 1, true ); + xCursor->setString(::rtl::OUString()); + } + catch( const uno::Exception& rEx) + { + (void)rEx; + } +} + +void DomainMapper_Impl::SetIsLastParagraphInSection( bool bIsLast ) +{ + m_bIsLastParaInSection = bIsLast; +} + + + +void DomainMapper_Impl::PushProperties(ContextType eId) +{ + SectionPropertyMap* pSectionContext = 0; + PropertyMapPtr pInsert(eId == CONTEXT_SECTION ? + (pSectionContext = new SectionPropertyMap( m_bIsFirstSection )) : + eId == CONTEXT_PARAGRAPH ? new ParagraphPropertyMap : new PropertyMap); + if(eId == CONTEXT_SECTION) + { + if( m_bIsFirstSection ) + m_bIsFirstSection = false; + // beginning with the second section group a section has to be inserted + // into the document + SectionPropertyMap* pSectionContext_ = dynamic_cast< SectionPropertyMap* >( pInsert.get() ); + uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; + if(xTextAppend.is()) + pSectionContext_->SetStart( xTextAppend->getEnd() ); + } + m_aPropertyStacks[eId].push( pInsert ); + m_aContextStack.push(eId); + + m_pTopContext = m_aPropertyStacks[eId].top(); +} + + +void DomainMapper_Impl::PushStyleProperties( PropertyMapPtr pStyleProperties ) +{ + m_aPropertyStacks[CONTEXT_STYLESHEET].push( pStyleProperties ); + m_aContextStack.push(CONTEXT_STYLESHEET); + + m_pTopContext = m_aPropertyStacks[CONTEXT_STYLESHEET].top(); +} + + +void DomainMapper_Impl::PushListProperties(PropertyMapPtr pListProperties) +{ + m_aPropertyStacks[CONTEXT_LIST].push( pListProperties ); + m_aContextStack.push(CONTEXT_LIST); + m_pTopContext = m_aPropertyStacks[CONTEXT_LIST].top(); +} + + +void DomainMapper_Impl::PopProperties(ContextType eId) +{ + OSL_ENSURE(!m_aPropertyStacks[eId].empty(), "section stack already empty"); + + if ( eId == CONTEXT_SECTION ) + { + m_pLastSectionContext = m_aPropertyStacks[eId].top( ); + } + + m_aPropertyStacks[eId].pop(); + m_aContextStack.pop(); + if(!m_aContextStack.empty() && !m_aPropertyStacks[m_aContextStack.top()].empty()) + + m_pTopContext = m_aPropertyStacks[m_aContextStack.top()].top(); + else + { + // OSL_ENSURE(eId == CONTEXT_SECTION, "this should happen at a section context end"); + m_pTopContext.reset(); + } +} + + +PropertyMapPtr DomainMapper_Impl::GetTopContextOfType(ContextType eId) +{ + PropertyMapPtr pRet; + OSL_ENSURE( !m_aPropertyStacks[eId].empty(), + "no context of this type available"); + if(!m_aPropertyStacks[eId].empty()) + pRet = m_aPropertyStacks[eId].top(); + return pRet; +} + + + +uno::Reference< text::XTextAppend > DomainMapper_Impl::GetTopTextAppend() +{ + OSL_ENSURE(!m_aTextAppendStack.empty(), "text append stack is empty" ); + return m_aTextAppendStack.top().xTextAppend; +} + + + +void DomainMapper_Impl::InitTabStopFromStyle( const uno::Sequence< style::TabStop >& rInitTabStops ) +{ + OSL_ENSURE(!m_aCurrentTabStops.size(), "tab stops already initialized"); + for( sal_Int32 nTab = 0; nTab < rInitTabStops.getLength(); ++nTab) + { + m_aCurrentTabStops.push_back( DeletableTabStop(rInitTabStops[nTab]) ); + } +} + + + +void DomainMapper_Impl::ModifyCurrentTabStop( Id nId, sal_Int32 nValue) +{ + OSL_ENSURE(nId == NS_rtf::LN_dxaAdd || m_nCurrentTabStopIndex < m_aCurrentTabStops.size(), + "tab stop creation error"); + + if( nId != NS_rtf::LN_dxaAdd && m_nCurrentTabStopIndex >= m_aCurrentTabStops.size()) + return; + static const style::TabAlign aTabAlignFromWord[] = + { + style::TabAlign_LEFT, + style::TabAlign_CENTER, + style::TabAlign_RIGHT, + style::TabAlign_DECIMAL, + style::TabAlign_LEFT + }; + static const sal_Unicode aTabFillCharWord[] = + { + ' ', + '.', + '-', + '_', + '_', + 0xb7 + }; + + switch(nId) + { + case NS_rtf::LN_dxaAdd: //set tab + m_aCurrentTabStops.push_back( + DeletableTabStop(style::TabStop(ConversionHelper::convertTwipToMM100(nValue), style::TabAlign_LEFT, ' ', ' '))); + break; + case NS_rtf::LN_dxaDel: //deleted tab + { + //mark the tab stop at the given position as deleted + ::std::vector<DeletableTabStop>::iterator aIt = m_aCurrentTabStops.begin(); + ::std::vector<DeletableTabStop>::iterator aEndIt = m_aCurrentTabStops.end(); + sal_Int32 nConverted = ConversionHelper::convertTwipToMM100(nValue); + for( ; aIt != aEndIt; ++aIt) + { + if( aIt->Position == nConverted ) + { + aIt->bDeleted = true; + break; + } + } + } + break; + case NS_rtf::LN_TLC: //tab leading characters - for decimal tabs + // 0 - no leader, 1- dotted, 2 - hyphenated, 3 - single line, 4 - heavy line, 5 - middle dot + if( nValue >= 0 && nValue < sal::static_int_cast<sal_Int32>(sizeof(aTabFillCharWord) / sizeof (sal_Unicode))) + m_aCurrentTabStops[m_nCurrentTabStopIndex].FillChar = aTabFillCharWord[nValue]; + break; + case NS_rtf::LN_JC: //tab justification + //0 - left, 1 - centered, 2 - right, 3 - decimal 4 - bar + if( nValue >= 0 && nValue < sal::static_int_cast<sal_Int32>(sizeof(aTabAlignFromWord) / sizeof (style::TabAlign))) + m_aCurrentTabStops[m_nCurrentTabStopIndex].Alignment = aTabAlignFromWord[nValue]; + break; + } +} + +void DomainMapper_Impl::IncorporateTabStop( const DeletableTabStop & rTabStop ) +{ + ::std::vector<DeletableTabStop>::iterator aIt = m_aCurrentTabStops.begin(); + ::std::vector<DeletableTabStop>::iterator aEndIt = m_aCurrentTabStops.end(); + sal_Int32 nConverted = rTabStop.Position; + bool bFound = false; + for( ; aIt != aEndIt; ++aIt) + { + if( aIt->Position == nConverted ) + { + bFound = true; + if( rTabStop.bDeleted ) + m_aCurrentTabStops.erase( aIt ); + else + *aIt = rTabStop; + break; + } + } + if( !bFound ) + m_aCurrentTabStops.push_back( rTabStop ); +} + + +uno::Sequence< style::TabStop > DomainMapper_Impl::GetCurrentTabStopAndClear() +{ + uno::Sequence< style::TabStop > aRet( sal_Int32( m_aCurrentTabStops.size() ) ); + style::TabStop* pArray = aRet.getArray(); + ::std::vector<DeletableTabStop>::const_iterator aIt = m_aCurrentTabStops.begin(); + ::std::vector<DeletableTabStop>::const_iterator aEndIt = m_aCurrentTabStops.end(); + sal_Int32 nDeleted = 0; + for(sal_Int32 nIndex = 0; aIt != aEndIt; ++aIt) + { + if(!aIt->bDeleted) + pArray[nIndex++] = *aIt; + else + ++nDeleted; + } + m_aCurrentTabStops.clear(); + m_nCurrentTabStopIndex = 0; + if(nDeleted) + { + aRet.realloc( aRet.getLength() - nDeleted); + } + return aRet; +} + +/*------------------------------------------------------------------------- + returns a the value from the current paragraph style - if available + TODO: What about parent styles? + -----------------------------------------------------------------------*/ +uno::Any DomainMapper_Impl::GetPropertyFromStyleSheet(PropertyIds eId) +{ + StyleSheetEntryPtr pEntry; + if( m_bInStyleSheetImport ) + pEntry = GetStyleSheetTable()->FindParentStyleSheet(::rtl::OUString()); + else + pEntry = + GetStyleSheetTable()->FindStyleSheetByISTD(GetCurrentParaStyleId()); + while(pEntry.get( ) ) + { + //is there a tab stop set? + if(pEntry->pProperties) + { + PropertyMap::const_iterator aPropertyIter = + pEntry->pProperties->find(PropertyDefinition(eId, false )); + if( aPropertyIter != pEntry->pProperties->end()) + { + return aPropertyIter->second; + } + } + //search until the property is set or no parent is available + pEntry = GetStyleSheetTable()->FindParentStyleSheet(pEntry->sBaseStyleIdentifier); + } + return uno::Any(); +} + + +ListsManager::Pointer DomainMapper_Impl::GetListTable() +{ + if(!m_pListTable) + m_pListTable.reset( + new ListsManager( m_rDMapper, m_xTextFactory )); + return m_pListTable; +} + + +void DomainMapper_Impl::deferBreak( BreakType deferredBreakType) +{ + switch (deferredBreakType) + { + case COLUMN_BREAK: + m_bIsColumnBreakDeferred = true; + break; + case PAGE_BREAK: + m_bIsPageBreakDeferred = true; + break; + default: + return; + } +} + +bool DomainMapper_Impl::isBreakDeferred( BreakType deferredBreakType ) +{ + switch (deferredBreakType) + { + case COLUMN_BREAK: + return m_bIsColumnBreakDeferred; + case PAGE_BREAK: + return m_bIsPageBreakDeferred; + default: + return false; + } +} + +void DomainMapper_Impl::clearDeferredBreaks() +{ + m_bIsColumnBreakDeferred = false; + m_bIsPageBreakDeferred = false; +} + +bool lcl_removeShape( const uno::Reference< text::XTextDocument >& rDoc, const uno::Reference< drawing::XShape >& rShape, TextContentStack& rAnchoredStack,TextAppendStack& rTextAppendStack ) +{ + bool bRet = false; + // probably unecessary but just double check that indeed the top of Anchored stack + // does contain the shape we intend to remove + uno::Reference< drawing::XShape > xAnchorShape(rAnchoredStack.top( ), uno::UNO_QUERY ); + if ( xAnchorShape == rShape ) + { + // because we only want to process the embedded object and not the associated + // shape we need to get rid of that shape from the Draw page and Anchored and + // Append stacks so it wont be processed further + try + { + uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(rDoc, uno::UNO_QUERY_THROW); + uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage(); + if ( xDrawPage.is() ) + { + xDrawPage->remove( rShape ); + } + rAnchoredStack.pop(); + rTextAppendStack.pop(); + bRet = true; + } + catch( uno::Exception& e ) + { + } + } + return bRet; +} + + + +void lcl_MoveBorderPropertiesToFrame(uno::Sequence<beans::PropertyValue>& rFrameProperties, + uno::Reference<text::XTextRange> xStartTextRange, + uno::Reference<text::XTextRange> xEndTextRange ) +{ + try + { + uno::Reference<text::XTextCursor> xRangeCursor = xStartTextRange->getText()->createTextCursorByRange( xStartTextRange ); + xRangeCursor->gotoRange( xEndTextRange, true ); + + uno::Reference<beans::XPropertySet> xTextRangeProperties(xRangeCursor, uno::UNO_QUERY); + if(!xTextRangeProperties.is()) + return ; + + PropertyIds aBorderProperties[] = + { + PROP_LEFT_BORDER, + PROP_RIGHT_BORDER, + PROP_TOP_BORDER, + PROP_BOTTOM_BORDER, + PROP_LEFT_BORDER_DISTANCE, + PROP_RIGHT_BORDER_DISTANCE, + PROP_TOP_BORDER_DISTANCE, + PROP_BOTTOM_BORDER_DISTANCE + }; + + sal_uInt32 nStart = rFrameProperties.getLength(); + sal_uInt32 nBorderPropertyCount = sizeof( aBorderProperties ) / sizeof(PropertyIds); + rFrameProperties.realloc(nStart + nBorderPropertyCount); + + beans::PropertyValue* pFrameProperties = rFrameProperties.getArray(); + PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + for( sal_uInt32 nProperty = 0; nProperty < nBorderPropertyCount; ++nProperty) + { + ::rtl::OUString sPropertyName = rPropNameSupplier.GetName(aBorderProperties[nProperty]); + pFrameProperties[nStart].Name = sPropertyName; + pFrameProperties[nStart].Value = xTextRangeProperties->getPropertyValue(sPropertyName); + if( nProperty < 4 ) + xTextRangeProperties->setPropertyValue( sPropertyName, uno::makeAny(table::BorderLine2())); + ++nStart; + } + rFrameProperties.realloc(nStart); + } + catch( const uno::Exception& rEx ) + { + (void)rEx; + } +} + + +void lcl_AddRangeAndStyle( + ParagraphPropertiesPtr& pToBeSavedProperties, + uno::Reference< text::XTextAppend > xTextAppend, + PropertyMapPtr pPropertyMap) +{ + uno::Reference<text::XParagraphCursor> xParaCursor( + xTextAppend->createTextCursorByRange( xTextAppend->getEnd()), uno::UNO_QUERY_THROW ); + pToBeSavedProperties->SetEndingRange(xParaCursor->getStart()); + xParaCursor->gotoStartOfParagraph( false ); + + pToBeSavedProperties->SetStartingRange(xParaCursor->getStart()); + if(pPropertyMap) + { + PropertyMap::iterator aParaStyleIter = pPropertyMap->find(PropertyDefinition( PROP_PARA_STYLE_NAME, false ) ); + if( aParaStyleIter != pPropertyMap->end()) + { + ::rtl::OUString sName; + aParaStyleIter->second >>= sName; + pToBeSavedProperties->SetParaStyleName(sName); + } + } +} + + +//define some default frame width - 0cm ATM: this allow the frame to be wrapped around the text +#define DEFAULT_FRAME_MIN_WIDTH 0 + +void DomainMapper_Impl::finishParagraph( PropertyMapPtr pPropertyMap ) +{ +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->startElement("finishParagraph"); +#endif + + ParagraphPropertyMap* pParaContext = dynamic_cast< ParagraphPropertyMap* >( pPropertyMap.get() ); + TextAppendContext& rAppendContext = m_aTextAppendStack.top(); + uno::Reference< text::XTextAppend > xTextAppend = rAppendContext.xTextAppend; + PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->attribute("isTextAppend", xTextAppend.is()); +#endif + + if(xTextAppend.is() && ! getTableManager( ).isIgnore() && pParaContext != NULL) + { + try + { + /*the following combinations of previous and current frame settings can occur: + (1) - no old frame and no current frame -> no special action + (2) - no old frame and current DropCap -> save DropCap for later use, don't call finishParagraph + remove character properties of the DropCap? + (3) - no old frame and current Frame -> save Frame for later use + (4) - old DropCap and no current frame -> add DropCap to the properties of the finished paragraph, delete previous setting + (5) - old DropCap and current frame -> add DropCap to the properties of the finished paragraph, save current frame settings + (6) - old Frame and new DropCap -> add old Frame, save DropCap for later use + (7) - old Frame and new same Frame -> continue + (8) - old Frame and new different Frame -> add old Frame, save new Frame for later use + (9) - old Frame and no current frame -> add old Frame, delete previous settings + + old _and_ new DropCap must not occur + */ + + bool bIsDropCap = + pParaContext->IsFrameMode() && + sal::static_int_cast<Id>(pParaContext->GetDropCap()) != NS_ooxml::LN_Value_wordprocessingml_ST_DropCap_none; + + style::DropCapFormat aDrop; + ParagraphPropertiesPtr pToBeSavedProperties; + bool bKeepLastParagraphProperties = false; + if( bIsDropCap ) + { + uno::Reference<text::XParagraphCursor> xParaCursor( + xTextAppend->createTextCursorByRange(xTextAppend->getEnd()), uno::UNO_QUERY_THROW); + //select paragraph + xParaCursor->gotoStartOfParagraph( true ); + uno::Reference< beans::XPropertyState > xParaProperties( xParaCursor, uno::UNO_QUERY_THROW ); + xParaProperties->setPropertyToDefault(rPropNameSupplier.GetName(PROP_CHAR_ESCAPEMENT)); + xParaProperties->setPropertyToDefault(rPropNameSupplier.GetName(PROP_CHAR_HEIGHT)); + //handles (2) and part of (6) + pToBeSavedProperties.reset( new ParagraphProperties(*pParaContext) ); + sal_Int32 nCount = xParaCursor->getString().getLength(); + pToBeSavedProperties->SetDropCapLength(nCount > 0 && nCount < 255 ? (sal_Int8)nCount : 1); + } + if( rAppendContext.pLastParagraphProperties.get() ) + { + if( sal::static_int_cast<Id>(rAppendContext.pLastParagraphProperties->GetDropCap()) != NS_ooxml::LN_Value_wordprocessingml_ST_DropCap_none) + { + //handles (4) and part of (5) + //create a DropCap property, add it to the property sequence of finishParagraph + sal_Int32 nLines = rAppendContext.pLastParagraphProperties->GetLines(); + aDrop.Lines = nLines > 0 && nLines < 254 ? (sal_Int8)++nLines : 2; + aDrop.Count = rAppendContext.pLastParagraphProperties->GetDropCapLength(); + aDrop.Distance = 0; //TODO: find distance value + //completes (5) + if( pParaContext->IsFrameMode() ) + pToBeSavedProperties.reset( new ParagraphProperties(*pParaContext) ); + } + else if(*rAppendContext.pLastParagraphProperties == *pParaContext ) + { + //handles (7) + rAppendContext.pLastParagraphProperties->SetEndingRange(xTextAppend->getEnd()); + bKeepLastParagraphProperties = true; + } + else + { + //handles (8)(9) and completes (6) + try + { + // + StyleSheetEntryPtr pParaStyle = + m_pStyleSheetTable->FindStyleSheetByConvertedStyleName(rAppendContext.pLastParagraphProperties->GetParaStyleName()); + + uno::Sequence< beans::PropertyValue > aFrameProperties(pParaStyle ? 15: 0); + if ( pParaStyle.get( ) ) + { + const ParagraphProperties* pStyleProperties = dynamic_cast<const ParagraphProperties*>( pParaStyle->pProperties.get() ); + beans::PropertyValue* pFrameProperties = aFrameProperties.getArray(); + pFrameProperties[0].Name = rPropNameSupplier.GetName(PROP_WIDTH); + pFrameProperties[1].Name = rPropNameSupplier.GetName(PROP_HEIGHT); + pFrameProperties[2].Name = rPropNameSupplier.GetName(PROP_SIZE_TYPE); + pFrameProperties[3].Name = rPropNameSupplier.GetName(PROP_WIDTH_TYPE); + pFrameProperties[4].Name = rPropNameSupplier.GetName(PROP_HORI_ORIENT); + pFrameProperties[5].Name = rPropNameSupplier.GetName(PROP_HORI_ORIENT_POSITION); + pFrameProperties[6].Name = rPropNameSupplier.GetName(PROP_HORI_ORIENT_RELATION); + pFrameProperties[7].Name = rPropNameSupplier.GetName(PROP_VERT_ORIENT); + pFrameProperties[8].Name = rPropNameSupplier.GetName(PROP_VERT_ORIENT_POSITION); + pFrameProperties[9].Name = rPropNameSupplier.GetName(PROP_VERT_ORIENT_RELATION); + pFrameProperties[10].Name = rPropNameSupplier.GetName(PROP_SURROUND); + pFrameProperties[11].Name = rPropNameSupplier.GetName(PROP_LEFT_MARGIN); + pFrameProperties[12].Name = rPropNameSupplier.GetName(PROP_RIGHT_MARGIN); + pFrameProperties[13].Name = rPropNameSupplier.GetName(PROP_TOP_MARGIN); + pFrameProperties[14].Name = rPropNameSupplier.GetName(PROP_BOTTOM_MARGIN); + sal_Int32 nWidth = + rAppendContext.pLastParagraphProperties->Getw() > 0 ? + rAppendContext.pLastParagraphProperties->Getw() : + pStyleProperties->Getw(); + bool bAutoWidth = nWidth < 1; + if( bAutoWidth ) + nWidth = DEFAULT_FRAME_MIN_WIDTH; + pFrameProperties[0].Value <<= nWidth; + pFrameProperties[1].Value <<= + rAppendContext.pLastParagraphProperties->Geth() > 0 ? + rAppendContext.pLastParagraphProperties->Geth() : + pStyleProperties->Geth(); + pFrameProperties[2].Value <<= sal_Int16( + rAppendContext.pLastParagraphProperties->GethRule() >= 0 ? + rAppendContext.pLastParagraphProperties->GethRule() : + pStyleProperties->GethRule() >=0 ? pStyleProperties->GethRule() : text::SizeType::VARIABLE); + + pFrameProperties[3].Value <<= bAutoWidth ? text::SizeType::MIN : text::SizeType::FIX; + + sal_Int16 nHoriOrient = sal_Int16( + rAppendContext.pLastParagraphProperties->GetxAlign() >= 0 ? + rAppendContext.pLastParagraphProperties->GetxAlign() : + pStyleProperties->GetxAlign() >= 0 ? pStyleProperties->GetxAlign() : text::HoriOrientation::NONE ); + pFrameProperties[4].Value <<= nHoriOrient; + + pFrameProperties[5].Value <<= + rAppendContext.pLastParagraphProperties->IsxValid() ? + rAppendContext.pLastParagraphProperties->Getx() : pStyleProperties->Getx(); + pFrameProperties[6].Value <<= sal_Int16( + rAppendContext.pLastParagraphProperties->GethAnchor() >= 0 ? + rAppendContext.pLastParagraphProperties->GethAnchor() : + pStyleProperties->GethAnchor() ); + + sal_Int16 nVertOrient = sal_Int16( + rAppendContext.pLastParagraphProperties->GetyAlign() >= 0 ? + rAppendContext.pLastParagraphProperties->GetyAlign() : + pStyleProperties->GetyAlign() >= 0 ? pStyleProperties->GetyAlign() : text::VertOrientation::NONE ); + pFrameProperties[7].Value <<= nVertOrient; + + pFrameProperties[8].Value <<= + rAppendContext.pLastParagraphProperties->IsyValid() ? + rAppendContext.pLastParagraphProperties->Gety() : pStyleProperties->Gety(); + pFrameProperties[9].Value <<= sal_Int16( + rAppendContext.pLastParagraphProperties->GetvAnchor() >= 0 ? + rAppendContext.pLastParagraphProperties->GetvAnchor() : + pStyleProperties->GetvAnchor() ); + + pFrameProperties[10].Value <<= text::WrapTextMode( + rAppendContext.pLastParagraphProperties->GetWrap() >= 0 ? + rAppendContext.pLastParagraphProperties->GetWrap() : + pStyleProperties->GetWrap()); + + sal_Int32 nBottomDist; + sal_Int32 nTopDist = nBottomDist = + rAppendContext.pLastParagraphProperties->GethSpace() >= 0 ? + rAppendContext.pLastParagraphProperties->GethSpace() : + pStyleProperties->GethSpace(); + + pFrameProperties[11].Value <<= nVertOrient == text::VertOrientation::TOP ? 0 : nTopDist; + pFrameProperties[12].Value <<= nVertOrient == text::VertOrientation::BOTTOM ? 0 : nBottomDist; + + sal_Int32 nRightDist; + sal_Int32 nLeftDist = nRightDist = + rAppendContext.pLastParagraphProperties->GetvSpace() >= 0 ? + rAppendContext.pLastParagraphProperties->GetvSpace() : + pStyleProperties->GetvSpace() >= 0 ? pStyleProperties->GetvSpace() : 0; + pFrameProperties[13].Value <<= nHoriOrient == text::HoriOrientation::LEFT ? 0 : nLeftDist; + pFrameProperties[14].Value <<= nHoriOrient == text::HoriOrientation::RIGHT ? 0 : nRightDist; + + lcl_MoveBorderPropertiesToFrame(aFrameProperties, + rAppendContext.pLastParagraphProperties->GetStartingRange(), + rAppendContext.pLastParagraphProperties->GetEndingRange()); + } + //frame conversion has to be executed after table conversion + RegisterFrameConversion( + rAppendContext.pLastParagraphProperties->GetStartingRange(), + rAppendContext.pLastParagraphProperties->GetEndingRange(), + aFrameProperties ); + // next frame follows directly + if( pParaContext->IsFrameMode() ) + { + pToBeSavedProperties.reset( new ParagraphProperties(*pParaContext) ); + lcl_AddRangeAndStyle(pToBeSavedProperties, xTextAppend, pPropertyMap); + } + } + catch( const uno::Exception& rEx ) + { + (void)rEx; + } + } + + } + else // + { + // (1) doesn't need handling + // + if( !bIsDropCap && pParaContext->IsFrameMode() ) + { + pToBeSavedProperties.reset( new ParagraphProperties(*pParaContext) ); + lcl_AddRangeAndStyle(pToBeSavedProperties, xTextAppend, pPropertyMap); + } + } + uno::Sequence< beans::PropertyValue > aProperties; + if( pPropertyMap.get() ) + { + aProperties = pPropertyMap->GetPropertyValues(); + } + if( !bIsDropCap ) + { + if( aDrop.Lines > 1 ) + { + sal_uInt32 nLength = aProperties.getLength(); + aProperties.realloc( nLength + 1 ); + aProperties[nLength].Value <<= aDrop; + aProperties[nLength].Name = rPropNameSupplier.GetName(PROP_DROP_CAP_FORMAT); + } + uno::Reference< text::XTextRange > xTextRange = + xTextAppend->finishParagraph( aProperties ); + getTableManager( ).handle(xTextRange); + + // Set the anchor of the objects to the created paragraph + while ( m_aAnchoredStack.size( ) > 0 && !m_bIsInShape ) + { + uno::Reference< text::XTextContent > xObj = m_aAnchoredStack.top( ); + try + { +#if DEBUG + rtl::OUString sText( xTextRange->getString( ) ); +#endif + xObj->attach( xTextRange ); + } + catch ( uno::RuntimeException& ) + { + // this is normal: the shape is already attached + } + m_aAnchoredStack.pop( ); + } + + // Get the end of paragraph character inserted + uno::Reference< text::XTextCursor > xCur = xTextRange->getText( )->createTextCursor( ); + xCur->gotoEnd( false ); + xCur->goLeft( 1 , true ); + uno::Reference< text::XTextRange > xParaEnd( xCur, uno::UNO_QUERY ); + CheckParaRedline( xParaEnd ); + + // Remove the last empty section paragraph if needed + if ( m_bIsLastParaInSection && !m_bParaChanged ) + { + RemoveLastParagraph( ); + m_bIsLastParaInSection = false; + } + + m_bParaChanged = false; + } + if( !bKeepLastParagraphProperties ) + rAppendContext.pLastParagraphProperties = pToBeSavedProperties; + } + catch(const lang::IllegalArgumentException& rIllegal) + { + (void)rIllegal; + OSL_FAIL( "IllegalArgumentException in DomainMapper_Impl::finishParagraph" ); + } + catch(const uno::Exception& rEx) + { + (void)rEx; + //OSL_ENSURE( false, "ArgumentException in DomainMapper_Impl::finishParagraph" ); + } + } + +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->endElement(); +#endif +} + + +util::DateTime lcl_DateStringToDateTime( const ::rtl::OUString& rDateTime ) +{ + util::DateTime aDateTime; + //xsd::DateTime in the format [-]CCYY-MM-DDThh:mm:ss[Z|(+|-)hh:mm] example: 2008-01-21T10:42:00Z + //OUString getToken( sal_Int32 token, sal_Unicode cTok, sal_Int32& index ) const SAL_THROW(()) + sal_Int32 nIndex = 0; + ::rtl::OUString sDate = rDateTime.getToken( 0, 'T', nIndex ); + ::rtl::OUString sTime = rDateTime.getToken( 0, 'Z', nIndex ); + nIndex = 0; + aDateTime.Year = sal_uInt16( sDate.getToken( 0, '-', nIndex ).toInt32() ); + aDateTime.Month = sal_uInt16( sDate.getToken( 0, '-', nIndex ).toInt32() ); + aDateTime.Day = sal_uInt16( sDate.copy( nIndex ).toInt32() ); + + nIndex = 0; + aDateTime.Hours = sal_uInt16( sTime.getToken( 0, ':', nIndex ).toInt32() ); + aDateTime.Minutes = sal_uInt16( sTime.getToken( 0, ':', nIndex ).toInt32() ); + aDateTime.Seconds = sal_uInt16( sTime.copy( nIndex ).toInt32() ); + + return aDateTime; +} +void DomainMapper_Impl::appendTextPortion( const ::rtl::OUString& rString, PropertyMapPtr pPropertyMap ) +{ + uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; + if(xTextAppend.is() && ! getTableManager( ).isIgnore()) + { + try + { + uno::Reference< text::XTextRange > xTextRange = + xTextAppend->appendTextPortion + (rString, pPropertyMap->GetPropertyValues()); + CheckRedline( xTextRange ); + m_bParaChanged = true; + + //getTableManager( ).handle(xTextRange); + } + catch(const lang::IllegalArgumentException& rEx) + { + (void)rEx; + OSL_FAIL( "IllegalArgumentException in DomainMapper_Impl::appendTextPortion" ); + } + catch(const uno::Exception& rEx) + { + (void)rEx; + OSL_FAIL( "Exception in DomainMapper_Impl::appendTextPortion" ); + } + } +} + + +void DomainMapper_Impl::appendTextContent( + const uno::Reference< text::XTextContent > xContent, + const uno::Sequence< beans::PropertyValue > xPropertyValues + ) +{ + uno::Reference< text::XTextAppendAndConvert > xTextAppendAndConvert( m_aTextAppendStack.top().xTextAppend, uno::UNO_QUERY ); + OSL_ENSURE( xTextAppendAndConvert.is(), "trying to append a text content without XTextAppendAndConvert" ); + if(xTextAppendAndConvert.is() && ! getTableManager( ).isIgnore()) + { + try + { + xTextAppendAndConvert->appendTextContent( xContent, xPropertyValues ); + } + catch(const lang::IllegalArgumentException& ) + { + } + catch(const uno::Exception& ) + { + } + } +} + + + +void DomainMapper_Impl::appendOLE( const ::rtl::OUString& rStreamName, OLEHandlerPtr pOLEHandler ) +{ + static const rtl::OUString sEmbeddedService(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.TextEmbeddedObject")); + try + { + uno::Reference< text::XTextContent > xOLE( m_xTextFactory->createInstance(sEmbeddedService), uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xOLEProperties(xOLE, uno::UNO_QUERY_THROW); + + xOLEProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_STREAM_NAME ), + uno::makeAny( rStreamName )); + awt::Size aSize = pOLEHandler->getSize(); + if( !aSize.Width ) + aSize.Width = 1000; + if( !aSize.Height ) + aSize.Height = 1000; + xOLEProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_WIDTH ), + uno::makeAny(aSize.Width)); + xOLEProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_HEIGHT ), + uno::makeAny(aSize.Height)); + + uno::Reference< graphic::XGraphic > xGraphic = pOLEHandler->getReplacement(); + xOLEProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_GRAPHIC ), + uno::makeAny(xGraphic)); + // mimic the treatment of graphics here.. it seems anchoring as character + // gives a better ( visually ) result + xOLEProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_ANCHOR_TYPE ), uno::makeAny( text::TextContentAnchorType_AS_CHARACTER ) ); + // remove ( if valid ) associated shape ( used for graphic replacement ) + if ( m_bShapeContextAdded ) + { + if ( lcl_removeShape( m_xTextDocument, pOLEHandler->getShape(), m_aAnchoredStack, m_aTextAppendStack ) ) + m_bShapeContextAdded = false; // ensure PopShapeContext processing doesn't pop the append stack + } + + // + appendTextContent( xOLE, uno::Sequence< beans::PropertyValue >() ); + + } + catch( const uno::Exception& rEx ) + { + (void)rEx; + OSL_FAIL( "Exception in creation of OLE object" ); + } + +} + + +uno::Reference< beans::XPropertySet > DomainMapper_Impl::appendTextSectionAfter( + uno::Reference< text::XTextRange >& xBefore ) +{ + uno::Reference< beans::XPropertySet > xRet; + uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; + if(xTextAppend.is()) + { + try + { + uno::Reference< text::XParagraphCursor > xCursor( + xTextAppend->createTextCursorByRange( xBefore ), uno::UNO_QUERY_THROW); + //the cursor has been moved to the end of the paragraph because of the appendTextPortion() calls + xCursor->gotoStartOfParagraph( false ); + xCursor->gotoEnd( true ); + //the paragraph after this new section is already inserted + xCursor->goLeft(1, true); + static const rtl::OUString sSectionService(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.TextSection")); + uno::Reference< text::XTextContent > xSection( m_xTextFactory->createInstance(sSectionService), uno::UNO_QUERY_THROW ); + xSection->attach( uno::Reference< text::XTextRange >( xCursor, uno::UNO_QUERY_THROW) ); + xRet = uno::Reference< beans::XPropertySet > (xSection, uno::UNO_QUERY ); + } + catch(const uno::Exception& ) + { + } + + } + + return xRet; +} + + +void DomainMapper_Impl::PushPageHeader(SectionPropertyMap::PageType eType) +{ + //get the section context + PropertyMapPtr pContext = DomainMapper_Impl::GetTopContextOfType(CONTEXT_SECTION); + //ask for the header name of the given type + SectionPropertyMap* pSectionContext = dynamic_cast< SectionPropertyMap* >( pContext.get() ); + if(pSectionContext) + { + uno::Reference< beans::XPropertySet > xPageStyle = + pSectionContext->GetPageStyle( + GetPageStyles(), + m_xTextFactory, + eType == SectionPropertyMap::PAGE_FIRST ); + try + { + PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + //switch on header use + xPageStyle->setPropertyValue( + rPropNameSupplier.GetName(PROP_HEADER_IS_ON), + uno::makeAny(sal_True) ); + // if a left header is available then header are not shared + bool bLeft = eType == SectionPropertyMap::PAGE_LEFT; + if( bLeft ) + xPageStyle->setPropertyValue(rPropNameSupplier.GetName(PROP_HEADER_IS_SHARED), uno::makeAny( false )); + + //set the interface + uno::Reference< text::XText > xHeaderText; + xPageStyle->getPropertyValue(rPropNameSupplier.GetName( bLeft ? PROP_HEADER_TEXT_LEFT : PROP_HEADER_TEXT) ) >>= xHeaderText; + m_aTextAppendStack.push( uno::Reference< text::XTextAppend >( xHeaderText, uno::UNO_QUERY_THROW)); + } + catch( uno::Exception& ) + { + } + } +} + + +void DomainMapper_Impl::PushPageFooter(SectionPropertyMap::PageType eType) +{ + //get the section context + PropertyMapPtr pContext = DomainMapper_Impl::GetTopContextOfType(CONTEXT_SECTION); + //ask for the footer name of the given type + SectionPropertyMap* pSectionContext = dynamic_cast< SectionPropertyMap* >( pContext.get() ); + if(pSectionContext) + { + uno::Reference< beans::XPropertySet > xPageStyle = + pSectionContext->GetPageStyle( + GetPageStyles(), + m_xTextFactory, + eType == SectionPropertyMap::PAGE_FIRST ); + try + { + PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + //switch on footer use + xPageStyle->setPropertyValue( + rPropNameSupplier.GetName(PROP_FOOTER_IS_ON), + uno::makeAny(sal_True) ); + // if a left header is available then footer is not shared + bool bLeft = eType == SectionPropertyMap::PAGE_LEFT; + if( bLeft ) + xPageStyle->setPropertyValue(rPropNameSupplier.GetName(PROP_FOOTER_IS_SHARED), uno::makeAny( false )); + //set the interface + uno::Reference< text::XText > xFooterText; + xPageStyle->getPropertyValue(rPropNameSupplier.GetName( bLeft ? PROP_FOOTER_TEXT_LEFT : PROP_FOOTER_TEXT) ) >>= xFooterText; + m_aTextAppendStack.push(uno::Reference< text::XTextAppend >( xFooterText, uno::UNO_QUERY_THROW )); + } + catch( uno::Exception& ) + { + } + } +} + + +void DomainMapper_Impl::PopPageHeaderFooter() +{ + //header and footer always have an empty paragraph at the end + //this has to be removed + RemoveLastParagraph( ); + m_aTextAppendStack.pop(); +} + + +void DomainMapper_Impl::PushFootOrEndnote( bool bIsFootnote ) +{ + try + { + PropertyMapPtr pTopContext = GetTopContext(); + uno::Reference< text::XText > xFootnoteText( GetTextFactory()->createInstance( + bIsFootnote ? + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.Footnote") ) : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.Endnote") )), + uno::UNO_QUERY_THROW ); + uno::Reference< text::XFootnote > xFootnote( xFootnoteText, uno::UNO_QUERY_THROW ); + pTopContext->SetFootnote( xFootnote ); + if( pTopContext->GetFootnoteSymbol() != 0) + { + xFootnote->setLabel( ::rtl::OUString( pTopContext->GetFootnoteSymbol() ) ); + } + FontTablePtr pFontTable = GetFontTable(); + uno::Sequence< beans::PropertyValue > aFontProperties; + if( pFontTable && pTopContext->GetFootnoteFontId() >= 0 && pFontTable->size() > (size_t)pTopContext->GetFootnoteFontId() ) + { + const FontEntry::Pointer_t pFontEntry(pFontTable->getFontEntry(sal_uInt32(pTopContext->GetFootnoteFontId()))); + PropertyMapPtr aFontProps( new PropertyMap ); + aFontProps->Insert(PROP_CHAR_FONT_NAME, true, uno::makeAny( pFontEntry->sFontName )); + aFontProps->Insert(PROP_CHAR_FONT_CHAR_SET, true, uno::makeAny( (sal_Int16)pFontEntry->nTextEncoding )); + aFontProps->Insert(PROP_CHAR_FONT_PITCH, true, uno::makeAny( pFontEntry->nPitchRequest )); + aFontProperties = aFontProps->GetPropertyValues(); + } + else if(pTopContext->GetFootnoteFontName().getLength()) + { + PropertyMapPtr aFontProps( new PropertyMap ); + aFontProps->Insert(PROP_CHAR_FONT_NAME, true, uno::makeAny( pTopContext->GetFootnoteFontName() )); + aFontProperties = aFontProps->GetPropertyValues(); + } + appendTextContent( uno::Reference< text::XTextContent >( xFootnoteText, uno::UNO_QUERY_THROW ), aFontProperties ); + m_aTextAppendStack.push(uno::Reference< text::XTextAppend >( xFootnoteText, uno::UNO_QUERY_THROW )); + + // Redlines for the footnote anchor + CheckRedline( xFootnote->getAnchor( ) ); + } + catch( uno::Exception& ) + { + OSL_FAIL( "exception in PushFootOrEndnote" ); + } +} + +void DomainMapper_Impl::CreateRedline( uno::Reference< text::XTextRange > xRange, RedlineParamsPtr& pRedline ) +{ + if ( pRedline.get( ) ) + { + try + { + ::rtl::OUString sType; + PropertyNameSupplier & rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier( ); + switch ( pRedline->m_nToken & 0xffff ) + { + case ooxml::OOXML_mod: + sType = rPropNameSupplier.GetName( PROP_FORMAT ); + break; + case ooxml::OOXML_ins: + sType = rPropNameSupplier.GetName( PROP_INSERT ); + break; + case ooxml::OOXML_del: + sType = rPropNameSupplier.GetName( PROP_DELETE ); + break; + } + uno::Reference < text::XRedline > xRedline( xRange, uno::UNO_QUERY_THROW ); + beans::PropertyValues aRedlineProperties( 2 ); + beans::PropertyValue * pRedlineProperties = aRedlineProperties.getArray( ); + pRedlineProperties[0].Name = rPropNameSupplier.GetName( PROP_REDLINE_AUTHOR ); + pRedlineProperties[0].Value <<= pRedline->m_sAuthor; + pRedlineProperties[1].Name = rPropNameSupplier.GetName( PROP_REDLINE_DATE_TIME ); + pRedlineProperties[1].Value <<= lcl_DateStringToDateTime( pRedline->m_sDate ); + + xRedline->makeRedline( sType, aRedlineProperties ); + } + catch( const uno::Exception & rEx ) + { + ( void ) rEx; + OSL_FAIL( "Exception in makeRedline" ); + } + } +} + +void DomainMapper_Impl::CheckParaRedline( uno::Reference< text::XTextRange > xRange ) +{ + if ( m_pParaRedline.get( ) ) + { + CreateRedline( xRange, m_pParaRedline ); + ResetParaRedline( ); + } +} + +void DomainMapper_Impl::CheckRedline( uno::Reference< text::XTextRange > xRange ) +{ + vector<RedlineParamsPtr>::iterator pIt = m_aRedlines.begin( ); + vector< RedlineParamsPtr > aCleaned; + for (; pIt != m_aRedlines.end( ); ++pIt ) + { + CreateRedline( xRange, *pIt ); + + // Adding the non-mod redlines to the temporary vector + if ( pIt->get( ) && ( ( *pIt )->m_nToken & 0xffff ) != ooxml::OOXML_mod ) + { + aCleaned.push_back( *pIt ); + } + } + + m_aRedlines.swap( aCleaned ); +} + +void DomainMapper_Impl::StartParaChange( ) +{ + m_bIsParaChange = true; +} + +void DomainMapper_Impl::EndParaChange( ) +{ + m_bIsParaChange = false; +} + + + +void DomainMapper_Impl::PushAnnotation() +{ + try + { + PropertyMapPtr pTopContext = GetTopContext(); + m_xAnnotationField = uno::Reference< beans::XPropertySet >( GetTextFactory()->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.TextField.Annotation") ) ), + uno::UNO_QUERY_THROW ); + uno::Reference< text::XText > xAnnotationText; + m_xAnnotationField->getPropertyValue(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("TextRange"))) >>= xAnnotationText; + m_aTextAppendStack.push(uno::Reference< text::XTextAppend >( xAnnotationText, uno::UNO_QUERY_THROW )); + } + catch( uno::Exception& ) + { + OSL_FAIL( "exception in PushFootOrEndnote" ); + } +} + + +void DomainMapper_Impl::PopFootOrEndnote() +{ + m_aTextAppendStack.pop(); +} + + +void DomainMapper_Impl::PopAnnotation() +{ + m_aTextAppendStack.pop(); + uno::Sequence< beans::PropertyValue > aEmptyProperties; + appendTextContent( uno::Reference< text::XTextContent >( m_xAnnotationField, uno::UNO_QUERY_THROW ), aEmptyProperties ); + m_xAnnotationField.clear(); + +} + +void DomainMapper_Impl::PushShapeContext( const uno::Reference< drawing::XShape > xShape ) +{ + m_bIsInShape = true; + try + { + // Add the shape to the text append stack + m_aTextAppendStack.push( uno::Reference< text::XTextAppend >( xShape, uno::UNO_QUERY_THROW ) ); + m_bShapeContextAdded = true; + + // Add the shape to the anchored objects stack + uno::Reference< text::XTextContent > xTxtContent( xShape, uno::UNO_QUERY_THROW ); + m_aAnchoredStack.push( xTxtContent ); + + PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + + uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY_THROW ); + uno::Reference< lang::XServiceInfo > xSInfo( xShape, uno::UNO_QUERY_THROW ); + bool bIsGraphic = xSInfo->supportsService( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.GraphicObjectShape" ) ) ); + + xProps->setPropertyValue( rPropNameSupplier.GetName( PROP_ANCHOR_TYPE ), bIsGraphic ? uno::makeAny( text::TextContentAnchorType_AS_CHARACTER ) : uno::makeAny( text::TextContentAnchorType_AT_PARAGRAPH ) ); + xProps->setPropertyValue( + rPropNameSupplier.GetName( PROP_OPAQUE ), + uno::makeAny( true ) ); + } + catch ( const uno::Exception& e ) + { +#if DEBUG + clog << "Exception when adding shape: "; + clog << rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_UTF8 ).getStr( ); + clog << endl; +#endif + } +} + + + +void DomainMapper_Impl::PopShapeContext() +{ + if ( m_bShapeContextAdded ) + { + m_aTextAppendStack.pop(); + m_bShapeContextAdded = false; + } + m_bIsInShape = false; +} + + +::rtl::OUString lcl_FindQuotedText( const ::rtl::OUString& rCommand, + const sal_Char* cStartQuote, const sal_Unicode uEndQuote ) +{ + ::rtl::OUString sRet; + ::rtl::OUString sStartQuote( ::rtl::OUString::createFromAscii(cStartQuote) ); + sal_Int32 nStartIndex = rCommand.indexOf( sStartQuote ); + if( nStartIndex >= 0 ) + { + sal_Int32 nStartLength = sStartQuote.getLength(); + sal_Int32 nEndIndex = rCommand.indexOf( uEndQuote, nStartIndex + nStartLength); + if( nEndIndex > nStartIndex ) + { + sRet = rCommand.copy( nStartIndex + nStartLength, nEndIndex - nStartIndex - nStartLength); + } + } + return sRet; + +} + + +sal_Int16 lcl_ParseNumberingType( const ::rtl::OUString& rCommand ) +{ + sal_Int16 nRet = style::NumberingType::PAGE_DESCRIPTOR; + + // The command looks like: " PAGE \* Arabic " + ::rtl::OUString sNumber = lcl_FindQuotedText(rCommand, "\\* ", ' '); + + if( sNumber.getLength() ) + { + //todo: might make sense to hash this list, too + struct NumberingPairs + { + const sal_Char* cWordName; + sal_Int16 nType; + }; + static const NumberingPairs aNumberingPairs[] = + { + {"Arabic", style::NumberingType::ARABIC} + ,{"ROMAN", style::NumberingType::ROMAN_UPPER} + ,{"roman", style::NumberingType::ROMAN_LOWER} + ,{"ALPHABETIC", style::NumberingType::CHARS_UPPER_LETTER} + ,{"alphabetic", style::NumberingType::CHARS_LOWER_LETTER} + ,{"CircleNum", style::NumberingType::CIRCLE_NUMBER} + ,{"ThaiArabic", style::NumberingType::CHARS_THAI} + ,{"ThaiCardText", style::NumberingType::CHARS_THAI} + ,{"ThaiLetter", style::NumberingType::CHARS_THAI} +// ,{"SBCHAR", style::NumberingType::} +// ,{"DBCHAR", style::NumberingType::} +// ,{"DBNUM1", style::NumberingType::} +// ,{"DBNUM2", style::NumberingType::} +// ,{"DBNUM3", style::NumberingType::} +// ,{"DBNUM4", style::NumberingType::} + ,{"Aiueo", style::NumberingType::AIU_FULLWIDTH_JA} + ,{"Iroha", style::NumberingType::IROHA_FULLWIDTH_JA} +// ,{"ZODIAC1", style::NumberingType::} +// ,{"ZODIAC2", style::NumberingType::} +// ,{"ZODIAC3", style::NumberingType::} +// ,{"CHINESENUM1", style::NumberingType::} +// ,{"CHINESENUM2", style::NumberingType::} +// ,{"CHINESENUM3", style::NumberingType::} + ,{"ArabicAlpha", style::NumberingType::CHARS_ARABIC} + ,{"ArabicAbjad", style::NumberingType::FULLWIDTH_ARABIC} +/* possible values: +style::NumberingType:: + + CHARS_UPPER_LETTER_N + CHARS_LOWER_LETTER_N + TRANSLITERATION + NATIVE_NUMBERING + CIRCLE_NUMBER + NUMBER_LOWER_ZH + NUMBER_UPPER_ZH + NUMBER_UPPER_ZH_TW + TIAN_GAN_ZH + DI_ZI_ZH + NUMBER_TRADITIONAL_JA + AIU_HALFWIDTH_JA + IROHA_HALFWIDTH_JA + NUMBER_UPPER_KO + NUMBER_HANGUL_KO + HANGUL_JAMO_KO + HANGUL_SYLLABLE_KO + HANGUL_CIRCLED_JAMO_KO + HANGUL_CIRCLED_SYLLABLE_KO + CHARS_HEBREW + CHARS_NEPALI + CHARS_KHMER + CHARS_LAO + CHARS_TIBETAN + CHARS_CYRILLIC_UPPER_LETTER_BG + CHARS_CYRILLIC_LOWER_LETTER_BG + CHARS_CYRILLIC_UPPER_LETTER_N_BG + CHARS_CYRILLIC_LOWER_LETTER_N_BG + CHARS_CYRILLIC_UPPER_LETTER_RU + CHARS_CYRILLIC_LOWER_LETTER_RU + CHARS_CYRILLIC_UPPER_LETTER_N_RU + CHARS_CYRILLIC_LOWER_LETTER_N_RU + CHARS_CYRILLIC_UPPER_LETTER_SR + CHARS_CYRILLIC_LOWER_LETTER_SR + CHARS_CYRILLIC_UPPER_LETTER_N_SR + CHARS_CYRILLIC_LOWER_LETTER_N_SR*/ + + }; + for( sal_uInt32 nNum = 0; nNum < sizeof(aNumberingPairs)/sizeof( NumberingPairs ); ++nNum) + { + if( /*sCommand*/sNumber.equalsAscii(aNumberingPairs[nNum].cWordName )) + { + nRet = aNumberingPairs[nNum].nType; + break; + } + } + + } + return nRet; +} + + +OUString lcl_ParseFormat( const ::rtl::OUString& rCommand ) +{ + // The command looks like: " DATE \@ "dd MMMM yyyy" + return lcl_FindQuotedText(rCommand, "\\@ \"", '\"'); +} +/*------------------------------------------------------------------------- +extract a parameter (with or without quotes) between the command and the following backslash + -----------------------------------------------------------------------*/ +::rtl::OUString lcl_ExtractParameter(const ::rtl::OUString& rCommand, sal_Int32 nCommandLength ) +{ + sal_Int32 nStartIndex = nCommandLength; + sal_Int32 nEndIndex = 0; + sal_Int32 nQuoteIndex = rCommand.indexOf( '\"', nStartIndex); + if( nQuoteIndex >= 0) + { + nStartIndex = nQuoteIndex + 1; + nEndIndex = rCommand.indexOf( '\"', nStartIndex + 1) - 1; + } + else + { + nEndIndex = rCommand.indexOf( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" \\")), nStartIndex); + } + ::rtl::OUString sRet; + if( nEndIndex > nStartIndex + 1 ) + { + //remove spaces at start and end of the result + if(nQuoteIndex <= 0) + { + const sal_Unicode* pCommandStr = rCommand.getStr(); + while( nStartIndex < nEndIndex && pCommandStr[nStartIndex] == ' ') + ++nStartIndex; + while( nEndIndex > nStartIndex && pCommandStr[nEndIndex] == ' ') + --nEndIndex; + } + sRet = rCommand.copy( nStartIndex, nEndIndex - nStartIndex + 1); + } + return sRet; +} + + + +::rtl::OUString lcl_ExctractAskVariableAndHint( const ::rtl::OUString& rCommand, ::rtl::OUString& rHint ) +{ + // the first word after "ASK " is the variable + // the text after the variable and before a '\' is the hint + // if no hint is set the variable is used as hint + // the quotes of the hint have to be removed + sal_Int32 nIndex = rCommand.indexOf( ' ', 2);//find last space after 'ASK' + while(rCommand.getStr()[nIndex] == ' ') + ++nIndex; + ::rtl::OUString sShortCommand( rCommand.copy( nIndex ) ); //cut off the " ASK " + + nIndex = 0; + sShortCommand = sShortCommand.getToken( 0, '\\', nIndex); + nIndex = 0; + ::rtl::OUString sRet = sShortCommand.getToken( 0, ' ', nIndex); + if( nIndex > 0) + rHint = sShortCommand.copy( nIndex ); + if( !rHint.getLength() ) + rHint = sRet; + return sRet; +} + + +bool lcl_FindInCommand( + const ::rtl::OUString& rCommand, + sal_Unicode cSwitch, + ::rtl::OUString& rValue ) +{ + bool bRet = false; + ::rtl::OUString sSearch('\\'); + sSearch += ::rtl::OUString( cSwitch ); + sal_Int32 nIndex = rCommand.indexOf( sSearch ); + if( nIndex >= 0 ) + { + bRet = true; + //find next '\' or end of string + sal_Int32 nEndIndex = rCommand.indexOf( '\\', nIndex + 1); + if( nEndIndex < 0 ) + nEndIndex = rCommand.getLength() - 1; + if( nEndIndex - nIndex > 3 ) + rValue = rCommand.copy( nIndex + 3, nEndIndex - nIndex - 3); + } + return bRet; +} + + + +void DomainMapper_Impl::GetCurrentLocale(lang::Locale& rLocale) +{ + PropertyMapPtr pTopContext = GetTopContext(); + PropertyDefinition aCharLocale( PROP_CHAR_LOCALE, true ); + PropertyMap::iterator aLocaleIter = pTopContext->find( aCharLocale ); + if( aLocaleIter != pTopContext->end()) + aLocaleIter->second >>= rLocale; + else + { + PropertyMapPtr pParaContext = GetTopContextOfType(CONTEXT_PARAGRAPH); + aLocaleIter = pParaContext->find(aCharLocale); + if( aLocaleIter != pParaContext->end()) + { + aLocaleIter->second >>= rLocale; + } + } +} + +/*------------------------------------------------------------------------- + extract the number format from the command and apply the resulting number + format to the XPropertySet + -----------------------------------------------------------------------*/ +void DomainMapper_Impl::SetNumberFormat( const ::rtl::OUString& rCommand, + uno::Reference< beans::XPropertySet >& xPropertySet ) +{ + OUString sFormatString = lcl_ParseFormat( rCommand ); + // find \h - hijri/luna calendar todo: what about saka/era calendar? + bool bHijri = 0 < rCommand.indexOf( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\\h "))); + lang::Locale aUSLocale; + aUSLocale.Language = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en")); + aUSLocale.Country = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("US")); + + //determine current locale - todo: is it necessary to initialize this locale? + lang::Locale aCurrentLocale = aUSLocale; + GetCurrentLocale( aCurrentLocale ); + ::rtl::OUString sFormat = ConversionHelper::ConvertMSFormatStringToSO( sFormatString, aCurrentLocale, bHijri); + //get the number formatter and convert the string to a format value + try + { + uno::Reference< util::XNumberFormatsSupplier > xNumberSupplier( m_xTextDocument, uno::UNO_QUERY_THROW ); + sal_Int32 nKey = xNumberSupplier->getNumberFormats()->addNewConverted( sFormat, aUSLocale, aCurrentLocale ); + xPropertySet->setPropertyValue( + PropertyNameSupplier::GetPropertyNameSupplier().GetName(PROP_NUMBER_FORMAT), + uno::makeAny( nKey )); + xPropertySet->getPropertyValue( + PropertyNameSupplier::GetPropertyNameSupplier().GetName(PROP_NUMBER_FORMAT ) ) >>= nKey; + } + catch(const uno::Exception&) + { + } +} + + + +uno::Reference< beans::XPropertySet > DomainMapper_Impl::FindOrCreateFieldMaster( + const sal_Char* pFieldMasterService, const ::rtl::OUString& rFieldMasterName ) + throw(::com::sun::star::uno::Exception) +{ + // query master, create if not available + uno::Reference< text::XTextFieldsSupplier > xFieldsSupplier( GetTextDocument(), uno::UNO_QUERY ); + uno::Reference< container::XNameAccess > xFieldMasterAccess = xFieldsSupplier->getTextFieldMasters(); + uno::Reference< beans::XPropertySet > xMaster; + ::rtl::OUString sFieldMasterService( ::rtl::OUString::createFromAscii(pFieldMasterService) ); + ::rtl::OUStringBuffer aFieldMasterName; + aFieldMasterName.appendAscii( pFieldMasterService ); + aFieldMasterName.append(sal_Unicode('.')); + aFieldMasterName.append(rFieldMasterName); + ::rtl::OUString sFieldMasterName = aFieldMasterName.makeStringAndClear(); + if(xFieldMasterAccess->hasByName(sFieldMasterName)) + { + //get the master + xMaster = uno::Reference< beans::XPropertySet >(xFieldMasterAccess->getByName(sFieldMasterName), + uno::UNO_QUERY_THROW); + } + else + { + //create the master + xMaster = uno::Reference< beans::XPropertySet >( + m_xTextFactory->createInstance(sFieldMasterService), uno::UNO_QUERY_THROW); + //set the master's name +// sal_Int32 nIndex = rtl_str_indexOfStr( pFieldMasterService, "Database" ); +// if( nIndex < 0 ) + xMaster->setPropertyValue( + PropertyNameSupplier::GetPropertyNameSupplier().GetName(PROP_NAME), + uno::makeAny(rFieldMasterName)); +// else +// { +// xMaster->setPropertyValue( +// PropertyNameSupplier::GetPropertyNameSupplier().GetName(PROP_DATA_COLUMN_NAME), +// uno::makeAny(rFieldMasterName)); +// } + } + return xMaster; +} + +/*------------------------------------------------------------------------- +//field context starts with a 0x13 + -----------------------------------------------------------------------*/ +void DomainMapper_Impl::PushFieldContext() +{ +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->element("pushFieldContext"); +#endif + + uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; + //insert a dummy char to make sure the start range doesn't move together with the to-be-appended text + xTextAppend->appendTextPortion(::rtl::OUString( '-' ), uno::Sequence< beans::PropertyValue >() ); + uno::Reference< text::XTextCursor > xCrsr = xTextAppend->createTextCursorByRange( xTextAppend->getEnd() ); + xCrsr->goLeft( 1, false ); + m_aFieldStack.push( FieldContextPtr( new FieldContext( xCrsr->getStart() ) ) ); +} +/*------------------------------------------------------------------------- +//the current field context waits for the completion of the command + -----------------------------------------------------------------------*/ +bool DomainMapper_Impl::IsOpenFieldCommand() const +{ + return !m_aFieldStack.empty() && !m_aFieldStack.top()->IsCommandCompleted(); +} +/*------------------------------------------------------------------------- +//the current field context waits for the completion of the command + -----------------------------------------------------------------------*/ +bool DomainMapper_Impl::IsOpenField() const +{ + return !m_aFieldStack.empty(); +} + + +FieldContext::FieldContext(uno::Reference< text::XTextRange > xStart) : + m_bFieldCommandCompleted( false ) + ,m_xStartRange( xStart ) +{ +} + + +FieldContext::~FieldContext() +{ +} + + +void FieldContext::AppendCommand(const ::rtl::OUString& rPart) +{ + m_sCommand += rPart; +} + +::std::vector<rtl::OUString> FieldContext::GetCommandParts() const +{ + ::std::vector<rtl::OUString> aResult; + sal_Int32 nIndex = 0; + bool bInString = false; + OUString sPart; + while (nIndex != -1) + { + OUString sToken = GetCommand().getToken(0, ' ', nIndex); + bool bInStringNext = bInString; + + if (sToken.getLength() == 0) + continue; + + if (sToken.getStr()[0] == '"') + { + bInStringNext = true; + sToken = sToken.copy(1); + } + if (sToken.getStr()[sToken.getLength() - 1] == '"') + { + bInStringNext = false; + sToken = sToken.copy(0, sToken.getLength() - 1); + } + + if (bInString) + { + if (bInStringNext) + { + sPart += OUString(' '); + sPart += sToken; + } + else + { + sPart += sToken; + aResult.push_back(sPart); + } + } + else + { + if (bInStringNext) + { + sPart = sToken; + } + else + { + aResult.push_back(sToken); + } + } + + bInString = bInStringNext; + } + + return aResult; +} + +/*------------------------------------------------------------------------- +//collect the pieces of the command + -----------------------------------------------------------------------*/ +void DomainMapper_Impl::AppendFieldCommand(::rtl::OUString& rPartOfCommand) +{ +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->startElement("appendFieldCommand"); + dmapper_logger->chars(rPartOfCommand); + dmapper_logger->endElement(); +#endif + + FieldContextPtr pContext = m_aFieldStack.top(); + OSL_ENSURE( pContext.get(), "no field context available"); + if( pContext.get() ) + { + pContext->AppendCommand( rPartOfCommand ); + } +} + + +typedef std::multimap < sal_Int32, ::rtl::OUString > TOCStyleMap; + +const FieldConversionMap_t & lcl_GetFieldConversion() +{ +static FieldConversionMap_t aFieldConversionMap; +static FieldConversionMap_t aEnhancedFieldConversionMap; + +static bool bFilled = false; + +if(!bFilled) +{ + static const FieldConversion aFields[] = + { +// {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ADDRESSBLOCK")), "", "", FIELD_ADDRESSBLOCK }, +// {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ADVANCE")), "", "", FIELD_ADVANCE }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ASK")), "SetExpression", "SetExpression", FIELD_ASK }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AUTONUM")), "SetExpression", "SetExpression", FIELD_AUTONUM }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AUTONUMLGL")), "SetExpression", "SetExpression", FIELD_AUTONUMLGL }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AUTONUMOUT")), "SetExpression", "SetExpression", FIELD_AUTONUMOUT }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AUTHOR")), "DocInfo.CreateAuthor", "", FIELD_AUTHOR }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DATE")), "DateTime", "", FIELD_DATE }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("COMMENTS")), "DocInfo.Description", "", FIELD_COMMENTS }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CREATEDATE")), "DocInfo.CreateDateTime", "", FIELD_CREATEDATE }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DOCPROPERTY")), "", "", FIELD_DOCPROPERTY }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DOCVARIABLE")), "User", "", FIELD_DOCVARIABLE }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("EDITTIME")), "DocInfo.EditTime", "", FIELD_EDITTIME }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FILLIN")), "Input", "", FIELD_FILLIN }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FILENAME")), "FileName", "", FIELD_FILENAME }, +// {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FILESIZE")), "", "", FIELD_FILESIZE }, +// {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FORMULA")), "", "", FIELD_FORMULA }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FORMCHECKBOX")), "", "", FIELD_FORMCHECKBOX}, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FORMDROPDOWN")), "DropDown", "", FIELD_FORMDROPDOWN}, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FORMTEXT")), "Input", "", FIELD_FORMTEXT}, +// {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GOTOBUTTON")), "", "", FIELD_GOTOBUTTON }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HYPERLINK")), "", "", FIELD_HYPERLINK }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IF")), "ConditionalText", "", FIELD_IF }, +// {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("INFO")), "","", FIELD_INFO }, +// {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("INCLUDEPICTURE")), "", "", FIELD_INCLUDEPICTURE}, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("KEYWORDS")), "DocInfo.KeyWords", "", FIELD_KEYWORDS }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("LASTSAVEDBY")), "DocInfo.ChangeAuthor", "", FIELD_LASTSAVEDBY }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MACROBUTTON")), "Macro", "", FIELD_MACROBUTTON }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MERGEFIELD")), "Database", "Database", FIELD_MERGEFIELD}, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MERGEREC")), "DatabaseNumberOfSet", "", FIELD_MERGEREC }, +// {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MERGESEQ")), "", "", FIELD_MERGESEQ }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NEXT")), "DatabaseNextSet", "", FIELD_NEXT }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NEXTIF")), "DatabaseNextSet", "", FIELD_NEXTIF }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PAGE")), "PageNumber", "", FIELD_PAGE }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("REF")), "GetReference", "", FIELD_REF }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("REVNUM")), "DocInfo.Revision", "", FIELD_REVNUM }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SAVEDATE")), "DocInfo.Change", "", FIELD_SAVEDATE }, +// {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SECTION")), "", "", FIELD_SECTION }, +// {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SECTIONPAGES")), "", "", FIELD_SECTIONPAGES }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SEQ")), "SetExpression", "SetExpression", FIELD_SEQ }, +// {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SET")), "","", FIELD_SET }, +// {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SKIPIF")),"", "", FIELD_SKIPIF }, +// {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("STYLEREF")),"", "", FIELD_STYLEREF }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SUBJECT")), "DocInfo.Subject", "", FIELD_SUBJECT }, +// {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SYMBOL")),"", "", FIELD_SYMBOL }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TEMPLATE")), "TemplateName", "", FIELD_TEMPLATE}, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TIME")), "DateTime", "", FIELD_TIME }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TITLE")), "DocInfo.Title", "", FIELD_TITLE }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("USERINITIALS")), "Author", "", FIELD_USERINITIALS }, +// {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("USERADDRESS")), "", "", FIELD_USERADDRESS }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("USERNAME")), "Author", "", FIELD_USERNAME }, + + + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TOC")), "com.sun.star.text.ContentIndex", "", FIELD_TOC}, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TC")), "com.sun.star.text.ContentIndexMark", "", FIELD_TC}, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NUMCHARS")), "CharacterCount", "", FIELD_NUMCHARS}, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NUMWORDS")), "WordCount", "", FIELD_NUMWORDS}, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NUMPAGES")), "PageCount", "", FIELD_NUMPAGES}, + +// {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("")), "", "", FIELD_}, + + }; + size_t nConversions = SAL_N_ELEMENTS(aFields); + for( size_t nConversion = 0; nConversion < nConversions; ++nConversion) + { + aFieldConversionMap.insert( FieldConversionMap_t::value_type( + aFields[nConversion].sWordCommand, + aFields[nConversion] )); + } + + bFilled = true; + } + + return aFieldConversionMap; +} + +const FieldConversionMap_t & lcl_GetEnhancedFieldConversion() +{ + static FieldConversionMap_t aEnhancedFieldConversionMap; + + static bool bFilled = false; + + if(!bFilled) + { + static const FieldConversion aEnhancedFields[] = + { + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FORMCHECKBOX")), "FormFieldmark", "", FIELD_FORMCHECKBOX}, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FORMDROPDOWN")), "FormFieldmark", "", FIELD_FORMDROPDOWN}, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FORMTEXT")), "Fieldmark", "", FIELD_FORMTEXT}, + }; + + size_t nConversions = SAL_N_ELEMENTS(aEnhancedFields); + for( size_t nConversion = 0; nConversion < nConversions; ++nConversion) + { + aEnhancedFieldConversionMap.insert( FieldConversionMap_t::value_type( + aEnhancedFields[nConversion].sWordCommand, + aEnhancedFields[nConversion] )); + } + } + return aEnhancedFieldConversionMap; +} + +void DomainMapper_Impl::handleFieldAsk + (FieldContextPtr pContext, + PropertyNameSupplier& rPropNameSupplier, + uno::Reference< uno::XInterface > & xFieldInterface, + uno::Reference< beans::XPropertySet > xFieldProperties) +{ + //doesn the command contain a variable name? + ::rtl::OUString sVariable, sHint; + + sVariable = lcl_ExctractAskVariableAndHint( pContext->GetCommand(), + sHint ); + if(sVariable.getLength()) + { + // determine field master name + uno::Reference< beans::XPropertySet > xMaster = + FindOrCreateFieldMaster + ("com.sun.star.text.FieldMaster.SetExpression", sVariable ); + + // attach the master to the field + uno::Reference< text::XDependentTextField > xDependentField + ( xFieldInterface, uno::UNO_QUERY_THROW ); + xDependentField->attachTextFieldMaster( xMaster ); + + // set input flag at the field + xFieldProperties->setPropertyValue( + rPropNameSupplier.GetName(PROP_IS_INPUT), uno::makeAny( true )); + // set the prompt + xFieldProperties->setPropertyValue( + rPropNameSupplier.GetName(PROP_HINT), + uno::makeAny( sHint )); + } + else + { + //don't insert the field + //todo: maybe import a 'normal' input field here? + xFieldInterface = 0; + } +} + +void DomainMapper_Impl::handleAutoNum + (FieldContextPtr pContext, + PropertyNameSupplier& rPropNameSupplier, + uno::Reference< uno::XInterface > & xFieldInterface, + uno::Reference< beans::XPropertySet > xFieldProperties) +{ + //create a sequence field master "AutoNr" + uno::Reference< beans::XPropertySet > xMaster = + FindOrCreateFieldMaster + ("com.sun.star.text.FieldMaster.SetExpression", + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AutoNr") )); + + xMaster->setPropertyValue( rPropNameSupplier.GetName(PROP_SUB_TYPE), + uno::makeAny(text::SetVariableType::SEQUENCE)); + + //apply the numbering type + xFieldProperties->setPropertyValue( + rPropNameSupplier.GetName(PROP_NUMBERING_TYPE), + uno::makeAny( lcl_ParseNumberingType(pContext->GetCommand()) )); + // attach the master to the field + uno::Reference< text::XDependentTextField > xDependentField + ( xFieldInterface, uno::UNO_QUERY_THROW ); + xDependentField->attachTextFieldMaster( xMaster ); +} + +void DomainMapper_Impl::handleAuthor + (FieldContextPtr pContext, + PropertyNameSupplier& rPropNameSupplier, + uno::Reference< uno::XInterface > & /*xFieldInterface*/, + uno::Reference< beans::XPropertySet > xFieldProperties, + FieldId eFieldId ) +{ + if ( eFieldId != FIELD_USERINITIALS ) + xFieldProperties->setPropertyValue + ( rPropNameSupplier.GetName(PROP_FULL_NAME), uno::makeAny( true )); + + sal_Int32 nLen = sizeof( " AUTHOR" ); + if ( eFieldId != FIELD_AUTHOR ) + { + if ( eFieldId == FIELD_USERINITIALS ) + nLen = sizeof( " USERINITIALS" ); + else if ( eFieldId == FIELD_USERNAME ) + nLen = sizeof( " USERNAME" ); + } + + ::rtl::OUString sParam = + lcl_ExtractParameter(pContext->GetCommand(), nLen ); + + if(sParam.getLength()) + { + xFieldProperties->setPropertyValue( + rPropNameSupplier.GetName( PROP_IS_FIXED ), + uno::makeAny( true )); + //PROP_CURRENT_PRESENTATION is set later anyway + } +} + + void DomainMapper_Impl::handleDocProperty + (FieldContextPtr pContext, + PropertyNameSupplier& rPropNameSupplier, + uno::Reference< uno::XInterface > & xFieldInterface, + uno::Reference< beans::XPropertySet > xFieldProperties) +{ + //some docproperties should be imported as document statistic fields, some as DocInfo fields + //others should be user fields + ::rtl::OUString sParam = + lcl_ExtractParameter(pContext->GetCommand(), sizeof(" DOCPROPERTY") ); + + if(sParam.getLength()) + { + #define SET_ARABIC 0x01 + #define SET_FULL_NAME 0x02 + #define SET_DATE 0x04 + struct DocPropertyMap + { + const sal_Char* pDocPropertyName; + const sal_Char* pServiceName; + sal_uInt8 nFlags; + }; + static const DocPropertyMap aDocProperties[] = + { + {"CreateTime", "DocInfo.CreateDateTime", SET_DATE}, + {"Characters", "CharacterCount", SET_ARABIC}, + {"Comments", "DocInfo.Description", 0}, + {"Keywords", "DocInfo.KeyWords", 0}, + {"LastPrinted", "DocInfo.PrintDateTime", 0}, + {"LastSavedBy", "DocInfo.ChangeAuthor", 0}, + {"LastSavedTime", "DocInfo.ChangeDateTime", SET_DATE}, + {"Paragraphs", "ParagraphCount", SET_ARABIC}, + {"RevisionNumber", "DocInfo.Revision", 0}, + {"Subject", "DocInfo.Subject", 0}, + {"Template", "TemplateName", 0}, + {"Title", "DocInfo.Title", 0}, + {"TotalEditingTime", "DocInfo.EditTime", 0}, + {"Words", "WordCount", SET_ARABIC} + + //other available DocProperties: + //Bytes, Category, CharactersWithSpaces, Company + //HyperlinkBase, + //Lines, Manager, NameofApplication, ODMADocId, Pages, + //Security, + }; + //search for a field mapping + ::rtl::OUString sFieldServiceName; + sal_uInt16 nMap = 0; + for( ; nMap < sizeof(aDocProperties) / sizeof(DocPropertyMap); + ++nMap ) + { + if(sParam.equalsAscii(aDocProperties[nMap].pDocPropertyName)) + { + sFieldServiceName = + ::rtl::OUString::createFromAscii + (aDocProperties[nMap].pServiceName); + break; + } + } + ::rtl::OUString sServiceName(RTL_CONSTASCII_USTRINGPARAM + ("com.sun.star.text.TextField.")); + bool bIsCustomField = false; + if(!sFieldServiceName.getLength()) + { + //create a custom property field + sServiceName += + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DocInfo.Custom")); + bIsCustomField = true; + } + else + { + sServiceName += sFieldServiceName; + } + xFieldInterface = m_xTextFactory->createInstance(sServiceName); + xFieldProperties = + uno::Reference< beans::XPropertySet >( xFieldInterface, + uno::UNO_QUERY_THROW); + if( bIsCustomField ) + xFieldProperties->setPropertyValue( + rPropNameSupplier.GetName(PROP_NAME), uno::makeAny( sParam )); + else + { + if(0 != (aDocProperties[nMap].nFlags & SET_ARABIC)) + xFieldProperties->setPropertyValue( + rPropNameSupplier.GetName(PROP_NUMBERING_TYPE), + uno::makeAny( style::NumberingType::ARABIC )); + else if(0 != (aDocProperties[nMap].nFlags & SET_FULL_NAME)) + xFieldProperties->setPropertyValue( + rPropNameSupplier.GetName(PROP_FULL_NAME), + uno::makeAny( true )); + else if(0 != (aDocProperties[nMap].nFlags & SET_DATE)) + { + xFieldProperties->setPropertyValue( + rPropNameSupplier.GetName(PROP_IS_DATE), + uno::makeAny( true )); + SetNumberFormat( pContext->GetCommand(), xFieldProperties ); + } + } + } + +#undef SET_ARABIC +#undef SET_FULL_NAME +#undef SET_DATE +} + +void DomainMapper_Impl::handleToc + (FieldContextPtr pContext, + PropertyNameSupplier& rPropNameSupplier, + uno::Reference< uno::XInterface > & /*xFieldInterface*/, + uno::Reference< beans::XPropertySet > /*xFieldProperties*/, + const ::rtl::OUString & sTOCServiceName) +{ + ::rtl::OUString sValue; + bool bTableOfFigures = false; + bool bHyperlinks = false; + bool bFromOutline = false; + bool bFromEntries = false; + sal_Int16 nMaxLevel = 10; + ::rtl::OUString sTemplate; + ::rtl::OUString sChapterNoSeparator; +// \a Builds a table of figures but does not include the captions's label and number + if( lcl_FindInCommand( pContext->GetCommand(), 'a', sValue )) + { //make it a table of figures + bTableOfFigures = true; + } +// \b Uses a bookmark to specify area of document from which to build table of contents +// if( lcl_FindInCommand( pContext->GetCommand(), 'b', sValue )) +// { //todo: sValue contains the bookmark name - unsupported feature +// } + if( lcl_FindInCommand( pContext->GetCommand(), 'c', sValue )) +// \c Builds a table of figures of the given label + { + //todo: sValue contains the label's name + bTableOfFigures = true; + } +// \d Defines the separator between sequence and page numbers + if( lcl_FindInCommand( pContext->GetCommand(), 'd', sValue )) + { + //todo: insert the chapter number into each level and insert the separator additionally + sChapterNoSeparator = sValue; + } +// \f Builds a table of contents using TC entries instead of outline levels + if( lcl_FindInCommand( pContext->GetCommand(), 'f', sValue )) + { + //todo: sValue can contain a TOC entry identifier - use unclear + bFromEntries = true; + } +// \h Hyperlinks the entries and page numbers within the table of contents + if( lcl_FindInCommand( pContext->GetCommand(), 'h', sValue )) + { + //todo: make all entries to hyperlinks + bHyperlinks = true; + } +// \l Defines the TC entries field level used to build a table of contents +// if( lcl_FindInCommand( pContext->GetCommand(), 'l', sValue )) +// { + //todo: entries can only be included completely +// } +// \n Builds a table of contents or a range of entries, sucah as �1-9�, in a table of contents without page numbers +// if( lcl_FindInCommand( pContext->GetCommand(), 'n', sValue )) +// { + //todo: what does the description mean? +// } +// \o Builds a table of contents by using outline levels instead of TC entries + if( lcl_FindInCommand( pContext->GetCommand(), 'o', sValue )) + { + bFromOutline = true; + UniString sParam( sValue ); + xub_StrLen nIndex = 0; + sParam.GetToken( 0, '-', nIndex ); + nMaxLevel = sal_Int16( sParam.Copy( nIndex ).ToInt32( ) ); + } +// \p Defines the separator between the table entry and its page number + if( lcl_FindInCommand( pContext->GetCommand(), 'p', sValue )) + { } +// \s Builds a table of contents by using a sequence type + if( lcl_FindInCommand( pContext->GetCommand(), 's', sValue )) + { } +// \t Builds a table of contents by using style names other than the standard outline styles + if( lcl_FindInCommand( pContext->GetCommand(), 't', sValue )) + { + sal_Int32 nPos = 0; + ::rtl::OUString sToken = sValue.getToken( 1, '"', nPos); + sTemplate = sToken.getLength() ? sToken : sValue; + } +// \u Builds a table of contents by using the applied paragraph outline level + if( lcl_FindInCommand( pContext->GetCommand(), 'u', sValue )) + { + bFromOutline = true; + //todo: what doesn 'the applied paragraph outline level' refer to? + } +// \w Preserve tab characters within table entries +// if( lcl_FindInCommand( pContext->GetCommand(), 'w', sValue )) +// { + //todo: not supported +// } +// \x Preserve newline characters within table entries +// if( lcl_FindInCommand( pContext->GetCommand(), 'x', sValue )) +// { + //todo: unsupported +// } +// \z Hides page numbers within the table of contens when shown in Web Layout View +// if( lcl_FindInCommand( pContext->GetCommand(), 'z', sValue )) +// { //todo: unsupported feature } + + //if there's no option then it should be created from outline + if( !bFromOutline && !bFromEntries && !sTemplate.getLength() ) + bFromOutline = true; + + uno::Reference< beans::XPropertySet > xTOC( + m_xTextFactory->createInstance + ( bTableOfFigures ? + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM + ("com.sun.star.text.IllustrationsIndex")) + : sTOCServiceName), + uno::UNO_QUERY_THROW); + xTOC->setPropertyValue(rPropNameSupplier.GetName( PROP_TITLE ), uno::makeAny(::rtl::OUString())); + if( !bTableOfFigures ) + { + xTOC->setPropertyValue( rPropNameSupplier.GetName( PROP_LEVEL ), uno::makeAny( nMaxLevel ) ); + xTOC->setPropertyValue( rPropNameSupplier.GetName( PROP_CREATE_FROM_OUTLINE ), uno::makeAny( bFromOutline )); + xTOC->setPropertyValue( rPropNameSupplier.GetName( PROP_CREATE_FROM_MARKS ), uno::makeAny( bFromEntries )); + if( sTemplate.getLength() ) + { + //the string contains comma separated the names and related levels + //like: "Heading 1,1,Heading 2,2" + TOCStyleMap aMap; + sal_Int32 nLevel; + sal_Int32 nPosition = 0; + while( nPosition >= 0) + { + ::rtl::OUString sStyleName = sTemplate.getToken( 0, ',', nPosition ); + //empty tokens should be skipped + while( !sStyleName.getLength() && nPosition > 0 ) + sStyleName = sTemplate.getToken( 0, ',', nPosition ); + nLevel = sTemplate.getToken( 0, ',', nPosition ).toInt32(); + if( !nLevel ) + nLevel = 1; + if( sStyleName.getLength() ) + aMap.insert( TOCStyleMap::value_type(nLevel, sStyleName) ); + } + uno::Reference< container::XIndexReplace> xParaStyles; + xTOC->getPropertyValue(rPropNameSupplier.GetName(PROP_LEVEL_PARAGRAPH_STYLES)) >>= xParaStyles; + for( nLevel = 1; nLevel < 10; ++nLevel) + { + sal_Int32 nLevelCount = aMap.count( nLevel ); + if( nLevelCount ) + { + TOCStyleMap::iterator aTOCStyleIter = aMap.find( nLevel ); + + uno::Sequence< rtl::OUString> aStyles( nLevelCount ); + for ( sal_Int32 nStyle = 0; nStyle < nLevelCount; ++nStyle, ++aTOCStyleIter ) + { + aStyles[nStyle] = aTOCStyleIter->second; + } + xParaStyles->replaceByIndex(nLevel - 1, uno::makeAny(aStyles)); + } + } + xTOC->setPropertyValue(rPropNameSupplier.GetName(PROP_CREATE_FROM_LEVEL_PARAGRAPH_STYLES), uno::makeAny( true )); + + } + if(bHyperlinks || sChapterNoSeparator.getLength()) + { + uno::Reference< container::XIndexReplace> xLevelFormats; + xTOC->getPropertyValue(rPropNameSupplier.GetName(PROP_LEVEL_FORMAT)) >>= xLevelFormats; + sal_Int32 nLevelCount = xLevelFormats->getCount(); + //start with level 1, 0 is the header level + for( sal_Int32 nLevel = 1; nLevel < nLevelCount; ++nLevel) + { + uno::Sequence< beans::PropertyValues > aLevel; + xLevelFormats->getByIndex( nLevel ) >>= aLevel; + //create a copy of the level and add two new entries - hyperlink start and end + bool bChapterNoSeparator = sChapterNoSeparator.getLength() > 0; + sal_Int32 nAdd = (bHyperlinks && bChapterNoSeparator) ? 4 : 2; + uno::Sequence< beans::PropertyValues > aNewLevel( aLevel.getLength() + nAdd); + beans::PropertyValues* pNewLevel = aNewLevel.getArray(); + if( bHyperlinks ) + { + beans::PropertyValues aHyperlink(1); + aHyperlink[0].Name = rPropNameSupplier.GetName( PROP_TOKEN_TYPE ); + aHyperlink[0].Value <<= rPropNameSupplier.GetName( PROP_TOKEN_HYPERLINK_START ); + pNewLevel[0] = aHyperlink; + aHyperlink[0].Value <<= rPropNameSupplier.GetName( PROP_TOKEN_HYPERLINK_END ); + pNewLevel[aNewLevel.getLength() -1] = aHyperlink; + } + if( bChapterNoSeparator ) + { + beans::PropertyValues aChapterNo(2); + aChapterNo[0].Name = rPropNameSupplier.GetName( PROP_TOKEN_TYPE ); + aChapterNo[0].Value <<= rPropNameSupplier.GetName( PROP_TOKEN_CHAPTER_INFO ); + aChapterNo[1].Name = rPropNameSupplier.GetName( PROP_CHAPTER_FORMAT ); + //todo: is ChapterFormat::Number correct? + aChapterNo[1].Value <<= (sal_Int16)text::ChapterFormat::NUMBER; + pNewLevel[aNewLevel.getLength() - (bHyperlinks ? 4 : 2) ] = aChapterNo; + + beans::PropertyValues aChapterSeparator(2); + aChapterSeparator[0].Name = rPropNameSupplier.GetName( PROP_TOKEN_TYPE ); + aChapterSeparator[0].Value <<= rPropNameSupplier.GetName( PROP_TOKEN_TEXT ); + aChapterSeparator[1].Name = rPropNameSupplier.GetName( PROP_TEXT ); + aChapterSeparator[1].Value <<= sChapterNoSeparator; + pNewLevel[aNewLevel.getLength() - (bHyperlinks ? 3 : 1)] = aChapterSeparator; + } + //copy the 'old' entries except the last (page no) + for( sal_Int32 nToken = 0; nToken < aLevel.getLength() - 1; ++nToken) + { + pNewLevel[nToken + 1] = aLevel[nToken]; + } + //copy page no entry (last or last but one depending on bHyperlinks + sal_Int32 nPageNo = aNewLevel.getLength() - (bHyperlinks ? 2 : 3); + pNewLevel[nPageNo] = aLevel[aLevel.getLength() - 1]; + + xLevelFormats->replaceByIndex( nLevel, uno::makeAny( aNewLevel ) ); + } + } + } + pContext->SetTOC( xTOC ); +} + + +/*------------------------------------------------------------------------- +//the field command has to be closed (0x14 appeared) + -----------------------------------------------------------------------*/ +void DomainMapper_Impl::CloseFieldCommand() +{ +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->element("closeFieldCommand"); +#endif + + FieldContextPtr pContext = m_aFieldStack.top(); + OSL_ENSURE( pContext.get(), "no field context available"); + if( pContext.get() ) + { + m_bSetUserFieldContent = false; + FieldConversionMap_t aFieldConversionMap = lcl_GetFieldConversion(); + bool bCreateEnhancedField = false; + + try + { + uno::Reference< uno::XInterface > xFieldInterface; + //at first determine the field type - erase leading and trailing whitespaces + ::rtl::OUString sCommand( pContext->GetCommand().trim() ); + sal_Int32 nSpaceIndex = sCommand.indexOf( ' ' ); + if( 0 <= nSpaceIndex ) + sCommand = sCommand.copy( 0, nSpaceIndex ); + + FieldConversionMap_t::iterator aIt = aFieldConversionMap.find(sCommand); + if(aIt != aFieldConversionMap.end()) + { + uno::Reference< beans::XPropertySet > xFieldProperties; + bool bCreateField = true; + switch (aIt->second.eFieldId) + { + case FIELD_HYPERLINK: + case FIELD_DOCPROPERTY: + case FIELD_TOC: + case FIELD_TC: + bCreateField = false; + break; + case FIELD_FORMCHECKBOX : + case FIELD_FORMTEXT : + case FIELD_FORMDROPDOWN : + { + // If we use 'enhanced' fields then FIELD_FORMCHECKBOX, + // FIELD_FORMTEXT & FIELD_FORMDROPDOWN are treated specially + if ( m_bUsingEnhancedFields ) + { + bCreateField = false; + bCreateEnhancedField = true; + } + // for non enhanced fields checkboxes are displayed + // as an awt control not a field + else if ( aIt->second.eFieldId == FIELD_FORMCHECKBOX ) + bCreateField = false; + break; + } + default: + break; + } + + if( bCreateField || bCreateEnhancedField ) + { + //add the service prefix + OUString sServiceName(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.")); + if ( bCreateEnhancedField ) + { + FieldConversionMap_t aEnhancedFieldConversionMap = lcl_GetEnhancedFieldConversion(); + FieldConversionMap_t::iterator aEnhancedIt = aEnhancedFieldConversionMap.find(sCommand); + if ( aEnhancedIt != aEnhancedFieldConversionMap.end()) + sServiceName += ::rtl::OUString::createFromAscii(aEnhancedIt->second.cFieldServiceName ); + } + else + { + sServiceName += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("TextField.")); + sServiceName += ::rtl::OUString::createFromAscii(aIt->second.cFieldServiceName ); + } + +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->startElement("fieldService"); + dmapper_logger->chars(sServiceName); + dmapper_logger->endElement(); +#endif + + xFieldInterface = m_xTextFactory->createInstance(sServiceName); + xFieldProperties = uno::Reference< beans::XPropertySet >( xFieldInterface, uno::UNO_QUERY_THROW); + } + PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + switch( aIt->second.eFieldId ) + { + case FIELD_ADDRESSBLOCK: break; + case FIELD_ADVANCE : break; + case FIELD_ASK : + handleFieldAsk(pContext, rPropNameSupplier, xFieldInterface, xFieldProperties); + break; + case FIELD_AUTONUM : + case FIELD_AUTONUMLGL : + case FIELD_AUTONUMOUT : + handleAutoNum(pContext, rPropNameSupplier, xFieldInterface, xFieldProperties); + break; + case FIELD_AUTHOR : + case FIELD_USERNAME : + case FIELD_USERINITIALS : + handleAuthor(pContext, rPropNameSupplier, xFieldInterface, xFieldProperties, aIt->second.eFieldId ); + break; + case FIELD_DATE: + { + //not fixed, + xFieldProperties->setPropertyValue( + rPropNameSupplier.GetName(PROP_IS_FIXED), + uno::makeAny( false )); + xFieldProperties->setPropertyValue( + rPropNameSupplier.GetName(PROP_IS_DATE), + uno::makeAny( true )); + SetNumberFormat( pContext->GetCommand(), xFieldProperties ); + } + break; + case FIELD_COMMENTS : + { + ::rtl::OUString sParam = lcl_ExtractParameter(pContext->GetCommand(), sizeof(" COMMENTS") ); + // A parameter with COMMENTS shouldn't set fixed + // ( or at least the binary filter doesn't ) + // If we set fixed then we wont export a field cmd. + // Additionally the para in COMMENTS is more like an + // instruction to set the document property comments + // with the param ( e.g. each COMMENT with a param will + // overwrite the Comments document property + // #TODO implement the above too + xFieldProperties->setPropertyValue( + rPropNameSupplier.GetName( PROP_IS_FIXED ), uno::makeAny( false )); + //PROP_CURRENT_PRESENTATION is set later anyway + } + break; + case FIELD_CREATEDATE : + { + xFieldProperties->setPropertyValue( + rPropNameSupplier.GetName( PROP_IS_DATE ), uno::makeAny( true )); + SetNumberFormat( pContext->GetCommand(), xFieldProperties ); + } + break; + case FIELD_DOCPROPERTY : + handleDocProperty(pContext, rPropNameSupplier, xFieldInterface, xFieldProperties); + break; + case FIELD_DOCVARIABLE : + { + ::rtl::OUString sParam = lcl_ExtractParameter(pContext->GetCommand(), sizeof(" DOCVARIABLE") ); + //create a user field and type + uno::Reference< beans::XPropertySet > xMaster = + FindOrCreateFieldMaster( "com.sun.star.text.FieldMaster.User", sParam ); + uno::Reference< text::XDependentTextField > xDependentField( xFieldInterface, uno::UNO_QUERY_THROW ); + xDependentField->attachTextFieldMaster( xMaster ); + m_bSetUserFieldContent = true; + } + break; + case FIELD_EDITTIME : + //it's a numbering type, no number format! SetNumberFormat( pContext->GetCommand(), xFieldProperties ); + break; + case FIELD_FILLIN : + { + sal_Int32 nIndex = 0; + xFieldProperties->setPropertyValue( + rPropNameSupplier.GetName(PROP_HINT), uno::makeAny( pContext->GetCommand().getToken( 1, '\"', nIndex))); + } + break; + case FIELD_FILENAME: + { + sal_Int32 nNumberingTypeIndex = pContext->GetCommand().indexOf( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\\p"))); + xFieldProperties->setPropertyValue( + rPropNameSupplier.GetName(PROP_FILE_FORMAT), + uno::makeAny( nNumberingTypeIndex > 0 ? text::FilenameDisplayFormat::FULL : text::FilenameDisplayFormat::NAME )); + } + break; + case FIELD_FILESIZE : break; + case FIELD_FORMULA : break; + case FIELD_FORMCHECKBOX : + case FIELD_FORMDROPDOWN : + case FIELD_FORMTEXT : + { + uno::Reference< text::XTextField > xTextField( xFieldInterface, uno::UNO_QUERY ); + if ( !xTextField.is() ) + { + FFDataHandler::Pointer_t + pFFDataHandler(pContext->getFFDataHandler()); + FormControlHelper::Pointer_t + pFormControlHelper(new FormControlHelper + (m_bUsingEnhancedFields ? aIt->second.eFieldId : FIELD_FORMCHECKBOX, + + m_xTextDocument, pFFDataHandler)); + pContext->setFormControlHelper(pFormControlHelper); + uno::Reference< text::XFormField > xFormField( xFieldInterface, uno::UNO_QUERY ); + uno::Reference< container::XNamed > xNamed( xFormField, uno::UNO_QUERY ); + if ( xNamed.is() ) + { + if ( pFFDataHandler && pFFDataHandler->getName().getLength() ) + xNamed->setName( pFFDataHandler->getName() ); + pContext->SetFormField( xFormField ); + } + } + else + { + if ( aIt->second.eFieldId == FIELD_FORMDROPDOWN ) + lcl_handleDropdownField( xFieldProperties, pContext->getFFDataHandler() ); + else + lcl_handleTextField( xFieldProperties, pContext->getFFDataHandler(), rPropNameSupplier ); + } + } + break; + case FIELD_GOTOBUTTON : break; + case FIELD_HYPERLINK: + { + ::std::vector<rtl::OUString> aParts = pContext->GetCommandParts(); + ::std::vector<rtl::OUString>::const_iterator aItEnd = aParts.end(); + ::std::vector<rtl::OUString>::const_iterator aPartIt = aParts.begin(); + + OUString sURL; + + while (aPartIt != aItEnd) + { + if (aPartIt->equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("\\l"))) + { + aPartIt++; + + if (aPartIt == aItEnd) + break; + + sURL = OUString('#'); + sURL += *aPartIt; + } + else if (aPartIt->equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("\\m")) || + aPartIt->equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("\\n"))) + { + } + else if (aPartIt->equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("\\o")) || + aPartIt->equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("\\t"))) + { + aPartIt++; + + if (aPartIt == aItEnd) + break; + } + else + { + sURL = *aPartIt; + } + + aPartIt++; + } + + if (sURL.getLength() > 0) + { + pContext->SetHyperlinkURL(sURL); + } + } + break; + case FIELD_IF : break; + case FIELD_INFO : break; + case FIELD_INCLUDEPICTURE: break; + case FIELD_KEYWORDS : + { + ::rtl::OUString sParam = lcl_ExtractParameter(pContext->GetCommand(), sizeof(" KEYWORDS") ); + if(sParam.getLength()) + { + xFieldProperties->setPropertyValue( + rPropNameSupplier.GetName( PROP_IS_FIXED ), uno::makeAny( true )); + //PROP_CURRENT_PRESENTATION is set later anyway + } + } + break; + case FIELD_LASTSAVEDBY : break; + case FIELD_MACROBUTTON: + { + //extract macro name + sal_Int32 nIndex = sizeof(" MACROBUTTON "); + ::rtl::OUString sMacro = pContext->GetCommand().getToken( 0, ' ', nIndex); + xFieldProperties->setPropertyValue( + rPropNameSupplier.GetName(PROP_MACRO_NAME), uno::makeAny( sMacro )); + + //extract quick help text + if( pContext->GetCommand().getLength() > nIndex + 1) + { + xFieldProperties->setPropertyValue( + rPropNameSupplier.GetName(PROP_HINT), + uno::makeAny( pContext->GetCommand().copy( nIndex ))); + } + } + break; + case FIELD_MERGEFIELD : + { + //todo: create a database field and fieldmaster pointing to a column, only + ::rtl::OUString sParam = lcl_ExtractParameter(pContext->GetCommand(), sizeof(" MERGEFIELD") ); + //create a user field and type + uno::Reference< beans::XPropertySet > xMaster = + FindOrCreateFieldMaster( "com.sun.star.text.FieldMaster.Database", sParam ); + + // xFieldProperties->setPropertyValue( + // ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FieldCode")), + // uno::makeAny( pContext->GetCommand().copy( nIndex + 1 ))); + uno::Reference< text::XDependentTextField > xDependentField( xFieldInterface, uno::UNO_QUERY_THROW ); + xDependentField->attachTextFieldMaster( xMaster ); + m_bSetUserFieldContent = true; + } + break; + case FIELD_MERGEREC : break; + case FIELD_MERGESEQ : break; + case FIELD_NEXT : break; + case FIELD_NEXTIF : break; + case FIELD_PAGE : + xFieldProperties->setPropertyValue( + rPropNameSupplier.GetName(PROP_NUMBERING_TYPE), + uno::makeAny( lcl_ParseNumberingType(pContext->GetCommand()) )); + xFieldProperties->setPropertyValue( + rPropNameSupplier.GetName(PROP_SUB_TYPE), + uno::makeAny( text::PageNumberType_CURRENT )); + + break; + case FIELD_REF: + { + ::rtl::OUString sBookmark = lcl_ExtractParameter(pContext->GetCommand(), sizeof(" REF") ); + xFieldProperties->setPropertyValue( + rPropNameSupplier.GetName(PROP_REFERENCE_FIELD_SOURCE), + uno::makeAny( sal_Int16(text::ReferenceFieldSource::BOOKMARK)) ); + xFieldProperties->setPropertyValue( + rPropNameSupplier.GetName(PROP_SOURCE_NAME), + uno::makeAny( sBookmark) ); + sal_Int16 nFieldPart = text::ReferenceFieldPart::TEXT; + ::rtl::OUString sValue; + if( lcl_FindInCommand( pContext->GetCommand(), 'p', sValue )) + { + //above-below + nFieldPart = text::ReferenceFieldPart::UP_DOWN; + } + xFieldProperties->setPropertyValue( + rPropNameSupplier.GetName( PROP_REFERENCE_FIELD_PART ), uno::makeAny( nFieldPart )); + } + break; + case FIELD_REVNUM : break; + case FIELD_SAVEDATE : + SetNumberFormat( pContext->GetCommand(), xFieldProperties ); + break; + case FIELD_SECTION : break; + case FIELD_SECTIONPAGES : break; + case FIELD_SEQ : break; + case FIELD_SET : break; + case FIELD_SKIPIF : break; + case FIELD_STYLEREF : break; + case FIELD_SUBJECT : + { + ::rtl::OUString sParam = lcl_ExtractParameter(pContext->GetCommand(), sizeof(" SUBJECT") ); + if(sParam.getLength()) + { + xFieldProperties->setPropertyValue( + rPropNameSupplier.GetName( PROP_IS_FIXED ), uno::makeAny( true )); + //PROP_CURRENT_PRESENTATION is set later anyway + } + } + break; + case FIELD_SYMBOL : break; + case FIELD_TEMPLATE: break; + case FIELD_TIME : + SetNumberFormat( pContext->GetCommand(), xFieldProperties ); + break; + case FIELD_TITLE : + { + ::rtl::OUString sParam = lcl_ExtractParameter(pContext->GetCommand(), sizeof(" TITLE") ); + if(sParam.getLength()) + { + xFieldProperties->setPropertyValue( + rPropNameSupplier.GetName( PROP_IS_FIXED ), uno::makeAny( true )); + //PROP_CURRENT_PRESENTATION is set later anyway + } + } + break; + case FIELD_USERADDRESS : //todo: user address collects street, city ... + break; + case FIELD_TOC: + handleToc(pContext, rPropNameSupplier, xFieldInterface, xFieldProperties, + ::rtl::OUString::createFromAscii(aIt->second.cFieldServiceName)); + break; + case FIELD_TC : + { + uno::Reference< beans::XPropertySet > xTC( + m_xTextFactory->createInstance( + ::rtl::OUString::createFromAscii(aIt->second.cFieldServiceName)), + uno::UNO_QUERY_THROW); + ::rtl::OUString sTCText = lcl_ExtractParameter(pContext->GetCommand(), sizeof(" TC") ); + if( sTCText.getLength()) + xTC->setPropertyValue(rPropNameSupplier.GetName(PROP_ALTERNATIVE_TEXT), + uno::makeAny(sTCText)); + ::rtl::OUString sValue; + // \f TC entry in doc with multiple tables + // if( lcl_FindInCommand( pContext->GetCommand(), 'f', sValue )) + // { + // todo: unsupported + // } + if( lcl_FindInCommand( pContext->GetCommand(), 'l', sValue )) + // \l Outline Level + { + sal_Int32 nLevel = sValue.toInt32(); + if( sValue.getLength() && nLevel >= 0 && nLevel <= 10 ) + xTC->setPropertyValue(rPropNameSupplier.GetName(PROP_LEVEL), uno::makeAny( (sal_Int16)nLevel )); + } + // if( lcl_FindInCommand( pContext->GetCommand(), 'n', sValue )) + // \n Suppress page numbers + // { + //todo: unsupported feature + // } + pContext->SetTC( xTC ); + } + break; + case FIELD_NUMCHARS: + case FIELD_NUMWORDS: + case FIELD_NUMPAGES: + xFieldProperties->setPropertyValue( + rPropNameSupplier.GetName(PROP_NUMBERING_TYPE), + uno::makeAny( lcl_ParseNumberingType(pContext->GetCommand()) )); + break; + + } + } + //set the text field if there is any + pContext->SetTextField( uno::Reference< text::XTextField >( xFieldInterface, uno::UNO_QUERY ) ); + } + catch( uno::Exception& rEx) + { + (void)rEx; + OSL_FAIL( "Exception in CloseFieldCommand()" ); + } + pContext->SetCommandCompleted(); + } +} +/*------------------------------------------------------------------------- +//the _current_ fields require a string type result while TOCs accept richt results + -----------------------------------------------------------------------*/ +bool DomainMapper_Impl::IsFieldResultAsString() +{ + bool bRet = false; + OSL_ENSURE( !m_aFieldStack.empty(), "field stack empty?"); + FieldContextPtr pContext = m_aFieldStack.top(); + OSL_ENSURE( pContext.get(), "no field context available"); + if( pContext.get() ) + { + bRet = pContext->GetTextField().is(); + } + return bRet; +} + + +void DomainMapper_Impl::SetFieldResult( ::rtl::OUString& rResult ) +{ +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->startElement("setFieldResult"); + dmapper_logger->chars(rResult); +#endif + + FieldContextPtr pContext = m_aFieldStack.top(); + OSL_ENSURE( pContext.get(), "no field context available"); + if( pContext.get() ) + { + uno::Reference<text::XTextField> xTextField = pContext->GetTextField(); + try + { + PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + OSL_ENSURE( xTextField.is() + //||m_xTOC.is() ||m_xTC.is() + //||m_sHyperlinkURL.getLength() + , "DomainMapper_Impl::SetFieldResult: field not created" ); + if(xTextField.is()) + { + try + { + if( m_bSetUserFieldContent ) + { + // user field content has to be set at the field master + uno::Reference< text::XDependentTextField > xDependentField( xTextField, uno::UNO_QUERY_THROW ); + xDependentField->getTextFieldMaster()->setPropertyValue( + rPropNameSupplier.GetName(PROP_CONTENT), + uno::makeAny( rResult )); + } + else + { + uno::Reference< beans::XPropertySet > xFieldProperties( xTextField, uno::UNO_QUERY_THROW); + xFieldProperties->setPropertyValue( + rPropNameSupplier.GetName(PROP_CURRENT_PRESENTATION), + uno::makeAny( rResult )); + } + } + catch( const beans::UnknownPropertyException& ) + { + //some fields don't have a CurrentPresentation (DateTime) + } + } + } + catch( uno::Exception& ) + { + + } + } +} + +void DomainMapper_Impl::SetFieldFFData(FFDataHandler::Pointer_t pFFDataHandler) +{ +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->startElement("setFieldFFData"); +#endif + + FieldContextPtr pContext = m_aFieldStack.top(); + if (pContext.get()) + { + pContext->setFFDataHandler(pFFDataHandler); + } + +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->endElement(); +#endif +} + +/*------------------------------------------------------------------------- +//the end of field is reached (0x15 appeared) - the command might still be open + -----------------------------------------------------------------------*/ +void DomainMapper_Impl::PopFieldContext() +{ +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->element("popFieldContext"); +#endif + + FieldContextPtr pContext = m_aFieldStack.top(); + OSL_ENSURE( pContext.get(), "no field context available"); + if( pContext.get() ) + { + if( !pContext->IsCommandCompleted() ) + CloseFieldCommand(); + + //insert the field, TC or TOC + uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; + if(xTextAppend.is()) + { + try + { + uno::Reference< text::XTextCursor > xCrsr = xTextAppend->createTextCursorByRange(pContext->GetStartRange()); + //remove the dummy character + xCrsr->goRight( 1, true ); + xCrsr->setString( ::rtl::OUString() ); + uno::Reference< text::XTextContent > xToInsert( pContext->GetTOC(), uno::UNO_QUERY ); + if( xToInsert.is() ) + { + xCrsr->gotoEnd( true ); + xToInsert->attach( uno::Reference< text::XTextRange >( xCrsr, uno::UNO_QUERY_THROW )); + } + else + { + xToInsert = uno::Reference< text::XTextContent >(pContext->GetTC(), uno::UNO_QUERY); + if( !xToInsert.is() ) + xToInsert = uno::Reference< text::XTextContent >(pContext->GetTextField(), uno::UNO_QUERY); + if( xToInsert.is() ) + { + uno::Reference< text::XTextAppendAndConvert > xTextAppendAndConvert( xTextAppend, uno::UNO_QUERY_THROW ); + xTextAppendAndConvert->appendTextContent( xToInsert, uno::Sequence< beans::PropertyValue >() ); + } + else + { + FormControlHelper::Pointer_t pFormControlHelper(pContext->getFormControlHelper()); + if (pFormControlHelper.get() != NULL && pFormControlHelper->hasFFDataHandler() ) + { + uno::Reference< text::XFormField > xFormField( pContext->GetFormField() ); + xToInsert.set(xFormField, uno::UNO_QUERY); + if ( xFormField.is() && xToInsert.is() ) + { + xCrsr->gotoEnd( true ); + xToInsert->attach( uno::Reference< text::XTextRange >( xCrsr, uno::UNO_QUERY_THROW )); + pFormControlHelper->processField( xFormField ); + } + else + { + uno::Reference<text::XTextRange> xTxtRange(xCrsr, uno::UNO_QUERY); + pFormControlHelper->insertControl(xTxtRange); + } + } + else if(pContext->GetHyperlinkURL().getLength()) + { + PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + xCrsr->gotoEnd( true ); + + uno::Reference< beans::XPropertySet > xCrsrProperties( xCrsr, uno::UNO_QUERY_THROW ); + xCrsrProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_HYPER_LINK_U_R_L), uno:: + makeAny(pContext->GetHyperlinkURL())); + } + } + } + } + catch(const lang::IllegalArgumentException& ) + { + OSL_FAIL( "IllegalArgumentException in PopFieldContext()" ); + } + catch(const uno::Exception& ) + { + OSL_FAIL( "exception in PopFieldContext()" ); + } + } + // + //TOCs have to include all the imported content + //... + } + //remove the field context + m_aFieldStack.pop(); +} + + +void DomainMapper_Impl::AddBookmark( const ::rtl::OUString& rBookmarkName, const ::rtl::OUString& rId ) +{ + uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; + BookmarkMap_t::iterator aBookmarkIter = m_aBookmarkMap.find( rId ); + //is the bookmark name already registered? + try + { + if( aBookmarkIter != m_aBookmarkMap.end() ) + { + static const rtl::OUString sBookmarkService(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.Bookmark")); + uno::Reference< text::XTextContent > xBookmark( m_xTextFactory->createInstance( sBookmarkService ), uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextCursor > xCursor; + uno::Reference< text::XText > xText = aBookmarkIter->second.m_xTextRange->getText(); + if( aBookmarkIter->second.m_bIsStartOfText ) + xCursor = xText->createTextCursorByRange( xText->getStart() ); + else + { + xCursor = xText->createTextCursorByRange( aBookmarkIter->second.m_xTextRange ); + xCursor->goRight( 1, false ); + } + + xCursor->gotoRange( xTextAppend->getEnd(), true ); + uno::Reference< container::XNamed > xBkmNamed( xBookmark, uno::UNO_QUERY_THROW ); + //todo: make sure the name is not used already! + xBkmNamed->setName( aBookmarkIter->second.m_sBookmarkName ); + xTextAppend->insertTextContent( uno::Reference< text::XTextRange >( xCursor, uno::UNO_QUERY_THROW), xBookmark, !xCursor->isCollapsed() ); + m_aBookmarkMap.erase( aBookmarkIter ); + } + else + { + //otherwise insert a text range as marker + uno::Reference< text::XTextCursor > xCursor = xTextAppend->createTextCursorByRange( xTextAppend->getEnd() ); + bool bIsStart = !xCursor->goLeft(1, false); + uno::Reference< text::XTextRange > xCurrent = xCursor->getStart(); + m_aBookmarkMap.insert(BookmarkMap_t::value_type( rId, BookmarkInsertPosition( bIsStart, rBookmarkName, xCurrent ) )); + } + } + catch( const uno::Exception& ) + { + //TODO: What happens to bookmarks where start and end are at different XText objects? + } +} + + +GraphicImportPtr DomainMapper_Impl::GetGraphicImport(GraphicImportType eGraphicImportType) +{ + if(!m_pGraphicImport) + m_pGraphicImport.reset( new GraphicImport( m_xComponentContext, m_xTextFactory, m_rDMapper, eGraphicImportType ) ); + return m_pGraphicImport; +} +/*------------------------------------------------------------------------- + reset graphic import if the last import resulted in a shape, not a graphic + -----------------------------------------------------------------------*/ +void DomainMapper_Impl::ResetGraphicImport() +{ + m_pGraphicImport.reset(); +} + + +void DomainMapper_Impl::ImportGraphic(writerfilter::Reference< Properties >::Pointer_t ref, GraphicImportType eGraphicImportType) +{ + GetGraphicImport(eGraphicImportType); + if( eGraphicImportType != IMPORT_AS_DETECTED_INLINE && eGraphicImportType != IMPORT_AS_DETECTED_ANCHOR ) + { + //create the graphic + ref->resolve( *m_pGraphicImport ); + } + + //insert it into the document at the current cursor position + + uno::Reference<text::XTextContent> xTextContent + (m_pGraphicImport->GetGraphicObject()); + + //insert it into the document at the current cursor position + OSL_ENSURE( xTextContent.is(), "DomainMapper_Impl::ImportGraphic"); + if( xTextContent.is()) + appendTextContent( xTextContent, uno::Sequence< beans::PropertyValue >() ); + + m_pGraphicImport.reset(); +} + + + +void DomainMapper_Impl::SetLineNumbering( sal_Int32 nLnnMod, sal_Int32 nLnc, sal_Int32 ndxaLnn ) +{ + if( !m_bLineNumberingSet ) + { + const PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + + try + { + uno::Reference< text::XLineNumberingProperties > xLineProperties( m_xTextDocument, uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xProperties = xLineProperties->getLineNumberingProperties(); + uno::Any aTrue( uno::makeAny( true )); + xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_IS_ON ), aTrue); + xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_COUNT_EMPTY_LINES ), aTrue ); + xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_COUNT_LINES_IN_FRAMES ), uno::makeAny( false ) ); + xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_INTERVAL ), uno::makeAny( static_cast< sal_Int16 >( nLnnMod ))); + xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_DISTANCE ), uno::makeAny( ConversionHelper::convertTwipToMM100(ndxaLnn) )); + xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_NUMBER_POSITION ), uno::makeAny( style::LineNumberPosition::LEFT)); + xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_NUMBERING_TYPE ), uno::makeAny( style::NumberingType::ARABIC)); + xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_RESTART_AT_EACH_PAGE ), uno::makeAny( nLnc == 0 )); + } + catch( const uno::Exception& ) + {} + + + +/* + { SW_PROP_NAME(UNO_NAME_CHAR_STYLE_NAME + { SW_PROP_NAME(UNO_NAME_COUNT_EMPTY_LINES + { SW_PROP_NAME(UNO_NAME_COUNT_LINES_IN_FRAMES + { SW_PROP_NAME(UNO_NAME_DISTANCE + { SW_PROP_NAME(UNO_NAME_IS_ON + { SW_PROP_NAME(UNO_NAME_INTERVAL + { SW_PROP_NAME(UNO_NAME_SEPARATOR_TEXT + { SW_PROP_NAME(UNO_NAME_NUMBER_POSITION + { SW_PROP_NAME(UNO_NAME_NUMBERING_TYPE + { SW_PROP_NAME(UNO_NAME_RESTART_AT_EACH_PAGE + { SW_PROP_NAME(UNO_NAME_SEPARATOR_INTERVAL +*/ + } + m_bLineNumberingSet = true; +} + + +void DomainMapper_Impl::SetPageMarginTwip( PageMarElement eElement, sal_Int32 nValue ) +{ + nValue = ConversionHelper::convertTwipToMM100(nValue); + switch(eElement) + { + case PAGE_MAR_TOP : m_aPageMargins.top = nValue; break; + case PAGE_MAR_RIGHT : m_aPageMargins.right = nValue; break; + case PAGE_MAR_BOTTOM : m_aPageMargins.bottom = nValue; break; + case PAGE_MAR_LEFT : m_aPageMargins.left = nValue; break; + case PAGE_MAR_HEADER : m_aPageMargins.header = nValue; break; + case PAGE_MAR_FOOTER : m_aPageMargins.footer = nValue; break; + case PAGE_MAR_GUTTER : m_aPageMargins.gutter = nValue; break; + } +} + + + +_PageMar::_PageMar() +{ + header = footer = top = bottom = ConversionHelper::convertTwipToMM100( sal_Int32(1440)); + right = left = ConversionHelper::convertTwipToMM100( sal_Int32(1800)); + gutter = 0; +} + + + +void DomainMapper_Impl::RegisterFrameConversion( + uno::Reference< text::XTextRange > xFrameStartRange, + uno::Reference< text::XTextRange > xFrameEndRange, + uno::Sequence< beans::PropertyValue > aFrameProperties + ) +{ + OSL_ENSURE( + !m_aFrameProperties.getLength() && !m_xFrameStartRange.is() && !m_xFrameEndRange.is(), + "frame properties not removed"); + m_aFrameProperties = aFrameProperties; + m_xFrameStartRange = xFrameStartRange; + m_xFrameEndRange = xFrameEndRange; +} + + +bool DomainMapper_Impl::ExecuteFrameConversion() +{ + bool bRet = false; + if( m_xFrameStartRange.is() && m_xFrameEndRange.is() ) + { + bRet = true; + try + { + uno::Reference< text::XTextAppendAndConvert > xTextAppendAndConvert( GetTopTextAppend(), uno::UNO_QUERY_THROW ); + xTextAppendAndConvert->convertToTextFrame( + m_xFrameStartRange, + m_xFrameEndRange, + m_aFrameProperties ); + } + catch( const uno::Exception& rEx) + { + (void)rEx; + bRet = false; + } + m_xFrameStartRange = 0; + m_xFrameEndRange = 0; + m_aFrameProperties.realloc( 0 ); + } + return bRet; +} + +void DomainMapper_Impl::AddNewRedline( ) +{ + RedlineParamsPtr pNew( new RedlineParams ); + pNew->m_nToken = ooxml::OOXML_mod; + if ( !m_bIsParaChange ) + { + m_aRedlines.push_back( pNew ); + } + else + { + m_pParaRedline.swap( pNew ); + } +} + +RedlineParamsPtr DomainMapper_Impl::GetTopRedline( ) +{ + RedlineParamsPtr pResult; + if ( !m_bIsParaChange && m_aRedlines.size( ) > 0 ) + pResult = m_aRedlines.back( ); + else if ( m_bIsParaChange ) + pResult = m_pParaRedline; + return pResult; +} + +sal_Int32 DomainMapper_Impl::GetCurrentRedlineToken( ) +{ + sal_Int32 nToken = 0; + RedlineParamsPtr pCurrent( GetTopRedline( ) ); + if ( pCurrent.get( ) ) + nToken = pCurrent->m_nToken; + return nToken; +} + +void DomainMapper_Impl::SetCurrentRedlineAuthor( rtl::OUString sAuthor ) +{ + RedlineParamsPtr pCurrent( GetTopRedline( ) ); + if ( pCurrent.get( ) ) + pCurrent->m_sAuthor = sAuthor; +} + +void DomainMapper_Impl::SetCurrentRedlineDate( rtl::OUString sDate ) +{ + RedlineParamsPtr pCurrent( GetTopRedline( ) ); + if ( pCurrent.get( ) ) + pCurrent->m_sDate = sDate; +} + +void DomainMapper_Impl::SetCurrentRedlineId( sal_Int32 sId ) +{ + RedlineParamsPtr pCurrent( GetTopRedline( ) ); + if ( pCurrent.get( ) ) + pCurrent->m_nId = sId; +} + +void DomainMapper_Impl::SetCurrentRedlineToken( sal_Int32 nToken ) +{ + RedlineParamsPtr pCurrent( GetTopRedline( ) ); + if ( pCurrent.get( ) ) + pCurrent->m_nToken = nToken; +} + + + +void DomainMapper_Impl::RemoveCurrentRedline( ) +{ + if ( m_aRedlines.size( ) > 0 ) + { + m_aRedlines.pop_back( ); + } +} + +void DomainMapper_Impl::ResetParaRedline( ) +{ + if ( m_pParaRedline.get( ) ) + { + RedlineParamsPtr pEmpty; + m_pParaRedline.swap( pEmpty ); + } +} + + + +void DomainMapper_Impl::ApplySettingsTable() +{ + if( m_pSettingsTable ) + { + try + { + uno::Reference< beans::XPropertySet > xTextDefaults( + m_xTextFactory->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.Defaults"))), uno::UNO_QUERY_THROW ); + sal_Int32 nDefTab = m_pSettingsTable->GetDefaultTabStop(); + xTextDefaults->setPropertyValue( PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_TAB_STOP_DISTANCE ), uno::makeAny(nDefTab) ); + } + catch(const uno::Exception& ) + { + } + } +} + +SectionPropertyMap * DomainMapper_Impl::GetSectionContext() +{ + SectionPropertyMap* pSectionContext = 0; + //the section context is not availabe before the first call of startSectionGroup() + if( !IsAnyTableImport() ) + { + PropertyMapPtr pContext = GetTopContextOfType(CONTEXT_SECTION); + OSL_ENSURE(pContext.get(), "Section context is not in the stack!"); + pSectionContext = dynamic_cast< SectionPropertyMap* >( pContext.get() ); + } + + return pSectionContext; +} + +}} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx new file mode 100644 index 000000000000..60ccc230b43d --- /dev/null +++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx @@ -0,0 +1,604 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef INCLUDED_DMAPPER_DOMAINMAPPER_IMPL_HXX +#define INCLUDED_DMAPPER_DOMAINMAPPER_IMPL_HXX + +#include <com/sun/star/text/XTextDocument.hpp> +#include <com/sun/star/text/XTextCursor.hpp> +#include <com/sun/star/text/XTextAppend.hpp> +#include <com/sun/star/text/XTextAppendAndConvert.hpp> +#include <com/sun/star/text/XTextFrame.hpp> +#include <com/sun/star/style/TabStop.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <vector> +#include <stack> + +#ifndef INCLUDED_RESOURCESIDS +#include <doctok/resourceids.hxx> +#include <ooxml/resourceids.hxx> +#endif +#include <dmapper/DomainMapper.hxx> +#include <DomainMapperTableManager.hxx> +#include <PropertyMap.hxx> +#include <FontTable.hxx> +#include <NumberingManager.hxx> +#include <StyleSheetTable.hxx> +#include <SettingsTable.hxx> +#include <ThemeTable.hxx> +#include <SettingsTable.hxx> +#include <GraphicImport.hxx> +#include <OLEHandler.hxx> +#include <FFDataHandler.hxx> +#include <FormControlHelper.hxx> +#include <map> + +#include <string.h> + +namespace com{ namespace sun{ namespace star{ + namespace awt{ + struct Size; + } + namespace lang{ + class XMultiServiceFactory; + struct Locale; + } + namespace text + { + class XTextField; + class XFormField; + } + namespace beans{ class XPropertySet;} +}}} + +namespace writerfilter { +namespace dmapper { + +using namespace com::sun::star; + +struct _PageMar +{ + sal_Int32 top; + sal_Int32 right; + sal_Int32 bottom; + sal_Int32 left; + sal_Int32 header; + sal_Int32 footer; + sal_Int32 gutter; + public: + _PageMar(); +}; +enum PageMarElement +{ + PAGE_MAR_TOP, + PAGE_MAR_RIGHT, + PAGE_MAR_BOTTOM, + PAGE_MAR_LEFT, + PAGE_MAR_HEADER, + PAGE_MAR_FOOTER, + PAGE_MAR_GUTTER +}; + +/*------------------------------------------------------------------------- + property stack element + -----------------------------------------------------------------------*/ +enum ContextType +{ + CONTEXT_SECTION, + CONTEXT_PARAGRAPH, + CONTEXT_CHARACTER, + CONTEXT_STYLESHEET, + CONTEXT_LIST, + NUMBER_OF_CONTEXTS +}; + +enum BreakType +{ + PAGE_BREAK, + COLUMN_BREAK +}; +/*-------------------------------------------------- + field stack element + * --------------------------------------------------*/ +class FieldContext +{ + bool m_bFieldCommandCompleted; + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > m_xStartRange; + + ::rtl::OUString m_sCommand; + + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextField > m_xTextField; + ::com::sun::star::uno::Reference< ::com::sun::star::text::XFormField > m_xFormField; + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > m_xTOC;//TOX + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > m_xTC;//TOX entry + ::rtl::OUString m_sHyperlinkURL; + FFDataHandler::Pointer_t m_pFFDataHandler; + FormControlHelper::Pointer_t m_pFormControlHelper; + +public: + FieldContext(::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > xStart); + ~FieldContext(); + + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > GetStartRange() const { return m_xStartRange; } + + void AppendCommand(const ::rtl::OUString& rPart); + const ::rtl::OUString& GetCommand() const {return m_sCommand; } + + void SetCommandCompleted() { m_bFieldCommandCompleted = true; } + bool IsCommandCompleted() const { return m_bFieldCommandCompleted; } + + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextField > GetTextField() const { return m_xTextField;} + void SetTextField(::com::sun::star::uno::Reference< ::com::sun::star::text::XTextField > xTextField) { m_xTextField = xTextField;} + ::com::sun::star::uno::Reference< ::com::sun::star::text::XFormField > GetFormField() const { return m_xFormField;} + void SetFormField(::com::sun::star::uno::Reference< ::com::sun::star::text::XFormField > xFormField) { m_xFormField = xFormField;} + + void SetTOC( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > xTOC ) { m_xTOC = xTOC; } + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > GetTOC() { return m_xTOC; } + + void SetTC( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > xTC ) { m_xTC = xTC; } + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > GetTC( ) { return m_xTC; } + + void SetHyperlinkURL( const ::rtl::OUString& rURL ) { m_sHyperlinkURL = rURL; } + const ::rtl::OUString& GetHyperlinkURL() { return m_sHyperlinkURL; } + + void setFFDataHandler(FFDataHandler::Pointer_t pFFDataHandler) { m_pFFDataHandler = pFFDataHandler; } + FFDataHandler::Pointer_t getFFDataHandler() const { return m_pFFDataHandler; } + + void setFormControlHelper(FormControlHelper::Pointer_t pFormControlHelper) { m_pFormControlHelper = pFormControlHelper; } + FormControlHelper::Pointer_t getFormControlHelper() const { return m_pFormControlHelper; } + + ::std::vector<rtl::OUString> GetCommandParts() const; +}; + +struct TextAppendContext +{ + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextAppend > xTextAppend; + ParagraphPropertiesPtr pLastParagraphProperties; + + TextAppendContext( const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextAppend >& xAppend ) : + xTextAppend( xAppend ){} +}; + +typedef boost::shared_ptr<FieldContext> FieldContextPtr; + +typedef std::stack<ContextType> ContextStack; +typedef std::stack<PropertyMapPtr> PropertyStack; +typedef std::stack< TextAppendContext > TextAppendStack; +typedef std::stack<FieldContextPtr> FieldStack; +typedef std::stack< com::sun::star::uno::Reference< com::sun::star::text::XTextContent > > TextContentStack; + + + +class FIB +{ + sal_Int32 aFIBData[ NS_rtf::LN_LCBSTTBFUSSR - NS_rtf::LN_WIDENT + 1]; + sal_Int32 nLNCHS; + public: + FIB() : + nLNCHS( 0 ) + { + memset(&aFIBData, 0x00, sizeof(aFIBData)); + } + + sal_Int32 GetLNCHS() const {return nLNCHS;} + void SetLNCHS(sal_Int32 nValue) {nLNCHS = nValue;} + sal_Int32 GetData( Id nName ); + void SetData( Id nName, sal_Int32 nValue ); +}; + +/*------------------------------------------------------------------------- + extended tab stop struct + -----------------------------------------------------------------------*/ +struct DeletableTabStop : public ::com::sun::star::style::TabStop +{ + bool bDeleted; + DeletableTabStop() : + bDeleted( false ){} + DeletableTabStop( const ::com::sun::star::style::TabStop& rTabStop ) : + TabStop( rTabStop ), + bDeleted( false ){} +}; +/*------------------------------------------------------------------------- + /// helper to remember bookmark start position + -----------------------------------------------------------------------*/ +struct BookmarkInsertPosition +{ + bool m_bIsStartOfText; + ::rtl::OUString m_sBookmarkName; + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > m_xTextRange; + BookmarkInsertPosition(bool bIsStartOfText, const ::rtl::OUString& rName, ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > xTextRange): + m_bIsStartOfText( bIsStartOfText ), + m_sBookmarkName( rName ), + m_xTextRange( xTextRange ) + {} +}; + +struct RedlineParams +{ + ::rtl::OUString m_sAuthor; + ::rtl::OUString m_sDate; + sal_Int32 m_nId; + sal_Int32 m_nToken; +}; +typedef boost::shared_ptr< RedlineParams > RedlineParamsPtr; + + + +struct LineNumberSettings +{ + bool bIsOn; + sal_Int32 nDistance; + sal_Int32 nInterval; + sal_Int32 bRestartAtEachPage; + sal_Int32 nStartValue; + LineNumberSettings() : + bIsOn(false) + ,nDistance(0) + ,nInterval(0) + ,bRestartAtEachPage(true) + ,nStartValue(1) + {} + +}; + + +class DomainMapper; +class WRITERFILTER_DLLPRIVATE DomainMapper_Impl +{ +public: + typedef TableManager< ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange >, PropertyMapPtr > TableManager_t; + typedef TableDataHandler< ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange >, TablePropertyMapPtr > TableDataHandler_t; + typedef std::map < ::rtl::OUString, BookmarkInsertPosition > BookmarkMap_t; + +private: + SourceDocumentType m_eDocumentType; + DomainMapper& m_rDMapper; + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextDocument > m_xTextDocument; + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > m_xDocumentSettings; + ::com::sun::star::uno::Reference < ::com::sun::star::lang::XMultiServiceFactory > m_xTextFactory; + ::com::sun::star::uno::Reference < com::sun::star::uno::XComponentContext > m_xComponentContext; + ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer > m_xPageStyles; + ::com::sun::star::uno::Reference< ::com::sun::star::text::XText > m_xBodyText; + + TextAppendStack m_aTextAppendStack; + + TextContentStack + m_aAnchoredStack; + + FieldStack m_aFieldStack; + bool m_bFieldMode; + bool m_bSetUserFieldContent; + bool m_bIsFirstSection; + bool m_bIsColumnBreakDeferred; + bool m_bIsPageBreakDeferred; + bool m_bIsInShape; + bool m_bShapeContextAdded; + + LineNumberSettings m_aLineNumberSettings; + + BookmarkMap_t m_aBookmarkMap; + + _PageMar m_aPageMargins; + + + // TableManagers are stacked: one for each stream to avoid any confusion + std::stack< boost::shared_ptr< DomainMapperTableManager > > m_aTableManagers; + + //each context needs a stack of currently used attributes + FIB m_aFIB; + PropertyStack m_aPropertyStacks[NUMBER_OF_CONTEXTS]; + ContextStack m_aContextStack; + FontTablePtr m_pFontTable; + ListsManager::Pointer m_pListTable; + StyleSheetTablePtr m_pStyleSheetTable; + ThemeTablePtr m_pThemeTable; + SettingsTablePtr m_pSettingsTable; + GraphicImportPtr m_pGraphicImport; + + + PropertyMapPtr m_pTopContext; + PropertyMapPtr m_pLastSectionContext; + + ::std::vector<DeletableTabStop> m_aCurrentTabStops; + sal_uInt32 m_nCurrentTabStopIndex; + ::rtl::OUString m_sCurrentParaStyleId; + bool m_bInStyleSheetImport; //in import of fonts, styles, lists or lfos + bool m_bInAnyTableImport; //in import of fonts, styles, lists or lfos + + bool m_bLineNumberingSet; + bool m_bIsInFootnoteProperties; + bool m_bIsCustomFtnMark; + + //registered frame properties + ::com::sun::star::uno::Sequence< beans::PropertyValue > m_aFrameProperties; + ::com::sun::star::uno::Reference< text::XTextRange > m_xFrameStartRange; + ::com::sun::star::uno::Reference< text::XTextRange > m_xFrameEndRange; + + // Redline stack + std::vector< RedlineParamsPtr > m_aRedlines; + RedlineParamsPtr m_pParaRedline; + bool m_bIsParaChange; + + bool m_bParaChanged; + bool m_bIsLastParaInSection; + bool m_bUsingEnhancedFields; + + //annotation import + uno::Reference< beans::XPropertySet > m_xAnnotationField; + + void GetCurrentLocale(::com::sun::star::lang::Locale& rLocale); + void SetNumberFormat( const ::rtl::OUString& rCommand, + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xPropertySet ); + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > + FindOrCreateFieldMaster( const sal_Char* pFieldMasterService, + const ::rtl::OUString& rFieldMasterName ) + throw(::com::sun::star::uno::Exception); + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > GetDocumentSettings(); + +public: + DomainMapper_Impl( + DomainMapper& rDMapper, + uno::Reference < uno::XComponentContext > xContext, + uno::Reference< lang::XComponent > xModel, + SourceDocumentType eDocumentType ); + DomainMapper_Impl(); + virtual ~DomainMapper_Impl(); + + SectionPropertyMap* GetLastSectionContext( ) + { + return dynamic_cast< SectionPropertyMap* >( m_pLastSectionContext.get( ) ); + } + + ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer > GetPageStyles(); + ::com::sun::star::uno::Reference< ::com::sun::star::text::XText > GetBodyText(); + ::com::sun::star::uno::Reference < ::com::sun::star::lang::XMultiServiceFactory > GetTextFactory() const + { + return m_xTextFactory; + } + ::com::sun::star::uno::Reference < com::sun::star::uno::XComponentContext > GetComponentContext() const + { + return m_xComponentContext; + } + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextDocument > GetTextDocument() const + { + return m_xTextDocument; + } + void SetDocumentSettingsProperty( const ::rtl::OUString& rPropName, const uno::Any& rValue ); + + void CreateRedline( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > xRange, RedlineParamsPtr& pRedline ); + + void CheckParaRedline( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > xRange ); + + void CheckRedline( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > xRange ); + + void StartParaChange( ); + void EndParaChange( ); + + void RemoveLastParagraph( ); + void SetIsLastParagraphInSection( bool bIsLast ); + + void deferBreak( BreakType deferredBreakType ); + bool isBreakDeferred( BreakType deferredBreakType ); + void clearDeferredBreaks(); + void finishParagraph( PropertyMapPtr pPropertyMap ); + void appendTextPortion( const ::rtl::OUString& rString, PropertyMapPtr pPropertyMap ); + void appendTextContent( const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextContent >, + const uno::Sequence< beans::PropertyValue > ); + void appendOLE( const ::rtl::OUString& rStreamName, OLEHandlerPtr pOleHandler ); + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > appendTextSectionAfter( + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange >& xBefore ); + + FIB& GetFIB() {return m_aFIB;} + // push the new properties onto the stack and make it the 'current' property map + void PushProperties(ContextType eId); + void PushStyleProperties(PropertyMapPtr pStyleProperties); + void PushListProperties(PropertyMapPtr pListProperties); + void PopProperties(ContextType eId); + + ContextType GetTopContextType() const { return m_aContextStack.top(); } + PropertyMapPtr GetTopContext() + { + return m_pTopContext; + } + PropertyMapPtr GetTopContextOfType(ContextType eId); + + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextAppend > GetTopTextAppend(); + + FontTablePtr GetFontTable() + { + if(!m_pFontTable) + m_pFontTable.reset(new FontTable()); + return m_pFontTable; + } + StyleSheetTablePtr GetStyleSheetTable() + { + if(!m_pStyleSheetTable) + m_pStyleSheetTable.reset(new StyleSheetTable( m_rDMapper, m_xTextDocument )); + return m_pStyleSheetTable; + } + ListsManager::Pointer GetListTable(); + ThemeTablePtr GetThemeTable() + { + if(!m_pThemeTable) + m_pThemeTable.reset( new ThemeTable ); + return m_pThemeTable; + } + + SettingsTablePtr GetSettingsTable() + { + if( !m_pSettingsTable ) + m_pSettingsTable.reset( new SettingsTable( m_rDMapper, m_xTextFactory ) ); + return m_pSettingsTable; + } + + GraphicImportPtr GetGraphicImport( GraphicImportType eGraphicImportType ); + void ResetGraphicImport(); + // this method deletes the current m_pGraphicImport after import + void ImportGraphic(writerfilter::Reference< Properties>::Pointer_t, GraphicImportType eGraphicImportType ); + + void InitTabStopFromStyle( const ::com::sun::star::uno::Sequence< ::com::sun::star::style::TabStop >& rInitTabStops ); + void ModifyCurrentTabStop( Id nId, sal_Int32 nValue); + void IncorporateTabStop( const DeletableTabStop &aTabStop ); + ::com::sun::star::uno::Sequence< ::com::sun::star::style::TabStop > GetCurrentTabStopAndClear(); + void NextTabStop() {++m_nCurrentTabStopIndex;} + + void SetCurrentParaStyleId(::rtl::OUString sStringValue) {m_sCurrentParaStyleId = sStringValue;} + ::rtl::OUString GetCurrentParaStyleId() const {return m_sCurrentParaStyleId;} + + ::com::sun::star::uno::Any GetPropertyFromStyleSheet(PropertyIds eId); + void SetStyleSheetImport( bool bSet ) { m_bInStyleSheetImport = bSet;} + bool IsStyleSheetImport()const { return m_bInStyleSheetImport;} + void SetAnyTableImport( bool bSet ) { m_bInAnyTableImport = bSet;} + bool IsAnyTableImport()const { return m_bInAnyTableImport;} + + void PushShapeContext( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape ); + void PopShapeContext(); + + void PushPageHeader(SectionPropertyMap::PageType eType); + void PushPageFooter(SectionPropertyMap::PageType eType); + + void PopPageHeaderFooter(); + + void PushFootOrEndnote( bool bIsFootnote ); + void PopFootOrEndnote(); + + void PushAnnotation(); + void PopAnnotation(); + + //field context starts with a 0x13 + void PushFieldContext(); + //the current field context waits for the completion of the command + bool IsOpenFieldCommand() const; + bool IsOpenField() const; + //collect the pieces of the command + void AppendFieldCommand(::rtl::OUString& rPartOfCommand); + void handleFieldAsk + (FieldContextPtr pContext, + PropertyNameSupplier& rPropNameSupplier, + uno::Reference< uno::XInterface > & xFieldInterface, + uno::Reference< beans::XPropertySet > xFieldProperties); + void handleAutoNum + (FieldContextPtr pContext, + PropertyNameSupplier& rPropNameSupplier, + uno::Reference< uno::XInterface > & xFieldInterface, + uno::Reference< beans::XPropertySet > xFieldProperties); + void handleAuthor + (FieldContextPtr pContext, + PropertyNameSupplier& rPropNameSupplier, + uno::Reference< uno::XInterface > & xFieldInterface, + uno::Reference< beans::XPropertySet > xFieldProperties, + FieldId eFieldId); + void handleDocProperty + (FieldContextPtr pContext, + PropertyNameSupplier& rPropNameSupplier, + uno::Reference< uno::XInterface > & xFieldInterface, + uno::Reference< beans::XPropertySet > xFieldProperties); + void handleToc + (FieldContextPtr pContext, + PropertyNameSupplier& rPropNameSupplier, + uno::Reference< uno::XInterface > & xFieldInterface, + uno::Reference< beans::XPropertySet > xFieldProperties, + const ::rtl::OUString & sTOCServiceName); + //the field command has to be closed (0x14 appeared) + void CloseFieldCommand(); + //the _current_ fields require a string type result while TOCs accept richt results + bool IsFieldResultAsString(); + //apply the result text to the related field + void SetFieldResult( ::rtl::OUString& rResult ); + // set FFData of top field context + void SetFieldFFData( FFDataHandler::Pointer_t pFFDataHandler ); + //the end of field is reached (0x15 appeared) - the command might still be open + void PopFieldContext(); + + void AddBookmark( const ::rtl::OUString& rBookmarkName, const ::rtl::OUString& rId ); + + DomainMapperTableManager& getTableManager() + { + boost::shared_ptr< DomainMapperTableManager > pMngr = m_aTableManagers.top(); + return *pMngr.get( ); + } + + void appendTableManager( ) + { + boost::shared_ptr< DomainMapperTableManager > pMngr( + new DomainMapperTableManager( m_eDocumentType == DOCUMENT_OOXML ) ); + m_aTableManagers.push( pMngr ); + } + + void popTableManager( ) + { + if ( m_aTableManagers.size( ) > 0 ) + m_aTableManagers.pop( ); + } + + void SetLineNumbering( sal_Int32 nLnnMod, sal_Int32 nLnc, sal_Int32 ndxaLnn ); + bool IsLineNumberingSet() const {return m_bLineNumberingSet;} + + DeletableTabStop m_aCurrentTabStop; + + bool IsOOXMLImport() const { return m_eDocumentType == DOCUMENT_OOXML; } + + void InitPageMargins() { m_aPageMargins = _PageMar(); } + void SetPageMarginTwip( PageMarElement eElement, sal_Int32 nValue ); + const _PageMar& GetPageMargins() const {return m_aPageMargins;} + + const LineNumberSettings& GetLineNumberSettings() const { return m_aLineNumberSettings;} + void SetLineNumberSettings(const LineNumberSettings& rSet) { m_aLineNumberSettings = rSet;} + + void SetInFootnoteProperties(bool bSet) { m_bIsInFootnoteProperties = bSet;} + bool IsInFootnoteProperties() const { return m_bIsInFootnoteProperties;} + + void SetCustomFtnMark(bool bSet) { m_bIsCustomFtnMark = bSet; } + bool IsCustomFtnMark() const { return m_bIsCustomFtnMark; } + + void RegisterFrameConversion( + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > xFrameStartRange, + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > xFrameEndRange, + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aFrameProperties + ); + bool ExecuteFrameConversion(); + + void AddNewRedline( ); + + RedlineParamsPtr GetTopRedline( ); + + sal_Int32 GetCurrentRedlineToken( ); + void SetCurrentRedlineAuthor( rtl::OUString sAuthor ); + void SetCurrentRedlineDate( rtl::OUString sDate ); + void SetCurrentRedlineId( sal_Int32 nId ); + void SetCurrentRedlineToken( sal_Int32 nToken ); + void RemoveCurrentRedline( ); + void ResetParaRedline( ); + + void ApplySettingsTable(); + SectionPropertyMap * GetSectionContext(); +}; +} //namespace dmapper +} //namespace writerfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/FFData.xml b/writerfilter/source/dmapper/FFData.xml new file mode 100644 index 000000000000..525f59391dc4 --- /dev/null +++ b/writerfilter/source/dmapper/FFData.xml @@ -0,0 +1,58 @@ +<model> + <class name="FFDataHandler"> + <parent name="Properties"/> + <typedef name="Pointer_t" type="shared_ptr"/> + <typedef name="DropDownEntries_t"> + <vector type="OUString"/> + </typedef> + <member name="name" type="OUString"/> + <member name="enabled" type="bool"/> + <member name="calcOnExit" type="bool"/> + <member name="entryMacro" type="OUString"/> + <member name="exitMacro" type="OUString"/> + <member name="helpTextType" type="sal_uInt32"/> + <member name="helpText" type="OUString"/> + <member name="statusTextType" type="sal_uInt32"/> + <member name="statusText" type="OUString"/> + <member name="checkboxHeight" type="sal_uInt32"/> + <member name="checkboxAutoHeight" type="bool"/> + <member name="checkboxDefault" type="bool"/> + <member name="checkboxChecked" type="bool"/> + <member name="dropDownResult" type="OUString"/> + <member name="dropDownDefault" type="OUString"/> + <member name="dropDownEntries" type="DropDownEntries_t"/> + <member name="textType" type="sal_uInt32"/> + <member name="textMaxLength" type="sal_uInt32"/> + <member name="textDefault" type="OUString"/> + <member name="textFormat" type="OUString"/> + <sprm> + <element name="name" action="set" id="NS_ooxml::LN_CT_FFData_name"/> + <element name="enabled" action="set" id="NS_ooxml::LN_CT_FFData_enabled"/> + <element name="calcOnExit" action="set" id="NS_ooxml::LN_CT_FFData_calcOnExit"/> + <element name="entryMacro" action="set" id="NS_ooxml::LN_CT_FFData_entryMacro"/> + <element name="exitMacro" action="set" id="NS_ooxml::LN_CT_FFData_exitMacro"/> + <element name="helpText" action="resolve" id="NS_ooxml::LN_CT_FFData_helpText"/> + <element name="statusText" action="resolve" id="NS_ooxml::LN_CT_FFData_statusText"/> + <element name="size" member="checkboxHeight" action="set" id="NS_ooxml::LN_CT_FFCheckBox_size"/> + <element name="sizeAuto" member="checkboxAutoHeight" action="set" id="NS_ooxml::LN_CT_FFCheckBox_sizeAuto"/> + <element name="default" member="checkboxDefault" action="set" id="NS_ooxml::LN_CT_FFCheckBox_default"/> + <element name="checked" member="checkboxChecked" action="set" id="NS_ooxml::LN_CT_FFCheckBox_checked"/> + <element name="checkBox" action="resolve" id="NS_ooxml::LN_CT_FFData_checkBox"/> + <element name="result" member="dropDownResult" action="set" id="NS_ooxml::LN_CT_FFDDList_result"/> + <element name="default" member="dropDownDefault" action="set" id="NS_ooxml::LN_CT_FFDDList_default"/> + <element name="listEntry" member="dropDownEntries" action="pushback" id="NS_ooxml::LN_CT_FFDDList_listEntry"/> + <element name="ddList" action="resolve" id="NS_ooxml::LN_CT_FFData_ddList"/> + <element name="type" member="textType" action="set" id="NS_ooxml::LN_CT_FFTextInput_type"/> + <element name="default" member="textDefault" action="set" id="NS_ooxml::LN_CT_FFTextInput_default"/> + <element name="maxLength" member="textMaxLength" action="set" id="NS_ooxml::LN_CT_FFTextInput_maxLength"/> + <element name="format" member="textFormat" action="set" id="NS_ooxml::LN_CT_FFTextInput_format"/> + <element name="textInput" action="resolve" id="NS_ooxml::LN_CT_FFData_textInput"/> + </sprm> + <attribute> + <attribute name="helpText:type" member="helpTextType" id="NS_ooxml::LN_CT_FFHelpText_type"/> + <attribute name="helpText:val" member="helpText" id="NS_ooxml::LN_CT_FFHelpText_val"/> + <attribute name="statusText:type" member="statusTextType" id="NS_ooxml::LN_CT_FFStatusText_type"/> + <attribute name="statusText:val" member="statusText" id="NS_ooxml::LN_CT_FFStatusText_val"/> + </attribute> + </class> +</model>
\ No newline at end of file diff --git a/writerfilter/source/dmapper/FFDataHandler.cxx b/writerfilter/source/dmapper/FFDataHandler.cxx new file mode 100644 index 000000000000..0b42591b9a5c --- /dev/null +++ b/writerfilter/source/dmapper/FFDataHandler.cxx @@ -0,0 +1,399 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include "FFDataHandler.hxx" + +#include <ooxml/resourceids.hxx> +#include "dmapperLoggers.hxx" + +namespace writerfilter { +namespace dmapper { + +/************************ + * class: FFDataHandler * + ************************/ + +FFDataHandler::FFDataHandler() : +LoggedProperties(dmapper_logger, "FFDataHandler"), +m_bEnabled(false), +m_bCalcOnExit(false), +m_nHelpTextType(0), +m_nStatusTextType(0), +m_nCheckboxHeight(0), +m_bCheckboxAutoHeight(false), +m_bCheckboxDefault(false), +m_bCheckboxChecked(false), +m_nTextType(0), +m_nTextMaxLength(0) +{ +} + + +FFDataHandler::~FFDataHandler() +{ +} + +// member: FFDataHandler::name +void FFDataHandler::setName(const rtl::OUString & r_sName) +{ + m_sName = r_sName; +} + +const rtl::OUString & FFDataHandler::getName() const +{ + return m_sName; +} + +// member: FFDataHandler::enabled +void FFDataHandler::setEnabled(bool r_enabled) +{ + m_bEnabled = r_enabled; +} + +bool FFDataHandler::getEnabled() const +{ + return m_bEnabled; +} + +// member: FFDataHandler::calcOnExit +void FFDataHandler::setCalcOnExit(bool r_calcOnExit) +{ + m_bCalcOnExit = r_calcOnExit; +} + +// member: FFDataHandler::entryMacro +void FFDataHandler::setEntryMacro(const rtl::OUString & r_sEntryMacro) +{ + m_sEntryMacro = r_sEntryMacro; +} + +// member: FFDataHandler::exitMacro +void FFDataHandler::setExitMacro(const rtl::OUString & r_sExitMacro) +{ + m_sExitMacro = r_sExitMacro; +} + +// member: FFDataHandler::helpTextType +void FFDataHandler::setHelpTextType(sal_uInt32 r_helpTextType) +{ + m_nHelpTextType = r_helpTextType; +} + +// member: FFDataHandler::helpText +void FFDataHandler::setHelpText(const rtl::OUString & r_sHelpText) +{ + m_sHelpText = r_sHelpText; +} + +const rtl::OUString & FFDataHandler::getHelpText() const +{ + return m_sHelpText; +} + +// member: FFDataHandler::statusTextType +void FFDataHandler::setStatusTextType(sal_uInt32 r_statusTextType) +{ + m_nStatusTextType = r_statusTextType; +} + +// member: FFDataHandler::statusText +void FFDataHandler::setStatusText(const rtl::OUString & r_sStatusText) +{ + m_sStatusText = r_sStatusText; +} + +const rtl::OUString & FFDataHandler::getStatusText() const +{ + return m_sStatusText; +} + +// member: FFDataHandler::checkboxHeight +void FFDataHandler::setCheckboxHeight(sal_uInt32 r_checkboxHeight) +{ + m_nCheckboxHeight = r_checkboxHeight; +} + +sal_uInt32 FFDataHandler::getCheckboxHeight() const +{ + return m_nCheckboxHeight; +} + +// member: FFDataHandler::checkboxAutoHeight +void FFDataHandler::setCheckboxAutoHeight(bool r_checkboxAutoHeight) +{ + m_bCheckboxAutoHeight = r_checkboxAutoHeight; +} + +bool FFDataHandler::getCheckboxAutoHeight() const +{ + return m_bCheckboxAutoHeight; +} + +// member: FFDataHandler::checkboxDefault +void FFDataHandler::setCheckboxDefault(bool r_checkboxDefault) +{ + m_bCheckboxDefault = r_checkboxDefault; +} + +// member: FFDataHandler::checkboxChecked +void FFDataHandler::setCheckboxChecked(bool r_checkboxChecked) +{ + m_bCheckboxChecked = r_checkboxChecked; +} + +bool FFDataHandler::getCheckboxChecked() const +{ + return m_bCheckboxChecked; +} + +// member: FFDataHandler::dropDownResult +void FFDataHandler::setDropDownResult(const rtl::OUString & r_sDropDownResult) +{ + m_sDropDownResult = r_sDropDownResult; +} + +const rtl::OUString & FFDataHandler::getDropDownResult() const +{ + return m_sDropDownResult; +} + +// member: FFDataHandler::dropDownDefault +void FFDataHandler::setDropDownDefault(const rtl::OUString & r_sDropDownDefault) +{ + m_sDropDownDefault = r_sDropDownDefault; +} + +const rtl::OUString & FFDataHandler::getDropDownDefault() const +{ + return m_sDropDownDefault; +} + +// member: FFDataHandler::dropDownEntries +void FFDataHandler::setDropDownEntries(const FFDataHandler::DropDownEntries_t & r_dropDownEntries) +{ + m_DropDownEntries = r_dropDownEntries; +} + +const FFDataHandler::DropDownEntries_t & FFDataHandler::getDropDownEntries() const +{ + return m_DropDownEntries; +} + +// member: FFDataHandler::textType +void FFDataHandler::setTextType(sal_uInt32 r_textType) +{ + m_nTextType = r_textType; +} + +sal_uInt32 FFDataHandler::getTextType() const +{ + return m_nTextType; +} + +// member: FFDataHandler::textMaxLength +void FFDataHandler::setTextMaxLength(sal_uInt32 r_textMaxLength) +{ + m_nTextMaxLength = r_textMaxLength; +} + +// member: FFDataHandler::textDefault +void FFDataHandler::setTextDefault(const rtl::OUString & r_sTextDefault) +{ + m_sTextDefault = r_sTextDefault; +} + +const rtl::OUString & FFDataHandler::getTextDefault() const +{ + return m_sTextDefault; +} + +// member: FFDataHandler::textFormat +void FFDataHandler::setTextFormat(const rtl::OUString & r_sTextFormat) +{ + m_sTextFormat = r_sTextFormat; +} + + +void FFDataHandler::lcl_sprm(Sprm & r_Sprm) +{ + switch(r_Sprm.getId()) + { + case NS_ooxml::LN_CT_FFData_name: + { + m_sName = r_Sprm.getValue()->getString(); + } + break; + case NS_ooxml::LN_CT_FFData_enabled: + { + m_bEnabled = r_Sprm.getValue()->getInt(); + } + break; + case NS_ooxml::LN_CT_FFData_calcOnExit: + { + m_bCalcOnExit = r_Sprm.getValue()->getInt(); + } + break; + case NS_ooxml::LN_CT_FFData_entryMacro: + { + m_sEntryMacro = r_Sprm.getValue()->getString(); + } + break; + case NS_ooxml::LN_CT_FFData_exitMacro: + { + m_sExitMacro = r_Sprm.getValue()->getString(); + } + break; + case NS_ooxml::LN_CT_FFData_helpText: + { + resolveSprm(r_Sprm); + } + break; + case NS_ooxml::LN_CT_FFData_statusText: + { + resolveSprm(r_Sprm); + } + break; + case NS_ooxml::LN_CT_FFCheckBox_size: + { + m_nCheckboxHeight = r_Sprm.getValue()->getInt(); + } + break; + case NS_ooxml::LN_CT_FFCheckBox_sizeAuto: + { + m_bCheckboxAutoHeight = r_Sprm.getValue()->getInt(); + } + break; + case NS_ooxml::LN_CT_FFCheckBox_default: + { + m_bCheckboxDefault = r_Sprm.getValue()->getInt(); + } + break; + case NS_ooxml::LN_CT_FFCheckBox_checked: + { + m_bCheckboxChecked = r_Sprm.getValue()->getInt(); + } + break; + case NS_ooxml::LN_CT_FFData_checkBox: + { + resolveSprm(r_Sprm); + } + break; + case NS_ooxml::LN_CT_FFDDList_result: + { + m_sDropDownResult = r_Sprm.getValue()->getString(); + } + break; + case NS_ooxml::LN_CT_FFDDList_default: + { + m_sDropDownDefault = r_Sprm.getValue()->getString(); + } + break; + case NS_ooxml::LN_CT_FFDDList_listEntry: + { + m_DropDownEntries.push_back(r_Sprm.getValue()->getString());; + } + break; + case NS_ooxml::LN_CT_FFData_ddList: + { + resolveSprm(r_Sprm); + } + break; + case NS_ooxml::LN_CT_FFTextInput_type: + { + m_nTextType = r_Sprm.getValue()->getInt(); + } + break; + case NS_ooxml::LN_CT_FFTextInput_default: + { + m_sTextDefault = r_Sprm.getValue()->getString(); + } + break; + case NS_ooxml::LN_CT_FFTextInput_maxLength: + { + m_nTextMaxLength = r_Sprm.getValue()->getInt(); + } + break; + case NS_ooxml::LN_CT_FFTextInput_format: + { + m_sTextFormat = r_Sprm.getValue()->getString(); + } + break; + case NS_ooxml::LN_CT_FFData_textInput: + { + resolveSprm(r_Sprm); + } + break; + default: +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->element("unhandled"); +#endif + break; + } +} + +void FFDataHandler::resolveSprm(Sprm & r_Sprm) +{ + writerfilter::Reference<Properties>::Pointer_t pProperties = r_Sprm.getProps(); + if( pProperties.get()) + pProperties->resolve(*this); +} + +void FFDataHandler::lcl_attribute(Id name, Value & val) +{ + switch (name) + { + case NS_ooxml::LN_CT_FFHelpText_type: + { + m_nHelpTextType = val.getInt(); + } + break; + case NS_ooxml::LN_CT_FFHelpText_val: + { + m_sHelpText = val.getString(); + } + break; + case NS_ooxml::LN_CT_FFStatusText_type: + { + m_nStatusTextType = val.getInt(); + } + break; + case NS_ooxml::LN_CT_FFStatusText_val: + { + m_sStatusText = val.getString(); + } + break; + default: +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->element("unhandled"); +#endif + break; + } +} + +}} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/FFDataHandler.hxx b/writerfilter/source/dmapper/FFDataHandler.hxx new file mode 100644 index 000000000000..c340cd5ce886 --- /dev/null +++ b/writerfilter/source/dmapper/FFDataHandler.hxx @@ -0,0 +1,154 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef INCLUDED_FFDataHandler_HXX +#define INCLUDED_FFDataHandler_HXX +#include <resourcemodel/LoggedResources.hxx> +#include <rtl/ustring.hxx> +namespace writerfilter { +namespace dmapper { +class FFDataHandler : public LoggedProperties +{ +public: + // typedefs + typedef ::boost::shared_ptr<FFDataHandler> Pointer_t; + typedef ::std::vector<rtl::OUString> DropDownEntries_t; + + // constructor + FFDataHandler(); + // destructor + virtual ~FFDataHandler(); + + // member: name + void setName(const rtl::OUString & r_sName); + const rtl::OUString & getName() const; + + // member: enabled + void setEnabled(bool r_enabled); + bool getEnabled() const; + + // member: calcOnExit + void setCalcOnExit(bool r_calcOnExit); + + // member: entryMacro + void setEntryMacro(const rtl::OUString & r_sEntryMacro); + + // member: exitMacro + void setExitMacro(const rtl::OUString & r_sExitMacro); + + // member: helpTextType + void setHelpTextType(sal_uInt32 r_helpTextType); + + // member: helpText + void setHelpText(const rtl::OUString & r_sHelpText); + const rtl::OUString & getHelpText() const; + + // member: statusTextType + void setStatusTextType(sal_uInt32 r_statusTextType); + + // member: statusText + void setStatusText(const rtl::OUString & r_sStatusText); + const rtl::OUString & getStatusText() const; + + // member: checkboxHeight + void setCheckboxHeight(sal_uInt32 r_checkboxHeight); + sal_uInt32 getCheckboxHeight() const; + + // member: checkboxAutoHeight + void setCheckboxAutoHeight(bool r_checkboxAutoHeight); + bool getCheckboxAutoHeight() const; + + // member: checkboxDefault + void setCheckboxDefault(bool r_checkboxDefault); + + // member: checkboxChecked + void setCheckboxChecked(bool r_checkboxChecked); + bool getCheckboxChecked() const; + + // member: dropDownResult + void setDropDownResult(const rtl::OUString & r_sDropDownResult); + const rtl::OUString & getDropDownResult() const; + + // member: dropDownDefault + void setDropDownDefault(const rtl::OUString & r_sDropDownDefault); + const rtl::OUString & getDropDownDefault() const; + + // member: dropDownEntries + void setDropDownEntries(const DropDownEntries_t & r_dropDownEntries); + const DropDownEntries_t & getDropDownEntries() const; + + // member: textType + void setTextType(sal_uInt32 r_textType); + sal_uInt32 getTextType() const; + + // member: textMaxLength + void setTextMaxLength(sal_uInt32 r_textMaxLength); + + // member: textDefault + void setTextDefault(const rtl::OUString & r_sTextDefault); + const rtl::OUString & getTextDefault() const; + + // member: textFormat + void setTextFormat(const rtl::OUString & r_sTextFormat); + + // sprm + void resolveSprm(Sprm & r_sprm); + +private: + rtl::OUString m_sName; + bool m_bEnabled; + bool m_bCalcOnExit; + rtl::OUString m_sEntryMacro; + rtl::OUString m_sExitMacro; + sal_uInt32 m_nHelpTextType; + rtl::OUString m_sHelpText; + sal_uInt32 m_nStatusTextType; + rtl::OUString m_sStatusText; + sal_uInt32 m_nCheckboxHeight; + bool m_bCheckboxAutoHeight; + bool m_bCheckboxDefault; + bool m_bCheckboxChecked; + rtl::OUString m_sDropDownResult; + rtl::OUString m_sDropDownDefault; + DropDownEntries_t m_DropDownEntries; + sal_uInt32 m_nTextType; + sal_uInt32 m_nTextMaxLength; + rtl::OUString m_sTextDefault; + rtl::OUString m_sTextFormat; + + // sprm + void lcl_sprm(Sprm & r_sprm); + + // attribute + void lcl_attribute(Id name, Value & val); +}; + + +}} +#endif //INCLUDED_FFDataHandler_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/FieldTypes.hxx b/writerfilter/source/dmapper/FieldTypes.hxx new file mode 100644 index 000000000000..a16c80816b7d --- /dev/null +++ b/writerfilter/source/dmapper/FieldTypes.hxx @@ -0,0 +1,302 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef INCLUDED_FIELD_TYPES_HXX +#define INCLUDED_FIELD_TYPES_HXX + +namespace writerfilter { +namespace dmapper { + +enum FieldId +{ + /* ADDRESSBLOCK \d \* MERGEFORMAT -> Addressblock completely unsupported*/ + FIELD_ADDRESSBLOCK + /* ADVANCE \d downvalue \l leftvalue \r rightvalue \u upvalue \x xvalue \y yvalue -> unsupported*/ + ,FIELD_ADVANCE + /* ASK bookmarkname "hint" \d defaultanswer \o \* MERGEFORMAT -> + the hint is not always quoted, inputfield with default answer, prompt before merge (\o) + */ + ,FIELD_ASK + /* AUTONUM \* Numberingswitch -> + mapped to sequence field "AutoNr" + */ + ,FIELD_AUTONUM + /* AUTONUMLGL \* Numberingswitch -> + mapped to sequence field "AutoNr" + */ + ,FIELD_AUTONUMLGL + /* AUTONUMOUT \* Numberingswitch -> + mapped to sequence field "AutoNr" + */ + ,FIELD_AUTONUMOUT + /* AUTHOR NewAuthor \* defaultswitch \* MERGEFORMAT -> + mapped to sequence field "AutoNr" + */ + ,FIELD_AUTHOR + /* COMMENTS "comment" \* MERGEFORMAT -> + Docinfo-Comments + */ + ,FIELD_COMMENTS + /* CREATEDATE \h \* MERGEFORMAT -> + docinfo-created-date + */ + ,FIELD_CREATEDATE + /* DATE \@ "number format" \s \* MERGEFORMAT -> + ww8filterimprovement: multiple languages now supported + */ + ,FIELD_DATE + /* DOCPROPERTY propertyname \* MERGEFORMAT -> + ww8filterimprovement: some fields imported as functionally equivalent fields if possible, + the others imported as UserField + */ + ,FIELD_DOCPROPERTY + /* DOCVARIABLE Name \* MERGEFORMAT -> + ww8filterimprovement: now imported as user fields + */ + ,FIELD_DOCVARIABLE + /* EDITTIME \# "displayformat" \* Numberingswitch \* MERGEFORMAT -> + DocInfo-Modified-Date + ww8filterimprovement: multiple languages now supported + */ + ,FIELD_EDITTIME + /* FILLIN "text to fill in" \d defaultanswer \o \* MERGEFORMAT -> + Function-InputField + */ + ,FIELD_FILLIN + /* FILENAME \p \* * MERGEFORMAT -> + file name (\p with path) + */ + ,FIELD_FILENAME + /* FILESIZE \* NumberingType \* MERGEFORMAT -> + not imported in old ww8 filter, see lcl_ParseNumberingType + todo find alternative field + */ + ,FIELD_FILESIZE + /* =formula \# "number format" + todo find alternative field + */ + ,FIELD_FORMULA + /* FORMCHECKBOX */ + ,FIELD_FORMCHECKBOX + /* FORMDROPDOWN */ + ,FIELD_FORMDROPDOWN + /* FORMTEXT */ + ,FIELD_FORMTEXT + /* GOTOBUTTON text \* MERGEFORMAT -> + not imported in old ww8 filter + todo find alternative field + */ + ,FIELD_GOTOBUTTON + /* HYPERLINK "link" \* MERGEFORMAT -> + not imported in old ww8 filter + ww8filterimprovement: now imported as hyperlink + */ + ,FIELD_HYPERLINK + /* IF condition "then text" "else text" -> + not imported in old ww8 filter + ww8filterimprovement: now imported + todo: condition, if text, else text still missing + */ + ,FIELD_IF + /* INFO NameOfInfo \* MERGEFORMAT -> old + todo: filter imports wrong? + */ + ,FIELD_INFO + /* INCLUDEPICTURE path \* MERGEFORMAT-> + old filter imports an embedded picture + todo: not yet supported + */ + ,FIELD_INCLUDEPICTURE + /* KEYWORDS keyword \* defaultswitch \* Numberingswitch \* MERGEFORMAT -> + DocInfo Keywords + */ + ,FIELD_KEYWORDS + /* LASTSAVEDBY \* MERGEFORMAT -> + DocInfo-Modified-Author + */ + ,FIELD_LASTSAVEDBY + /* MACROBUTTON MacroName quick help text -> + Macro field + */ + ,FIELD_MACROBUTTON + /* MERGEFIELD ColumName \b prefix \f suffix \* MERGEFORMAT -> + ww8filterimprovement: column-only API now upporterd + */ + ,FIELD_MERGEFIELD + /* MERGEREC \* MERGEFORMAT -> + RecordNumber field, maybe without db name + todo: currently unchecked + */ + ,FIELD_MERGEREC + /* MERGESEQ \* MERGEFORMAT -> + not imported in old ww8 filter + ww8filterimprovement: now imported + todo: currently unchecked + */ + ,FIELD_MERGESEQ + /* NEXT text -> + Next record + todo: currently unchecked + */ + ,FIELD_NEXT + /* NEXTIF condition + todo: condition not imported + */ + ,FIELD_NEXTIF + /* PAGE \* Numberingswitch \* MERGEFORMAT -> + see lcl_ParseNumberingType + */ + ,FIELD_PAGE + /* REF targetbkm \f \* MERGEFORMAT -> + imports a ShowVariable (bookmarkname)? + \h hyerlink to paragraph + \p relative to para above/below + \f refenence number + \d separator number separator + \n paragraph number + \r paragraph number in relative context + \t suppres non delimiters + \w paragraph number in full context + \* Upper/Lower... + */ + ,FIELD_REF // + /* REVNUM \* Numberingswitch \* MERGEFORMAT -> + DocInfo-revision number + */ + ,FIELD_REVNUM + /* SAVEDATE \@ "NumberFormat"\* MERGEFORMAT -> + DocInfo-modified-date + */ + ,FIELD_SAVEDATE + /* SECTION \* NumberFormat \* MERGEFORMAT -> + not imported in old ww8 filter see lcl_ParseNumberingType + todo: find alternative + */ + ,FIELD_SECTION + /* SECTIONPAGES \* NumberFormat \* MERGEFORMAT -> + not imported in old ww8 filter see lcl_ParseNumberingType + todo: find alternative + */ + ,FIELD_SECTIONPAGES + /* SEQ sequencename \h \c \n \r \s \* MERGEFORMAT -> + number range name:sequencename value:sequencename+1 + todo: only partially implemented, switches unsupported + */ + ,FIELD_SEQ + /* SET bookmarkname newtext \* MERGEFORMAT -> + SetVariable bookmarkname = newtext + todo: not implemented yet + */ + ,FIELD_SET + /* SKIPIF condition \* MERGEFORMAT -> + ?? + todo: not implemented yet + */ + ,FIELD_SKIPIF + /* STYLEREF stylename \* MERGEFORMAT -> + not imported in old ww8 filter + todo: add an equivalent field type + */ + ,FIELD_STYLEREF + /* SUBJECT subject \* Defaultswitch \* MERGEFORMAT -> + DocInfo - subject + */ + ,FIELD_SUBJECT + /* SYMBOL symbolnumber \* MERGEFORMAT -> + inserts a special char (symbolnumber) + todo: find alternative + */ + ,FIELD_SYMBOL + /* TEMPLATE \* Defaultswitch \* MERGEFORMAT + TemplateName field + */ + ,FIELD_TEMPLATE + /* TIME \@ "number format" \* MERGEFORMAT + ww8filterimprovement: multiple languages now supported + */ + ,FIELD_TIME + /* TITLE \* Defaultswitch \* MERGEFORMAT -> + DocInfo-title + */ + ,FIELD_TITLE + /* USERINITIALS newinitials \* MERGEFORMAT -> + ExtendedUser field (SHORTCUT) + */ + ,FIELD_USERINITIALS + /* USERADDRESS \* MERGEFORMAT -> + not imported in old ww8 filter + todo: find alternative + */ + ,FIELD_USERADDRESS + /* USERNAME newusername \* MERGEFORMAT -> + not imported in old ww8 filter + todo: import as extended user field(s) + */ + ,FIELD_USERNAME + /* + TOC options: + \a Builds a table of figures but does not include the captions's label and number + \b Uses a bookmark to specify area of document from which to build table of contents + \c Builds a table of figures of the given label + \d Defines the separator between sequence and page numbers + \f Builds a table of contents using TC entries instead of outline levels + \h Hyperlinks the entries and page numbers within the table of contents + \l Defines the TC entries field level used to build a table of contents + \n Builds a table of contents or a range of entries, sucah as “1-9”, in a table of contents without page numbers + \o Builds a table of contents by using outline levels instead of TC entries + \p Defines the separator between the table entry and its page number + \s Builds a table of contents by using a sequence type + \t Builds a table of contents by using style names other than the standard outline styles + \u Builds a table of contents by using the applied paragraph outline level + \w Preserve tab characters within table entries + \x Preserve newline characters within table entries + \z Hides page numbers within the table of contens when shown in Web Layout View + */ + ,FIELD_TOC + /* + TOC entry: “text” + \f TC entry in doc with multiple tables + \l Outline Level + \n Suppress page numbers + example: TOC "EntryText \f \l 2 \n + */ + ,FIELD_TC + /* document statistic - number of characters + */ + ,FIELD_NUMCHARS + /* document statistic - number of words + */ + ,FIELD_NUMWORDS + /* document statistic - number of pages + */ + ,FIELD_NUMPAGES +}; + +}} +#endif // INCLUDED_FIELD_TYPES_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/FontTable.cxx b/writerfilter/source/dmapper/FontTable.cxx new file mode 100644 index 000000000000..310c99afa1c6 --- /dev/null +++ b/writerfilter/source/dmapper/FontTable.cxx @@ -0,0 +1,239 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <FontTable.hxx> +#ifndef INCLUDED_RESOURCESIDS +#include <doctok/resourceids.hxx> +#include <ooxml/resourceids.hxx> +#endif +#include <vector> +#include <stdio.h> +#include <rtl/tencinfo.h> + +#include "dmapperLoggers.hxx" + +namespace writerfilter { +namespace dmapper +{ + +struct FontTable_Impl +{ + std::vector< FontEntry::Pointer_t > aFontEntries; + FontEntry::Pointer_t pCurrentEntry; + FontTable_Impl() {} +}; + +FontTable::FontTable() +: LoggedProperties(dmapper_logger, "FontTable") +, LoggedTable(dmapper_logger, "FontTable") +, LoggedStream(dmapper_logger, "FontTable") +, m_pImpl( new FontTable_Impl ) +{ +} + +FontTable::~FontTable() +{ + delete m_pImpl; +} + +void FontTable::lcl_attribute(Id Name, Value & val) +{ + OSL_ENSURE( m_pImpl->pCurrentEntry, "current entry has to be set here"); + if(!m_pImpl->pCurrentEntry) + return ; + int nIntValue = val.getInt(); + ::rtl::OUString sValue = val.getString(); + switch(Name) + { + case NS_rtf::LN_CBFFNM1: + m_pImpl->pCurrentEntry->sFontName1 = sValue; + break; + case NS_rtf::LN_PRQ: + m_pImpl->pCurrentEntry->nPitchRequest = static_cast<sal_Int16>( nIntValue ); + break; + case NS_rtf::LN_FTRUETYPE: + m_pImpl->pCurrentEntry->bTrueType = nIntValue == 1 ? true : false; + break; + case NS_rtf::LN_UNUSED1_3: //unused + case NS_rtf::LN_FF: //unused + case NS_rtf::LN_UNUSED1_7: //unused + break; + case NS_rtf::LN_WWEIGHT: + m_pImpl->pCurrentEntry->nBaseWeight = nIntValue; + break; + case NS_rtf::LN_CHS: + m_pImpl->pCurrentEntry->nTextEncoding = nIntValue; + break; + case NS_rtf::LN_IXCHSZALT: + break; + case NS_rtf::LN_PANOSE: + m_pImpl->pCurrentEntry->sPanose += sValue; + break; + case NS_rtf::LN_FS: + m_pImpl->pCurrentEntry->sFontSignature += sValue; + break; + case NS_rtf::LN_F: + break; + case NS_rtf::LN_ALTFONTNAME: + m_pImpl->pCurrentEntry->sAlternativeFont = sValue; + break; + case NS_rtf::LN_XSZFFN: + case NS_ooxml::LN_CT_Font_name: + m_pImpl->pCurrentEntry->sFontName = sValue; + break; + case NS_ooxml::LN_CT_Charset_val: + // w:characterSet has higher priority, set only if that one is not set + if( m_pImpl->pCurrentEntry->nTextEncoding == RTL_TEXTENCODING_DONTKNOW ) + m_pImpl->pCurrentEntry->nTextEncoding = rtl_getTextEncodingFromWindowsCharset( nIntValue ); + break; + case NS_ooxml::LN_CT_Charset_characterSet: + { + rtl::OString tmp; + sValue.convertToString( &tmp, RTL_TEXTENCODING_ASCII_US, OUSTRING_TO_OSTRING_CVTFLAGS ); + m_pImpl->pCurrentEntry->nTextEncoding = rtl_getTextEncodingFromMimeCharset( tmp ); + break; + } + default: + { + //----> debug + int nVal = val.getInt(); + ++nVal; + //<---- debug + } + } +} + +void FontTable::lcl_sprm(Sprm& rSprm) +{ + OSL_ENSURE( m_pImpl->pCurrentEntry, "current entry has to be set here"); + if(!m_pImpl->pCurrentEntry) + return ; + sal_uInt32 nSprmId = rSprm.getId(); + + Value::Pointer_t pValue = rSprm.getValue(); + sal_Int32 nIntValue = pValue->getInt(); + (void)nIntValue; + rtl::OUString sStringValue = pValue->getString(); + switch(nSprmId) + { + case NS_ooxml::LN_CT_Font_charset: + resolveSprm( rSprm ); + break; + } +} + +void FontTable::resolveSprm(Sprm & r_Sprm) +{ + writerfilter::Reference<Properties>::Pointer_t pProperties = r_Sprm.getProps(); + if( pProperties.get()) + pProperties->resolve(*this); +} + +void FontTable::lcl_entry(int /*pos*/, writerfilter::Reference<Properties>::Pointer_t ref) +{ + //create a new font entry + OSL_ENSURE( !m_pImpl->pCurrentEntry, "current entry has to be NULL here"); + m_pImpl->pCurrentEntry.reset(new FontEntry); + ref->resolve(*this); + //append it to the table + m_pImpl->aFontEntries.push_back( m_pImpl->pCurrentEntry ); + m_pImpl->pCurrentEntry.reset(); +} + +void FontTable::lcl_startSectionGroup() +{ +} + +void FontTable::lcl_endSectionGroup() +{ +} + +void FontTable::lcl_startParagraphGroup() +{ +} + +void FontTable::lcl_endParagraphGroup() +{ +} + +void FontTable::lcl_startCharacterGroup() +{ +} + +void FontTable::lcl_endCharacterGroup() +{ +} + +void FontTable::lcl_text(const sal_uInt8*, size_t ) +{ +} + +void FontTable::lcl_utext(const sal_uInt8* , size_t) +{ +} + +void FontTable::lcl_props(writerfilter::Reference<Properties>::Pointer_t) +{ +} + +void FontTable::lcl_table(Id, writerfilter::Reference<Table>::Pointer_t) +{ +} + +void FontTable::lcl_substream(Id, ::writerfilter::Reference<Stream>::Pointer_t) +{ +} + +void FontTable::lcl_info(const string& ) +{ +} + +void FontTable::lcl_startShape( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > ) +{ +} + +void FontTable::lcl_endShape( ) +{ +} + +const FontEntry::Pointer_t FontTable::getFontEntry(sal_uInt32 nIndex) +{ + return (m_pImpl->aFontEntries.size() > nIndex) + ? m_pImpl->aFontEntries[nIndex] + : FontEntry::Pointer_t(); +} + +sal_uInt32 FontTable::size() +{ + return m_pImpl->aFontEntries.size(); +} + +}//namespace dmapper +}//namespace writerfilter + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/FontTable.hxx b/writerfilter/source/dmapper/FontTable.hxx new file mode 100644 index 000000000000..d2849107558c --- /dev/null +++ b/writerfilter/source/dmapper/FontTable.hxx @@ -0,0 +1,112 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef INCLUDED_FONTTABLE_HXX +#define INCLUDED_FONTTABLE_HXX + +#include <boost/shared_ptr.hpp> +#include <WriterFilterDllApi.hxx> +#include <resourcemodel/LoggedResources.hxx> +#include <com/sun/star/lang/XComponent.hpp> + +namespace writerfilter { +namespace dmapper +{ + +struct FontTable_Impl; +struct FontEntry +{ + typedef boost::shared_ptr<FontEntry> Pointer_t; + + ::rtl::OUString sFontName; + ::rtl::OUString sFontName1; + bool bTrueType; + sal_Int16 nPitchRequest; + sal_Int32 nTextEncoding; + sal_Int32 nFontFamilyId; + sal_Int32 nBaseWeight; + sal_Int32 nAltFontIndex; + ::rtl::OUString sPanose; + ::rtl::OUString sFontSignature; + ::rtl::OUString sAlternativeFont; + FontEntry() : + bTrueType(false), + nPitchRequest( 0 ), + nTextEncoding( RTL_TEXTENCODING_DONTKNOW ), + nFontFamilyId( 0 ), + nBaseWeight( 0 ), + nAltFontIndex( 0 ) + {} +}; + +class WRITERFILTER_DLLPRIVATE FontTable : public LoggedProperties, public LoggedTable + /*,public BinaryObj*/, public LoggedStream +{ + FontTable_Impl *m_pImpl; + + public: + FontTable(); + virtual ~FontTable(); + + sal_uInt32 size(); + const FontEntry::Pointer_t getFontEntry(sal_uInt32 nIndex); + + private: + // Properties + virtual void lcl_attribute(Id Name, Value & val); + virtual void lcl_sprm(Sprm & sprm); + void resolveSprm(Sprm & r_sprm); + + // Table + virtual void lcl_entry(int pos, writerfilter::Reference<Properties>::Pointer_t ref); + + // Stream + virtual void lcl_startSectionGroup(); + virtual void lcl_endSectionGroup(); + virtual void lcl_startParagraphGroup(); + virtual void lcl_endParagraphGroup(); + virtual void lcl_startCharacterGroup(); + virtual void lcl_endCharacterGroup(); + virtual void lcl_text(const sal_uInt8 * data, size_t len); + virtual void lcl_utext(const sal_uInt8 * data, size_t len); + virtual void lcl_props(writerfilter::Reference<Properties>::Pointer_t ref); + virtual void lcl_table(Id name, + writerfilter::Reference<Table>::Pointer_t ref); + virtual void lcl_substream(Id name, + ::writerfilter::Reference<Stream>::Pointer_t ref); + virtual void lcl_info(const string & info); + virtual void lcl_startShape( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape ); + virtual void lcl_endShape( ); + +}; +typedef boost::shared_ptr< FontTable > FontTablePtr; +}} + +#endif // + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/FormControlHelper.cxx b/writerfilter/source/dmapper/FormControlHelper.cxx new file mode 100644 index 000000000000..8311f94296dc --- /dev/null +++ b/writerfilter/source/dmapper/FormControlHelper.cxx @@ -0,0 +1,373 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <math.h> + +#include <com/sun/star/awt/XControlModel.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/container/XIndexContainer.hpp> +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/drawing/XControlShape.hpp> +#include <com/sun/star/drawing/XDrawPage.hpp> +#include <com/sun/star/drawing/XDrawPageSupplier.hpp> +#include <com/sun/star/form/XForm.hpp> +#include <com/sun/star/form/XFormComponent.hpp> +#include <com/sun/star/form/XFormsSupplier.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/text/TextContentAnchorType.hpp> +#include <com/sun/star/text/VertOrientation.hpp> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Type.hxx> + +#include "FormControlHelper.hxx" +#include <xmloff/odffields.hxx> +#include <comphelper/stlunosequence.hxx> + +namespace writerfilter { +namespace dmapper { + +using namespace ::com::sun::star; + +struct FormControlHelper::FormControlHelper_Impl +{ + FieldId m_eFieldId; + awt::Size aSize; + uno::Reference<drawing::XDrawPage> rDrawPage; + uno::Reference<form::XForm> rForm; + uno::Reference<form::XFormComponent> rFormComponent; + uno::Reference<lang::XMultiServiceFactory> rServiceFactory; + uno::Reference<text::XTextDocument> rTextDocument; + + uno::Reference<drawing::XDrawPage> getDrawPage(); + uno::Reference<lang::XMultiServiceFactory> getServiceFactory(); + uno::Reference<form::XForm> getForm(); + uno::Reference<container::XIndexContainer> getFormComps(); +}; + +uno::Reference<drawing::XDrawPage> FormControlHelper::FormControlHelper_Impl::getDrawPage() +{ + if (! rDrawPage.is()) + { + uno::Reference<drawing::XDrawPageSupplier> + xDrawPageSupplier(rTextDocument, uno::UNO_QUERY); + if (xDrawPageSupplier.is()) + rDrawPage = xDrawPageSupplier->getDrawPage(); + } + + return rDrawPage; +} + +uno::Reference<lang::XMultiServiceFactory> FormControlHelper::FormControlHelper_Impl::getServiceFactory() +{ + if (! rServiceFactory.is()) + rServiceFactory = uno::Reference<lang::XMultiServiceFactory>(rTextDocument, uno::UNO_QUERY); + + return rServiceFactory; +} + +uno::Reference<form::XForm> FormControlHelper::FormControlHelper_Impl::getForm() +{ + if (! rForm.is()) + { + uno::Reference<form::XFormsSupplier> xFormsSupplier(getDrawPage(), uno::UNO_QUERY); + + if (xFormsSupplier.is()) + { + uno::Reference<container::XNameContainer> xFormsNamedContainer(xFormsSupplier->getForms()); + static ::rtl::OUString sDOCXForm(RTL_CONSTASCII_USTRINGPARAM("DOCX-Standard")); + + ::rtl::OUString sFormName(sDOCXForm); + sal_uInt16 nUnique = 0; + + while (xFormsNamedContainer->hasByName(sFormName)) + { + ++nUnique; + sFormName = sDOCXForm; + sFormName += ::rtl::OUString::valueOf(nUnique); + } + + uno::Reference<uno::XInterface> + xForm(getServiceFactory()->createInstance + (::rtl::OUString + (RTL_CONSTASCII_USTRINGPARAM + ("com.sun.star.form.component.Form")))); + if (xForm.is()) + { + uno::Reference<beans::XPropertySet> + xFormProperties(xForm, uno::UNO_QUERY); + uno::Any aAny(sFormName); + static ::rtl::OUString sName(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Name"))); + xFormProperties->setPropertyValue(sName, aAny); + } + + rForm = uno::Reference<form::XForm>(xForm, uno::UNO_QUERY); + + uno::Reference<container::XIndexContainer> xForms(xFormsNamedContainer, uno::UNO_QUERY); + uno::Any aAny(xForm); + xForms->insertByIndex(xForms->getCount(), aAny); + } + } + + return rForm; +} + +uno::Reference<container::XIndexContainer> FormControlHelper::FormControlHelper_Impl::getFormComps() +{ + uno::Reference<container::XIndexContainer> xIndexContainer(getForm(), uno::UNO_QUERY); + + return xIndexContainer; +} + +FormControlHelper::FormControlHelper(FieldId eFieldId, + uno::Reference<text::XTextDocument> rTextDocument, + FFDataHandler::Pointer_t pFFData) + : m_pFFData(pFFData), m_pImpl(new FormControlHelper_Impl) +{ + m_pImpl->m_eFieldId = eFieldId; + m_pImpl->rTextDocument = rTextDocument; +} + +FormControlHelper::~FormControlHelper() +{ +} + +bool FormControlHelper::createCheckbox(uno::Reference<text::XTextRange> xTextRange, + const ::rtl::OUString & rControlName) +{ + if ( !m_pFFData ) + return false; + uno::Reference<lang::XMultiServiceFactory> + xServiceFactory(m_pImpl->getServiceFactory()); + + if (! xServiceFactory.is()) + return false; + + uno::Reference<uno::XInterface> xInterface = + xServiceFactory->createInstance + (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.form.component.CheckBox"))); + + if (!xInterface.is()) + return false; + + m_pImpl->rFormComponent = uno::Reference<form::XFormComponent>(xInterface, uno::UNO_QUERY); + if (!m_pImpl->rFormComponent.is()) + return false; + + uno::Reference<beans::XPropertySet> xPropSet(xInterface, uno::UNO_QUERY); + + sal_uInt32 nCheckBoxHeight = 16 * m_pFFData->getCheckboxHeight(); + + if (m_pFFData->getCheckboxAutoHeight()) + { + uno::Reference<beans::XPropertySet> xTextRangeProps(xTextRange, uno::UNO_QUERY); + + try + { + static ::rtl::OUString sCharHeight(RTL_CONSTASCII_USTRINGPARAM("CharHeight")); + float fCheckBoxHeight = 0.0; + xTextRangeProps->getPropertyValue(sCharHeight) >>= fCheckBoxHeight; + nCheckBoxHeight = floor(fCheckBoxHeight * 35.3); + } + catch (beans::UnknownPropertyException & rException) + { + } + } + + m_pImpl->aSize.Width = nCheckBoxHeight; + m_pImpl->aSize.Height = m_pImpl->aSize.Width; + + uno::Any aAny; + if (m_pFFData->getStatusText().getLength()) + { + aAny <<= m_pFFData->getStatusText(); + + xPropSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HelpText")), aAny); + } + + aAny <<= m_pFFData->getCheckboxChecked(); + xPropSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultState")), aAny); + + if (m_pFFData->getHelpText().getLength()) + { + aAny <<= m_pFFData->getHelpText(); + xPropSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HelpF1Text")), aAny); + } + + aAny <<= rControlName; + xPropSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Name")), aAny); + + return true; +} + +bool FormControlHelper::processField(uno::Reference<text::XFormField> xFormField) +{ + bool bRes = true; + uno::Reference<container::XNameContainer> xNameCont = xFormField->getParameters(); + uno::Reference<container::XNamed> xNamed( xFormField, uno::UNO_QUERY ); + if ( m_pFFData && xNamed.is() && xNameCont.is() ) + { + + if (m_pImpl->m_eFieldId == FIELD_FORMTEXT ) + { + xFormField->setFieldType( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ODF_FORMTEXT))); + if ( m_pFFData->getName().getLength() ) + { + xNamed->setName( m_pFFData->getName() ); + } + } + else if (m_pImpl->m_eFieldId == FIELD_FORMCHECKBOX ) + { + xFormField->setFieldType( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ODF_FORMCHECKBOX))); + uno::Reference<beans::XPropertySet> xPropSet(xFormField, uno::UNO_QUERY); + uno::Any aAny; + aAny <<= m_pFFData->getCheckboxChecked(); + if ( xPropSet.is() ) + xPropSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Checked")), aAny); + rtl::OUString sName; + } + else if (m_pImpl->m_eFieldId == FIELD_FORMDROPDOWN ) + { + xFormField->setFieldType( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ODF_FORMDROPDOWN))); + uno::Sequence< rtl::OUString > sItems; + sItems.realloc( m_pFFData->getDropDownEntries().size() ); + ::std::copy( m_pFFData->getDropDownEntries().begin(), m_pFFData->getDropDownEntries().end(), ::comphelper::stl_begin(sItems)); + if ( sItems.getLength() ) + { + if ( xNameCont->hasByName( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ODF_FORMDROPDOWN_LISTENTRY)) ) ) + xNameCont->replaceByName( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ODF_FORMDROPDOWN_LISTENTRY)), uno::makeAny( sItems ) ); + else + xNameCont->insertByName( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ODF_FORMDROPDOWN_LISTENTRY)), uno::makeAny( sItems ) ); + + sal_Int32 nResult = m_pFFData->getDropDownResult().toInt32(); + if ( nResult ) + { + if ( xNameCont->hasByName( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ODF_FORMDROPDOWN_RESULT)) ) ) + xNameCont->replaceByName( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ODF_FORMDROPDOWN_RESULT)), uno::makeAny( nResult ) ); + else + xNameCont->insertByName( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ODF_FORMDROPDOWN_RESULT)), uno::makeAny( nResult ) ); + } + } + } + } + else + bRes = false; + return bRes; +} + +bool FormControlHelper::insertControl(uno::Reference<text::XTextRange> xTextRange) +{ + bool bCreated = false; + if ( !m_pFFData ) + return false; + uno::Reference<container::XNameContainer> xFormCompsByName(m_pImpl->getForm(), uno::UNO_QUERY); + uno::Reference<container::XIndexContainer> xFormComps(m_pImpl->getFormComps()); + if (! xFormComps.is()) + return false; + + static ::rtl::OUString sControl(RTL_CONSTASCII_USTRINGPARAM("Control")); + + sal_Int32 nControl = 0; + bool bDone = false; + ::rtl::OUString sControlName; + + do + { + ::rtl::OUString sTmp(sControl); + sTmp += ::rtl::OUString::valueOf(nControl); + + nControl++; + if (! xFormCompsByName->hasByName(sTmp)) + { + sControlName = sTmp; + bDone = true; + } + } + while (! bDone); + + switch (m_pImpl->m_eFieldId) + { + case FIELD_FORMCHECKBOX: + bCreated = createCheckbox(xTextRange, sControlName); + break; + default: + break; + } + + if (!bCreated) + return false; + + uno::Any aAny(m_pImpl->rFormComponent); + xFormComps->insertByIndex(xFormComps->getCount(), aAny); + + if (! m_pImpl->getServiceFactory().is()) + return false; + + uno::Reference<uno::XInterface> xInterface = + m_pImpl->getServiceFactory()->createInstance + (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.ControlShape"))); + + if (! xInterface.is()) + return false; + + uno::Reference<drawing::XShape> xShape(xInterface, uno::UNO_QUERY); + + if (! xShape.is()) + return false; + + xShape->setSize(m_pImpl->aSize); + + uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY); + + sal_uInt16 nTmp = text::TextContentAnchorType_AS_CHARACTER; + aAny <<= nTmp; + + static const ::rtl::OUString sAnchorType(RTL_CONSTASCII_USTRINGPARAM("AnchorType")); + xShapeProps->setPropertyValue(sAnchorType, aAny); + + static const ::rtl::OUString sVertOrient(RTL_CONSTASCII_USTRINGPARAM("VertOrient")); + nTmp = text::VertOrientation::CENTER; + aAny <<= nTmp; + xShapeProps->setPropertyValue(sVertOrient, aAny); + + aAny <<= xTextRange; + + static const ::rtl::OUString sTextRange(RTL_CONSTASCII_USTRINGPARAM("TextRange")); + xShapeProps->setPropertyValue(sTextRange, aAny); + + uno::Reference<drawing::XControlShape> xControlShape(xShape, uno::UNO_QUERY); + uno::Reference<awt::XControlModel> xControlModel(m_pImpl->rFormComponent, uno::UNO_QUERY); + xControlShape->setControl(xControlModel); + + m_pImpl->getDrawPage()->add(xShape); + + return true; +} + +}} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/FormControlHelper.hxx b/writerfilter/source/dmapper/FormControlHelper.hxx new file mode 100644 index 000000000000..a56597f5becb --- /dev/null +++ b/writerfilter/source/dmapper/FormControlHelper.hxx @@ -0,0 +1,71 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef INCLUDED_FORM_CONTROL_HELPER_HXX +#define INCLUDED_FORM_CONTROL_HELPER_HXX + +#include <FFDataHandler.hxx> +#include <com/sun/star/text/XTextDocument.hpp> +#include <com/sun/star/text/XFormField.hpp> +#include <com/sun/star/uno/Reference.hxx> +#include "FieldTypes.hxx" + +namespace writerfilter { +namespace dmapper { + +using namespace ::com::sun::star; + +class FormControlHelper +{ +public: + typedef boost::shared_ptr<FormControlHelper> Pointer_t; + FormControlHelper(FieldId eFieldId, + uno::Reference<text::XTextDocument> rTextDocument, + FFDataHandler::Pointer_t pFFData); + ~FormControlHelper(); + + bool insertControl(uno::Reference<text::XTextRange> xTextRange); + bool processField(uno::Reference<text::XFormField> xFormField); + bool hasFFDataHandler() const { return (m_pFFData != NULL); } +private: + FFDataHandler::Pointer_t m_pFFData; + struct FormControlHelper_Impl; + typedef boost::shared_ptr<FormControlHelper_Impl> ImplPointer_t; + ImplPointer_t m_pImpl; + + bool createCheckbox(uno::Reference<text::XTextRange> xTextRange, + const ::rtl::OUString & rControlName); + bool createDropdown(uno::Reference<text::XTextRange> xTextRange, + const ::rtl::OUString & rControlName); +}; + +} +} + +#endif // INCLUDED_FORM_CONTROL_HELPER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/GraphicHelpers.cxx b/writerfilter/source/dmapper/GraphicHelpers.cxx new file mode 100644 index 000000000000..d3af9dac4c35 --- /dev/null +++ b/writerfilter/source/dmapper/GraphicHelpers.cxx @@ -0,0 +1,236 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +#include "ConversionHelper.hxx" +#include "GraphicHelpers.hxx" + +#include <ooxml/resourceids.hxx> + +#include <com/sun/star/text/HoriOrientation.hpp> +#include <com/sun/star/text/VertOrientation.hpp> +#include <com/sun/star/text/RelOrientation.hpp> +#include <com/sun/star/text/WrapTextMode.hpp> + +#include "dmapperLoggers.hxx" + +#include <iostream> +using namespace std; + +namespace writerfilter { +namespace dmapper { + +using namespace com::sun::star; + +PositionHandler::PositionHandler( ) : +LoggedProperties(dmapper_logger, "PositionHandler") +{ + m_nOrient = text::VertOrientation::NONE; + m_nRelation = text::RelOrientation::FRAME; + m_nPosition = 0; +} + +PositionHandler::~PositionHandler( ) +{ +} + +void PositionHandler::lcl_attribute( Id aName, Value& rVal ) +{ + sal_Int32 nIntValue = rVal.getInt( ); + switch ( aName ) + { + case NS_ooxml::LN_CT_PosV_relativeFrom: + { + // TODO There are some other unhandled values + static Id pVertRelValues[] = + { + NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromV_margin, + NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromV_page, + NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromV_paragraph, + NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromV_line + }; + + static sal_Int16 pVertRelations[] = + { + text::RelOrientation::PAGE_PRINT_AREA, + text::RelOrientation::PAGE_FRAME, + text::RelOrientation::FRAME, + text::RelOrientation::TEXT_LINE + }; + + for ( int i = 0; i < 4; i++ ) + { + if ( pVertRelValues[i] == sal_uInt32( nIntValue ) ) + m_nRelation = pVertRelations[i]; + } + } + break; + case NS_ooxml::LN_CT_PosH_relativeFrom: + { + // TODO There are some other unhandled values + static Id pHoriRelValues[] = + { + NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromH_margin, + NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromH_page, + NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromH_column, + NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromH_character + }; + + static sal_Int16 pHoriRelations[] = + { + text::RelOrientation::PAGE_PRINT_AREA, + text::RelOrientation::PAGE_FRAME, + text::RelOrientation::FRAME, + text::RelOrientation::CHAR, + }; + + for ( int i = 0; i < 4; i++ ) + { + if ( pHoriRelValues[i] == sal_uInt32( nIntValue ) ) + m_nRelation = pHoriRelations[i]; + } + } + break; + default: +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->element("unhandled"); +#endif + break; + } +} + +void PositionHandler::lcl_sprm( Sprm& rSprm ) +{ + Value::Pointer_t pValue = rSprm.getValue(); + sal_Int32 nIntValue = pValue->getInt(); + + switch ( rSprm.getId( ) ) + { + case NS_ooxml::LN_CT_PosV_align: + { + static Id pVertValues[] = + { + NS_ooxml::LN_Value_wordprocessingDrawing_ST_AlignV_top, + NS_ooxml::LN_Value_wordprocessingDrawing_ST_AlignV_bottom, + NS_ooxml::LN_Value_wordprocessingDrawing_ST_AlignV_center, + NS_ooxml::LN_Value_wordprocessingDrawing_ST_AlignV_inside, + NS_ooxml::LN_Value_wordprocessingDrawing_ST_AlignV_outside + }; + + static sal_Int16 pVertOrients[] = + { + text::VertOrientation::TOP, + text::VertOrientation::BOTTOM, + text::VertOrientation::CENTER, + text::VertOrientation::NONE, + text::VertOrientation::NONE + }; + + for ( int i = 0; i < 5; i++ ) + { + if ( pVertValues[i] == sal_uInt32( nIntValue ) ) + m_nOrient = pVertOrients[i]; + } + } + break; + case NS_ooxml::LN_CT_PosH_align: + { + static Id pHoriValues[] = + { + NS_ooxml::LN_Value_wordprocessingDrawing_ST_AlignH_left, + NS_ooxml::LN_Value_wordprocessingDrawing_ST_AlignH_right, + NS_ooxml::LN_Value_wordprocessingDrawing_ST_AlignH_center, + NS_ooxml::LN_Value_wordprocessingDrawing_ST_AlignH_inside, + NS_ooxml::LN_Value_wordprocessingDrawing_ST_AlignH_outside + }; + + static sal_Int16 pHoriOrients[] = + { + text::HoriOrientation::LEFT, + text::HoriOrientation::RIGHT, + text::HoriOrientation::CENTER, + text::HoriOrientation::INSIDE, + text::HoriOrientation::OUTSIDE + }; + + for ( int i = 0; i < 5; i++ ) + { + if ( pHoriValues[i] == sal_uInt32( nIntValue ) ) + m_nOrient = pHoriOrients[i]; + } + } + break; + case NS_ooxml::LN_CT_PosH_posOffset: + case NS_ooxml::LN_CT_PosV_posOffset: + m_nPosition = ConversionHelper::convertEMUToMM100( nIntValue ); + default: +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->element("unhandled"); +#endif + break; + } +} + +WrapHandler::WrapHandler( ) : +LoggedProperties(dmapper_logger, "WrapHandler"), + m_nType( 0 ), + m_nSide( 0 ) +{ +} + +WrapHandler::~WrapHandler( ) +{ +} + +void WrapHandler::lcl_attribute( Id aName, Value& rVal ) +{ + switch ( aName ) + { + case NS_ooxml::LN_CT_Wrap_type: + m_nType = sal_Int32( rVal.getInt( ) ); + break; + case NS_ooxml::LN_CT_Wrap_side: + m_nSide = sal_Int32( rVal.getInt( ) ); + break; + default:; + } +} + +void WrapHandler::lcl_sprm( Sprm& ) +{ +} + +sal_Int32 WrapHandler::getWrapMode( ) +{ + sal_Int32 nMode = com::sun::star::text::WrapTextMode_NONE; + + switch ( m_nType ) + { + case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapType_square: + case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapType_tight: + { + switch ( m_nSide ) + { + case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapSide_left: + nMode = com::sun::star::text::WrapTextMode_LEFT; + break; + case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapSide_right: + nMode = com::sun::star::text::WrapTextMode_RIGHT; + break; + default: + nMode = com::sun::star::text::WrapTextMode_PARALLEL; + } + } + break; + case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapType_through: + nMode = com::sun::star::text::WrapTextMode_THROUGHT; + break; + case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapType_topAndBottom: + case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapType_none: + default: + nMode = com::sun::star::text::WrapTextMode_NONE; + } + + return nMode; +} + +} } + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/GraphicHelpers.hxx b/writerfilter/source/dmapper/GraphicHelpers.hxx new file mode 100644 index 000000000000..c7761132359c --- /dev/null +++ b/writerfilter/source/dmapper/GraphicHelpers.hxx @@ -0,0 +1,53 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +#ifndef INCLUDED_GRAPHICHELPERS_HXX +#define INCLUDED_GRAPHICHELPERS_HXX + +#include "PropertyMap.hxx" + +#include <WriterFilterDllApi.hxx> +#include <resourcemodel/LoggedResources.hxx> + +#include <boost/shared_ptr.hpp> + +namespace writerfilter { +namespace dmapper +{ + +class WRITERFILTER_DLLPRIVATE PositionHandler: public LoggedProperties +{ +public: + PositionHandler( ); + ~PositionHandler( ); + + sal_Int16 m_nOrient; + sal_Int16 m_nRelation; + sal_Int32 m_nPosition; + + private: + virtual void lcl_attribute( Id aName, Value& rVal ); + virtual void lcl_sprm( Sprm& rSprm ); +}; +typedef boost::shared_ptr<PositionHandler> PositionHandlerPtr; + +class WRITERFILTER_DLLPRIVATE WrapHandler: public LoggedProperties +{ +public: + WrapHandler( ); + ~WrapHandler( ); + + sal_Int32 m_nType; + sal_Int32 m_nSide; + + sal_Int32 getWrapMode( ); + + private: + virtual void lcl_attribute( Id aName, Value& rVal ); + virtual void lcl_sprm( Sprm& rSprm ); +}; +typedef boost::shared_ptr<WrapHandler> WrapHandlerPtr; + +} } + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/GraphicImport.cxx b/writerfilter/source/dmapper/GraphicImport.cxx new file mode 100644 index 000000000000..e96bc1933234 --- /dev/null +++ b/writerfilter/source/dmapper/GraphicImport.cxx @@ -0,0 +1,1604 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <string.h> + +#include <com/sun/star/awt/Size.hpp> +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/drawing/ColorMode.hpp> +#include <com/sun/star/drawing/PointSequenceSequence.hpp> +#include <com/sun/star/drawing/XShape.hpp> +#include <com/sun/star/graphic/XGraphic.hpp> +#include <com/sun/star/graphic/XGraphicProvider.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/table/BorderLine2.hpp> +#include <com/sun/star/text/GraphicCrop.hpp> +#include <com/sun/star/text/HoriOrientation.hpp> +#include <com/sun/star/text/RelOrientation.hpp> +#include <com/sun/star/text/TextContentAnchorType.hpp> +#include <com/sun/star/text/VertOrientation.hpp> +#include <com/sun/star/text/WrapTextMode.hpp> +#include <com/sun/star/text/XTextContent.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> + +#include <cppuhelper/implbase1.hxx> +#include <rtl/ustrbuf.hxx> + +#include <dmapper/DomainMapper.hxx> +#include <doctok/resourceids.hxx> +#include <ooxml/resourceids.hxx> +#include <resourcemodel/ResourceModelHelper.hxx> + +#include "ConversionHelper.hxx" +#include "GraphicHelpers.hxx" +#include "GraphicImport.hxx" +#include "PropertyMap.hxx" +#include "WrapPolygonHandler.hxx" +#include "dmapperLoggers.hxx" + +namespace writerfilter { + +using resourcemodel::resolveSprmProps; + +namespace dmapper +{ +using namespace ::std; +using namespace ::com::sun::star; + +class XInputStreamHelper : public cppu::WeakImplHelper1 +< io::XInputStream > +{ + const sal_uInt8* m_pBuffer; + const sal_Int32 m_nLength; + sal_Int32 m_nPosition; + bool m_bBmp; + + const sal_uInt8* m_pBMPHeader; //default BMP-header + sal_Int32 m_nHeaderLength; +public: + XInputStreamHelper(const sal_uInt8* buf, size_t len, bool bBmp); + ~XInputStreamHelper(); + + virtual ::sal_Int32 SAL_CALL readBytes( uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nBytesToRead ) throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL readSomeBytes( uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nMaxBytesToRead ) throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException); + virtual void SAL_CALL skipBytes( ::sal_Int32 nBytesToSkip ) throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL available( ) throw (io::NotConnectedException, io::IOException, uno::RuntimeException); + virtual void SAL_CALL closeInput( ) throw (io::NotConnectedException, io::IOException, uno::RuntimeException); +}; + + +XInputStreamHelper::XInputStreamHelper(const sal_uInt8* buf, size_t len, bool bBmp) : + m_pBuffer( buf ), + m_nLength( len ), + m_nPosition( 0 ), + m_bBmp( bBmp ) +{ + static const sal_uInt8 aHeader[] = + {0x42, 0x4d, 0xe6, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 }; + m_pBMPHeader = aHeader; + m_nHeaderLength = m_bBmp ? sizeof( aHeader ) / sizeof(sal_uInt8) : 0; + +} + + +XInputStreamHelper::~XInputStreamHelper() +{ +} + + +::sal_Int32 XInputStreamHelper::readBytes( uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nBytesToRead ) + throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException) +{ + return readSomeBytes( aData, nBytesToRead ); +} + + +::sal_Int32 XInputStreamHelper::readSomeBytes( uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nMaxBytesToRead ) + throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException) +{ + sal_Int32 nRet = 0; + if( nMaxBytesToRead > 0 ) + { + if( nMaxBytesToRead > (m_nLength + m_nHeaderLength) - m_nPosition ) + nRet = (m_nLength + m_nHeaderLength) - m_nPosition; + else + nRet = nMaxBytesToRead; + aData.realloc( nRet ); + sal_Int8* pData = aData.getArray(); + sal_Int32 nHeaderRead = 0; + if( m_nPosition < m_nHeaderLength) + { + //copy header content first + nHeaderRead = m_nHeaderLength - m_nPosition; + memcpy( pData, m_pBMPHeader + (m_nPosition ), nHeaderRead ); + nRet -= nHeaderRead; + m_nPosition += nHeaderRead; + } + if( nRet ) + { + memcpy( pData + nHeaderRead, m_pBuffer + (m_nPosition - m_nHeaderLength), nRet ); + m_nPosition += nRet; + } + } + return nRet; +} + + +void XInputStreamHelper::skipBytes( ::sal_Int32 nBytesToSkip ) throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException) +{ + if( nBytesToSkip < 0 || m_nPosition + nBytesToSkip > (m_nLength + m_nHeaderLength)) + throw io::BufferSizeExceededException(); + m_nPosition += nBytesToSkip; +} + + +::sal_Int32 XInputStreamHelper::available( ) throw (io::NotConnectedException, io::IOException, uno::RuntimeException) +{ + return ( m_nLength + m_nHeaderLength ) - m_nPosition; +} + + +void XInputStreamHelper::closeInput( ) throw (io::NotConnectedException, io::IOException, uno::RuntimeException) +{ +} + + +struct GraphicBorderLine +{ + sal_Int32 nLineWidth; + sal_Int32 nLineColor; + sal_Int32 nLineDistance; + bool bHasShadow; + + GraphicBorderLine() : + nLineWidth(0) + ,nLineColor(0) + ,nLineDistance(0) + ,bHasShadow(false) + {} + +}; + +class GraphicImport_Impl +{ +private: + sal_Int32 nXSize; + bool bXSizeValid; + sal_Int32 nYSize; + bool bYSizeValid; + +public: + GraphicImportType eGraphicImportType; + DomainMapper& rDomainMapper; + + sal_Int32 nHoriScaling; + sal_Int32 nVertScaling; + sal_Int32 nLeftPosition; + sal_Int32 nTopPosition; + sal_Int32 nRightPosition; + sal_Int32 nBottomPosition; + sal_Int32 nLeftCrop; + sal_Int32 nTopCrop; + sal_Int32 nRightCrop; + sal_Int32 nBottomCrop; + + bool bUseSimplePos; + + sal_Int16 nHoriOrient; + sal_Int16 nHoriRelation; + bool bPageToggle; + sal_Int16 nVertOrient; + sal_Int16 nVertRelation; + sal_Int32 nWrap; + bool bOpaque; + bool bContour; + bool bContourOutside; + WrapPolygon::Pointer_t mpWrapPolygon; + bool bIgnoreWRK; + + sal_Int32 nLeftMargin; + sal_Int32 nRightMargin; + sal_Int32 nTopMargin; + sal_Int32 nBottomMargin; + + sal_Int32 nContrast; + sal_Int32 nBrightness; + double fGamma; + + sal_Int32 nFillColor; + + drawing::ColorMode eColorMode; + + GraphicBorderLine aBorders[4]; + sal_Int32 nCurrentBorderLine; + + sal_Int32 nDffType; + bool bIsGraphic; + bool bIsBitmap; + bool bIsTiff; + sal_Int32 nBitsPerPixel; + + bool bHoriFlip; + bool bVertFlip; + + bool bSizeProtected; + bool bPositionProtected; + + bool bInShapeOptionMode; + sal_Int32 nShapeOptionType; + + ::rtl::OUString sName; + ::rtl::OUString sAlternativeText; + + GraphicImport_Impl(GraphicImportType eImportType, DomainMapper& rDMapper) : + nXSize(0) + ,bXSizeValid(false) + ,nYSize(0) + ,bYSizeValid(false) + ,eGraphicImportType( eImportType ) + ,rDomainMapper( rDMapper ) + ,nHoriScaling(0) + ,nVertScaling(0) + ,nLeftPosition(0) + ,nTopPosition(0) + ,nRightPosition(0) + ,nBottomPosition(0) + ,nLeftCrop(0) + ,nTopCrop (0) + ,nRightCrop (0) + ,nBottomCrop(0) + ,bUseSimplePos(false) + ,nHoriOrient( text::HoriOrientation::NONE ) + ,nHoriRelation( text::RelOrientation::FRAME ) + ,bPageToggle( false ) + ,nVertOrient( text::VertOrientation::NONE ) + ,nVertRelation( text::RelOrientation::FRAME ) + ,nWrap(0) + ,bOpaque( true ) + ,bContour(false) + ,bContourOutside(true) + ,bIgnoreWRK(true) + ,nLeftMargin(319) + ,nRightMargin(319) + ,nTopMargin(0) + ,nBottomMargin(0) + ,nContrast(0) + ,nBrightness(0) + ,fGamma( -1.0 ) + ,nFillColor( 0xffffffff ) + ,eColorMode( drawing::ColorMode_STANDARD ) + ,nCurrentBorderLine(BORDER_TOP) + ,nDffType( 0 ) + ,bIsGraphic(false) + ,bIsBitmap(false) + ,bIsTiff(false) + ,nBitsPerPixel(0) + ,bHoriFlip(false) + ,bVertFlip(false) + ,bSizeProtected(false) + ,bPositionProtected(false) + ,bInShapeOptionMode(false) + {} + + void setXSize(sal_Int32 _nXSize) + { + nXSize = _nXSize; + bXSizeValid = true; + } + + sal_uInt32 getXSize() const + { + return nXSize; + } + + bool isXSizeValid() const + { + return bXSizeValid; + } + + void setYSize(sal_Int32 _nYSize) + { + nYSize = _nYSize; + bYSizeValid = true; + } + + sal_uInt32 getYSize() const + { + return nYSize; + } + + bool isYSizeValis () const + { + return bYSizeValid; + } +}; + + +GraphicImport::GraphicImport(uno::Reference < uno::XComponentContext > xComponentContext, + uno::Reference< lang::XMultiServiceFactory > xTextFactory, + DomainMapper& rDMapper, + GraphicImportType eImportType ) +: LoggedProperties(dmapper_logger, "GraphicImport") +, LoggedTable(dmapper_logger, "GraphicImport") +, LoggedStream(dmapper_logger, "GraphicImport") +, m_pImpl( new GraphicImport_Impl( eImportType, rDMapper )) +, m_xComponentContext( xComponentContext ) +, m_xTextFactory( xTextFactory) +{ +} + + +GraphicImport::~GraphicImport() +{ + delete m_pImpl; +} + +void GraphicImport::handleWrapTextValue(sal_uInt32 nVal) +{ + switch (nVal) + { + case NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_bothSides: // 90920; + m_pImpl->nWrap = text::WrapTextMode_PARALLEL; + break; + case NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_left: // 90921; + m_pImpl->nWrap = text::WrapTextMode_LEFT; + break; + case NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_right: // 90922; + m_pImpl->nWrap = text::WrapTextMode_RIGHT; + break; + case NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_largest: // 90923; + m_pImpl->nWrap = text::WrapTextMode_DYNAMIC; + break; + default:; + } +} + + + +void GraphicImport::lcl_attribute(Id nName, Value & val) +{ + sal_Int32 nIntValue = val.getInt(); + switch( nName ) + { + case NS_rtf::LN_LCB: break;//byte count + case NS_rtf::LN_CBHEADER: break;//ignored + case NS_rtf::LN_MFP: //MetafilePict + case NS_rtf::LN_DffRecord: //dff record - expands to an sprm which expands to ... + case NS_rtf::LN_shpopt: //shape options + case NS_rtf::LN_shpfbse: //BLIP store entry + case NS_rtf::LN_BRCTOP: //top border + case NS_rtf::LN_BRCLEFT: //left border + case NS_rtf::LN_BRCBOTTOM: //bottom border + case NS_rtf::LN_BRCRIGHT: //right border + case NS_rtf::LN_shape: //shape + case NS_rtf::LN_blip: //the binary graphic data in a shape + { + switch(nName) + { + case NS_rtf::LN_BRCTOP: //top border + m_pImpl->nCurrentBorderLine = BORDER_TOP; + break; + case NS_rtf::LN_BRCLEFT: //left border + m_pImpl->nCurrentBorderLine = BORDER_LEFT; + break; + case NS_rtf::LN_BRCBOTTOM: //bottom border + m_pImpl->nCurrentBorderLine = BORDER_BOTTOM; + break; + case NS_rtf::LN_BRCRIGHT: //right border + m_pImpl->nCurrentBorderLine = BORDER_RIGHT; + break; + case NS_rtf::LN_shpopt: + m_pImpl->bInShapeOptionMode = true; + break; + default:; + } + writerfilter::Reference<Properties>::Pointer_t pProperties = val.getProperties(); + if( pProperties.get()) + { + pProperties->resolve(*this); + } + switch(nName) + { + case NS_rtf::LN_shpopt: + m_pImpl->bInShapeOptionMode = false; + break; + default:; + } + } + break; + case NS_rtf::LN_payload : + { + writerfilter::Reference<BinaryObj>::Pointer_t pPictureData = val.getBinary(); + if( pPictureData.get()) + pPictureData->resolve(*this); + } + break; + case NS_rtf::LN_BM_RCWINMF: //windows bitmap structure - if it's a bitmap + break; + case NS_rtf::LN_DXAGOAL: //x-size in twip + case NS_rtf::LN_DYAGOAL: //y-size in twip + break; + case NS_rtf::LN_MX: + m_pImpl->nHoriScaling = nIntValue; + break;// hori scaling in 0.001% + case NS_rtf::LN_MY: + m_pImpl->nVertScaling = nIntValue; + break;// vert scaling in 0.001% + case NS_rtf::LN_DXACROPLEFT: + m_pImpl->nLeftCrop = ConversionHelper::convertTwipToMM100(nIntValue); + break;// left crop in twips + case NS_rtf::LN_DYACROPTOP: + m_pImpl->nTopCrop = ConversionHelper::convertTwipToMM100(nIntValue); + break;// top crop in twips + case NS_rtf::LN_DXACROPRIGHT: + m_pImpl->nRightCrop = ConversionHelper::convertTwipToMM100(nIntValue); + break;// right crop in twips + case NS_rtf::LN_DYACROPBOTTOM: + m_pImpl->nBottomCrop = ConversionHelper::convertTwipToMM100(nIntValue); + break;// bottom crop in twips + case NS_rtf::LN_BRCL: + break;//border type - legacy - + case NS_rtf::LN_FFRAMEEMPTY: + break;// picture consists of a single frame + case NS_rtf::LN_FBITMAP: + m_pImpl->bIsBitmap = nIntValue > 0 ? true : false; + break;//1 if it's a bitmap ??? + case NS_rtf::LN_FDRAWHATCH: + break;//1 if it's an active OLE object + case NS_rtf::LN_FERROR: + break;// 1 if picture is an error message + case NS_rtf::LN_BPP: + m_pImpl->nBitsPerPixel = nIntValue; + break;//bits per pixel 0 - unknown, 1- mono, 4 - VGA + + case NS_rtf::LN_DXAORIGIN: //horizontal offset of hand annotation origin + case NS_rtf::LN_DYAORIGIN: //vertical offset of hand annotation origin + break; + case NS_rtf::LN_CPROPS:break;// unknown - ignored + //metafilepict + case NS_rtf::LN_MM: + + break; //mapmode + case NS_rtf::LN_XEXT: + m_pImpl->setXSize(nIntValue); + break; // x-size + case NS_rtf::LN_YEXT: + m_pImpl->setYSize(nIntValue); + break; // y-size + case NS_rtf::LN_HMF: break; //identifier - ignored + + //sprm 0xf004 and 0xf008, 0xf00b + case NS_rtf::LN_dfftype:// + m_pImpl->nDffType = nIntValue; + break; + case NS_rtf::LN_dffinstance: + //todo: does this still work for PICF? + //in case of LN_dfftype == 0xf01f the instance contains the bitmap type: + if(m_pImpl->nDffType == 0xf01f) + switch( nIntValue ) + { + case 0x216 : // Metafile header then compressed WMF + + case 0x3D4 : // Metafile header then compressed EMF + + case 0x542 : // Metafile hd. then compressed PICT + + { + + } + + break; + + case 0x46A : break;// One byte tag then JPEG (= JFIF) data + + case 0x6E0 : break;// One byte tag then PNG data + + case 0x7A8 : m_pImpl->bIsBitmap = true; + break; + + } + break; + case NS_rtf::LN_dffversion:// ignored + break; + + //sprm 0xf008 + case NS_rtf::LN_shptype: + break; + case NS_rtf::LN_shpid: + break; + case NS_rtf::LN_shpfGroup: + break;// This shape is a group shape + case NS_rtf::LN_shpfChild: + break;// Not a top-level shape + case NS_rtf::LN_shpfPatriarch: + break;// This is the topmost group shape. Exactly one of these per drawing. + case NS_rtf::LN_shpfDeleted: + break;// The shape has been deleted + case NS_rtf::LN_shpfOleShape: + break;// The shape is an OLE object + case NS_rtf::LN_shpfHaveMaster: + break;// Shape has a hspMaster property + case NS_rtf::LN_shpfFlipH: // Shape is flipped horizontally + m_pImpl->bHoriFlip = nIntValue ? true : false; + break; + case NS_rtf::LN_shpfFlipV: // Shape is flipped vertically + m_pImpl->bVertFlip = nIntValue ? true : false; + break; + case NS_rtf::LN_shpfConnector: + break;// Connector type of shape + case NS_rtf::LN_shpfHaveAnchor: + break;// Shape has an anchor of some kind + case NS_rtf::LN_shpfBackground: + break;// Background shape + case NS_rtf::LN_shpfHaveSpt: + break;// Shape has a shape type property + case NS_rtf::LN_shptypename: + break;// shape type name + case NS_rtf::LN_shppid: + m_pImpl->nShapeOptionType = nIntValue; + break; //type of shape option + case NS_rtf::LN_shpfBid: + break; //ignored + case NS_rtf::LN_shpfComplex: + break; + case NS_rtf::LN_shpop: + { + if(NS_dff::LN_shpwzDescription != sal::static_int_cast<Id>(m_pImpl->nShapeOptionType) ) + ProcessShapeOptions( val ); + } + break; + case NS_rtf::LN_shpname: + break; + case NS_rtf::LN_shpvalue: + { + if( NS_dff::LN_shpwzDescription == sal::static_int_cast<Id>(m_pImpl->nShapeOptionType) ) + ProcessShapeOptions( val ); + } + break; + + //BLIP store entry + case NS_rtf::LN_shpbtWin32: + break; + case NS_rtf::LN_shpbtMacOS: + break; + case NS_rtf::LN_shprgbUid: + break; + case NS_rtf::LN_shptag: + break; + case NS_rtf::LN_shpsize: + break; + case NS_rtf::LN_shpcRef: + break; + case NS_rtf::LN_shpfoDelay: + break; + case NS_rtf::LN_shpusage: + break; + case NS_rtf::LN_shpcbName: + break; + case NS_rtf::LN_shpunused2: + break; + case NS_rtf::LN_shpunused3: + break; + + //border properties + case NS_rtf::LN_shpblipbname : + break; + + case NS_rtf::LN_DPTLINEWIDTH: // 0x1759 + m_pImpl->aBorders[m_pImpl->nCurrentBorderLine].nLineWidth = nIntValue; + break; + case NS_rtf::LN_BRCTYPE: // 0x175a + //graphic borders don't support different line types + break; + case NS_rtf::LN_ICO: // 0x175b + m_pImpl->aBorders[m_pImpl->nCurrentBorderLine].nLineColor = ConversionHelper::ConvertColor( nIntValue ); + break; + case NS_rtf::LN_DPTSPACE: // 0x175c + m_pImpl->aBorders[m_pImpl->nCurrentBorderLine].nLineDistance = nIntValue; + break; + case NS_rtf::LN_FSHADOW: // 0x175d + m_pImpl->aBorders[m_pImpl->nCurrentBorderLine].bHasShadow = nIntValue ? true : false; + break; + case NS_rtf::LN_FFRAME: // ignored + case NS_rtf::LN_UNUSED2_15: // ignored + break; + + case NS_rtf::LN_SPID: + break; + case NS_rtf::LN_XALEFT: + m_pImpl->nLeftPosition = ConversionHelper::convertTwipToMM100(nIntValue); + break; //left position + case NS_rtf::LN_YATOP: + m_pImpl->nTopPosition = ConversionHelper::convertTwipToMM100(nIntValue); + break; //top position + case NS_rtf::LN_XARIGHT: + m_pImpl->nRightPosition = ConversionHelper::convertTwipToMM100(nIntValue); + break; //right position + case NS_rtf::LN_YABOTTOM: + m_pImpl->nBottomPosition = ConversionHelper::convertTwipToMM100(nIntValue); + break;//bottom position + case NS_rtf::LN_FHDR: + case NS_rtf::LN_XAlign: + if( nIntValue < 6 && nIntValue > 0 ) + { + static const sal_Int16 aHoriOrientTab[ 6 ] = + { + text::HoriOrientation::NONE, + text::HoriOrientation::LEFT, + text::HoriOrientation::CENTER, + text::HoriOrientation::RIGHT, + text::HoriOrientation::INSIDE, + text::HoriOrientation::OUTSIDE + }; + m_pImpl->nHoriOrient = aHoriOrientTab[nIntValue]; + m_pImpl->bPageToggle = nIntValue > 3; + } + break; + case NS_rtf::LN_YAlign: + if( nIntValue < 6 && nIntValue > 0) + { + static const sal_Int16 aVertOrientTab[ 6 ] = + { + text::VertOrientation::NONE, // From Top position + text::VertOrientation::TOP, // top + text::VertOrientation::CENTER, // centered + text::VertOrientation::BOTTOM, // bottom + text::VertOrientation::LINE_TOP, // inside (obscure) + text::VertOrientation::LINE_BOTTOM // outside (obscure) + }; + static const sal_Int16 aToLineVertOrientTab[ 6 ] = + { + text::VertOrientation::NONE, // below + text::VertOrientation::LINE_BOTTOM, // top + text::VertOrientation::LINE_CENTER, // centered + text::VertOrientation::LINE_TOP, // bottom + text::VertOrientation::LINE_BOTTOM, // inside (obscure) + text::VertOrientation::LINE_TOP // outside (obscure) + }; + m_pImpl->nVertOrient = m_pImpl->nVertRelation == text::RelOrientation::TEXT_LINE ? + aToLineVertOrientTab[nIntValue] : aVertOrientTab[nIntValue]; + } + break; + case NS_rtf::LN_LayoutInTableCell: break; //currently unknown + case NS_rtf::LN_XRelTo: + case NS_rtf::LN_BX: //hori orient relation + switch( nIntValue ) + { + case 0: m_pImpl->nHoriRelation = text::RelOrientation::PAGE_PRINT_AREA; break; + case 1: m_pImpl->nHoriRelation = text::RelOrientation::PAGE_FRAME; break; + case 2: m_pImpl->nHoriRelation = text::RelOrientation::FRAME; break; + //case : + default:m_pImpl->nHoriRelation = text::RelOrientation::CHAR; + } + break; + case NS_rtf::LN_YRelTo: + case NS_rtf::LN_BY: //vert orient relation + switch( nIntValue ) + { + case 0: m_pImpl->nVertRelation = text::RelOrientation::PAGE_PRINT_AREA; break; + case 1: m_pImpl->nVertRelation = text::RelOrientation::PAGE_FRAME; break; + case 2: m_pImpl->nVertRelation = text::RelOrientation::FRAME; break; + //case : + default:m_pImpl->nVertRelation = text::RelOrientation::TEXT_LINE; + } + + break; + case NS_rtf::LN_WR: //wrapping + switch( nIntValue ) + { + case 0: //0 like 2, but doesn't require absolute object + m_pImpl->bIgnoreWRK = false; + case 2: //2 wrap around absolute object + m_pImpl->nWrap = text::WrapTextMode_PARALLEL; + break; + case 1: //1 no text next to shape + m_pImpl->nWrap = text::WrapTextMode_NONE; + break; + case 3: //3 wrap as if no object present + m_pImpl->nWrap = text::WrapTextMode_THROUGHT; + break; + case 4: //4 wrap tightly around object + m_pImpl->bIgnoreWRK = false; + case 5: //5 wrap tightly, but allow holes + m_pImpl->nWrap = text::WrapTextMode_PARALLEL; + m_pImpl->bContour = true; + break; + default:; + } + break; + case NS_rtf::LN_WRK: + if( !m_pImpl->bIgnoreWRK ) + switch( nIntValue ) + { + case 0: //0 like 2, but doesn't require absolute object + case 2: //2 wrap around absolute object + m_pImpl->nWrap = text::WrapTextMode_PARALLEL; + break; + case 1: //1 no text next to shape + m_pImpl->nWrap = text::WrapTextMode_NONE; + break; + case 3: //3 wrap as if no object present + m_pImpl->nWrap = text::WrapTextMode_THROUGHT; + break; + case 4: //4 wrap tightly around object + case 5: //5 wrap tightly, but allow holes + m_pImpl->nWrap = text::WrapTextMode_PARALLEL; + m_pImpl->bContour = true; + break; + default:; + } + break; + case NS_rtf::LN_FRCASIMPLE: + case NS_rtf::LN_FBELOWTEXT: + case NS_rtf::LN_FANCHORLOCK: + case NS_rtf::LN_CTXBX: + break; + case NS_rtf::LN_shptxt: + //todo: text content + break; + case NS_rtf::LN_dffheader: break; + case NS_ooxml::LN_CT_PositiveSize2D_cx:// 90407; + case NS_ooxml::LN_CT_PositiveSize2D_cy:// 90408; + { + sal_Int32 nDim = ConversionHelper::convertEMUToMM100( nIntValue ); + if( nName == NS_ooxml::LN_CT_PositiveSize2D_cx ) + m_pImpl->setXSize(nDim); + else + m_pImpl->setYSize(nDim); + } + break; + case NS_ooxml::LN_CT_EffectExtent_l:// 90907; + case NS_ooxml::LN_CT_EffectExtent_t:// 90908; + case NS_ooxml::LN_CT_EffectExtent_r:// 90909; + case NS_ooxml::LN_CT_EffectExtent_b:// 90910; + //todo: extends the wrapping size of the object, e.g. if shadow is added + break; + case NS_ooxml::LN_CT_NonVisualDrawingProps_id:// 90650; + //id of the object - ignored + break; + case NS_ooxml::LN_CT_NonVisualDrawingProps_name:// 90651; + //name of the object + m_pImpl->sName = val.getString(); + break; + case NS_ooxml::LN_CT_NonVisualDrawingProps_descr:// 90652; + //alternative text + m_pImpl->sAlternativeText = val.getString(); + break; + case NS_ooxml::LN_CT_GraphicalObjectFrameLocking_noChangeAspect://90644; + //disallow aspect ratio change - ignored + break; + case NS_ooxml::LN_CT_GraphicalObjectFrameLocking_noMove:// 90645; + m_pImpl->bPositionProtected = true; + break; + case NS_ooxml::LN_CT_GraphicalObjectFrameLocking_noResize: // 90646; + m_pImpl->bSizeProtected = true; + break; + case NS_ooxml::LN_CT_Anchor_distT: // 90983; + case NS_ooxml::LN_CT_Anchor_distB: // 90984; + case NS_ooxml::LN_CT_Anchor_distL: // 90985; + case NS_ooxml::LN_CT_Anchor_distR: // 90986; + { + //redirect to shape option processing + switch( nName ) + { + case NS_ooxml::LN_CT_Anchor_distT: // 90983; + m_pImpl->nShapeOptionType = NS_dff::LN_shpdyWrapDistTop; + break; + case NS_ooxml::LN_CT_Anchor_distB: // 90984; + m_pImpl->nShapeOptionType = NS_dff::LN_shpdyWrapDistBottom; + break; + case NS_ooxml::LN_CT_Anchor_distL: // 90985; + m_pImpl->nShapeOptionType = NS_dff::LN_shpdxWrapDistLeft; + break; + case NS_ooxml::LN_CT_Anchor_distR: // 90986; + m_pImpl->nShapeOptionType = NS_dff::LN_shpdxWrapDistRight; + break; + //m_pImpl->nShapeOptionType = NS_dff::LN_shpcropFromTop + default: ; + } + ProcessShapeOptions(val); + } + break; + case NS_ooxml::LN_CT_Anchor_simplePos_attr: // 90987; + m_pImpl->bUseSimplePos = nIntValue > 0; + break; + case NS_ooxml::LN_CT_Anchor_relativeHeight: // 90988; + //z-order + break; + case NS_ooxml::LN_CT_Anchor_behindDoc: // 90989; - in background + if( nIntValue > 0 ) + m_pImpl->bOpaque = false; + break; + case NS_ooxml::LN_CT_Anchor_locked: // 90990; - ignored + case NS_ooxml::LN_CT_Anchor_layoutInCell: // 90991; - ignored + case NS_ooxml::LN_CT_Anchor_hidden: // 90992; - ignored + break; + case NS_ooxml::LN_CT_Anchor_allowOverlap: // 90993; + //enable overlapping - ignored + break; + case NS_ooxml::LN_CT_Point2D_x: // 90405; + m_pImpl->nLeftPosition = ConversionHelper::convertTwipToMM100(nIntValue); + m_pImpl->nHoriRelation = text::RelOrientation::PAGE_FRAME; + m_pImpl->nHoriOrient = text::HoriOrientation::NONE; + break; + case NS_ooxml::LN_CT_Point2D_y: // 90406; + m_pImpl->nTopPosition = ConversionHelper::convertTwipToMM100(nIntValue); + m_pImpl->nVertRelation = text::RelOrientation::PAGE_FRAME; + m_pImpl->nVertOrient = text::VertOrientation::NONE; + break; + case NS_ooxml::LN_CT_WrapTight_wrapText: // 90934; + m_pImpl->bContour = true; + m_pImpl->bContourOutside = true; + + handleWrapTextValue(val.getInt()); + + break; + case NS_ooxml::LN_CT_WrapThrough_wrapText: + /* WRITERFILTERSTATUS: done: 100, planned: 0.5, spent: 0 */ + m_pImpl->bContour = true; + m_pImpl->bContourOutside = false; + + handleWrapTextValue(val.getInt()); + + break; + case NS_ooxml::LN_CT_WrapSquare_wrapText: //90928; + /* WRITERFILTERSTATUS: done: 100, planned: 0.5, spent: 0 */ + + handleWrapTextValue(val.getInt()); + break; + case NS_ooxml::LN_shape: + { + uno::Reference< drawing::XShape> xShape; + val.getAny( ) >>= xShape; + + if ( xShape.is( ) ) + { + // Is it a graphic image + bool bUseShape = true; + try + { + uno::Reference< beans::XPropertySet > xShapeProps + ( xShape, uno::UNO_QUERY_THROW ); + + rtl::OUString sUrl; + xShapeProps->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GraphicURL")) ) >>= sUrl; + + ::com::sun::star::beans::PropertyValues aMediaProperties( 1 ); + aMediaProperties[0].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("URL")); + aMediaProperties[0].Value <<= sUrl; + + m_xGraphicObject = createGraphicObject( aMediaProperties ); + + bUseShape = !m_xGraphicObject.is( ); + + if ( !bUseShape ) + { + // Define the object size + uno::Reference< beans::XPropertySet > xGraphProps( m_xGraphicObject, + uno::UNO_QUERY ); + awt::Size aSize = xShape->getSize( ); + xGraphProps->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Height")), + uno::makeAny( aSize.Height ) ); + xGraphProps->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Width")), + uno::makeAny( aSize.Width ) ); + } + } + catch( const beans::UnknownPropertyException e ) + { + // It isn't a graphic image + } + + if ( bUseShape ) + m_xShape = xShape; + + + if ( m_xShape.is( ) ) + { + uno::Reference< beans::XPropertySet > xShapeProps + (m_xShape, uno::UNO_QUERY_THROW); + + + PropertyNameSupplier& rPropNameSupplier = + PropertyNameSupplier::GetPropertyNameSupplier(); + xShapeProps->setPropertyValue + (rPropNameSupplier.GetName(PROP_ANCHOR_TYPE), + uno::makeAny + (text::TextContentAnchorType_AS_CHARACTER)); + xShapeProps->setPropertyValue + (rPropNameSupplier.GetName(PROP_TEXT_RANGE), + uno::makeAny + (m_pImpl->rDomainMapper.GetCurrentTextRange())); + + awt::Point aPoint(m_xShape->getPosition()); + awt::Size aSize(m_xShape->getSize()); + + if (m_pImpl->isXSizeValid()) + aSize.Width = m_pImpl->getXSize(); + if (m_pImpl->isYSizeValis()) + aSize.Height = m_pImpl->getYSize(); + + m_xShape->setSize(aSize); + + m_pImpl->bIsGraphic = true; + } + } + } + break; + case NS_ooxml::LN_CT_Inline_distT: + case NS_ooxml::LN_CT_Inline_distB: + case NS_ooxml::LN_CT_Inline_distL: + case NS_ooxml::LN_CT_Inline_distR: + //TODO: need to be handled + break; + case NS_ooxml::LN_CT_GraphicalObjectData_uri: + val.getString(); + //TODO: does it need to be handled? + break; + default: +#ifdef DEBUG_DMAPPER_GRAPHIC_IMPORT + dmapper_logger->element("unhandled"); +#endif + ; + } +} + +uno::Reference<text::XTextContent> GraphicImport::GetGraphicObject() +{ + uno::Reference<text::XTextContent> xResult; + + if (m_xGraphicObject.is()) + xResult = m_xGraphicObject; + else if (m_xShape.is()) + { + xResult.set(m_xShape, uno::UNO_QUERY_THROW); + } + + return xResult; +} + + + +void GraphicImport::ProcessShapeOptions(Value& val) +{ + sal_Int32 nIntValue = val.getInt(); + sal_Int32 nTwipValue = ConversionHelper::convertTwipToMM100(nIntValue); + switch( m_pImpl->nShapeOptionType ) + { + case NS_dff::LN_shpcropFromTop /*256*/ : + m_pImpl->nTopCrop = nTwipValue; + break;// rtf:shpcropFromTop + case NS_dff::LN_shpcropFromBottom /*257*/ : + m_pImpl->nBottomCrop= nTwipValue; + break;// rtf:shpcropFromBottom + case NS_dff::LN_shpcropFromLeft /*258*/ : + m_pImpl->nLeftCrop = nTwipValue; + break;// rtf:shpcropFromLeft + case NS_dff::LN_shpcropFromRight/*259*/ : + m_pImpl->nRightCrop = nTwipValue; + break;// rtf:shpcropFromRight + case NS_dff::LN_shppib/*260*/: + break; // rtf:shppib + case NS_dff::LN_shppibName/*261*/: + break; // rtf:shppibName + case NS_dff::LN_shppibFlags/*262*/: // rtf:shppibFlags + break; + case NS_dff::LN_shppictureContrast/*264*/: // rtf:shppictureContrast docu: "1<<16" + /* + 0x10000 is msoffice 50% + < 0x10000 is in units of 1/50th of 0x10000 per 1% + > 0x10000 is in units where + a msoffice x% is stored as 50/(100-x) * 0x10000 + + plus, a (ui) microsoft % ranges from 0 to 100, OOO + from -100 to 100, so also normalize into that range + */ + if ( nIntValue > 0x10000 ) + { + double fX = nIntValue; + fX /= 0x10000; + fX /= 51; // 50 + 1 to round + fX = 1/fX; + m_pImpl->nContrast = static_cast<sal_Int32>(fX); + m_pImpl->nContrast -= 100; + m_pImpl->nContrast = -m_pImpl->nContrast; + m_pImpl->nContrast = (m_pImpl->nContrast-50)*2; + } + else if ( nIntValue == 0x10000 ) + m_pImpl->nContrast = 0; + else + { + m_pImpl->nContrast = nIntValue * 101; //100 + 1 to round + m_pImpl->nContrast /= 0x10000; + m_pImpl->nContrast -= 100; + } + break; + case NS_dff::LN_shppictureBrightness/*265*/: // rtf:shppictureBrightness + m_pImpl->nBrightness = ( (sal_Int32) nIntValue / 327 ); + break; + case NS_dff::LN_shppictureGamma/*266*/: // rtf:shppictureGamma + //todo check gamma value with _real_ document + m_pImpl->fGamma = double(nIntValue/655); + break; + case NS_dff::LN_shppictureId /*267*/: + break; // rtf:shppictureId + case NS_dff::LN_shppictureDblCrMod /*268*/: + break; // rtf:shppictureDblCrMod + case NS_dff::LN_shppictureFillCrMod /*269*/: + break; // rtf:shppictureFillCrMod + case NS_dff::LN_shppictureLineCrMod /*270*/: + break; // rtf:shppictureLineCrMod + + case NS_dff::LN_shppictureActive/*319*/: // rtf:shppictureActive + switch( nIntValue & 0x06 ) + { + case 0 : m_pImpl->eColorMode = drawing::ColorMode_STANDARD; break; + case 4 : m_pImpl->eColorMode = drawing::ColorMode_GREYS; break; + case 6 : m_pImpl->eColorMode = drawing::ColorMode_MONO; break; + default:; + } + break; + case NS_dff::LN_shpfillColor /*385*/: + m_pImpl->nFillColor = (m_pImpl->nFillColor & 0xff000000) + ConversionHelper::ConvertColor( nIntValue ); + break; + case NS_dff::LN_shpfillOpacity /*386*/: + { + sal_Int32 nTrans = 0xff - ( nIntValue * 0xff ) / 0xffff; + m_pImpl->nFillColor = (nTrans << 0x18 ) + (m_pImpl->nFillColor & 0xffffff); + } + break; + case NS_dff::LN_shpfNoFillHitTest /*447*/: + break; // rtf:shpfNoFillHitTest + case NS_dff::LN_shplineColor /*448*/: + m_pImpl->aBorders[m_pImpl->nCurrentBorderLine].nLineColor = ConversionHelper::ConvertColor( nIntValue ); + break; + case NS_dff::LN_shplineWidth /*459*/: + //1pt == 12700 units + m_pImpl->aBorders[m_pImpl->nCurrentBorderLine].nLineWidth = ConversionHelper::convertTwipToMM100(nIntValue / 635); + break; + case NS_dff::LN_shplineDashing /*462*/: + //graphic borders don't support different dashing + /*MSOLINEDASHING + msolineSolid, // Solid (continuous) pen + msolineDashSys, // PS_DASH system dash style + msolineDotSys, // PS_DOT system dash style + msolineDashDotSys, // PS_DASHDOT system dash style + msolineDashDotDotSys, // PS_DASHDOTDOT system dash style + msolineDotGEL, // square dot style + msolineDashGEL, // dash style + msolineLongDashGEL, // long dash style + msolineDashDotGEL, // dash short dash + msolineLongDashDotGEL, // long dash short dash + msolineLongDashDotDotGEL // long dash short dash short dash*/ + break; + case NS_dff::LN_shpfNoLineDrawDash /*511*/: + break; // rtf:shpfNoLineDrawDash + case NS_dff::LN_shpwzDescription /*897*/: //alternative text + m_pImpl->sAlternativeText = val.getString(); + break; + case NS_dff::LN_shppWrapPolygonVertices/*899*/: + break; // rtf:shppWrapPolygonVertices + case NS_dff::LN_shpdxWrapDistLeft /*900*/: // contains a twip/635 value + //todo: changes have to be applied depending on the orientation, see SwWW8ImplReader::AdjustLRWrapForWordMargins() + m_pImpl->nLeftMargin = nIntValue / 360; + break; + case NS_dff::LN_shpdyWrapDistTop /*901*/: // contains a twip/635 value + //todo: changes have to be applied depending on the orientation, see SwWW8ImplReader::AdjustULWrapForWordMargins() + m_pImpl->nTopMargin = nIntValue / 360; + break; + case NS_dff::LN_shpdxWrapDistRight /*902*/:// contains a twip/635 value + //todo: changes have to be applied depending on the orientation, see SwWW8ImplReader::AdjustLRWrapForWordMargins() + m_pImpl->nRightMargin = nIntValue / 360; + break; + case NS_dff::LN_shpdyWrapDistBottom /*903*/:// contains a twip/635 value + //todo: changes have to be applied depending on the orientation, see SwWW8ImplReader::AdjustULWrapForWordMargins() + m_pImpl->nBottomMargin = nIntValue / 360; + break; + case NS_dff::LN_shpfPrint /*959*/: + break; // rtf:shpfPrint + default: + OSL_FAIL( "shape option unsupported?"); + } +} + + +void GraphicImport::lcl_sprm(Sprm & rSprm) +{ + sal_uInt32 nSprmId = rSprm.getId(); + Value::Pointer_t pValue = rSprm.getValue(); + + switch(nSprmId) + { + case 0xf004: //dff record + case 0xf00a: //part of 0xf004 - shape properties + case 0xf00b: //part of 0xf004 + case 0xf007: + case 0xf122: //udefprop + case NS_ooxml::LN_CT_Inline_extent: // 90911; + case NS_ooxml::LN_CT_Inline_effectExtent: // 90912; + case NS_ooxml::LN_CT_Inline_docPr: // 90913; + case NS_ooxml::LN_CT_Inline_cNvGraphicFramePr: // 90914; + case NS_ooxml::LN_CT_NonVisualGraphicFrameProperties_graphicFrameLocks:// 90657 + case NS_ooxml::LN_CT_Inline_a_graphic:// 90915 + case NS_ooxml::LN_CT_Anchor_simplePos_elem: // 90975; + case NS_ooxml::LN_CT_Anchor_extent: // 90978; + case NS_ooxml::LN_CT_Anchor_effectExtent: // 90979; + case NS_ooxml::LN_EG_WrapType_wrapSquare: // 90945; + case NS_ooxml::LN_EG_WrapType_wrapTight: // 90946; + case NS_ooxml::LN_EG_WrapType_wrapThrough: + case NS_ooxml::LN_CT_Anchor_docPr: // 90980; + case NS_ooxml::LN_CT_Anchor_cNvGraphicFramePr: // 90981; + case NS_ooxml::LN_CT_Anchor_a_graphic: // 90982; + case NS_ooxml::LN_CT_WrapPath_start: // 90924; + case NS_ooxml::LN_CT_WrapPath_lineTo: // 90925; + case NS_ooxml::LN_graphic_graphic: + case NS_ooxml::LN_pic_pic: + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + { + pProperties->resolve(*this); + } + } + break; + case NS_ooxml::LN_CT_WrapTight_wrapPolygon: + case NS_ooxml::LN_CT_WrapThrough_wrapPolygon: + /* WRITERFILTERSTATUS: done: 100, planned: 4, spent: 2 */ + { + WrapPolygonHandler aHandler; + + resolveSprmProps(aHandler, rSprm); + + m_pImpl->mpWrapPolygon = aHandler.getPolygon(); + } + break; + case NS_ooxml::LN_CT_Anchor_positionH: // 90976; + { + // Use a special handler for the positionning + PositionHandlerPtr pHandler( new PositionHandler ); + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get( ) ) + { + pProperties->resolve( *pHandler ); + if( !m_pImpl->bUseSimplePos ) + { + m_pImpl->nHoriRelation = pHandler->m_nRelation; + m_pImpl->nHoriOrient = pHandler->m_nOrient; + m_pImpl->nLeftPosition = pHandler->m_nPosition; + } + } + } + break; + case NS_ooxml::LN_CT_Anchor_positionV: // 90977; + { + // Use a special handler for the positionning + PositionHandlerPtr pHandler( new PositionHandler ); + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get( ) ) + { + pProperties->resolve( *pHandler ); + if( !m_pImpl->bUseSimplePos ) + { + m_pImpl->nVertRelation = pHandler->m_nRelation; + m_pImpl->nVertOrient = pHandler->m_nOrient; + m_pImpl->nTopPosition = pHandler->m_nPosition; + } + } + } + break; + case 0x271b: + case 0x271c: + { + if( nSprmId != 0x271c || m_pImpl->nDffType == 0xf01f || m_pImpl->nDffType == 0xf01e ) + { + writerfilter::Reference<BinaryObj>::Pointer_t pPictureData = rSprm.getBinary(); + if( pPictureData.get()) + pPictureData->resolve(*this); + } + } + break; + case NS_ooxml::LN_EG_WrapType_wrapNone: // 90944; - doesn't contain attributes + //depending on the behindDoc attribute text wraps through behind or in fron of the object + m_pImpl->nWrap = text::WrapTextMode_THROUGHT; + break; + case NS_ooxml::LN_EG_WrapType_wrapTopAndBottom: // 90948; + m_pImpl->nWrap = text::WrapTextMode_NONE; + break; + case 0xf010: + case 0xf011: + //ignore - doesn't contain useful members + break; + case NS_ooxml::LN_CT_GraphicalObject_graphicData:// 90660; + { + m_pImpl->bIsGraphic = true; + + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + pProperties->resolve(*this); + } + break; + default: +#if OSL_DEBUG_LEVEL > 0 + ::rtl::OString sMessage( "GraphicImport::sprm() - Id: "); + sMessage += ::rtl::OString::valueOf( sal_Int32( nSprmId ), 10 ); + sMessage += ::rtl::OString(" / 0x"); + sMessage += ::rtl::OString::valueOf( sal_Int32( nSprmId ), 16 ); + OSL_FAIL( sMessage.getStr()) +#endif + ; + } +} + + +void GraphicImport::lcl_entry(int /*pos*/, writerfilter::Reference<Properties>::Pointer_t /*ref*/) +{ +} +/*------------------------------------------------------------------------- + crop is stored as "fixed float" as 16.16 fraction value + related to width/or height + -----------------------------------------------------------------------*/ +void lcl_CalcCrop( sal_Int32& nCrop, sal_Int32 nRef ) +{ + nCrop = ((nCrop >> 16 ) * nRef ) + + (((nCrop & 0xffff) * nRef ) >> 16); +} + +uno::Reference< text::XTextContent > GraphicImport::createGraphicObject( const beans::PropertyValues& aMediaProperties ) +{ + uno::Reference< text::XTextContent > xGraphicObject; + try + { + uno::Reference< graphic::XGraphicProvider > xGraphicProvider( + m_xComponentContext->getServiceManager()->createInstanceWithContext( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.graphic.GraphicProvider")), + m_xComponentContext), + uno::UNO_QUERY_THROW ); + + uno::Reference< graphic::XGraphic > xGraphic = xGraphicProvider->queryGraphic( aMediaProperties ); + + if(xGraphic.is()) + { + PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + + uno::Reference< beans::XPropertySet > xGraphicObjectProperties( + m_xTextFactory->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.TextGraphicObject"))), + uno::UNO_QUERY_THROW); + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_GRAPHIC), uno::makeAny( xGraphic )); + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_ANCHOR_TYPE), + uno::makeAny( m_pImpl->eGraphicImportType == IMPORT_AS_SHAPE || m_pImpl->eGraphicImportType == IMPORT_AS_DETECTED_ANCHOR ? + text::TextContentAnchorType_AT_CHARACTER : + text::TextContentAnchorType_AS_CHARACTER )); + xGraphicObject = uno::Reference< text::XTextContent >( xGraphicObjectProperties, uno::UNO_QUERY_THROW ); + + //shapes have only one border, PICF might have four + table::BorderLine2 aBorderLine; + for( sal_Int32 nBorder = 0; nBorder < 4; ++nBorder ) + { + if( m_pImpl->eGraphicImportType == IMPORT_AS_GRAPHIC || !nBorder ) + { + aBorderLine.Color = m_pImpl->aBorders[m_pImpl->eGraphicImportType == IMPORT_AS_SHAPE ? BORDER_TOP : static_cast<BorderPosition>(nBorder) ].nLineColor; + aBorderLine.InnerLineWidth = 0; + aBorderLine.OuterLineWidth = (sal_Int16)m_pImpl->aBorders[m_pImpl->eGraphicImportType == IMPORT_AS_SHAPE ? BORDER_TOP : static_cast<BorderPosition>(nBorder) ].nLineWidth; + aBorderLine.LineDistance = 0; + } + PropertyIds aBorderProps[4] = + { + PROP_LEFT_BORDER, + PROP_RIGHT_BORDER, + PROP_TOP_BORDER, + PROP_BOTTOM_BORDER + }; + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( aBorderProps[nBorder]), uno::makeAny(aBorderLine)); + } + + // setting properties for all types + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_TITLE ), + uno::makeAny( m_pImpl->sAlternativeText )); + if( m_pImpl->bPositionProtected ) + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_POSITION_PROTECTED ), + uno::makeAny(true)); + if( m_pImpl->bSizeProtected ) + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_SIZE_PROTECTED ), + uno::makeAny(true)); + + if( m_pImpl->eGraphicImportType == IMPORT_AS_SHAPE || m_pImpl->eGraphicImportType == IMPORT_AS_DETECTED_ANCHOR ) + { + sal_Int32 nWidth = m_pImpl->nRightPosition - m_pImpl->nLeftPosition; + if( m_pImpl->eGraphicImportType == IMPORT_AS_SHAPE ) + { + sal_Int32 nHeight = m_pImpl->nBottomPosition - m_pImpl->nTopPosition; + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_SIZE), + uno::makeAny( awt::Size( nWidth, nHeight ))); + } + //adjust margins + if( (m_pImpl->nHoriOrient == text::HoriOrientation::LEFT && + (m_pImpl->nHoriRelation == text::RelOrientation::PAGE_PRINT_AREA || + m_pImpl->nHoriRelation == text::RelOrientation::FRAME) ) || + (m_pImpl->nHoriOrient == text::HoriOrientation::INSIDE && + m_pImpl->nHoriRelation == text::RelOrientation::PAGE_PRINT_AREA )) + m_pImpl->nLeftMargin = 0; + if((m_pImpl->nHoriOrient == text::HoriOrientation::RIGHT && + (m_pImpl->nHoriRelation == text::RelOrientation::PAGE_PRINT_AREA || + m_pImpl->nHoriRelation == text::RelOrientation::FRAME) ) || + (m_pImpl->nHoriOrient == text::HoriOrientation::INSIDE && + m_pImpl->nHoriRelation == text::RelOrientation::PAGE_PRINT_AREA )) + m_pImpl->nRightMargin = 0; + // adjust top/bottom margins + if( m_pImpl->nVertOrient == text::VertOrientation::TOP && + ( m_pImpl->nVertRelation == text::RelOrientation::PAGE_PRINT_AREA || + m_pImpl->nVertRelation == text::RelOrientation::PAGE_FRAME)) + m_pImpl->nTopMargin = 0; + if( m_pImpl->nVertOrient == text::VertOrientation::BOTTOM && + ( m_pImpl->nVertRelation == text::RelOrientation::PAGE_PRINT_AREA || + m_pImpl->nVertRelation == text::RelOrientation::PAGE_FRAME)) + m_pImpl->nBottomMargin = 0; + if( m_pImpl->nVertOrient == text::VertOrientation::BOTTOM && + m_pImpl->nVertRelation == text::RelOrientation::PAGE_PRINT_AREA ) + m_pImpl->nBottomMargin = 0; + + //adjust alignment + if( m_pImpl->nHoriOrient == text::HoriOrientation::INSIDE && + m_pImpl->nHoriRelation == text::RelOrientation::PAGE_FRAME ) + { + // convert 'left to page' to 'from left -<width> to page text area' + m_pImpl->nHoriOrient = text::HoriOrientation::NONE; + m_pImpl->nHoriRelation = text::RelOrientation::PAGE_PRINT_AREA; + m_pImpl->nLeftPosition = - nWidth; + } + else if( m_pImpl->nHoriOrient == text::HoriOrientation::OUTSIDE && + m_pImpl->nHoriRelation == text::RelOrientation::PAGE_FRAME ) + { + // convert 'right to page' to 'from left 0 to right page border' + m_pImpl->nHoriOrient = text::HoriOrientation::NONE; + m_pImpl->nHoriRelation = text::RelOrientation::PAGE_RIGHT; + m_pImpl->nLeftPosition = 0; + } + + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_HORI_ORIENT ), + uno::makeAny(m_pImpl->nHoriOrient)); + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_HORI_ORIENT_POSITION), + uno::makeAny(m_pImpl->nLeftPosition)); + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_HORI_ORIENT_RELATION ), + uno::makeAny(m_pImpl->nHoriRelation)); + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_PAGE_TOGGLE ), + uno::makeAny(m_pImpl->bPageToggle)); + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_VERT_ORIENT ), + uno::makeAny(m_pImpl->nVertOrient)); + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_VERT_ORIENT_POSITION), + uno::makeAny(m_pImpl->nTopPosition)); + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_VERT_ORIENT_RELATION ), + uno::makeAny(m_pImpl->nVertRelation)); + if( !m_pImpl->bOpaque ) + { + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_OPAQUE ), + uno::makeAny(m_pImpl->bOpaque)); + } + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_SURROUND ), + uno::makeAny(m_pImpl->nWrap)); + + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_SURROUND_CONTOUR ), + uno::makeAny(m_pImpl->bContour)); + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_CONTOUR_OUTSIDE ), + uno::makeAny(m_pImpl->bContourOutside)); + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_LEFT_MARGIN ), + uno::makeAny(m_pImpl->nLeftMargin)); + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_RIGHT_MARGIN ), + uno::makeAny(m_pImpl->nRightMargin)); + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_TOP_MARGIN ), + uno::makeAny(m_pImpl->nTopMargin)); + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_BOTTOM_MARGIN ), + uno::makeAny(m_pImpl->nBottomMargin)); + + if( m_pImpl->eColorMode == drawing::ColorMode_STANDARD && + m_pImpl->nContrast == -70 && + m_pImpl->nBrightness == 70 ) + { + // strange definition of WATERMARK! + m_pImpl->nContrast = 0; + m_pImpl->nBrightness = 0; + m_pImpl->eColorMode = drawing::ColorMode_WATERMARK; + } + + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_ADJUST_CONTRAST ), + uno::makeAny((sal_Int16)m_pImpl->nContrast)); + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_ADJUST_LUMINANCE ), + uno::makeAny((sal_Int16)m_pImpl->nBrightness)); + if(m_pImpl->eColorMode != drawing::ColorMode_STANDARD) + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_GRAPHIC_COLOR_MODE ), + uno::makeAny(m_pImpl->eColorMode)); + if(m_pImpl->fGamma > 0. ) + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_GAMMA ), + uno::makeAny(m_pImpl->fGamma )); + if(m_pImpl->bHoriFlip) + { + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_HORI_MIRRORED_ON_EVEN_PAGES ), + uno::makeAny( m_pImpl->bHoriFlip )); + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_HORI_MIRRORED_ON_ODD_PAGES ), + uno::makeAny( m_pImpl->bHoriFlip )); + } + + if( m_pImpl->bVertFlip ) + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_VERT_MIRRORED ), + uno::makeAny( m_pImpl->bVertFlip )); + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_BACK_COLOR ), + uno::makeAny( m_pImpl->nFillColor )); + + //there seems to be no way to detect the original size via _real_ API + uno::Reference< beans::XPropertySet > xGraphicProperties( xGraphic, uno::UNO_QUERY_THROW ); + awt::Size aGraphicSize, aGraphicSizePixel; + xGraphicProperties->getPropertyValue(rPropNameSupplier.GetName( PROP_SIZE100th_M_M )) >>= aGraphicSize; + xGraphicProperties->getPropertyValue(rPropNameSupplier.GetName( PROP_SIZE_PIXEL )) >>= aGraphicSizePixel; + + uno::Any aContourPolyPolygon; + if( aGraphicSize.Width && aGraphicSize.Height && + m_pImpl->mpWrapPolygon.get() != NULL) + { + awt::Size aDstSize(m_pImpl->getXSize(), m_pImpl->getYSize()); + WrapPolygon::Pointer_t pCorrected = m_pImpl->mpWrapPolygon->correctWordWrapPolygon(aGraphicSize, aDstSize); + aContourPolyPolygon <<= pCorrected->getPointSequenceSequence(); + } + + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_CONTOUR_POLY_POLYGON), + aContourPolyPolygon); + + if( aGraphicSize.Width && aGraphicSize.Height ) + { + //todo: i71651 graphic size is not provided by the GraphicDescriptor + lcl_CalcCrop( m_pImpl->nTopCrop, aGraphicSize.Height ); + lcl_CalcCrop( m_pImpl->nBottomCrop, aGraphicSize.Height ); + lcl_CalcCrop( m_pImpl->nLeftCrop, aGraphicSize.Width ); + lcl_CalcCrop( m_pImpl->nRightCrop, aGraphicSize.Width ); + + + xGraphicProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_GRAPHIC_CROP ), + uno::makeAny(text::GraphicCrop(m_pImpl->nTopCrop, m_pImpl->nBottomCrop, m_pImpl->nLeftCrop, m_pImpl->nRightCrop))); + } + + } + + if(m_pImpl->eGraphicImportType == IMPORT_AS_DETECTED_INLINE || m_pImpl->eGraphicImportType == IMPORT_AS_DETECTED_ANCHOR) + { + if( m_pImpl->getXSize() && m_pImpl->getYSize() ) + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_SIZE), + uno::makeAny( awt::Size( m_pImpl->getXSize(), m_pImpl->getYSize() ))); + try + { + if( m_pImpl->sName.getLength() ) + { + uno::Reference< container::XNamed > xNamed( xGraphicObjectProperties, uno::UNO_QUERY_THROW ); + xNamed->setName( m_pImpl->sName ); + } + } + catch( const uno::Exception& ) + { + } + } + } + } + catch( const uno::Exception& e ) + { + clog << __FILE__ << ":" << __LINE__ << " failed. Message :" ; + clog << rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_UTF8 ).getStr( ) << endl; + } + return xGraphicObject; +} + + + +void GraphicImport::data(const sal_uInt8* buf, size_t len, writerfilter::Reference<Properties>::Pointer_t /*ref*/) +{ + PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + + ::com::sun::star::beans::PropertyValues aMediaProperties( 1 ); + aMediaProperties[0].Name = rPropNameSupplier.GetName(PROP_INPUT_STREAM); + + uno::Reference< io::XInputStream > xIStream = new XInputStreamHelper( buf, len, m_pImpl->bIsBitmap ); + aMediaProperties[0].Value <<= xIStream; + + m_xGraphicObject = createGraphicObject( aMediaProperties ); +} + + +void GraphicImport::lcl_startSectionGroup() +{ +} + + +void GraphicImport::lcl_endSectionGroup() +{ +} + + +void GraphicImport::lcl_startParagraphGroup() +{ +} + + +void GraphicImport::lcl_endParagraphGroup() +{ +} + + +void GraphicImport::lcl_startCharacterGroup() +{ +} + + +void GraphicImport::lcl_endCharacterGroup() +{ +} + + +void GraphicImport::lcl_text(const sal_uInt8 * /*_data*/, size_t /*len*/) +{ +} + + +void GraphicImport::lcl_utext(const sal_uInt8 * /*_data*/, size_t /*len*/) +{ +} + + +void GraphicImport::lcl_props(writerfilter::Reference<Properties>::Pointer_t /*ref*/) +{ +} + + +void GraphicImport::lcl_table(Id /*name*/, writerfilter::Reference<Table>::Pointer_t /*ref*/) +{ +} + + +void GraphicImport::lcl_substream(Id /*name*/, ::writerfilter::Reference<Stream>::Pointer_t /*ref*/) +{ +} + + +void GraphicImport::lcl_info(const string & /*info*/) +{ +} + +void GraphicImport::lcl_startShape( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > /*xShape*/ ) +{ +} + +void GraphicImport::lcl_endShape( ) +{ +} + + + +bool GraphicImport::IsGraphic() const +{ + return m_pImpl->bIsGraphic; +} + +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/GraphicImport.hxx b/writerfilter/source/dmapper/GraphicImport.hxx new file mode 100644 index 000000000000..cc609a705e40 --- /dev/null +++ b/writerfilter/source/dmapper/GraphicImport.hxx @@ -0,0 +1,132 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef INCLUDED_GRAPHICIMPORT_HXX +#define INCLUDED_GRAPHICIMPORT_HXX + +#include <resourcemodel/LoggedResources.hxx> + +namespace com{ namespace sun { namespace star { + namespace uno{ + class XComponentContext; + } + namespace lang + { + class XMultiServiceFactory; + } + namespace text + { + class XTextContent; + } + namespace drawing + { + class XShape; + } + namespace beans + { + class PropertyValue; + typedef ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > PropertyValues; + } +}}} + +namespace writerfilter { +namespace dmapper +{ +class GraphicImport_Impl; +class DomainMapper; + +enum GraphicImportType +{ + IMPORT_AS_GRAPHIC, + IMPORT_AS_SHAPE, + IMPORT_AS_DETECTED_INLINE, + IMPORT_AS_DETECTED_ANCHOR +}; + +class WRITERFILTER_DLLPRIVATE GraphicImport : public LoggedProperties, public LoggedTable + ,public BinaryObj, public LoggedStream +{ + GraphicImport_Impl* m_pImpl; + ::com::sun::star::uno::Reference < ::com::sun::star::uno::XComponentContext > m_xComponentContext; + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xTextFactory; + + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextContent > m_xGraphicObject; + + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape> m_xShape; + void ProcessShapeOptions(Value & val); + + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextContent > createGraphicObject( + const ::com::sun::star::beans::PropertyValues& aMediaProperties ); + +public: + explicit GraphicImport(::com::sun::star::uno::Reference < ::com::sun::star::uno::XComponentContext > xComponentContext, + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xTextFactory, + DomainMapper& rDomainMapper, + GraphicImportType eGraphicImportType); + virtual ~GraphicImport(); + + // BinaryObj + virtual void data(const sal_uInt8* buf, size_t len, writerfilter::Reference<Properties>::Pointer_t ref); + + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextContent > GetGraphicObject(); + bool IsGraphic() const; + + private: + // Properties + virtual void lcl_attribute(Id Name, Value & val); + virtual void lcl_sprm(Sprm & sprm); + + // Table + virtual void lcl_entry(int pos, writerfilter::Reference<Properties>::Pointer_t ref); + + // Stream + virtual void lcl_startSectionGroup(); + virtual void lcl_endSectionGroup(); + virtual void lcl_startParagraphGroup(); + virtual void lcl_endParagraphGroup(); + virtual void lcl_startCharacterGroup(); + virtual void lcl_endCharacterGroup(); + virtual void lcl_text(const sal_uInt8 * data, size_t len); + virtual void lcl_utext(const sal_uInt8 * data, size_t len); + virtual void lcl_props(writerfilter::Reference<Properties>::Pointer_t ref); + virtual void lcl_table(Id name, + writerfilter::Reference<Table>::Pointer_t ref); + virtual void lcl_substream(Id name, + ::writerfilter::Reference<Stream>::Pointer_t ref); + virtual void lcl_info(const string & info); + virtual void lcl_startShape( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape ); + virtual void lcl_endShape( ); + + void handleWrapTextValue(sal_uInt32 nVal); +}; + +typedef boost::shared_ptr< GraphicImport > GraphicImportPtr; +}} + +#endif // + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/MeasureHandler.cxx b/writerfilter/source/dmapper/MeasureHandler.cxx new file mode 100644 index 000000000000..51d351f10b3f --- /dev/null +++ b/writerfilter/source/dmapper/MeasureHandler.cxx @@ -0,0 +1,124 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include <MeasureHandler.hxx> +#include <PropertyMap.hxx> +#include <doctok/resourceids.hxx> +#include <ConversionHelper.hxx> +#include <ooxml/resourceids.hxx> +#include <com/sun/star/text/SizeType.hpp> +#include "dmapperLoggers.hxx" + +namespace writerfilter { +namespace dmapper { + +using namespace ::com::sun::star; + + + +MeasureHandler::MeasureHandler() : +LoggedProperties(dmapper_logger, "MeasureHandler"), +m_nMeasureValue( 0 ), +m_nUnit( -1 ), +m_nRowHeightSizeType( text::SizeType::MIN ) +{ +} + + +MeasureHandler::~MeasureHandler() +{ +} + + +void MeasureHandler::lcl_attribute(Id rName, Value & rVal) +{ + sal_Int32 nIntValue = rVal.getInt(); + (void)rName; + switch( rName ) + { + case NS_rtf::LN_unit: + case NS_ooxml::LN_CT_TblWidth_type:// = 90668; + //can be: NS_ooxml::LN_Value_ST_TblWidth_nil, NS_ooxml::LN_Value_ST_TblWidth_pct, + // NS_ooxml::LN_Value_ST_TblWidth_dxa, NS_ooxml::LN_Value_ST_TblWidth_auto; + m_nUnit = nIntValue; + break; + case NS_ooxml::LN_CT_Height_hRule: // 90666; + { + ::rtl::OUString sHeightType = rVal.getString(); + if( sHeightType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "exact" ) ) ) + m_nRowHeightSizeType = text::SizeType::FIX; + } + break; + case NS_rtf::LN_trleft: + case NS_rtf::LN_preferredWidth: + case NS_ooxml::LN_CT_TblWidth_w:// = 90667; + m_nMeasureValue = nIntValue; + break; + case NS_ooxml::LN_CT_Height_val: // 90665 -- a string value + { + m_nUnit = NS_ooxml::LN_Value_ST_TblWidth_dxa; + ::rtl::OUString sHeight = rVal.getString(); + m_nMeasureValue = sHeight.toInt32(); + } + break; + default: + OSL_FAIL( "unknown attribute"); + } +} + + +void MeasureHandler::lcl_sprm(Sprm & rSprm) +{ + (void)rSprm; +} + + +sal_Int32 MeasureHandler::getMeasureValue() const +{ + sal_Int32 nRet = 0; + if( m_nMeasureValue != 0 && m_nUnit >= 0 ) + { + // TODO m_nUnit 3 - twip, other values unknown :-( + if( m_nUnit == 3 || sal::static_int_cast<Id>(m_nUnit) == NS_ooxml::LN_Value_ST_TblWidth_dxa) + nRet = ConversionHelper::convertTwipToMM100( m_nMeasureValue ); + //todo: handle additional width types: + //NS_ooxml::LN_Value_ST_TblWidth_nil, NS_ooxml::LN_Value_ST_TblWidth_pct, + //NS_ooxml::LN_Value_ST_TblWidth_dxa, NS_ooxml::LN_Value_ST_TblWidth_auto; + } + return nRet; +} + + +bool MeasureHandler::isAutoWidth() const +{ + return sal::static_int_cast<Id>(m_nUnit) == NS_ooxml::LN_Value_ST_TblWidth_auto; +} + +} //namespace dmapper +} //namespace writerfilter + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/MeasureHandler.hxx b/writerfilter/source/dmapper/MeasureHandler.hxx new file mode 100644 index 000000000000..1fc9ae96985c --- /dev/null +++ b/writerfilter/source/dmapper/MeasureHandler.hxx @@ -0,0 +1,69 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef INCLUDED_MEASUREHANDLER_HXX +#define INCLUDED_MEASUREHANDLER_HXX + +#include <WriterFilterDllApi.hxx> +#include <resourcemodel/LoggedResources.hxx> +#include <boost/shared_ptr.hpp> + +namespace writerfilter { +namespace dmapper +{ +class PropertyMap; +/** Handler for sprms that contain a measure and a unit + - Left indent of tables + - Preferred width of tables + */ +class WRITERFILTER_DLLPRIVATE MeasureHandler : public LoggedProperties +{ + sal_Int32 m_nMeasureValue; + sal_Int32 m_nUnit; + sal_Int16 m_nRowHeightSizeType; //table row height type + + // Properties + virtual void lcl_attribute(Id Name, Value & val); + virtual void lcl_sprm(Sprm & sprm); + +public: + MeasureHandler(); + virtual ~MeasureHandler(); + + sal_Int32 getMeasureValue() const; + //at least tables can have automatic width + bool isAutoWidth() const; + + sal_Int16 GetRowHeightSizeType() const { return m_nRowHeightSizeType;} +}; +typedef boost::shared_ptr + < MeasureHandler > MeasureHandlerPtr; +}} + +#endif // + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/ModelEventListener.cxx b/writerfilter/source/dmapper/ModelEventListener.cxx new file mode 100644 index 000000000000..c151c5056335 --- /dev/null +++ b/writerfilter/source/dmapper/ModelEventListener.cxx @@ -0,0 +1,95 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include <ModelEventListener.hxx> +#include <com/sun/star/document/XEventBroadcaster.hpp> +#include <com/sun/star/text/XDocumentIndex.hpp> +#include <com/sun/star/text/XDocumentIndexesSupplier.hpp> + +namespace writerfilter { +namespace dmapper { + +using namespace ::com::sun::star; + + + + +ModelEventListener::ModelEventListener() +{ +} + + +ModelEventListener::~ModelEventListener() +{ +} + + +void ModelEventListener::notifyEvent( const document::EventObject& rEvent ) throw (uno::RuntimeException) +{ + if( rEvent.EventName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("OnFocus"))) + { + try + { + uno::Reference< text::XDocumentIndexesSupplier> xIndexesSupplier( rEvent.Source, uno::UNO_QUERY ); + //remove listener + uno::Reference<document::XEventBroadcaster>(rEvent.Source, uno::UNO_QUERY )->removeEventListener( + uno::Reference<document::XEventListener>(this)); + + uno::Reference< container::XIndexAccess > xIndexes = xIndexesSupplier->getDocumentIndexes(); + + sal_Int32 nIndexes = xIndexes->getCount(); + for( sal_Int32 nIndex = 0; nIndex < nIndexes; ++nIndex) + { + uno::Reference< text::XDocumentIndex> xIndex( xIndexes->getByIndex( nIndex ), uno::UNO_QUERY ); + xIndex->update(); + } + } + catch( const uno::Exception& rEx ) + { + (void)rEx; + OSL_FAIL( "exception while updating indexes" ); + } + } +} + + +void ModelEventListener::disposing( const lang::EventObject& rEvent ) throw (uno::RuntimeException) +{ + try + { + uno::Reference<document::XEventBroadcaster>(rEvent.Source, uno::UNO_QUERY )->removeEventListener( + uno::Reference<document::XEventListener>(this)); + } + catch( const uno::Exception& ) + { + } +} + +} //namespace dmapper +} //namespace writerfilter + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/ModelEventListener.hxx b/writerfilter/source/dmapper/ModelEventListener.hxx new file mode 100644 index 000000000000..957af5fa4804 --- /dev/null +++ b/writerfilter/source/dmapper/ModelEventListener.hxx @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef INCLUDED_MODELEVENTLISTENER_HXX +#define INCLUDED_MODELEVENTLISTENER_HXX + +#include <WriterFilterDllApi.hxx> +#include <com/sun/star/document/XEventListener.hpp> +#include <cppuhelper/implbase1.hxx> + +namespace writerfilter { +namespace dmapper{ + + +class WRITERFILTER_DLLPRIVATE ModelEventListener : + public cppu::WeakImplHelper1< ::com::sun::star::document::XEventListener > +{ +public: + ModelEventListener(); + ~ModelEventListener(); + + virtual void SAL_CALL notifyEvent( const ::com::sun::star::document::EventObject& Event ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException); + +}; +}//namespace writerfilter +}//namespace dmapper +#endif // + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/NumberingManager.cxx b/writerfilter/source/dmapper/NumberingManager.cxx new file mode 100644 index 000000000000..fb2cd53f0190 --- /dev/null +++ b/writerfilter/source/dmapper/NumberingManager.cxx @@ -0,0 +1,993 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +#include "ConversionHelper.hxx" +#include "NumberingManager.hxx" +#include "StyleSheetTable.hxx" +#include "PropertyIds.hxx" + +#include <doctok/resourceids.hxx> +#include <doctok/sprmids.hxx> +#include <ooxml/resourceids.hxx> + +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/style/XStyleFamiliesSupplier.hpp> +#include <com/sun/star/style/NumberingType.hpp> +#include <com/sun/star/text/HoriOrientation.hpp> +#include <com/sun/star/text/PositionAndSpaceMode.hpp> +#include <com/sun/star/text/XChapterNumberingSupplier.hpp> + +#if DEBUG +#include <stdio.h> +#endif + +#include "dmapperLoggers.hxx" + +using namespace com::sun::star; + +using ::rtl::OUString; +using ::rtl::OString; +using ::rtl::OUStringToOString; + +#define MAKE_PROPVAL(NameId, Value) \ + beans::PropertyValue(aPropNameSupplier.GetName(NameId), 0, uno::makeAny(Value), beans::PropertyState_DIRECT_VALUE ) + +#define OUSTR_TO_C( x ) OUStringToOString( x, RTL_TEXTENCODING_UTF8 ).getStr( ) + +#define NUMBERING_MAX_LEVELS 10 + + +namespace writerfilter { +namespace dmapper { + +//--------------------------------------------------- Utility functions + +void lcl_printProperties( uno::Sequence< beans::PropertyValue > aProps ) +{ + sal_Int32 nLen = aProps.getLength( ); + for ( sal_Int32 i = 0; i < nLen; i++ ) + { + uno::Any aValue = aProps[i].Value; + sal_Int32 nValue = 0; + OUString sValue; + + if ( !( aValue >>= sValue ) && ( aValue >>= nValue ) ) + sValue = OUString::valueOf( nValue ); + +#if DEBUG + fprintf( stderr, "Property %s: %s\n", + OUSTR_TO_C( aProps[i].Name ), + OUSTR_TO_C( sValue ) ); +#endif + } +} + +sal_Int32 lcl_findProperty( uno::Sequence< beans::PropertyValue > aProps, OUString sName ) +{ + sal_Int32 i = 0; + sal_Int32 nLen = aProps.getLength( ); + sal_Int32 nPos = -1; + + while ( nPos == -1 && i < nLen ) + { + if ( aProps[i].Name.equals( sName ) ) + nPos = i; + else + i++; + } + + return nPos; +} + +void lcl_mergeProperties( uno::Sequence< beans::PropertyValue >& aSrc, + uno::Sequence< beans::PropertyValue >& aDst ) +{ + for ( sal_Int32 i = 0, nSrcLen = aSrc.getLength( ); i < nSrcLen; i++ ) + { + // Look for the same property in aDst + sal_Int32 nPos = lcl_findProperty( aDst, aSrc[i].Name ); + if ( nPos >= 0 ) + { + // Replace the property value by the one in aSrc + aDst[nPos] = aSrc[i]; + } + else + { + // Simply add the new value + aDst.realloc( aDst.getLength( ) + 1 ); + aDst[ aDst.getLength( ) - 1 ] = aSrc[i]; + } + } +} + +//-------------------------------------------- ListLevel implementation +void ListLevel::SetValue( Id nId, sal_Int32 nValue ) +{ + switch( nId ) + { + case NS_rtf::LN_ISTARTAT: + m_nIStartAt = nValue; + break; + case NS_rtf::LN_NFC: + m_nNFC = nValue; + break; + case NS_rtf::LN_JC: + m_nJC = nValue; + break; + case NS_rtf::LN_FLEGAL: + m_nFLegal = nValue; + break; + case NS_rtf::LN_FNORESTART: + m_nFNoRestart = nValue; + break; + case NS_rtf::LN_FIDENTSAV: + m_nFPrev = nValue; + break; + case NS_rtf::LN_FCONVERTED: + m_nFPrevSpace = nValue; + break; +#if 0 + case NS_rtf::LN_FWORD6: + m_nFWord6 = nValue; + break; +#endif + case NS_rtf::LN_IXCHFOLLOW: + m_nXChFollow = nValue; + break; + case NS_ooxml::LN_CT_TabStop_pos: + m_nTabstop = nValue; + break; + default: + OSL_FAIL( "this line should never be reached"); + } +} + +sal_Int16 ListLevel::GetParentNumbering( OUString sText, sal_Int16 nLevel, + OUString& rPrefix, OUString& rSuffix ) +{ + sal_Int16 nParentNumbering = nLevel; + + //now parse the text to find %n from %1 to %nLevel+1 + //everything before the first % and the last %x is prefix and suffix + OUString sLevelText( sText ); + sal_Int32 nCurrentIndex = 0; + sal_Int32 nFound = sLevelText.indexOf( '%', nCurrentIndex ); + if( nFound > 0 ) + { + rPrefix = sLevelText.copy( 0, nFound ); + sLevelText = sLevelText.copy( nFound ); + } + sal_Int32 nMinLevel = nLevel; + //now the text should either be empty or start with % + nFound = sLevelText.getLength( ) > 1 ? 0 : -1; + while( nFound >= 0 ) + { + if( sLevelText.getLength() > 1 ) + { + sal_Unicode cLevel = sLevelText.getStr()[1]; + if( cLevel >= '1' && cLevel <= '9' ) + { + if( cLevel - '1' < nMinLevel ) + nMinLevel = cLevel - '1'; + //remove first char - next char is removed later + sLevelText = sLevelText.copy( 1 ); + } + } + //remove old '%' or number + sLevelText = sLevelText.copy( 1 ); + nCurrentIndex = 0; + nFound = sLevelText.indexOf( '%', nCurrentIndex ); + //remove the text before the next % + if(nFound > 0) + sLevelText = sLevelText.copy( nFound -1 ); + } + if( nMinLevel < nLevel ) + { + nParentNumbering = sal_Int16( nLevel - nMinLevel + 1); + } + + rSuffix = sLevelText; + + return nParentNumbering; +} + +uno::Sequence< beans::PropertyValue > ListLevel::GetProperties( ) +{ + uno::Sequence< beans::PropertyValue > aLevelProps = GetLevelProperties( ); + if ( m_pParaStyle.get( ) ) + { + // Merge with the paragraph properties + uno::Sequence< beans::PropertyValue > aParaProps = GetParaProperties( ); + lcl_mergeProperties( aParaProps, aLevelProps ); + } + return aLevelProps; +} + +uno::Sequence< beans::PropertyValue > ListLevel::GetCharStyleProperties( ) +{ + PropertyValueVector_t rProperties; + PropertyNameSupplier& aPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + + _PropertyMap::const_iterator aMapIter = begin(); + _PropertyMap::const_iterator aEndIter = end(); + for( ; aMapIter != aEndIter; ++aMapIter ) + { + switch( aMapIter->first.eId ) + { + case PROP_ADJUST: + case PROP_INDENT_AT: + case PROP_FIRST_LINE_INDENT: + case PROP_FIRST_LINE_OFFSET: + case PROP_LEFT_MARGIN: + case PROP_CHAR_FONT_NAME: + // Do nothing: handled in the GetPropertyValues method + break; + default: + { + rProperties.push_back( + beans::PropertyValue( + aPropNameSupplier.GetName( aMapIter->first.eId ), 0, + aMapIter->second, beans::PropertyState_DIRECT_VALUE )); + } + } + } + + uno::Sequence< beans::PropertyValue > aRet( rProperties.size() ); + beans::PropertyValue* pValues = aRet.getArray(); + PropertyValueVector_t::const_iterator aIt = rProperties.begin(); + PropertyValueVector_t::const_iterator aEndIt = rProperties.end(); + for(sal_uInt32 nIndex = 0; aIt != aEndIt; ++aIt,++nIndex) + { + pValues[nIndex] = *aIt; + } + return aRet; +} + +uno::Sequence< beans::PropertyValue > ListLevel::GetLevelProperties( ) +{ + const sal_Int16 aWWToUnoAdjust[] = + { + text::HoriOrientation::LEFT, + text::HoriOrientation::CENTER, + text::HoriOrientation::RIGHT, + }; + + PropertyNameSupplier& aPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + PropertyValueVector_t aNumberingProperties; + + if( m_nIStartAt >= 0) + aNumberingProperties.push_back( MAKE_PROPVAL(PROP_START_WITH, (sal_Int16)m_nIStartAt) ); + + sal_Int16 nNumberFormat = ConversionHelper::ConvertNumberingType(m_nNFC); + if( m_nNFC >= 0) + aNumberingProperties.push_back( MAKE_PROPVAL(PROP_NUMBERING_TYPE, nNumberFormat )); + + if( m_nJC >= 0 && m_nJC <= sal::static_int_cast<sal_Int32>(sizeof(aWWToUnoAdjust) / sizeof(sal_Int16)) ) + aNumberingProperties.push_back( MAKE_PROPVAL(PROP_ADJUST, aWWToUnoAdjust[m_nJC])); + + // todo: this is not the bullet char + if( nNumberFormat == style::NumberingType::CHAR_SPECIAL && m_sBulletChar.getLength() ) + aNumberingProperties.push_back( MAKE_PROPVAL(PROP_BULLET_CHAR, m_sBulletChar.copy(0,1))); + + aNumberingProperties.push_back( MAKE_PROPVAL( PROP_LISTTAB_STOP_POSITION, m_nTabstop ) ); + + //TODO: handling of nFLegal? + //TODO: nFNoRestart lower levels do not restart when higher levels are incremented, like: + //1. + //1.1 + //2.2 + //2.3 + //3.4 + // + + if( m_nFWord6 > 0) //Word 6 compatibility + { + if( m_nFPrev == 1) + aNumberingProperties.push_back( MAKE_PROPVAL( PROP_PARENT_NUMBERING, (sal_Int16) NUMBERING_MAX_LEVELS )); + //TODO: prefixing space nFPrevSpace; - has not been used in WW8 filter + } + +// TODO: sRGBXchNums; array of inherited numbers + +// TODO: nXChFollow; following character 0 - tab, 1 - space, 2 - nothing + + _PropertyMap::const_iterator aMapIter = begin(); + _PropertyMap::const_iterator aEndIter = end(); + for( ; aMapIter != aEndIter; ++aMapIter ) + { + switch( aMapIter->first.eId ) + { + case PROP_ADJUST: + case PROP_INDENT_AT: + case PROP_FIRST_LINE_INDENT: + case PROP_FIRST_LINE_OFFSET: + case PROP_LEFT_MARGIN: + aNumberingProperties.push_back( + beans::PropertyValue( aPropNameSupplier.GetName( aMapIter->first.eId ), 0, aMapIter->second, beans::PropertyState_DIRECT_VALUE )); + break; + case PROP_CHAR_FONT_NAME: + aNumberingProperties.push_back( + beans::PropertyValue( aPropNameSupplier.GetName( PROP_BULLET_FONT_NAME ), 0, aMapIter->second, beans::PropertyState_DIRECT_VALUE )); + break; + default: + { + // Handled in GetCharStyleProperties method + } + + } + } + + uno::Sequence< beans::PropertyValue > aRet(aNumberingProperties.size()); + beans::PropertyValue* pValues = aRet.getArray(); + PropertyValueVector_t::const_iterator aIt = aNumberingProperties.begin(); + PropertyValueVector_t::const_iterator aEndIt = aNumberingProperties.end(); + for(sal_uInt32 nIndex = 0; aIt != aEndIt; ++aIt,++nIndex) + { + pValues[nIndex] = *aIt; + } + return aRet; +} + +uno::Sequence< beans::PropertyValue > ListLevel::GetParaProperties( ) +{ + PropertyNameSupplier& aPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + + uno::Sequence< beans::PropertyValue > aParaProps = m_pParaStyle->pProperties->GetPropertyValues( ); + uno::Sequence< beans::PropertyValue > aProps; + + // ParaFirstLineIndent -> FirstLineIndent + // ParaLeftMargin -> IndentAt + + OUString sParaIndent = aPropNameSupplier.GetName( + PROP_PARA_FIRST_LINE_INDENT ); + OUString sFirstLineIndent = aPropNameSupplier.GetName( + PROP_FIRST_LINE_INDENT ); + OUString sParaLeftMargin = aPropNameSupplier.GetName( + PROP_PARA_LEFT_MARGIN ); + OUString sIndentAt = aPropNameSupplier.GetName( + PROP_INDENT_AT ); + + sal_Int32 nLen = aParaProps.getLength( ); + for ( sal_Int32 i = 0; i < nLen; i++ ) + { + if ( aParaProps[i].Name.equals( sParaIndent ) ) + { + aProps.realloc( aProps.getLength() + 1 ); + aProps[aProps.getLength( ) - 1] = aParaProps[i]; + aProps[aProps.getLength( ) - 1].Name = sFirstLineIndent; + } + else if ( aParaProps[i].Name.equals( sParaLeftMargin ) ) + { + aProps.realloc( aProps.getLength() + 1 ); + aProps[aProps.getLength( ) - 1] = aParaProps[i]; + aProps[aProps.getLength( ) - 1].Name = sIndentAt; + } + + } + + return aProps; +} + +//--------------------------------------- AbstractListDef implementation + +AbstractListDef::AbstractListDef( ) : + m_nTPLC( -1 ) + ,m_nSimpleList( -1 ) + ,m_nRestart( -1 ) + ,m_nUnsigned( -1 ) + ,m_nId( -1 ) +{ +} + +AbstractListDef::~AbstractListDef( ) +{ +} + +void AbstractListDef::SetValue( sal_uInt32 nSprmId, sal_Int32 nValue ) +{ + switch( nSprmId ) + { + case NS_rtf::LN_TPLC: + m_nTPLC = nValue; + break; + case NS_rtf::LN_FSIMPLELIST: + m_nSimpleList = nValue; + break; + case NS_rtf::LN_fAutoNum: + m_nRestart = nValue; + break; + case NS_rtf::LN_fHybrid: + m_nUnsigned = nValue; + break; + default: + OSL_FAIL( "this line should never be reached"); + } +} + +ListLevel::Pointer AbstractListDef::GetLevel( sal_uInt16 nLvl ) +{ + ListLevel::Pointer pLevel; + if ( m_aLevels.size( ) > nLvl ) + pLevel = m_aLevels[ nLvl ]; + return pLevel; +} + +void AbstractListDef::AddLevel( ) +{ + ListLevel::Pointer pLevel( new ListLevel ); + m_pCurrentLevel = pLevel; + m_aLevels.push_back( pLevel ); +} + +uno::Sequence< uno::Sequence< beans::PropertyValue > > AbstractListDef::GetPropertyValues( ) +{ + uno::Sequence< uno::Sequence< beans::PropertyValue > > result( sal_Int32( m_aLevels.size( ) ) ); + uno::Sequence< beans::PropertyValue >* aResult = result.getArray( ); + + int nLevels = m_aLevels.size( ); + for ( int i = 0; i < nLevels; i++ ) + { + aResult[i] = m_aLevels[i]->GetProperties( ); + } + + return result; +} + +//---------------------------------------------- ListDef implementation + +ListDef::ListDef( ) : AbstractListDef( ) +{ +} + +ListDef::~ListDef( ) +{ +} + +OUString ListDef::GetStyleName( sal_Int32 nId ) +{ + OUString sStyleName( RTL_CONSTASCII_USTRINGPARAM("WWNum") ); + sStyleName += OUString::valueOf( nId ); + + return sStyleName; +} + +uno::Sequence< uno::Sequence< beans::PropertyValue > > ListDef::GetPropertyValues( ) +{ + // [1] Call the same method on the abstract list + uno::Sequence< uno::Sequence< beans::PropertyValue > > aAbstract = m_pAbstractDef->GetPropertyValues( ); + + // [2] Call the upper class method + uno::Sequence< uno::Sequence< beans::PropertyValue > > aThis = AbstractListDef::GetPropertyValues( ); + + // Merge the results of [2] in [1] + sal_Int32 nThisCount = aThis.getLength( ); + for ( sal_Int32 i = 0; i < nThisCount; i++ ) + { + uno::Sequence< beans::PropertyValue > level = aThis[i]; + if ( level.getLength( ) == 0 ) + { + // If the the element contains something, merge it + lcl_mergeProperties( level, aAbstract[i] ); + } + } + + return aAbstract; +} + +uno::Reference< container::XNameContainer > lcl_getUnoNumberingStyles( + uno::Reference< lang::XMultiServiceFactory > xFactory ) +{ + uno::Reference< container::XNameContainer > xStyles; + + try + { + uno::Reference< style::XStyleFamiliesSupplier > xFamilies( xFactory, uno::UNO_QUERY_THROW ); + uno::Any oFamily = xFamilies->getStyleFamilies( )->getByName( OUString(RTL_CONSTASCII_USTRINGPARAM("NumberingStyles")) ); + + oFamily >>= xStyles; + } + catch ( const uno::Exception ) + { + } + + return xStyles; +} + +void ListDef::CreateNumberingRules( DomainMapper& rDMapper, + uno::Reference< lang::XMultiServiceFactory> xFactory ) +{ + // Get the UNO Numbering styles + uno::Reference< container::XNameContainer > xStyles = lcl_getUnoNumberingStyles( xFactory ); + + // Do the whole thing + if( !m_xNumRules.is() && xFactory.is() && xStyles.is( ) ) + { + try + { + // Create the numbering style + uno::Reference< beans::XPropertySet > xStyle ( + xFactory->createInstance( + OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.style.NumberingStyle"))), + uno::UNO_QUERY_THROW ); + + rtl::OUString sStyleName = GetStyleName( GetId( ) ); + + xStyles->insertByName( sStyleName, makeAny( xStyle ) ); + + uno::Any oStyle = xStyles->getByName( sStyleName ); + xStyle.set( oStyle, uno::UNO_QUERY_THROW ); + + PropertyNameSupplier& aPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + + // Get the default OOo Numbering style rules + uno::Any aRules = xStyle->getPropertyValue( aPropNameSupplier.GetName( PROP_NUMBERING_RULES ) ); + aRules >>= m_xNumRules; + + uno::Sequence< uno::Sequence< beans::PropertyValue > > aProps = GetPropertyValues( ); + + sal_Int32 nAbstLevels = m_pAbstractDef->Size( ); + sal_Int16 nLevel = 0; + while ( nLevel < nAbstLevels ) + { + ListLevel::Pointer pAbsLevel = m_pAbstractDef->GetLevel( nLevel ); + ListLevel::Pointer pLevel = GetLevel( nLevel ); + + // Get the merged level properties + uno::Sequence< beans::PropertyValue > aLvlProps = aProps[sal_Int32( nLevel )]; + + lcl_printProperties( aLvlProps ); + + // Get the char style + uno::Sequence< beans::PropertyValue > aAbsCharStyleProps = pAbsLevel->GetCharStyleProperties( ); + uno::Sequence< beans::PropertyValue >& rAbsCharStyleProps = aAbsCharStyleProps; + if ( pLevel.get( ) ) + { + uno::Sequence< beans::PropertyValue > aCharStyleProps = + pLevel->GetCharStyleProperties( ); + uno::Sequence< beans::PropertyValue >& rCharStyleProps = aCharStyleProps; + lcl_mergeProperties( rAbsCharStyleProps, rCharStyleProps ); + } + + if( aAbsCharStyleProps.getLength() ) + { + // Change the sequence into a vector + PropertyValueVector_t aStyleProps; + for ( sal_Int32 i = 0, nLen = aAbsCharStyleProps.getLength() ; i < nLen; i++ ) + { + aStyleProps.push_back( aAbsCharStyleProps[i] ); + } + + //create (or find) a character style containing the character + // attributes of the symbol and apply it to the numbering level + OUString sStyle = rDMapper.getOrCreateCharStyle( aStyleProps ); + aLvlProps.realloc( aLvlProps.getLength() + 1); + aLvlProps[aLvlProps.getLength() - 1].Name = aPropNameSupplier.GetName( PROP_CHAR_STYLE_NAME ); + aLvlProps[aLvlProps.getLength() - 1].Value <<= sStyle; + } + + // Get the prefix / suffix / Parent numbering + // and add them to the level properties + OUString sText = pAbsLevel->GetBulletChar( ); + if ( pLevel.get( ) ) + sText = pLevel->GetBulletChar( ); + + OUString sPrefix; + OUString sSuffix; + OUString& rPrefix = sPrefix; + OUString& rSuffix = sSuffix; + sal_Int16 nParentNum = ListLevel::GetParentNumbering( + sText, nLevel, rPrefix, rSuffix ); + + aLvlProps.realloc( aLvlProps.getLength( ) + 4 ); + aLvlProps[ aLvlProps.getLength( ) - 4 ] = MAKE_PROPVAL( PROP_PREFIX, rPrefix ); + aLvlProps[ aLvlProps.getLength( ) - 3 ] = MAKE_PROPVAL( PROP_SUFFIX, rSuffix ); + aLvlProps[ aLvlProps.getLength( ) - 2 ] = MAKE_PROPVAL( PROP_PARENT_NUMBERING, nParentNum ); + + aLvlProps[ aLvlProps.getLength( ) - 1 ] = MAKE_PROPVAL( PROP_POSITION_AND_SPACE_MODE, + sal_Int16( text::PositionAndSpaceMode::LABEL_ALIGNMENT ) ); + // Replace the numbering rules for the level + m_xNumRules->replaceByIndex( nLevel, uno::makeAny( aLvlProps ) ); + + // Handle the outline level here + StyleSheetEntryPtr pParaStyle = pAbsLevel->GetParaStyle( ); + if ( pParaStyle.get( ) ) + { + uno::Reference< text::XChapterNumberingSupplier > xOutlines ( + xFactory, uno::UNO_QUERY_THROW ); + uno::Reference< container::XIndexReplace > xOutlineRules = + xOutlines->getChapterNumberingRules( ); + + aLvlProps.realloc( aLvlProps.getLength() + 1 ); + aLvlProps[aLvlProps.getLength( ) - 1] = MAKE_PROPVAL( PROP_HEADING_STYLE_NAME, pParaStyle->sConvertedStyleName ); + + xOutlineRules->replaceByIndex( nLevel, uno::makeAny( aLvlProps ) ); + } + + nLevel++; + } + + // Create the numbering style for these rules + OUString sNumRulesName = aPropNameSupplier.GetName( PROP_NUMBERING_RULES ); + xStyle->setPropertyValue( sNumRulesName, uno::makeAny( m_xNumRules ) ); + } + catch( const uno::Exception& rEx) + { + OSL_FAIL( "ListTable::CreateNumberingRules"); + } + } + +} + +//------------------------------------- NumberingManager implementation + + +ListsManager::ListsManager(DomainMapper& rDMapper, + const uno::Reference< lang::XMultiServiceFactory > xFactory) : +LoggedProperties(dmapper_logger, "ListsManager"), +LoggedTable(dmapper_logger, "ListsManager"), +m_rDMapper( rDMapper ), +m_xFactory( xFactory ) +{ +} + +ListsManager::~ListsManager( ) +{ +} + +void ListsManager::lcl_attribute( Id nName, Value& rVal ) +{ + OSL_ENSURE( m_pCurrentDefinition.get(), "current entry has to be set here"); + if(!m_pCurrentDefinition.get()) + return ; + int nIntValue = rVal.getInt(); + + ListLevel::Pointer pCurrentLvl = m_pCurrentDefinition->GetCurrentLevel( ); + + + switch(nName) + { + case NS_rtf::LN_RGBXCHNUMS: + if(pCurrentLvl.get()) + pCurrentLvl->AddRGBXchNums( rVal.getString( ) ); + break; + case NS_ooxml::LN_CT_LevelText_val: + { + //this strings contains the definition of the level + //the level number is marked as %n + //these numbers can be mixed randomly toghether with seperators pre- and suffixes + //the Writer supports only a number of upper levels to show, separators is always a dot + //and each level can have a prefix and a suffix + if(pCurrentLvl.get()) + pCurrentLvl->SetBulletChar( rVal.getString() ); + } + break; + case NS_rtf::LN_ISTARTAT: + case NS_rtf::LN_NFC: + case NS_rtf::LN_JC: + case NS_rtf::LN_FLEGAL: + case NS_rtf::LN_FNORESTART: + case NS_rtf::LN_FIDENTSAV: + case NS_rtf::LN_FCONVERTED: +#if 0 + case NS_rtf::LN_FWORD6: +#endif + case NS_rtf::LN_IXCHFOLLOW: + if ( pCurrentLvl.get( ) ) + pCurrentLvl->SetValue( nName, sal_Int32( nIntValue ) ); + break; + case NS_rtf::LN_RGISTD: + m_pCurrentDefinition->AddRGISTD( rVal.getString() ); + break; + case NS_ooxml::LN_CT_Num_numId: + m_pCurrentDefinition->SetId( rVal.getString().toInt32( ) ); + break; + case NS_rtf::LN_LSID: + m_pCurrentDefinition->SetId( nIntValue ); + break; + case NS_rtf::LN_TPLC: + case NS_rtf::LN_FSIMPLELIST: + case NS_rtf::LN_fAutoNum: + case NS_rtf::LN_fHybrid: + m_pCurrentDefinition->SetValue( nName, nIntValue ); + break; + case NS_ooxml::LN_CT_NumLvl_ilvl: + case NS_rtf::LN_LISTLEVEL: + { + //add a new level to the level vector and make it the current one + m_pCurrentDefinition->AddLevel(); + + writerfilter::Reference<Properties>::Pointer_t pProperties; + if((pProperties = rVal.getProperties()).get()) + pProperties->resolve(*this); + } + break; + case NS_ooxml::LN_CT_AbstractNum_abstractNumId: + { + // This one corresponds to the AbstractNum Id definition + // The reference to the abstract num is in the sprm method + sal_Int32 nVal = rVal.getString().toInt32(); + m_pCurrentDefinition->SetId( nVal ); + } + break; + case NS_ooxml::LN_CT_Ind_left: + pCurrentLvl->Insert( + PROP_INDENT_AT, true, uno::makeAny( ConversionHelper::convertTwipToMM100( nIntValue ) )); + break; + case NS_ooxml::LN_CT_Ind_hanging: + pCurrentLvl->Insert( + PROP_FIRST_LINE_INDENT, true, uno::makeAny( - ConversionHelper::convertTwipToMM100( nIntValue ) )); + break; + case NS_ooxml::LN_CT_Ind_firstLine: + pCurrentLvl->Insert( + PROP_FIRST_LINE_INDENT, true, uno::makeAny( ConversionHelper::convertTwipToMM100( nIntValue ) )); + break; + case NS_ooxml::LN_CT_Lvl_ilvl: //overrides previous level - unsupported + case NS_ooxml::LN_CT_Lvl_tplc: //template code - unsupported + case NS_ooxml::LN_CT_Lvl_tentative: //marks level as unused in the document - unsupported + break; + case NS_ooxml::LN_CT_TabStop_pos: + { + //no paragraph attributes in ListTable char style sheets + if ( pCurrentLvl.get( ) ) + pCurrentLvl->SetValue( nName, + ConversionHelper::convertTwipToMM100( nIntValue ) ); + } + break; + case NS_ooxml::LN_CT_TabStop_val: + { + // TODO Do something of that + } + break; + default: + { +#if OSL_DEBUG_LEVEL > 0 + ::rtl::OString sMessage( "ListTable::attribute() - Id: "); + sMessage += ::rtl::OString::valueOf( sal_Int32( nName ), 10 ); + sMessage += ::rtl::OString(" / 0x"); + sMessage += ::rtl::OString::valueOf( sal_Int32( nName ), 16 ); + sMessage += ::rtl::OString(" value: "); + sMessage += ::rtl::OString::valueOf( sal_Int32( nIntValue ), 10 ); + sMessage += ::rtl::OString(" / 0x"); + sMessage += ::rtl::OString::valueOf( sal_Int32( nIntValue ), 16 ); + OSL_FAIL( sMessage.getStr()); // +#endif + } + } +} + +void ListsManager::lcl_sprm( Sprm& rSprm ) +{ + //fill the attributes of the style sheet + sal_uInt32 nSprmId = rSprm.getId(); + if( m_pCurrentDefinition.get() || + nSprmId == NS_ooxml::LN_CT_Numbering_abstractNum || + nSprmId == NS_ooxml::LN_CT_Numbering_num ) + { + sal_Int32 nIntValue = rSprm.getValue()->getInt(); + switch( nSprmId ) + { + case NS_ooxml::LN_CT_Numbering_abstractNum: + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if(pProperties.get()) + { + //create a new Abstract list entry + OSL_ENSURE( !m_pCurrentDefinition.get(), "current entry has to be NULL here"); + m_pCurrentDefinition.reset( new AbstractListDef ); + pProperties->resolve( *this ); + //append it to the table + m_aAbstractLists.push_back( m_pCurrentDefinition ); + m_pCurrentDefinition = AbstractListDef::Pointer(); + } + } + break; + case NS_ooxml::LN_CT_Numbering_num: + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if(pProperties.get()) + { + // Create a new list entry + OSL_ENSURE( !m_pCurrentDefinition.get(), "current entry has to be NULL here"); + ListDef::Pointer listDef( new ListDef ); + m_pCurrentDefinition = listDef; + pProperties->resolve( *this ); + //append it to the table + m_aLists.push_back( listDef ); + + m_pCurrentDefinition = AbstractListDef::Pointer(); + } + } + break; + case NS_ooxml::LN_CT_Num_abstractNumId: + { + sal_Int32 nAbstractNumId = rSprm.getValue()->getInt(); + ListDef* pListDef = dynamic_cast< ListDef* >( m_pCurrentDefinition.get( ) ); + if ( pListDef != NULL ) + { + // The current def should be a ListDef + pListDef->SetAbstractDefinition( + GetAbstractList( nAbstractNumId ) ); + } + } + break; + case NS_ooxml::LN_CT_AbstractNum_multiLevelType: + break; + case NS_rtf::LN_TPLC: + m_pCurrentDefinition->SetValue( nSprmId, nIntValue ); + break; + case NS_ooxml::LN_CT_AbstractNum_lvl: + { + m_pCurrentDefinition->AddLevel(); + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if(pProperties.get()) + pProperties->resolve(*this); + } + break; + case NS_rtf::LN_RGBXCHNUMS: break; + case NS_rtf::LN_ISTARTAT: + case NS_rtf::LN_NFC: + case NS_rtf::LN_JC: + case NS_rtf::LN_FLEGAL: + case NS_rtf::LN_FNORESTART: + case NS_rtf::LN_FIDENTSAV: + case NS_rtf::LN_FCONVERTED: +#if 0 + case NS_rtf::LN_FWORD6: +#endif + case NS_rtf::LN_IXCHFOLLOW: + m_pCurrentDefinition->GetCurrentLevel( )->SetValue( nSprmId, nIntValue ); + break; + case NS_ooxml::LN_CT_Lvl_lvlText: + case NS_ooxml::LN_CT_Lvl_rPr : //contains LN_EG_RPrBase_rFonts + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if(pProperties.get()) + pProperties->resolve(*this); + } + break; + case NS_ooxml::LN_CT_NumLvl_lvl: + { + // overwrite level + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if(pProperties.get()) + pProperties->resolve(*this); + } + break; + case NS_ooxml::LN_CT_Lvl_lvlJc: + { + static sal_Int16 aWWAlignments[ ] = + { + text::HoriOrientation::LEFT, + text::HoriOrientation::CENTER, + text::HoriOrientation::RIGHT + }; + m_pCurrentDefinition->GetCurrentLevel( )->Insert( + PROP_ADJUST, true, uno::makeAny( aWWAlignments[ nIntValue ] ) ); + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + } + break; + case NS_ooxml::LN_CT_Lvl_pPr: + case NS_ooxml::LN_CT_PPrBase_ind: + { + //todo: how to handle paragraph properties within numbering levels (except LeftIndent and FirstLineIndent)? + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if(pProperties.get()) + pProperties->resolve(*this); + } + break; + case NS_ooxml::LN_CT_PPrBase_tabs: + case NS_ooxml::LN_CT_Tabs_tab: + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if(pProperties.get()) + pProperties->resolve(*this); + } + break; + case NS_ooxml::LN_CT_Lvl_suff: + //todo: currently unsupported suffix + //can be: "none", "space", "tab" + break; + case NS_ooxml::LN_CT_Lvl_pStyle: + { + OUString sStyleName = rSprm.getValue( )->getString( ); + ListLevel::Pointer pLevel = m_pCurrentDefinition->GetCurrentLevel( ); + StyleSheetTablePtr pStylesTable = m_rDMapper.GetStyleSheetTable( ); + const StyleSheetEntryPtr pStyle = pStylesTable->FindStyleSheetByISTD( sStyleName ); + pLevel->SetParaStyle( pStyle ); + } + break; + case NS_ooxml::LN_EG_RPrBase_rFonts: //contains font properties + case NS_ooxml::LN_EG_RPrBase_color: + case NS_ooxml::LN_EG_RPrBase_u: + case NS_sprm::LN_CHps: // sprmCHps + case NS_ooxml::LN_EG_RPrBase_lang: + case NS_ooxml::LN_EG_RPrBase_eastAsianLayout: + //no break! + default: + if( m_pCurrentDefinition->GetCurrentLevel( ).get()) + { + m_rDMapper.PushListProperties( m_pCurrentDefinition->GetCurrentLevel( ) ); + m_rDMapper.sprm( rSprm ); + m_rDMapper.PopListProperties(); + } + } + } +} + +void ListsManager::lcl_entry( int /* pos */, + writerfilter::Reference<Properties>::Pointer_t ref ) +{ + if( m_rDMapper.IsOOXMLImport() ) + { + ref->resolve(*this); + } + else + { + if ( m_bIsLFOImport ) + { + // Create ListDef's + OSL_ENSURE( !m_pCurrentDefinition.get(), "current entry has to be NULL here"); + ListDef::Pointer pList( new ListDef() ); + m_pCurrentDefinition = pList; + ref->resolve(*this); + //append it to the table + m_aLists.push_back( pList ); + m_pCurrentDefinition = AbstractListDef::Pointer(); + } + else + { + // Create AbstractListDef's + OSL_ENSURE( !m_pCurrentDefinition.get(), "current entry has to be NULL here"); + m_pCurrentDefinition.reset( new AbstractListDef( ) ); + ref->resolve(*this); + //append it to the table + m_aAbstractLists.push_back( m_pCurrentDefinition ); + m_pCurrentDefinition = AbstractListDef::Pointer(); + } + } +} + +AbstractListDef::Pointer ListsManager::GetAbstractList( sal_Int32 nId ) +{ + AbstractListDef::Pointer pAbstractList; + + int nLen = m_aAbstractLists.size( ); + int i = 0; + while ( !pAbstractList.get( ) && i < nLen ) + { + if ( m_aAbstractLists[i]->GetId( ) == nId ) + pAbstractList = m_aAbstractLists[i]; + i++; + } + + return pAbstractList; +} + +ListDef::Pointer ListsManager::GetList( sal_Int32 nId ) +{ + ListDef::Pointer pList; + + int nLen = m_aLists.size( ); + int i = 0; + while ( !pList.get( ) && i < nLen ) + { + if ( m_aLists[i]->GetId( ) == nId ) + pList = m_aLists[i]; + i++; + } + + return pList; +} + +void ListsManager::CreateNumberingRules( ) +{ + // Loop over the definitions + std::vector< ListDef::Pointer >::iterator listIt = m_aLists.begin( ); + for ( ; listIt != m_aLists.end( ); ++listIt ) + { + (*listIt)->CreateNumberingRules( m_rDMapper, m_xFactory ); + } +} + +} } + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/NumberingManager.hxx b/writerfilter/source/dmapper/NumberingManager.hxx new file mode 100644 index 000000000000..d001805f4333 --- /dev/null +++ b/writerfilter/source/dmapper/NumberingManager.hxx @@ -0,0 +1,228 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +#ifndef INCLUDED_NUMBERINGMANAGER_HXX +#define INCLUDED_NUMBERINGMANAGER_HXX + +#include "PropertyMap.hxx" + +#include <WriterFilterDllApi.hxx> +#include <dmapper/DomainMapper.hxx> +#include <resourcemodel/LoggedResources.hxx> + +#include <com/sun/star/container/XIndexReplace.hpp> + +namespace writerfilter { +namespace dmapper { + +class DomainMapper; +class StyleSheetEntry; + + +/** Class representing the numbering level properties. + */ +class ListLevel : public PropertyMap +{ + sal_Int32 m_nIStartAt; //LN_ISTARTAT + sal_Int32 m_nNFC; //LN_NFC + sal_Int32 m_nJC; //LN_JC + sal_Int32 m_nFLegal; //LN_FLEGAL + sal_Int32 m_nFNoRestart; //LN_FNORESTART + sal_Int32 m_nFPrev; //LN_FPREV + sal_Int32 m_nFPrevSpace; //LN_FPREVSPACE + sal_Int32 m_nFWord6; //LN_FWORD6 + ::rtl::OUString m_sRGBXchNums; //LN_RGBXCHNUMS + sal_Int32 m_nXChFollow; //LN_IXCHFOLLOW + ::rtl::OUString m_sBulletChar; + sal_Int32 m_nTabstop; + boost::shared_ptr< StyleSheetEntry > m_pParaStyle; + +public: + + typedef boost::shared_ptr< ListLevel > Pointer; + + ListLevel() : + m_nIStartAt(-1) + ,m_nNFC(-1) + ,m_nJC(-1) + ,m_nFLegal(-1) + ,m_nFNoRestart(-1) + ,m_nFPrev(-1) + ,m_nFPrevSpace(-1) + ,m_nFWord6(-1) + ,m_nXChFollow(-1) + ,m_nTabstop( 0 ) + {} + + ~ListLevel( ){ } + + // Setters for the import + void SetValue( Id nId, sal_Int32 nValue ); + void SetBulletChar( rtl::OUString sValue ) { m_sBulletChar = sValue; }; + void SetParaStyle( boost::shared_ptr< StyleSheetEntry > pStyle ) + { + m_pParaStyle = pStyle; + }; + void AddRGBXchNums( rtl::OUString sValue ) { m_sRGBXchNums += sValue; }; + + // Getters + rtl::OUString GetBulletChar( ) { return m_sBulletChar; }; + boost::shared_ptr< StyleSheetEntry > GetParaStyle( ) { return m_pParaStyle; }; + + // UNO mapping functions + + // rPrefix and rSuffix are out parameters + static sal_Int16 GetParentNumbering( rtl::OUString sText, sal_Int16 nLevel, + rtl::OUString& rPrefix, rtl::OUString& rSuffix ); + + com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > + GetProperties( ); + + com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue> + GetCharStyleProperties( ); +private: + + com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > + GetLevelProperties( ); + + com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > + GetParaProperties( ); +}; + +class AbstractListDef +{ +private: + sal_Int32 m_nTPLC; //LN_TPLC + ::rtl::OUString m_sRGISTD; //LN_RGISTD + sal_Int32 m_nSimpleList; //LN_FSIMPLELIST + sal_Int32 m_nRestart; //LN_FRESTARTHDN + sal_Int32 m_nUnsigned; //LN_UNSIGNED26_2 + + // The ID member reflects either the abstractNumId or the numId + // depending on the use of the class + sal_Int32 m_nId; + + // Properties of each level. This can also reflect the overridden + // levels of a numbering. + ::std::vector< ListLevel::Pointer > m_aLevels; + + // Only used during the numberings import + ListLevel::Pointer m_pCurrentLevel; + +public: + typedef boost::shared_ptr< AbstractListDef > Pointer; + + AbstractListDef( ); + ~AbstractListDef( ); + + // Setters using during the import + void SetId( sal_Int32 nId ) { m_nId = nId; }; + void SetValue( sal_uInt32 nSprmId, sal_Int32 nValue ); + void AddRGISTD( rtl::OUString sValue ) { m_sRGISTD += sValue; }; + + // Accessors + sal_Int32 GetId( ) { return m_nId; }; + + sal_Int16 Size( ) { return sal_Int16( m_aLevels.size( ) ); }; + ListLevel::Pointer GetLevel( sal_uInt16 nLvl ); + void AddLevel( ); + + ListLevel::Pointer GetCurrentLevel( ) { return m_pCurrentLevel; }; + + virtual com::sun::star::uno::Sequence< + com::sun::star::uno::Sequence< + com::sun::star::beans::PropertyValue > > GetPropertyValues( ); +}; + +class ListDef : public AbstractListDef +{ +private: + // Pointer to the abstract numbering + AbstractListDef::Pointer m_pAbstractDef; + + // Cache for the UNO numbering rules + uno::Reference< container::XIndexReplace > m_xNumRules; + +public: + typedef boost::shared_ptr< ListDef > Pointer; + + ListDef( ); + ~ListDef( ); + + // Accessors + void SetAbstractDefinition( AbstractListDef::Pointer pAbstract ) { m_pAbstractDef = pAbstract; }; + AbstractListDef::Pointer GetAbstractDefinition( ) { return m_pAbstractDef; }; + + // Mapping functions + static rtl::OUString GetStyleName( sal_Int32 nId ); + + com::sun::star::uno::Sequence< + com::sun::star::uno::Sequence< + com::sun::star::beans::PropertyValue > > GetPropertyValues( ); + + void CreateNumberingRules( + DomainMapper& rDMapper, + com::sun::star::uno::Reference< + com::sun::star::lang::XMultiServiceFactory> xFactory ); + + ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexReplace > + GetNumberingRules( ) { return m_xNumRules; }; + +}; + +/** This class provides access to the defined numbering styles. + */ +class ListsManager : + public LoggedProperties, + public LoggedTable +{ +private: + + DomainMapper& m_rDMapper; + com::sun::star::uno::Reference< + com::sun::star::lang::XMultiServiceFactory > m_xFactory; + + // The numbering entries + std::vector< AbstractListDef::Pointer > m_aAbstractLists; + std::vector< ListDef::Pointer > m_aLists; + + + // These members are used for import only + AbstractListDef::Pointer m_pCurrentDefinition; + bool m_bIsLFOImport; + + AbstractListDef::Pointer GetAbstractList( sal_Int32 nId ); + + // Properties + virtual void lcl_attribute( Id nName, Value & rVal ); + virtual void lcl_sprm(Sprm & sprm); + + // Table + virtual void lcl_entry(int pos, writerfilter::Reference<Properties>::Pointer_t ref); + +public: + + ListsManager( + DomainMapper& rDMapper, + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xFactory); + virtual ~ListsManager(); + + typedef boost::shared_ptr< ListsManager > Pointer; + + // Config methods + void SetLFOImport( bool bLFOImport ) { m_bIsLFOImport = bLFOImport; }; + + // Numberings accessors + AbstractListDef::Pointer GetCurrentDef( ) { return m_pCurrentDefinition; }; + + sal_uInt32 Size() const + { return sal_uInt32( m_aLists.size( ) ); }; + ListDef::Pointer GetList( sal_Int32 nId ); + + // Mapping methods + void CreateNumberingRules( ); +}; + +} } + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/OLEHandler.cxx b/writerfilter/source/dmapper/OLEHandler.cxx new file mode 100644 index 000000000000..1e89825550f0 --- /dev/null +++ b/writerfilter/source/dmapper/OLEHandler.cxx @@ -0,0 +1,244 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include <OLEHandler.hxx> +#include <PropertyMap.hxx> +#include "GraphicHelpers.hxx" + +#include <doctok/resourceids.hxx> +#include <ooxml/resourceids.hxx> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/document/XEmbeddedObjectResolver.hpp> +#include <com/sun/star/document/XStorageBasedDocument.hpp> +#include <com/sun/star/drawing/XShape.hpp> +#include <com/sun/star/embed/XEmbeddedObject.hpp> +#include <com/sun/star/embed/XEmbedObjectCreator.hpp> +#include <com/sun/star/graphic/XGraphic.hpp> +#include <com/sun/star/io/XStream.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/text/XTextDocument.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> + +#include "dmapperLoggers.hxx" + +namespace writerfilter { +namespace dmapper { + +using namespace ::com::sun::star; + + +OLEHandler::OLEHandler() : +LoggedProperties(dmapper_logger, "OLEHandler"), +m_nDxaOrig(0), +m_nDyaOrig(0), + m_nWrapMode(1) +{ +} + + +OLEHandler::~OLEHandler() +{ +} + + +void OLEHandler::lcl_attribute(Id rName, Value & rVal) +{ + rtl::OUString sStringValue = rVal.getString(); + (void)rName; + switch( rName ) + { + case NS_ooxml::LN_CT_OLEObject_Type: + m_sObjectType = sStringValue; + break; + case NS_ooxml::LN_CT_OLEObject_ProgID: + m_sProgId = sStringValue; + break; + case NS_ooxml::LN_CT_OLEObject_ShapeID: + m_sShapeId = sStringValue; + break; + case NS_ooxml::LN_CT_OLEObject_DrawAspect: + m_sDrawAspect = sStringValue; + break; + case NS_ooxml::LN_CT_OLEObject_ObjectID: + m_sObjectId = sStringValue; + break; + case NS_ooxml::LN_CT_OLEObject_r_id: + m_sr_id = sStringValue; + break; + case NS_ooxml::LN_inputstream: + rVal.getAny() >>= m_xInputStream; + break; + case NS_ooxml::LN_CT_Object_dxaOrig: + m_nDxaOrig = rVal.getInt(); + break; + case NS_ooxml::LN_CT_Object_dyaOrig: + m_nDyaOrig = rVal.getInt(); + break; + case NS_ooxml::LN_shape: + { + uno::Reference< drawing::XShape > xTempShape; + rVal.getAny() >>= xTempShape; + if( xTempShape.is() ) + { + m_xShape.set( xTempShape ); + + try + { + m_aShapeSize = xTempShape->getSize(); + m_aShapePosition = xTempShape->getPosition(); + + uno::Reference< beans::XPropertySet > xShapeProps( xTempShape, uno::UNO_QUERY_THROW ); + PropertyNameSupplier& rNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + + xShapeProps->getPropertyValue( rNameSupplier.GetName( PROP_BITMAP ) ) >>= m_xReplacement; + + xShapeProps->setPropertyValue( + rNameSupplier.GetName( PROP_SURROUND ), + uno::makeAny( m_nWrapMode ) ); + } + catch( const uno::Exception& e ) + { +#if DEBUG + clog << "Exception in OLE Handler: "; + clog << rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_UTF8 ).getStr( ) << endl; +#endif + } + } + } + break; + default: + OSL_FAIL( "unknown attribute"); + } +} + + +void OLEHandler::lcl_sprm(Sprm & rSprm) +{ + sal_uInt32 nSprmId = rSprm.getId(); + switch( nSprmId ) + { + case NS_ooxml::LN_OLEObject_OLEObject: + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + { + pProperties->resolve(*this); + } + } + break; + case NS_ooxml::LN_wrap_wrap: + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if ( pProperties.get( ) ) + { + WrapHandlerPtr pHandler( new WrapHandler ); + pProperties->resolve( *pHandler ); + + m_nWrapMode = pHandler->getWrapMode( ); + + try + { + uno::Reference< beans::XPropertySet > xShapeProps( m_xShape, uno::UNO_QUERY_THROW ); + PropertyNameSupplier& rNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + + xShapeProps->setPropertyValue( + rNameSupplier.GetName( PROP_SURROUND ), + uno::makeAny( m_nWrapMode ) ); + } + catch( const uno::Exception& e ) + { +#if DEBUG + clog << "Exception in OLE Handler: "; + clog << rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_UTF8 ).getStr( ) << endl; +#endif + } + } + } + break; + default: + { + OSL_FAIL( "unknown attribute"); + } + } +} + + +::rtl::OUString OLEHandler::copyOLEOStream( uno::Reference< text::XTextDocument > xTextDocument ) +{ + ::rtl::OUString sRet; + if( !m_xInputStream.is( ) ) + return sRet; + try + { + uno::Reference < lang::XMultiServiceFactory > xFactory(xTextDocument, uno::UNO_QUERY_THROW); + uno::Reference< document::XEmbeddedObjectResolver > xEmbeddedResolver( + xFactory->createInstance( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.ImportEmbeddedObjectResolver" ))), uno::UNO_QUERY_THROW ); + //hack to work with the ImportEmbeddedObjectResolver + static sal_Int32 nObjectCount = 100; + uno::Reference< container::XNameAccess > xNA( xEmbeddedResolver, uno::UNO_QUERY_THROW ); + ::rtl::OUString aURL(RTL_CONSTASCII_USTRINGPARAM("Obj" )); + aURL += ::rtl::OUString::valueOf( nObjectCount++ ); + uno::Reference < io::XOutputStream > xOLEStream; + if( (xNA->getByName( aURL ) >>= xOLEStream) && xOLEStream.is() ) + { + const sal_Int32 nReadRequest = 0x1000; + uno::Sequence< sal_Int8 > aData; + + while( true ) + { + sal_Int32 nRead = m_xInputStream->readBytes( aData, nReadRequest ); + xOLEStream->writeBytes( aData ); + if( nRead < nReadRequest ) + { + xOLEStream->closeOutput(); + break; + } + } + + static const ::rtl::OUString sProtocol = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.EmbeddedObject:" )); + ::rtl::OUString aPersistName( xEmbeddedResolver->resolveEmbeddedObjectURL( aURL ) ); + sRet = aPersistName.copy( sProtocol.getLength() ); + + } + uno::Reference< lang::XComponent > xComp( xEmbeddedResolver, uno::UNO_QUERY_THROW ); + xComp->dispose(); + } + catch( const uno::Exception& rEx) + { + (void)rEx; + OSL_FAIL("exception in OLEHandler::createOLEObject"); + } + return sRet; +} + +} //namespace dmapper +} //namespace writerfilter + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/OLEHandler.hxx b/writerfilter/source/dmapper/OLEHandler.hxx new file mode 100644 index 000000000000..7a40f53986db --- /dev/null +++ b/writerfilter/source/dmapper/OLEHandler.hxx @@ -0,0 +1,109 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef INCLUDED_OLEHANDLER_HXX +#define INCLUDED_OLEHANDLER_HXX + +#include <WriterFilterDllApi.hxx> +#include <resourcemodel/LoggedResources.hxx> +#include <boost/shared_ptr.hpp> +#include <com/sun/star/awt/Size.hpp> +#include <com/sun/star/awt/Point.hpp> + +#include <com/sun/star/drawing/XShape.hpp> + +namespace com{ namespace sun{ namespace star{ + namespace embed{ + class XEmbeddedObject; + } + namespace graphic{ + class XGraphic; + } + namespace io{ + class XInputStream; + } + namespace text{ + class XTextDocument; + } + namespace uno{ + class XComponentContext; + } +}}} +namespace writerfilter { +namespace dmapper +{ +//class PropertyMap; +/** Handler for OLE objects + */ +class WRITERFILTER_DLLPRIVATE OLEHandler : public LoggedProperties +{ + ::rtl::OUString m_sObjectType; + ::rtl::OUString m_sProgId; + ::rtl::OUString m_sShapeId; + ::rtl::OUString m_sDrawAspect; + ::rtl::OUString m_sObjectId; + ::rtl::OUString m_sr_id; + + sal_Int32 m_nDxaOrig; + sal_Int32 m_nDyaOrig; + sal_Int32 m_nWrapMode; + + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > m_xShape; + + ::com::sun::star::awt::Size m_aShapeSize; + ::com::sun::star::awt::Point m_aShapePosition; + + ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic > m_xReplacement; + + ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > m_xInputStream; + + // Properties + virtual void lcl_attribute(Id Name, Value & val); + virtual void lcl_sprm(Sprm & sprm); + +public: + OLEHandler(); + virtual ~OLEHandler(); + + inline ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > getShape( ) { return m_xShape; }; + + inline bool isOLEObject( ) { return m_xInputStream.is( ); }; + + ::rtl::OUString copyOLEOStream( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextDocument > xTextDocument ); + + ::com::sun::star::awt::Size getSize() const { return m_aShapeSize;} + ::com::sun::star::awt::Point getPosition() const { return m_aShapePosition;} + ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic > + getReplacement() const { return m_xReplacement; } + +}; +typedef boost::shared_ptr< OLEHandler > OLEHandlerPtr; +}} + +#endif // + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/PageBordersHandler.cxx b/writerfilter/source/dmapper/PageBordersHandler.cxx new file mode 100644 index 000000000000..41469d6cf507 --- /dev/null +++ b/writerfilter/source/dmapper/PageBordersHandler.cxx @@ -0,0 +1,127 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +#include "PageBordersHandler.hxx" + +#include <ooxml/resourceids.hxx> + +#include "dmapperLoggers.hxx" + +namespace writerfilter { +namespace dmapper { + +_PgBorder::_PgBorder( ) : + m_nDistance( 0 ), + m_ePos( BORDER_RIGHT ) +{ +} + +_PgBorder::~_PgBorder( ) +{ +} + +PageBordersHandler::PageBordersHandler( ) : +LoggedProperties(dmapper_logger, "PageBordersHandler"), +m_nDisplay( 0 ), +m_nOffset( 0 ) +{ +} + +PageBordersHandler::~PageBordersHandler( ) +{ +} + +void PageBordersHandler::lcl_attribute( Id eName, Value& rVal ) +{ + int nIntValue = rVal.getInt( ); + switch ( eName ) + { + case NS_ooxml::LN_CT_PageBorders_display: + { + switch ( nIntValue ) + { + default: + case NS_ooxml::LN_Value_wordprocessingml_ST_PageBorderDisplay_allPages: + m_nDisplay = 0; + break; + case NS_ooxml::LN_Value_wordprocessingml_ST_PageBorderDisplay_firstPage: + m_nDisplay = 1; + break; + case NS_ooxml::LN_Value_wordprocessingml_ST_PageBorderDisplay_notFirstPage: + m_nDisplay = 2; + break; + } + } + break; + case NS_ooxml::LN_CT_PageBorders_offsetFrom: + { + switch ( nIntValue ) + { + default: + case NS_ooxml::LN_Value_wordprocessingml_ST_PageBorderOffset_page: + m_nOffset = 1; + break; + case NS_ooxml::LN_Value_wordprocessingml_ST_PageBorderOffset_text: + m_nOffset = 0; + break; + } + } + break; + default:; + } +} + +void PageBordersHandler::lcl_sprm( Sprm& rSprm ) +{ + switch ( rSprm.getId( ) ) + { + case NS_ooxml::LN_CT_PageBorders_top: + case NS_ooxml::LN_CT_PageBorders_left: + case NS_ooxml::LN_CT_PageBorders_bottom: + case NS_ooxml::LN_CT_PageBorders_right: + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + { + BorderHandlerPtr pBorderHandler( new BorderHandler( true ) ); + pProperties->resolve(*pBorderHandler); + BorderPosition ePos = BorderPosition( 0 ); + switch( rSprm.getId( ) ) + { + case NS_ooxml::LN_CT_PageBorders_top: + ePos = BORDER_TOP; + break; + case NS_ooxml::LN_CT_PageBorders_left: + ePos = BORDER_LEFT; + break; + case NS_ooxml::LN_CT_PageBorders_bottom: + ePos = BORDER_BOTTOM; + break; + case NS_ooxml::LN_CT_PageBorders_right: + ePos = BORDER_RIGHT; + break; + default:; + } + + _PgBorder aPgBorder; + aPgBorder.m_rLine = pBorderHandler->getBorderLine( ); + aPgBorder.m_nDistance = pBorderHandler->getLineDistance( ); + aPgBorder.m_ePos = ePos; + m_aBorders.push_back( aPgBorder ); + } + } + break; + default:; + } +} + +void PageBordersHandler::SetBorders( SectionPropertyMap* pSectContext ) +{ + for ( int i = 0, length = m_aBorders.size( ); i < length; i++ ) + { + _PgBorder aBorder = m_aBorders[i]; + pSectContext->SetBorder( aBorder.m_ePos, aBorder.m_nDistance, aBorder.m_rLine ); + } +} + +} } + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/PageBordersHandler.hxx b/writerfilter/source/dmapper/PageBordersHandler.hxx new file mode 100644 index 000000000000..d238a71981d7 --- /dev/null +++ b/writerfilter/source/dmapper/PageBordersHandler.hxx @@ -0,0 +1,60 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +#ifndef INCLUDED_PAGEBORDERSHANDLER_HXX +#define INCLUDED_PAGEBORDERSHANDLER_HXX + +#include "BorderHandler.hxx" +#include "PropertyMap.hxx" + +#include <WriterFilterDllApi.hxx> +#include <resourcemodel/LoggedResources.hxx> +#include <boost/shared_ptr.hpp> + +#include <com/sun/star/table/BorderLine2.hpp> + +#include <vector> + + +namespace writerfilter { +namespace dmapper { + +class _PgBorder +{ +public: + com::sun::star::table::BorderLine2 m_rLine; + sal_Int32 m_nDistance; + BorderPosition m_ePos; + + _PgBorder( ); + ~_PgBorder( ); +}; + +class WRITERFILTER_DLLPRIVATE PageBordersHandler : public LoggedProperties +{ +private: + + // See implementation of SectionPropertyMap::ApplyBorderToPageStyles + sal_Int32 m_nDisplay; + sal_Int32 m_nOffset; + vector<_PgBorder> m_aBorders; + + // Properties + virtual void lcl_attribute( Id eName, Value& rVal ); + virtual void lcl_sprm( Sprm& rSprm ); + +public: + PageBordersHandler( ); + ~PageBordersHandler( ); + + inline sal_Int32 GetDisplayOffset( ) + { + return ( m_nOffset << 5 ) + m_nDisplay; + }; + void SetBorders( SectionPropertyMap* pSectContext ); +}; +typedef boost::shared_ptr< PageBordersHandler > PageBordersHandlerPtr; + +} } + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/PropertyIds.cxx b/writerfilter/source/dmapper/PropertyIds.cxx new file mode 100644 index 000000000000..5373c005ee55 --- /dev/null +++ b/writerfilter/source/dmapper/PropertyIds.cxx @@ -0,0 +1,335 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include <PropertyIds.hxx> +#include <rtl/ustring.hxx> +#include <map> + +namespace writerfilter { +namespace dmapper{ + +typedef ::std::map< PropertyIds, ::rtl::OUString> PropertyNameMap_t; + +struct PropertyNameSupplier_Impl +{ + PropertyNameMap_t aNameMap; +}; + + + +PropertyNameSupplier::PropertyNameSupplier() : + m_pImpl(new PropertyNameSupplier_Impl) +{ +} + + +PropertyNameSupplier::~PropertyNameSupplier() +{ + delete m_pImpl; +} + + +const rtl::OUString& PropertyNameSupplier::GetName( PropertyIds eId ) const +{ + PropertyNameMap_t::iterator aIt = m_pImpl->aNameMap.find(eId); + if(aIt == m_pImpl->aNameMap.end()) + { + ::rtl::OUString sName; + switch(eId) + { + case PROP_CHAR_WEIGHT: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharWeight")); break; + case PROP_CHAR_POSTURE: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharPosture")); break; + case PROP_CHAR_STRIKEOUT: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharStrikeout")); break; + case PROP_CHAR_CONTOURED: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharContoured")); break; + case PROP_CHAR_SHADOWED: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharShadowed")); break; + case PROP_CHAR_CASE_MAP: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharCaseMap")); break; + case PROP_CHAR_COLOR: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharColor")); break; + case PROP_CHAR_RELIEF: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharRelief")); break; + case PROP_CHAR_UNDERLINE: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharUnderline")); break; + case PROP_CHAR_UNDERLINE_COLOR: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharUnderlineColor")); break; + case PROP_CHAR_UNDERLINE_HAS_COLOR: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharUnderlineHasColor")); break; + case PROP_CHAR_WORD_MODE: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharWordMode")); break; + case PROP_CHAR_ESCAPEMENT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharEscapement")); break; + case PROP_CHAR_ESCAPEMENT_HEIGHT: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharEscapementHeight")); break; + case PROP_CHAR_HEIGHT: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharHeight")); break; + case PROP_CHAR_HEIGHT_COMPLEX: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharHeightComplex")); break; + case PROP_CHAR_LOCALE: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharLocale")); break; + case PROP_CHAR_LOCALE_ASIAN: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharLocaleAsian")); break; + case PROP_CHAR_LOCALE_COMPLEX: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharLocaleComplex")); break; + case PROP_CHAR_WEIGHT_COMPLEX : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharWeightComplex")); break; + case PROP_CHAR_POSTURE_COMPLEX: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharPostureComplex")); break; + case PROP_CHAR_CHAR_KERNING: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharKerning")); break; + case PROP_CHAR_AUTO_KERNING: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharAutoKerning")); break; + case PROP_CHAR_SCALE_WIDTH: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharScaleWidth")); break; + case PROP_CHAR_STYLE_NAME: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharStyleName")); break; + case PROP_CHAR_FONT_NAME: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharFontName")); break; + case PROP_CHAR_FONT_STYLE: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharFontStyle")); break; + case PROP_CHAR_FONT_FAMILY: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharFontFamily")); break; + case PROP_CHAR_FONT_CHAR_SET: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharFontCharSet")); break; + case PROP_CHAR_FONT_PITCH: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharFontPitch")); break; + case PROP_CHAR_FONT_NAME_ASIAN : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharFontNameAsian")); break; + case PROP_CHAR_HEIGHT_ASIAN : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharHeightAsian")); break; + case PROP_CHAR_FONT_STYLE_ASIAN : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharFontStyleAsian")); break; + case PROP_CHAR_FONT_FAMILY_ASIAN : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharFontFamilyAsian")); break; + case PROP_CHAR_FONT_CHAR_SET_ASIAN : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharFontCharSetAsian")); break; + case PROP_CHAR_FONT_PITCH_ASIAN : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharFontPitchAsian")); break; + case PROP_CHAR_FONT_NAME_COMPLEX : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharFontNameComplex")); break; + case PROP_CHAR_FONT_STYLE_COMPLEX : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharFontStyleComplex")); break; + case PROP_CHAR_FONT_FAMILY_COMPLEX: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharFontFamilyComplex")); break; + case PROP_CHAR_FONT_CHAR_SET_COMPLEX: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharFontCharSetComplex")); break; + case PROP_CHAR_FONT_PITCH_COMPLEX: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharFontPitchComplex")); break; + case PROP_CHAR_HIDDEN : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharHidden")); break; + case PROP_CHAR_WEIGHT_ASIAN : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharWeightAsian")); break; + case PROP_CHAR_POSTURE_ASIAN : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharPostureAsian")); break; + case PROP_CHAR_BACK_COLOR: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharBackColor")); break; + case PROP_CHAR_EMPHASIS: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharEmphasis")); break; + case PROP_CHAR_COMBINE_IS_ON: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharCombineIsOn")); break; + case PROP_CHAR_COMBINE_PREFIX: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharCombinePrefix")); break; + case PROP_CHAR_COMBINE_SUFFIX: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharCombineSuffix")); break; + case PROP_CHAR_ROTATION: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharRotation")); break; + case PROP_CHAR_ROTATION_IS_FIT_TO_LINE: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharRotationIsFitToLine")); break; + case PROP_CHAR_FLASH: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharFlash")); break; + + case PROP_PARA_STYLE_NAME: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaStyleName")); break; + case PROP_PARA_ADJUST: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaAdjust")); break; + case PROP_PARA_LAST_LINE_ADJUST: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaLastLineAdjust")); break; + case PROP_PARA_RIGHT_MARGIN : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaRightMargin")); break; + case PROP_PARA_LEFT_MARGIN : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaLeftMargin")); break; + case PROP_PARA_FIRST_LINE_INDENT: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaFirstLineIndent")); break; + case PROP_PARA_KEEP_TOGETHER: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaKeepTogether")); break; + case PROP_PARA_TOP_MARGIN: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaTopMargin")); break; + case PROP_PARA_BOTTOM_MARGIN: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaBottomMargin")); break; + case PROP_PARA_IS_HYPHENATION: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaIsHyphenation")); break; + case PROP_PARA_LINE_NUMBER_COUNT: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaLineNumberCount")); break; + case PROP_PARA_IS_HANGING_PUNCTUATION: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaIsHangingPunctuation")); break; + case PROP_PARA_LINE_SPACING: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaLineSpacing")); break; + case PROP_PARA_TAB_STOPS: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaTabStops")); break; + case PROP_PARA_WIDOWS: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaWidows")); break; + case PROP_PARA_ORPHANS: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaOrphans")); break; + case PROP_PARA_LINE_NUMBER_START_VALUE: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaLineNumberStartValue")); break; + case PROP_NUMBERING_LEVEL: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NumberingLevel")); break; + case PROP_NUMBERING_RULES: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NumberingRules")); break; + case PROP_NUMBERING_TYPE: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NumberingType")); break; + case PROP_START_WITH: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StartWith")); break; + case PROP_ADJUST: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Adjust")); break; + case PROP_PARENT_NUMBERING: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParentNumbering")); break; + case PROP_RIGHT_MARGIN : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RightMargin")); break; + case PROP_LEFT_MARGIN : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("LeftMargin")); break; + case PROP_TOP_MARGIN : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TopMargin")); break; + case PROP_BOTTOM_MARGIN : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BottomMargin")); break; + case PROP_FIRST_LINE_OFFSET: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FirstLineOffset")); break; + case PROP_LEFT_BORDER : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("LeftBorder"));break; + case PROP_RIGHT_BORDER : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RightBorder"));break; + case PROP_TOP_BORDER : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TopBorder"));break; + case PROP_BOTTOM_BORDER : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BottomBorder"));break; + case PROP_TABLE_BORDER : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TableBorder"));break; + case PROP_LEFT_BORDER_DISTANCE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("LeftBorderDistance")); break; + case PROP_RIGHT_BORDER_DISTANCE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RightBorderDistance")); break; + case PROP_TOP_BORDER_DISTANCE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TopBorderDistance"));break; + case PROP_BOTTOM_BORDER_DISTANCE: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BottomBorderDistance")); break; + case PROP_CURRENT_PRESENTATION : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CurrentPresentation")); break; + case PROP_IS_FIXED : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IsFixed")); break; + case PROP_SUB_TYPE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SubType")); break; + case PROP_FILE_FORMAT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FileFormat")); break; + case PROP_HYPER_LINK_U_R_L : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HyperLinkURL")); break; + case PROP_NUMBER_FORMAT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NumberFormat")); break; + case PROP_NAME : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Name")); break; + case PROP_IS_INPUT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IsInput")); break; + case PROP_HINT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Hint")); break; + case PROP_FULL_NAME : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FullName")); break; + case PROP_KEYWORDS : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Keywords")); break; + case PROP_DESCRIPTION : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Description")); break; + case PROP_MACRO_NAME : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MacroName")); break; + case PROP_SUBJECT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Subject")); break; + case PROP_USER_DATA_TYPE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UserDataType")); break; + case PROP_TITLE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Title")); break; + case PROP_CONTENT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Content")); break; + case PROP_DATA_COLUMN_NAME : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DataColumnName")); break; + case PROP_INPUT_STREAM : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("InputStream")); break; + case PROP_GRAPHIC : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Graphic")); break; + case PROP_ANCHOR_TYPE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AnchorType")); break; + case PROP_SIZE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Size")); break; + case PROP_HORI_ORIENT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HoriOrient")); break; + case PROP_HORI_ORIENT_POSITION : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HoriOrientPosition")); break; + case PROP_HORI_ORIENT_RELATION : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HoriOrientRelation")); break; + case PROP_VERT_ORIENT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VertOrient")); break; + case PROP_VERT_ORIENT_POSITION : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VertOrientPosition")); break; + case PROP_VERT_ORIENT_RELATION : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VertOrientRelation")); break; + case PROP_GRAPHIC_CROP : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GraphicCrop")); break; + case PROP_SIZE100th_M_M : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Size100thMM")); break; + case PROP_SIZE_PIXEL : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SizePixel")); break; + case PROP_SURROUND : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Surround")); break; + case PROP_SURROUND_CONTOUR : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SurroundContour")); break; + case PROP_ADJUST_CONTRAST : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AdjustContrast")); break; + case PROP_ADJUST_LUMINANCE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AdjustLuminance")); break; + case PROP_GRAPHIC_COLOR_MODE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GraphicColorMode")); break; + case PROP_GAMMA : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Gamma")); break; + case PROP_HORI_MIRRORED_ON_EVEN_PAGES: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HoriMirroredOnEvenPages")); break; + case PROP_HORI_MIRRORED_ON_ODD_PAGES : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HoriMirroredOnOddPages")); break; + case PROP_VERT_MIRRORED : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VertMirrored")); break; + case PROP_CONTOUR_OUTSIDE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ContourOutside")); break; + case PROP_CONTOUR_POLY_POLYGON : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ContourPolyPolygon")); break; + case PROP_PAGE_TOGGLE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PageToggle")); break; + case PROP_BACK_COLOR : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BackColor")); break; + case PROP_ALTERNATIVE_TEXT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AlternativeText")); break; + case PROP_HEADER_TEXT_LEFT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HeaderTextLeft")); break; + case PROP_HEADER_TEXT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HeaderText")); break; + case PROP_HEADER_IS_SHARED : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HeaderIsShared")); break; + case PROP_HEADER_IS_ON : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HeaderIsOn")); break; + case PROP_FOOTER_TEXT_LEFT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FooterTextLeft")); break; + case PROP_FOOTER_TEXT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FooterText")); break; + case PROP_FOOTER_IS_SHARED : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FooterIsShared")); break; + case PROP_FOOTER_IS_ON : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FooterIsOn")); break; + case PROP_WIDTH : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Width")); break; + case PROP_HEIGHT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Height")); break; + case PROP_SEPARATOR_LINE_IS_ON : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SeparatorLineIsOn")); break; + case PROP_TEXT_COLUMNS : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TextColumns")); break; + case PROP_AUTOMATIC_DISTANCE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AutomaticDistance")); break; + case PROP_IS_LANDSCAPE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IsLandscape")); break; + case PROP_PRINTER_PAPER_TRAY_INDEX: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PrinterPaperTrayIndex")); break; + case PROP_FIRST_PAGE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("First Page")); break; + case PROP_DEFAULT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Default")); break; + case PROP_PAGE_DESC_NAME : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PageDescName")); break; + case PROP_PAGE_NUMBER_OFFSET: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PageNumberOffset")); break; + case PROP_BREAK_TYPE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BreakType")); break; + case PROP_FOOTER_IS_DYNAMIC_HEIGHT: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FooterIsDynamicHeight")); break; + case PROP_FOOTER_DYNAMIC_SPACING: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FooterDynamicSpacing")); break; + case PROP_FOOTER_HEIGHT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FooterHeight")); break; + case PROP_FOOTER_BODY_DISTANCE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FooterBodyDistance")); break; + case PROP_HEADER_IS_DYNAMIC_HEIGHT: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HeaderIsDynamicHeight")); break; + case PROP_HEADER_DYNAMIC_SPACING: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HeaderDynamicSpacing")); break; + case PROP_HEADER_HEIGHT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HeaderHeight")); break; + case PROP_HEADER_BODY_DISTANCE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HeaderBodyDistance")); break; + case PROP_WRITING_MODE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("WritingMode")); break; + case PROP_GRID_MODE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GridMode")); break; + case PROP_GRID_DISPLAY : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GridDisplay")); break; + case PROP_GRID_PRINT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GridPrint")); break; + case PROP_ADD_EXTERNAL_LEADING : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AddExternalLeading")); break; + case PROP_GRID_LINES : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GridLines")); break; + case PROP_GRID_BASE_HEIGHT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GridBaseHeight")); break; + case PROP_GRID_RUBY_HEIGHT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GridRubyHeight")); break; + case PROP_IS_ON : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IsOn")); break; + case PROP_RESTART_AT_EACH_PAGE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RestartAtEachPage")); break; + case PROP_COUNT_EMPTY_LINES : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CountEmptyLines")); break; + case PROP_COUNT_LINES_IN_FRAMES : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CountLinesInFrames")); break; + case PROP_INTERVAL : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Interval")); break; + case PROP_DISTANCE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Distance")); break; + case PROP_NUMBER_POSITION : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NumberPosition")); break; + case PROP_LEVEL : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Level")); break; + case PROP_LEVEL_PARAGRAPH_STYLES : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("LevelParagraphStyles")); break; + case PROP_LEVEL_FORMAT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("LevelFormat")); break; + case PROP_TOKEN_TYPE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TokenType")); break; + case PROP_TOKEN_HYPERLINK_START : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TokenHyperlinkStart")); break; + case PROP_TOKEN_HYPERLINK_END : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TokenHyperlinkEnd")); break; + case PROP_TOKEN_CHAPTER_INFO : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TokenChapterInfo")); break; + case PROP_CHAPTER_FORMAT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ChapterFormat")); break; + case PROP_TOKEN_TEXT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TokenText")); break; + case PROP_TEXT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Text")); break; + case PROP_CREATE_FROM_OUTLINE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CreateFromOutline")); break; + case PROP_CREATE_FROM_MARKS : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CreateFromMarks")); break; + case PROP_STANDARD : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Standard")); break; + case PROP_IS_SPLIT_ALLOWED : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IsSplitAllowed")); break; + case META_PROP_VERTICAL_BORDER : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VerticalBorder")); break; + case META_PROP_HORIZONTAL_BORDER : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HorizontalBorder")); break; + case PROP_HEADER_ROW_COUNT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HeaderRowCount")); break; + case PROP_IS_AUTO_HEIGHT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IsAutoHeight")); break; + case PROP_SIZE_TYPE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SizeType")); break; + case PROP_TABLE_COLUMN_SEPARATORS: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TableColumnSeparators")); break; + case META_PROP_TABLE_STYLE_NAME : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TableStyleName")); break; + case PROP_REDLINE_AUTHOR : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RedlineAuthor")); break; + case PROP_REDLINE_DATE_TIME : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RedlineDateTime")); break; + case PROP_REDLINE_COMMENT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RedlineComment")); break; + case PROP_REDLINE_TYPE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RedlineType")); break; + case PROP_REDLINE_SUCCESSOR_DATA: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RedlineSuccessorData")); break; + case PROP_REDLINE_IDENTIFIER : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RedlineIdentifier")); break; + case PROP_SIZE_PROTECTED : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SizeProtected")); break; + case PROP_POSITION_PROTECTED : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PositionProtected")); break; + case PROP_OPAQUE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Opaque")); break; + case PROP_VERTICAL_MERGE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VerticalMerge")); break; + case PROP_BULLET_CHAR : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BulletChar")); break; + case PROP_BULLET_FONT_NAME : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BulletFontName")); break; + case PROP_PARA_BACK_COLOR : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaBackColor")); break; + case PROP_TABS_RELATIVE_TO_INDENT: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TabsRelativeToIndent")); break; + case PROP_PREFIX : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Prefix")); break; + case PROP_SUFFIX : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Suffix")); break; + case PROP_CREATE_FROM_LEVEL_PARAGRAPH_STYLES: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CreateFromLevelParagraphStyles")); break; + case PROP_DROP_CAP_FORMAT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DropCapFormat")); break; + case PROP_REFERENCE_FIELD_PART : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReferenceFieldPart")); break; + case PROP_SOURCE_NAME: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SourceName")); break; + case PROP_REFERENCE_FIELD_SOURCE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReferenceFieldSource")); break; + case PROP_WIDTH_TYPE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("WidthType")); break; + case PROP_TEXT_RANGE: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TextRange")); break; + case PROP_SERVICE_CHAR_STYLE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.style.CharacterStyle")); break; + case PROP_SERVICE_PARA_STYLE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.style.ParagraphStyle")); break; + case PROP_CHARACTER_STYLES : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharacterStyles")); break; + case PROP_PARAGRAPH_STYLES : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParagraphStyles")); break; + case PROP_TABLE_BORDER_DISTANCES: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TableBorderDistances")); break; + case META_PROP_CELL_MAR_TOP : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MetaPropCellMarTop")); break; + case META_PROP_CELL_MAR_BOTTOM : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MetaPropCellMarBottom")); break; + case META_PROP_CELL_MAR_LEFT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MetaPropCellMarLeft")); break; + case META_PROP_CELL_MAR_RIGHT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MetaPropCellMarRight")); break; + case PROP_START_AT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StartAt")); break; + case PROP_ADD_PARA_TABLE_SPACING : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AddParaTableSpacing")); break; + case PROP_CHAR_PROP_HEIGHT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharPropHeight")); break; + case PROP_CHAR_PROP_HEIGHT_ASIAN : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharPropHeightAsian")); break; + case PROP_CHAR_PROP_HEIGHT_COMPLEX: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharPropHeightComplex")); break; + case PROP_FORMAT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Format")); break; + case PROP_INSERT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Insert")); break; + case PROP_DELETE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Delete")); break; + case PROP_STREAM_NAME: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StreamName")); break; + case PROP_BITMAP : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Bitmap")); break; + case PROP_IS_DATE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IsDate")); break; + case PROP_TAB_STOP_DISTANCE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TabStopDistance")); break; + case PROP_CNF_STYLE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CnfStyle")); break; + case PROP_INDENT_AT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IndentAt")); break; + case PROP_FIRST_LINE_INDENT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FirstLineIndent")); break; + case PROP_NUMBERING_STYLE_NAME : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NumberingStyleName")); break; + case PROP_OUTLINE_LEVEL : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OutlineLevel")); break; + case PROP_LISTTAB_STOP_POSITION : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ListtabStopPosition")); break; + case PROP_POSITION_AND_SPACE_MODE : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PositionAndSpaceMode")); break; + case PROP_PARA_SPLIT: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaSplit")); break; + case PROP_HELP: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Help")); break; + case PROP_HEADING_STYLE_NAME: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HeadingStyleName")); break; + case PROP_FRM_DIRECTION: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FRMDirection")); break; + } + ::std::pair<PropertyNameMap_t::iterator,bool> aInsertIt = + m_pImpl->aNameMap.insert( PropertyNameMap_t::value_type( eId, sName )); + if(aInsertIt.second) + aIt = aInsertIt.first; + } + return aIt->second; +} +PropertyNameSupplier& PropertyNameSupplier::GetPropertyNameSupplier() +{ + static PropertyNameSupplier aNameSupplier; + return aNameSupplier; +} + +} //namespace dmapper +} //namespace writerfilter + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/PropertyIds.hxx b/writerfilter/source/dmapper/PropertyIds.hxx new file mode 100644 index 000000000000..6ddd1d86a16b --- /dev/null +++ b/writerfilter/source/dmapper/PropertyIds.hxx @@ -0,0 +1,307 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef INCLUDED_DMAPPER_PROPERTYIDS_HXX +#define INCLUDED_DMAPPER_PROPERTYIDS_HXX + +namespace rtl{ class OUString;} + +namespace writerfilter { +namespace dmapper{ +enum PropertyIds + { + PROP_ID_START = 1 + ,META_PROP_CELL_MAR_BOTTOM = PROP_ID_START + ,META_PROP_CELL_MAR_LEFT + ,META_PROP_CELL_MAR_RIGHT + ,META_PROP_CELL_MAR_TOP + ,META_PROP_HORIZONTAL_BORDER + ,META_PROP_TABLE_STYLE_NAME + ,META_PROP_VERTICAL_BORDER + ,PROP_ADD_EXTERNAL_LEADING + ,PROP_ADD_PARA_TABLE_SPACING + ,PROP_ADJUST + ,PROP_ADJUST_CONTRAST + ,PROP_ADJUST_LUMINANCE + ,PROP_ALTERNATIVE_TEXT + ,PROP_ANCHOR_TYPE + ,PROP_AUTOMATIC_DISTANCE + ,PROP_BACK_COLOR + ,PROP_BITMAP + ,PROP_BOTTOM_BORDER + ,PROP_BOTTOM_BORDER_DISTANCE + ,PROP_BOTTOM_MARGIN + ,PROP_BREAK_TYPE + ,PROP_BULLET_CHAR + ,PROP_BULLET_FONT_NAME + ,PROP_CHAPTER_FORMAT + ,PROP_CHARACTER_STYLES + ,PROP_CHAR_AUTO_KERNING + ,PROP_CHAR_BACK_COLOR + ,PROP_CHAR_CASE_MAP + ,PROP_CHAR_CHAR_KERNING + ,PROP_CHAR_COLOR + ,PROP_CHAR_COMBINE_IS_ON + ,PROP_CHAR_COMBINE_PREFIX + ,PROP_CHAR_COMBINE_SUFFIX + ,PROP_CHAR_CONTOURED + ,PROP_CHAR_EMPHASIS + ,PROP_CHAR_ESCAPEMENT + ,PROP_CHAR_ESCAPEMENT_HEIGHT + ,PROP_CHAR_FLASH + ,PROP_CHAR_FONT_CHAR_SET + ,PROP_CHAR_FONT_CHAR_SET_ASIAN + ,PROP_CHAR_FONT_CHAR_SET_COMPLEX + ,PROP_CHAR_FONT_FAMILY + ,PROP_CHAR_FONT_FAMILY_ASIAN + ,PROP_CHAR_FONT_FAMILY_COMPLEX + ,PROP_CHAR_FONT_NAME + ,PROP_CHAR_FONT_NAME_ASIAN + ,PROP_CHAR_FONT_NAME_COMPLEX + ,PROP_CHAR_FONT_PITCH + ,PROP_CHAR_FONT_PITCH_ASIAN + ,PROP_CHAR_FONT_PITCH_COMPLEX + ,PROP_CHAR_FONT_STYLE + ,PROP_CHAR_FONT_STYLE_ASIAN + ,PROP_CHAR_FONT_STYLE_COMPLEX + ,PROP_CHAR_HEIGHT + ,PROP_CHAR_HEIGHT_ASIAN + ,PROP_CHAR_HEIGHT_COMPLEX + ,PROP_CHAR_HIDDEN + ,PROP_CHAR_LOCALE + ,PROP_CHAR_LOCALE_ASIAN + ,PROP_CHAR_LOCALE_COMPLEX + ,PROP_CHAR_POSTURE + ,PROP_CHAR_POSTURE_ASIAN + ,PROP_CHAR_POSTURE_COMPLEX + ,PROP_CHAR_PROP_HEIGHT + ,PROP_CHAR_PROP_HEIGHT_ASIAN + ,PROP_CHAR_PROP_HEIGHT_COMPLEX + ,PROP_CHAR_RELIEF + ,PROP_CHAR_ROTATION + ,PROP_CHAR_ROTATION_IS_FIT_TO_LINE + ,PROP_CHAR_SCALE_WIDTH + ,PROP_CHAR_SHADOWED + ,PROP_CHAR_STRIKEOUT + ,PROP_CHAR_STYLE_NAME + ,PROP_CHAR_UNDERLINE + ,PROP_CHAR_UNDERLINE_COLOR + ,PROP_CHAR_UNDERLINE_HAS_COLOR + ,PROP_CHAR_WEIGHT + ,PROP_CHAR_WEIGHT_ASIAN + ,PROP_CHAR_WEIGHT_COMPLEX + ,PROP_CHAR_WORD_MODE + ,PROP_CNF_STYLE + ,PROP_CONTENT + ,PROP_CONTOUR_OUTSIDE + ,PROP_CONTOUR_POLY_POLYGON + ,PROP_COUNT_EMPTY_LINES + ,PROP_COUNT_LINES_IN_FRAMES + ,PROP_CREATE_FROM_LEVEL_PARAGRAPH_STYLES + ,PROP_CREATE_FROM_MARKS + ,PROP_CREATE_FROM_OUTLINE + ,PROP_CURRENT_PRESENTATION + ,PROP_DATA_COLUMN_NAME + ,PROP_DEFAULT + ,PROP_DELETE + ,PROP_DESCRIPTION + ,PROP_DISTANCE + ,PROP_DROP_CAP_FORMAT + ,PROP_FILE_FORMAT + ,PROP_FIRST_LINE_INDENT + ,PROP_FIRST_LINE_OFFSET + ,PROP_FIRST_PAGE + ,PROP_FOOTER_BODY_DISTANCE + ,PROP_FOOTER_DYNAMIC_SPACING + ,PROP_FOOTER_HEIGHT + ,PROP_FOOTER_IS_DYNAMIC_HEIGHT + ,PROP_FOOTER_IS_ON + ,PROP_FOOTER_IS_SHARED + ,PROP_FOOTER_TEXT + ,PROP_FOOTER_TEXT_LEFT + ,PROP_FORMAT + ,PROP_FULL_NAME + ,PROP_GAMMA + ,PROP_GRAPHIC + ,PROP_GRAPHIC_COLOR_MODE + ,PROP_GRAPHIC_CROP + ,PROP_GRID_BASE_HEIGHT + ,PROP_GRID_DISPLAY + ,PROP_GRID_LINES + ,PROP_GRID_MODE + ,PROP_GRID_PRINT + ,PROP_GRID_RUBY_HEIGHT + ,PROP_HEADER_BODY_DISTANCE + ,PROP_HEADER_DYNAMIC_SPACING + ,PROP_HEADER_HEIGHT + ,PROP_HEADER_IS_DYNAMIC_HEIGHT + ,PROP_HEADER_IS_ON + ,PROP_HEADER_IS_SHARED + ,PROP_HEADER_ROW_COUNT + ,PROP_HEADER_TEXT + ,PROP_HEADER_TEXT_LEFT + ,PROP_HEADING_STYLE_NAME + ,PROP_HEIGHT + ,PROP_HELP + ,PROP_HINT + ,PROP_HORI_MIRRORED_ON_EVEN_PAGES + ,PROP_HORI_MIRRORED_ON_ODD_PAGES + ,PROP_HORI_ORIENT + ,PROP_HORI_ORIENT_POSITION + ,PROP_HORI_ORIENT_RELATION + ,PROP_HYPER_LINK_U_R_L + ,PROP_INDENT_AT + ,PROP_INPUT_STREAM + ,PROP_INSERT + ,PROP_INTERVAL + ,PROP_IS_AUTO_HEIGHT + ,PROP_IS_DATE + ,PROP_IS_FIXED + ,PROP_IS_INPUT + ,PROP_IS_LANDSCAPE + ,PROP_IS_ON + ,PROP_IS_SPLIT_ALLOWED + ,PROP_KEYWORDS + ,PROP_LEFT_BORDER + ,PROP_LEFT_BORDER_DISTANCE + ,PROP_LEFT_MARGIN + ,PROP_LEVEL + ,PROP_LEVEL_FORMAT + ,PROP_LEVEL_PARAGRAPH_STYLES + ,PROP_LISTTAB_STOP_POSITION + ,PROP_MACRO_NAME + ,PROP_NAME + ,PROP_NUMBERING_LEVEL + ,PROP_NUMBERING_RULES + ,PROP_NUMBERING_STYLE_NAME + ,PROP_NUMBERING_TYPE + ,PROP_NUMBER_FORMAT + ,PROP_NUMBER_POSITION + ,PROP_OPAQUE + ,PROP_OUTLINE_LEVEL + ,PROP_PAGE_DESC_NAME + ,PROP_PAGE_NUMBER_OFFSET + ,PROP_PAGE_TOGGLE + ,PROP_PARAGRAPH_STYLES + ,PROP_PARA_ADJUST + ,PROP_PARA_BACK_COLOR + ,PROP_PARA_BOTTOM_MARGIN + ,PROP_PARA_FIRST_LINE_INDENT + ,PROP_PARA_IS_HANGING_PUNCTUATION + ,PROP_PARA_IS_HYPHENATION + ,PROP_PARA_KEEP_TOGETHER + ,PROP_PARA_LAST_LINE_ADJUST + ,PROP_PARA_LEFT_MARGIN + ,PROP_PARA_LINE_NUMBER_COUNT + ,PROP_PARA_LINE_NUMBER_START_VALUE + ,PROP_PARA_LINE_SPACING + ,PROP_PARA_ORPHANS + ,PROP_PARA_RIGHT_MARGIN + ,PROP_PARA_SPLIT + ,PROP_PARA_STYLE_NAME + ,PROP_PARA_TAB_STOPS + ,PROP_PARA_TOP_MARGIN + ,PROP_PARA_WIDOWS + ,PROP_PARENT_NUMBERING + ,PROP_POSITION_AND_SPACE_MODE + ,PROP_POSITION_PROTECTED + ,PROP_PREFIX + ,PROP_PRINTER_PAPER_TRAY_INDEX + ,PROP_REDLINE_AUTHOR + ,PROP_REDLINE_COMMENT + ,PROP_REDLINE_DATE_TIME + ,PROP_REDLINE_IDENTIFIER + ,PROP_REDLINE_SUCCESSOR_DATA + ,PROP_REDLINE_TYPE + ,PROP_REFERENCE_FIELD_PART + ,PROP_REFERENCE_FIELD_SOURCE + ,PROP_RESTART_AT_EACH_PAGE + ,PROP_RIGHT_BORDER + ,PROP_RIGHT_BORDER_DISTANCE + ,PROP_RIGHT_MARGIN + ,PROP_SEPARATOR_LINE_IS_ON + ,PROP_SERVICE_CHAR_STYLE + ,PROP_SERVICE_PARA_STYLE + ,PROP_SIZE + ,PROP_SIZE100th_M_M + ,PROP_SIZE_PIXEL + ,PROP_SIZE_PROTECTED + ,PROP_SIZE_TYPE + ,PROP_SOURCE_NAME + ,PROP_STANDARD + ,PROP_START_AT + ,PROP_START_WITH + ,PROP_STREAM_NAME + ,PROP_SUBJECT + ,PROP_SUB_TYPE + ,PROP_SUFFIX + ,PROP_SURROUND + ,PROP_SURROUND_CONTOUR + ,PROP_TABLE_BORDER + ,PROP_TABLE_BORDER_DISTANCES + ,PROP_TABLE_COLUMN_SEPARATORS + ,PROP_TABS_RELATIVE_TO_INDENT + ,PROP_TAB_STOP_DISTANCE + ,PROP_TEXT + ,PROP_TEXT_COLUMNS + ,PROP_TEXT_RANGE + ,PROP_TITLE + ,PROP_TOKEN_CHAPTER_INFO + ,PROP_TOKEN_HYPERLINK_END + ,PROP_TOKEN_HYPERLINK_START + ,PROP_TOKEN_TEXT + ,PROP_TOKEN_TYPE + ,PROP_TOP_BORDER + ,PROP_TOP_BORDER_DISTANCE + ,PROP_TOP_MARGIN + ,PROP_USER_DATA_TYPE + ,PROP_VERTICAL_MERGE + ,PROP_VERT_MIRRORED + ,PROP_VERT_ORIENT + ,PROP_VERT_ORIENT_POSITION + ,PROP_VERT_ORIENT_RELATION + ,PROP_WIDTH + ,PROP_WIDTH_TYPE + ,PROP_WRITING_MODE +/*253*/ ,PROP_FRM_DIRECTION + }; +struct PropertyNameSupplier_Impl; +class PropertyNameSupplier +{ + PropertyNameSupplier_Impl* m_pImpl; +public: + PropertyNameSupplier(); + ~PropertyNameSupplier(); + const rtl::OUString& GetName( PropertyIds eId ) const; + + static PropertyNameSupplier& GetPropertyNameSupplier(); +}; +} //namespace dmapper +} // namespace writerfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/PropertyMap.cxx b/writerfilter/source/dmapper/PropertyMap.cxx new file mode 100644 index 000000000000..9ae05891e072 --- /dev/null +++ b/writerfilter/source/dmapper/PropertyMap.cxx @@ -0,0 +1,1226 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include <PropertyMap.hxx> +#include <ooxml/resourceids.hxx> +#include <DomainMapper_Impl.hxx> +#include <ConversionHelper.hxx> +#include <i18npool/paper.hxx> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/table/BorderLine2.hpp> +#include <com/sun/star/container/XEnumeration.hpp> +#include <com/sun/star/container/XEnumerationAccess.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/style/BreakType.hpp> +#include <com/sun/star/text/RelOrientation.hpp> +#include <com/sun/star/text/WritingMode.hpp> +#include <com/sun/star/text/XTextColumns.hpp> +#include <com/sun/star/text/XText.hpp> +#include <com/sun/star/text/TextGridMode.hpp> +#include <com/sun/star/text/XTextCopy.hpp> +#include "dmapperLoggers.hxx" +#include "PropertyMapHelper.hxx" + +using namespace ::com::sun::star; + +namespace writerfilter { +namespace dmapper{ + + + +PropertyMap::PropertyMap() : + m_cFootnoteSymbol( 0 ), + m_nFootnoteFontId( -1 ) +{ +} + + +PropertyMap::~PropertyMap() +{ +} + + +uno::Sequence< beans::PropertyValue > PropertyMap::GetPropertyValues() +{ + if(!m_aValues.getLength() && size()) + { + m_aValues.realloc( size() ); + ::com::sun::star::beans::PropertyValue* pValues = m_aValues.getArray(); + //style names have to be the first elements within the property sequence + //otherwise they will overwrite 'hard' attributes + sal_Int32 nValue = 0; + PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + PropertyMap::iterator aParaStyleIter = find(PropertyDefinition( PROP_PARA_STYLE_NAME, false ) ); + if( aParaStyleIter != end()) + { + pValues[nValue].Name = rPropNameSupplier.GetName( aParaStyleIter->first.eId ); + pValues[nValue].Value = aParaStyleIter->second; + ++nValue; + } + + PropertyMap::iterator aCharStyleIter = find(PropertyDefinition( PROP_CHAR_STYLE_NAME, false )); + if( aCharStyleIter != end()) + { + pValues[nValue].Name = rPropNameSupplier.GetName( aCharStyleIter->first.eId ); + pValues[nValue].Value = aCharStyleIter->second; + ++nValue; + } + PropertyMap::iterator aNumRuleIter = find(PropertyDefinition( PROP_NUMBERING_RULES, false ) ); + if( aNumRuleIter != end()) + { + pValues[nValue].Name = rPropNameSupplier.GetName( aNumRuleIter->first.eId ); + pValues[nValue].Value = aNumRuleIter->second; + ++nValue; + } + PropertyMap::iterator aMapIter = begin(); + for( ; nValue < m_aValues.getLength(); ++aMapIter ) + { + if( aMapIter != aParaStyleIter && aMapIter != aCharStyleIter && aMapIter != aNumRuleIter ) + { + pValues[nValue].Name = rPropNameSupplier.GetName( aMapIter->first.eId ); + pValues[nValue].Value = aMapIter->second; + ++nValue; + } + } + } + return m_aValues; +} + +#ifdef DEBUG_DMAPPER_PROPERTY_MAP +static void lcl_AnyToTag(const uno::Any & rAny) +{ + try { + sal_Int32 aInt = 0; + rAny >>= aInt; + dmapper_logger->attribute("value", aInt); + + sal_uInt32 auInt = 0; + rAny >>= auInt; + dmapper_logger->attribute("unsignedValue", auInt); + + float aFloat = 0.0f; + rAny >>= aFloat; + dmapper_logger->attribute("floatValue", aFloat); + + ::rtl::OUString aStr; + rAny >>= aStr; + dmapper_logger->attribute("stringValue", aStr); + } + catch (...) { + } +} +#endif + +void PropertyMap::Insert( PropertyIds eId, bool bIsTextProperty, const uno::Any& rAny, bool bOverwrite ) +{ +#ifdef DEBUG_DMAPPER_PROPERTY_MAP + const ::rtl::OUString& rInsert = PropertyNameSupplier:: + GetPropertyNameSupplier().GetName(eId); + + dmapper_logger->startElement("propertyMap.insert"); + dmapper_logger->attribute("name", rInsert); + lcl_AnyToTag(rAny); + dmapper_logger->endElement(); +#endif + + PropertyMap::iterator aElement = find(PropertyDefinition( eId, bIsTextProperty ) ); + if( aElement != end()) + { + if(!bOverwrite) + return; + erase( aElement ); + } + _PropertyMap::insert( PropertyMap::value_type + (PropertyDefinition( eId, bIsTextProperty), + rAny )); + Invalidate(); +} + +#ifdef DEBUG_DOMAINMAPPER +void PropertyMap::dumpXml( const TagLogger::Pointer_t pLogger ) const +{ + pLogger->startElement("PropertyMap"); + + PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + PropertyMap::const_iterator aMapIter = begin(); + while (aMapIter != end()) + { + pLogger->startElement("property"); + + pLogger->attribute("name", rPropNameSupplier.GetName( aMapIter->first.eId )); + + switch (aMapIter->first.eId) + { + case PROP_TABLE_COLUMN_SEPARATORS: + lcl_DumpTableColumnSeparators(pLogger, aMapIter->second); + break; + default: + { + try { + sal_Int32 aInt = 0; + aMapIter->second >>= aInt; + pLogger->attribute("value", aInt); + + sal_uInt32 auInt = 0; + aMapIter->second >>= auInt; + pLogger->attribute("unsignedValue", auInt); + + float aFloat = 0.0; + aMapIter->second >>= aFloat; + pLogger->attribute("floatValue", aFloat); + + ::rtl::OUString aStr; + aMapIter->second >>= auInt; + pLogger->attribute("stringValue", aStr); + } + catch (...) { + } + } + break; + } + + pLogger->endElement(); + + ++aMapIter; + } + + pLogger->endElement(); +} +#endif + + + +template<class T> + struct removeExistingElements : public ::std::unary_function<T, void> +{ + PropertyMap& rMap; + + removeExistingElements(PropertyMap& _rMap ) : rMap(_rMap) {} + void operator() (T x) + { + PropertyMap::iterator aElement = rMap.find(x.first); + if( aElement != rMap.end()) + rMap.erase( aElement ); + } +}; + + +void PropertyMap::insert( const PropertyMapPtr pMap, bool bOverwrite ) +{ + if( pMap.get() ) + { + if( bOverwrite ) + ::std::for_each( pMap->begin(), pMap->end(), removeExistingElements<PropertyMap::value_type>(*this) ); + _PropertyMap::insert(pMap->begin(), pMap->end()); + insertTableProperties(pMap.get()); + + Invalidate(); + } +} + + +const uno::Reference< text::XFootnote>& PropertyMap::GetFootnote() const +{ + return m_xFootnote; +} + + +void PropertyMap::insertTableProperties( const PropertyMap* ) +{ +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->element("PropertyMap.insertTableProperties"); +#endif +} + + +SectionPropertyMap::SectionPropertyMap(bool bIsFirstSection) : + m_bIsFirstSection( bIsFirstSection ) + ,m_nBorderParams( 0 ) + ,m_bTitlePage( false ) + ,m_nColumnCount( 0 ) + ,m_nColumnDistance( 1249 ) + ,m_bSeparatorLineIsOn( false ) + ,m_bEvenlySpaced( false ) + ,m_bIsLandscape( false ) + ,m_bPageNoRestart( false ) + ,m_nPageNumber( -1 ) + ,m_nBreakType( -1 ) + ,m_nPaperBin( -1 ) + ,m_nFirstPaperBin( -1 ) + ,m_nLeftMargin( 3175 ) //page left margin, default 0x708 (1800) twip -> 3175 1/100 mm + ,m_nRightMargin( 3175 )//page right margin, default 0x708 (1800) twip -> 3175 1/100 mm + ,m_nTopMargin( 2540 ) + ,m_nBottomMargin( 2540 ) + ,m_nHeaderTop( 1270 ) //720 twip + ,m_nHeaderBottom( 1270 )//720 twip + ,m_nDzaGutter( 0 ) + ,m_bGutterRTL( false ) + ,m_bSFBiDi( false ) + ,m_nGridType(0) + ,m_nGridLinePitch( 1 ) + ,m_nDxtCharSpace( 0 ) + ,m_nLnnMod( 0 ) + ,m_nLnc( 0 ) + ,m_ndxaLnn( 0 ) + ,m_nLnnMin( 0 ) +{ + static sal_Int32 nNumber = 0; + nSectionNumber = nNumber++; + memset(&m_pBorderLines, 0x00, sizeof(m_pBorderLines)); + for( sal_Int32 nBorder = 0; nBorder < 4; ++nBorder ) + m_nBorderDistances[ nBorder ] = -1; + //todo: set defaults in ApplyPropertiesToPageStyles + //initialize defaults + PaperInfo aLetter(PAPER_LETTER); + //page height, 1/100mm + Insert( PROP_HEIGHT, false, uno::makeAny( (sal_Int32) aLetter.getHeight() ) ); + //page width, 1/100mm + Insert( PROP_WIDTH, false, uno::makeAny( (sal_Int32) aLetter.getWidth() ) ); + //page left margin, default 0x708 (1800) twip -> 3175 1/100 mm + Insert( PROP_LEFT_MARGIN, false, uno::makeAny( (sal_Int32) 3175 ) ); + //page right margin, default 0x708 (1800) twip -> 3175 1/100 mm + Insert( PROP_RIGHT_MARGIN, false, uno::makeAny( (sal_Int32) 3175 ) ); + //page top margin, default 0x5a0 (1440) twip -> 2540 1/100 mm + Insert( PROP_TOP_MARGIN, false, uno::makeAny( (sal_Int32)2540 ) ); + //page bottom margin, default 0x5a0 (1440) twip -> 2540 1/100 mm + Insert( PROP_BOTTOM_MARGIN, false, uno::makeAny( (sal_Int32) 2540 ) ); + uno::Any aFalse( ::uno::makeAny( false ) ); + Insert( PROP_GRID_DISPLAY, false, aFalse); + Insert( PROP_GRID_PRINT, false, aFalse); + Insert( PROP_GRID_MODE, false, uno::makeAny(text::TextGridMode::NONE)); + + + if( m_bIsFirstSection ) + { + PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + m_sFirstPageStyleName = rPropNameSupplier.GetName( PROP_FIRST_PAGE ); + m_sFollowPageStyleName = rPropNameSupplier.GetName( PROP_STANDARD ); + } +} + + +SectionPropertyMap::~SectionPropertyMap() +{ + for( sal_Int16 ePos = BORDER_LEFT; ePos <= BORDER_BOTTOM; ++ePos) + delete m_pBorderLines[ePos]; +} + + +const ::rtl::OUString& SectionPropertyMap::GetPageStyleName( bool bFirst ) +{ + return bFirst ? m_sFirstPageStyleName : m_sFollowPageStyleName; +} + + +void SectionPropertyMap::SetPageStyleName( bool bFirst, const ::rtl::OUString& rName) +{ + if( bFirst ) + m_sFirstPageStyleName = rName; + else + m_sFollowPageStyleName = rName; +} + + +::rtl::OUString lcl_FindUnusedPageStyleName(const uno::Sequence< ::rtl::OUString >& rPageStyleNames) +{ + static const sal_Char cDefaultStyle[] = "Converted"; + //find the hightest number x in each style with the name "cDefaultStyle+x" and + //return an incremented name + sal_Int32 nMaxIndex = 0; + const sal_Int32 nDefaultLength = sizeof(cDefaultStyle)/sizeof(sal_Char) - 1; + const ::rtl::OUString sDefaultStyle( cDefaultStyle, nDefaultLength, RTL_TEXTENCODING_ASCII_US ); + + const ::rtl::OUString* pStyleNames = rPageStyleNames.getConstArray(); + for( sal_Int32 nStyle = 0; nStyle < rPageStyleNames.getLength(); ++nStyle) + { + if( pStyleNames[nStyle].getLength() > nDefaultLength && + !rtl_ustr_compare_WithLength( sDefaultStyle.getStr(), nDefaultLength, pStyleNames[nStyle].getStr(), nDefaultLength)) + { + sal_Int32 nIndex = pStyleNames[nStyle].copy( nDefaultLength ).toInt32(); + if( nIndex > nMaxIndex) + nMaxIndex = nIndex; + } + } + ::rtl::OUString sRet( sDefaultStyle ); + sRet += rtl::OUString::valueOf( nMaxIndex + 1); + return sRet; +} + + + +uno::Reference< beans::XPropertySet > SectionPropertyMap::GetPageStyle( + const uno::Reference< container::XNameContainer >& xPageStyles, + const uno::Reference < lang::XMultiServiceFactory >& xTextFactory, + bool bFirst ) +{ + uno::Reference< beans::XPropertySet > xRet; + try + { + if( bFirst ) + { + if( !m_sFirstPageStyleName.getLength() ) + { + uno::Sequence< ::rtl::OUString > aPageStyleNames = xPageStyles->getElementNames(); + m_sFirstPageStyleName = lcl_FindUnusedPageStyleName(aPageStyleNames); + m_aFirstPageStyle = uno::Reference< beans::XPropertySet > ( + xTextFactory->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.style.PageStyle") )), + uno::UNO_QUERY); + xPageStyles->insertByName( m_sFirstPageStyleName, uno::makeAny(m_aFirstPageStyle) ); + } + else if( !m_aFirstPageStyle.is() ) + { + xPageStyles->getByName(m_sFirstPageStyleName) >>= m_aFirstPageStyle; + } + xRet = m_aFirstPageStyle; + } + else + { + if( !m_sFollowPageStyleName.getLength() ) + { + uno::Sequence< ::rtl::OUString > aPageStyleNames = xPageStyles->getElementNames(); + m_sFollowPageStyleName = lcl_FindUnusedPageStyleName(aPageStyleNames); + m_aFollowPageStyle = uno::Reference< beans::XPropertySet > ( + xTextFactory->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.style.PageStyle") )), + uno::UNO_QUERY); + xPageStyles->insertByName( m_sFollowPageStyleName, uno::makeAny(m_aFollowPageStyle) ); + } + else if(!m_aFollowPageStyle.is() ) + { + xPageStyles->getByName(m_sFollowPageStyleName) >>= m_aFollowPageStyle; + } + xRet = m_aFollowPageStyle; + } + + } + catch( const uno::Exception& ) + { + } + + return xRet; +} + + +void SectionPropertyMap::SetBorder( BorderPosition ePos, sal_Int32 nLineDistance, const table::BorderLine2& rBorderLine ) +{ + delete m_pBorderLines[ePos]; + m_pBorderLines[ePos] = new table::BorderLine2( rBorderLine ); + m_nBorderDistances[ePos] = nLineDistance; +} + + +void SectionPropertyMap::ApplyBorderToPageStyles( + const uno::Reference< container::XNameContainer >& xPageStyles, + const uno::Reference < lang::XMultiServiceFactory >& xTextFactory, + sal_Int32 nValue ) +{ + /* + page border applies to: + nIntValue & 0x07 -> + 0 all pages in this section + 1 first page in this section + 2 all pages in this section but first + 3 whole document (all sections) + nIntValue & 0x18 -> page border depth 0 - in front 1- in back + nIntValue & 0xe0 -> + page border offset from: + 0 offset from text + 1 offset from edge of page + */ + uno::Reference< beans::XPropertySet > xFirst; + uno::Reference< beans::XPropertySet > xSecond; + sal_Int32 nOffsetFrom = (nValue & 0x00E0) >> 5; + //todo: negative spacing (from ww8par6.cxx) + switch( nValue & 0x07) + { + case 0: /*all styles*/ + if ( m_sFollowPageStyleName.getLength( ) > 0 ) + xFirst = GetPageStyle( xPageStyles, xTextFactory, false ); + if ( m_sFirstPageStyleName.getLength( ) > 0 ) + xSecond = GetPageStyle( xPageStyles, xTextFactory, true ); + break; + case 1: /*first page*/ + if ( m_sFirstPageStyleName.getLength( ) > 0 ) + xFirst = GetPageStyle( xPageStyles, xTextFactory, true ); + break; + case 2: /*left and right*/ + if ( m_sFollowPageStyleName.getLength( ) > 0 ) + xFirst = GetPageStyle( xPageStyles, xTextFactory, false ); + break; + case 3: //whole document? + //todo: how to apply a border to the whole document - find all sections or access all page styles? + default: + return; + } + //has to be sorted like enum BorderPosition: l-r-t-b + static const PropertyIds aBorderIds[4] = + { + PROP_LEFT_BORDER, + PROP_RIGHT_BORDER, + PROP_TOP_BORDER, + PROP_BOTTOM_BORDER + }; + static const PropertyIds aBorderDistanceIds[4] = + { + PROP_LEFT_BORDER_DISTANCE, + PROP_RIGHT_BORDER_DISTANCE, + PROP_TOP_BORDER_DISTANCE, + PROP_BOTTOM_BORDER_DISTANCE + }; + static const PropertyIds aMarginIds[4] = + { + PROP_LEFT_MARGIN, + PROP_RIGHT_MARGIN, + PROP_TOP_MARGIN, + PROP_BOTTOM_MARGIN + }; + + PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + for( sal_Int32 nBorder = 0; nBorder < 4; ++nBorder) + { + if( m_pBorderLines[nBorder] ) + { + const ::rtl::OUString sBorderName = rPropNameSupplier.GetName( aBorderIds[nBorder] ); + xFirst->setPropertyValue( sBorderName, uno::makeAny( *m_pBorderLines[nBorder] )); + if(xSecond.is()) + xSecond->setPropertyValue( sBorderName, uno::makeAny( *m_pBorderLines[nBorder] )); + } + if( m_nBorderDistances[nBorder] >= 0 ) + { + SetBorderDistance( xFirst, aMarginIds[nBorder], aBorderDistanceIds[nBorder], + m_nBorderDistances[nBorder], nOffsetFrom ); + if(xSecond.is()) + SetBorderDistance( xSecond, aMarginIds[nBorder], aBorderDistanceIds[nBorder], + m_nBorderDistances[nBorder], nOffsetFrom ); + } + } +} + +void SectionPropertyMap::SetBorderDistance( uno::Reference< beans::XPropertySet > xStyle, + PropertyIds eMarginId, PropertyIds eDistId, sal_Int32 nDistance, sal_Int32 nOffsetFrom ) +{ + PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + + sal_Int32 nDist = nDistance; + if( nOffsetFrom == 1 ) + { + const ::rtl::OUString sMarginName = rPropNameSupplier.GetName( eMarginId ); + uno::Any aMargin = xStyle->getPropertyValue( sMarginName ); + sal_Int32 nMargin = 0; + aMargin >>= nMargin; + + // Change the margins with the border distance + xStyle->setPropertyValue( sMarginName, uno::makeAny( nDistance ) ); + + // Set the distance to ( Margin - distance ) + nDist = nMargin - nDistance; + } + const ::rtl::OUString sBorderDistanceName = rPropNameSupplier.GetName( eDistId ); + xStyle->setPropertyValue( sBorderDistanceName, uno::makeAny( nDist )); +} + + + +uno::Reference< text::XTextColumns > SectionPropertyMap::ApplyColumnProperties( + uno::Reference< beans::XPropertySet > xColumnContainer ) +{ + uno::Reference< text::XTextColumns > xColumns; + try + { + PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + const ::rtl::OUString sTextColumns = rPropNameSupplier.GetName( PROP_TEXT_COLUMNS ); + xColumnContainer->getPropertyValue(sTextColumns) >>= xColumns; + uno::Reference< beans::XPropertySet > xColumnPropSet( xColumns, uno::UNO_QUERY_THROW ); + if( !m_bEvenlySpaced && + (sal_Int32(m_aColWidth.size()) == (m_nColumnCount + 1 )) && + (sal_Int32(m_aColDistance.size()) == m_nColumnCount)) + { + //the column width in word is an absolute value, in OOo it's relative + //the distances are both absolute + sal_Int32 nColSum = 0; + for( sal_Int32 nCol = 0; nCol <= m_nColumnCount; ++nCol) + { + nColSum += m_aColWidth[nCol]; + if(nCol) + nColSum += m_aColDistance[nCol -1]; + } + + sal_Int32 nRefValue = xColumns->getReferenceValue(); + double fRel = double( nRefValue ) / double( nColSum ); + uno::Sequence< text::TextColumn > aColumns( m_nColumnCount + 1 ); + text::TextColumn* pColumn = aColumns.getArray(); + + nColSum = 0; + for( sal_Int32 nCol = 0; nCol <= m_nColumnCount; ++nCol) + { + pColumn[nCol].LeftMargin = nCol ? m_aColDistance[nCol - 1 ] / 2 : 0; + pColumn[nCol].RightMargin = nCol == m_nColumnCount ? 0 : m_aColDistance[nCol] / 2; + pColumn[nCol].Width = sal_Int32((double( m_aColWidth[nCol] + pColumn[nCol].RightMargin + pColumn[nCol].LeftMargin ) + 0.5 ) * fRel ); + nColSum += pColumn[nCol].Width; + } + if( nColSum != nRefValue ) + pColumn[m_nColumnCount].Width -= ( nColSum - nRefValue ); + xColumns->setColumns( aColumns ); + } + else + { + xColumns->setColumnCount( m_nColumnCount + 1 ); + xColumnPropSet->setPropertyValue( rPropNameSupplier.GetName( PROP_AUTOMATIC_DISTANCE ), uno::makeAny( m_nColumnDistance )); + } + + if(m_bSeparatorLineIsOn) + xColumnPropSet->setPropertyValue( + rPropNameSupplier.GetName( PROP_SEPARATOR_LINE_IS_ON ), + uno::makeAny( m_bSeparatorLineIsOn )); + xColumnContainer->setPropertyValue( sTextColumns, uno::makeAny( xColumns ) ); + } + catch( const uno::Exception& ) + { + OSL_FAIL( "Exception in SectionPropertyMap::ApplyColumnProperties"); + } + return xColumns; +} + + + +bool SectionPropertyMap::HasHeader(bool bFirstPage) const +{ + bool bRet = false; + if( (bFirstPage && m_aFirstPageStyle.is()) ||( !bFirstPage && m_aFollowPageStyle.is()) ) + { + if( bFirstPage ) + m_aFirstPageStyle->getPropertyValue( + PropertyNameSupplier::GetPropertyNameSupplier().GetName(PROP_HEADER_IS_ON) ) >>= bRet; + else + m_aFollowPageStyle->getPropertyValue( + PropertyNameSupplier::GetPropertyNameSupplier().GetName(PROP_HEADER_IS_ON) ) >>= bRet; + } + return bRet; +} + + +bool SectionPropertyMap::HasFooter(bool bFirstPage) const +{ + bool bRet = false; + if( (bFirstPage && m_aFirstPageStyle.is()) ||( !bFirstPage && m_aFollowPageStyle.is()) ) + { + if( bFirstPage ) + m_aFirstPageStyle->getPropertyValue( + PropertyNameSupplier::GetPropertyNameSupplier().GetName(PROP_FOOTER_IS_ON) ) >>= bRet; + else + m_aFollowPageStyle->getPropertyValue( + PropertyNameSupplier::GetPropertyNameSupplier().GetName(PROP_FOOTER_IS_ON) ) >>= bRet; + } + return bRet; +} + + +#define MIN_HEAD_FOOT_HEIGHT 100 //minimum header/footer height + +void SectionPropertyMap::CopyLastHeaderFooter( bool bFirstPage, DomainMapper_Impl& rDM_Impl ) +{ +#if DEBUG + clog << "START>>> SectionPropertyMap::CopyLastHeaderFooter()" << endl; +#endif + SectionPropertyMap* pLastContext = rDM_Impl.GetLastSectionContext( ); + if ( pLastContext ) + { + uno::Reference< beans::XPropertySet > xPrevStyle = pLastContext->GetPageStyle( + rDM_Impl.GetPageStyles(), + rDM_Impl.GetTextFactory(), + bFirstPage ); + uno::Reference< beans::XPropertySet > xStyle = GetPageStyle( + rDM_Impl.GetPageStyles(), + rDM_Impl.GetTextFactory(), + bFirstPage ); + + PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + + try { + // Loop over the Header and Footer properties to copy them + static PropertyIds aProperties[] = + { + PROP_HEADER_TEXT, + PROP_FOOTER_TEXT, + }; + + bool bHasPrevHeader = false; + bool bHasHeader = false; + + rtl::OUString sHeaderIsOn = rPropNameSupplier.GetName( PROP_HEADER_IS_ON ); + xPrevStyle->getPropertyValue( sHeaderIsOn ) >>= bHasPrevHeader; + xStyle->getPropertyValue( sHeaderIsOn ) >>= bHasHeader; + bool bCopyHeader = bHasPrevHeader && !bHasHeader; + + if ( bCopyHeader ) + xStyle->setPropertyValue( sHeaderIsOn, uno::makeAny( sal_True ) ); + + bool bHasPrevFooter = false; + bool bHasFooter = false; + + rtl::OUString sFooterIsOn = rPropNameSupplier.GetName( PROP_FOOTER_IS_ON ); + xPrevStyle->getPropertyValue( sFooterIsOn ) >>= bHasPrevFooter; + xStyle->getPropertyValue( sFooterIsOn ) >>= bHasFooter; + bool bCopyFooter = bHasPrevFooter && !bHasFooter; + + if ( bCopyFooter ) + xStyle->setPropertyValue( sFooterIsOn, uno::makeAny( sal_True ) ); + + // Copying the text properties + for ( int i = 0, nNbProps = 2; i < nNbProps; i++ ) + { + bool bIsHeader = ( i < nNbProps / 2 ); + PropertyIds aPropId = aProperties[i]; + rtl::OUString sName = rPropNameSupplier.GetName( aPropId ); + + if ( ( bIsHeader && bCopyHeader ) || ( !bIsHeader && bCopyFooter ) ) + { +#if DEBUG + clog << "Copying "; + clog << rtl::OUStringToOString( sName, RTL_TEXTENCODING_UTF8 ).getStr( ) << endl; +#endif + // TODO has to be copied + uno::Reference< text::XTextCopy > xTxt( + xStyle->getPropertyValue( sName ), uno::UNO_QUERY_THROW ); + + uno::Reference< text::XTextCopy > xPrevTxt( + xPrevStyle->getPropertyValue( sName ), uno::UNO_QUERY_THROW ); + + xTxt->copyText( xPrevTxt ); + } + } + } + catch ( const uno::Exception& e ) + { +#if DEBUG + clog << "An exception occurred in SectionPropertyMap::CopyLastHeaderFooter( ) - "; + clog << rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_UTF8 ).getStr( ) << endl; +#endif + } + } +#if DEBUG + clog << "END>>> SectionPropertyMap::CopyLastHeaderFooter()" << endl; +#endif +} + +void SectionPropertyMap::PrepareHeaderFooterProperties( bool bFirstPage ) +{ + sal_Int32 nTopMargin = m_nTopMargin; + if(HasHeader(bFirstPage)) + { + m_nTopMargin = m_nHeaderTop; + if( nTopMargin > 0 && nTopMargin > m_nHeaderTop ) + m_nHeaderTop = nTopMargin - m_nHeaderTop; + else + m_nHeaderTop = 0; + + //minimum header height 1mm + if( m_nHeaderTop < MIN_HEAD_FOOT_HEIGHT ) + m_nHeaderTop = MIN_HEAD_FOOT_HEIGHT; + } + + + if( nTopMargin >= 0 ) //fixed height header -> see WW8Par6.hxx + { + operator[]( PropertyDefinition( PROP_HEADER_IS_DYNAMIC_HEIGHT, false )) = uno::makeAny( true ); + operator[]( PropertyDefinition( PROP_HEADER_DYNAMIC_SPACING, false )) = uno::makeAny( true ); + operator[]( PropertyDefinition( PROP_HEADER_BODY_DISTANCE, false )) = uno::makeAny( m_nHeaderTop - MIN_HEAD_FOOT_HEIGHT );// ULSpace.Top() + operator[]( PropertyDefinition( PROP_HEADER_HEIGHT, false )) = uno::makeAny( m_nHeaderTop ); + + } + else + { + //todo: old filter fakes a frame into the header/footer to support overlapping + //current setting is completely wrong! + operator[]( PropertyDefinition( PROP_HEADER_HEIGHT, false )) = uno::makeAny( m_nHeaderTop ); + operator[]( PropertyDefinition( PROP_HEADER_BODY_DISTANCE, false )) = uno::makeAny( nTopMargin - m_nHeaderTop ); + operator[]( PropertyDefinition( PROP_HEADER_IS_DYNAMIC_HEIGHT, false)) = uno::makeAny( false ); + operator[]( PropertyDefinition( PROP_HEADER_DYNAMIC_SPACING, false)) = uno::makeAny( false ); + } + + sal_Int32 nBottomMargin = m_nBottomMargin; + if( HasFooter( bFirstPage ) ) + { + m_nBottomMargin = m_nHeaderBottom; + if( nBottomMargin > 0 && nBottomMargin > m_nHeaderBottom ) + m_nHeaderBottom = nBottomMargin - m_nHeaderBottom; + else + m_nHeaderBottom = 0; + if( m_nHeaderBottom < MIN_HEAD_FOOT_HEIGHT ) + m_nHeaderBottom = MIN_HEAD_FOOT_HEIGHT; + } + + if( nBottomMargin >= 0 ) //fixed height footer -> see WW8Par6.hxx + { + operator[]( PropertyDefinition( PROP_FOOTER_IS_DYNAMIC_HEIGHT, false )) = uno::makeAny( true ); + operator[]( PropertyDefinition( PROP_FOOTER_DYNAMIC_SPACING, false )) = uno::makeAny( true ); + operator[]( PropertyDefinition( PROP_FOOTER_BODY_DISTANCE, false )) = uno::makeAny( m_nHeaderBottom - MIN_HEAD_FOOT_HEIGHT); + operator[]( PropertyDefinition( PROP_FOOTER_HEIGHT, false )) = uno::makeAny( m_nHeaderBottom ); + } + else + { + //todo: old filter fakes a frame into the header/footer to support overlapping + //current setting is completely wrong! + operator[]( PropertyDefinition( PROP_FOOTER_IS_DYNAMIC_HEIGHT, false)) = uno::makeAny( false ); + operator[]( PropertyDefinition( PROP_FOOTER_DYNAMIC_SPACING, false)) = uno::makeAny( false ); + operator[]( PropertyDefinition( PROP_FOOTER_HEIGHT, false )) = uno::makeAny( nBottomMargin - m_nHeaderBottom ); + operator[]( PropertyDefinition( PROP_FOOTER_BODY_DISTANCE, false )) = uno::makeAny( m_nHeaderBottom ); + } + + //now set the top/bottom margin for the follow page style + operator[]( PropertyDefinition( PROP_TOP_MARGIN, false )) = uno::makeAny( m_nTopMargin ); + operator[]( PropertyDefinition( PROP_BOTTOM_MARGIN, false )) = uno::makeAny( m_nBottomMargin ); +} + + +void SectionPropertyMap::CloseSectionGroup( DomainMapper_Impl& rDM_Impl ) +{ + PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + if( m_nLnnMod ) + { + bool bFirst = rDM_Impl.IsLineNumberingSet(); + rDM_Impl.SetLineNumbering( m_nLnnMod, m_nLnc, m_ndxaLnn ); + if( m_nLnnMin > 0 || (bFirst && m_nLnc == 1)) + { + //set the starting value at the beginning of the section + try + { + uno::Reference< beans::XPropertySet > xRangeProperties; + if( m_xStartingRange.is() ) + { + xRangeProperties = uno::Reference< beans::XPropertySet >( m_xStartingRange, uno::UNO_QUERY_THROW ); + } + else + { + //set the start value at the beginning of the document + xRangeProperties = uno::Reference< beans::XPropertySet >( rDM_Impl.GetTextDocument()->getText()->getStart(), uno::UNO_QUERY_THROW ); + } + xRangeProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_PARA_LINE_NUMBER_START_VALUE ), uno::makeAny( m_nLnnMin + 1 )); + } + catch( const uno::Exception& ) + { + OSL_FAIL( "Exception in SectionPropertyMap::CloseSectionGroup"); + } + } + } + + //depending on the break type no page styles should be created + if(m_nBreakType == 0) + { + //todo: insert a section or access the already inserted section + uno::Reference< beans::XPropertySet > xSection = + rDM_Impl.appendTextSectionAfter( m_xStartingRange ); + if( m_nColumnCount > 0 && xSection.is()) + ApplyColumnProperties( xSection ); + } + else + { + //get the properties and create appropriate page styles + uno::Reference< beans::XPropertySet > xFollowPageStyle = GetPageStyle( rDM_Impl.GetPageStyles(), rDM_Impl.GetTextFactory(), false ); + + if( m_nDzaGutter > 0 ) + { + //todo: iGutterPos from DocProperties are missing + if( m_bGutterRTL ) + m_nRightMargin += m_nDzaGutter; + else + m_nLeftMargin += m_nDzaGutter; + } + operator[]( PropertyDefinition( PROP_LEFT_MARGIN, false )) = uno::makeAny( m_nLeftMargin ); + operator[]( PropertyDefinition( PROP_RIGHT_MARGIN, false )) = uno::makeAny( m_nRightMargin ); + + /*** if headers/footers are available then the top/bottom margins of the + header/footer are copied to the top/bottom margin of the page + */ + CopyLastHeaderFooter( false, rDM_Impl ); + PrepareHeaderFooterProperties( false ); + + const ::rtl::OUString sTrayIndex = rPropNameSupplier.GetName( PROP_PRINTER_PAPER_TRAY_INDEX ); + if( m_nPaperBin >= 0 ) + xFollowPageStyle->setPropertyValue( sTrayIndex, uno::makeAny( m_nPaperBin ) ); + uno::Reference< text::XTextColumns > xColumns; + if( m_nColumnCount > 0 ) + xColumns = ApplyColumnProperties( xFollowPageStyle ); + + //prepare text grid properties + sal_Int32 nHeight = 1; + PropertyMap::iterator aElement = find(PropertyDefinition( PROP_HEIGHT, false )); + if( aElement != end()) + aElement->second >>= nHeight; + + sal_Int32 nWidth = 1; + aElement = find(PropertyDefinition( PROP_WIDTH, false )); + if( aElement != end()) + aElement->second >>= nWidth; + + text::WritingMode eWritingMode = text::WritingMode_LR_TB; + aElement = find(PropertyDefinition( PROP_WRITING_MODE, false )); + if( aElement != end()) + aElement->second >>= eWritingMode; + + + + sal_Int32 nTextAreaHeight = eWritingMode == text::WritingMode_LR_TB ? + nHeight - m_nTopMargin - m_nBottomMargin : + nWidth - m_nLeftMargin - m_nRightMargin; + + operator[]( PropertyDefinition( PROP_GRID_LINES, false )) = + uno::makeAny( static_cast<sal_Int16>(nTextAreaHeight/m_nGridLinePitch)); + + sal_Int32 nCharWidth = 423; //240 twip/ 12 pt + //todo: is '0' the right index here? + const StyleSheetEntryPtr pEntry = rDM_Impl.GetStyleSheetTable()->FindStyleSheetByISTD(::rtl::OUString::valueOf(static_cast<sal_Int32>(0), 16)); + if( pEntry.get( ) ) + { + PropertyMap::iterator aElement_ = pEntry->pProperties->find(PropertyDefinition( PROP_CHAR_HEIGHT_ASIAN, false )); + if( aElement_ != pEntry->pProperties->end()) + { + double fHeight = 0; + if( aElement_->second >>= fHeight ) + nCharWidth = ConversionHelper::convertTwipToMM100( (long)( fHeight * 20.0 + 0.5 )); + } + } + + //dxtCharSpace + if(m_nDxtCharSpace) + { + sal_Int32 nCharSpace = m_nDxtCharSpace; + //main lives in top 20 bits, and is signed. + sal_Int32 nMain = (nCharSpace & 0xFFFFF000); + nMain /= 0x1000; + nCharWidth += ConversionHelper::convertTwipToMM100( nMain * 20 ); + + sal_Int32 nFraction = (nCharSpace & 0x00000FFF); + nFraction = (nFraction * 20)/0xFFF; + nCharWidth += ConversionHelper::convertTwipToMM100( nFraction ); + } + operator[]( PropertyDefinition( PROP_GRID_BASE_HEIGHT, false )) = uno::makeAny( nCharWidth ); + sal_Int32 nRubyHeight = m_nGridLinePitch - nCharWidth; + if(nRubyHeight < 0 ) + nRubyHeight = 0; + operator[]( PropertyDefinition( PROP_GRID_RUBY_HEIGHT, false )) = uno::makeAny( nRubyHeight ); + + sal_Int16 nGridMode = text::TextGridMode::NONE; + + switch (m_nGridType) + { + case NS_ooxml::LN_Value_wordprocessingml_ST_DocGrid_lines: + nGridMode = text::TextGridMode::LINES; + break; + case NS_ooxml::LN_Value_wordprocessingml_ST_DocGrid_linesAndChars: + nGridMode = text::TextGridMode::LINES_AND_CHARS; + break; + default: + break; + } + + operator[](PropertyDefinition(PROP_GRID_MODE, false)) = uno::makeAny(nGridMode); + + _ApplyProperties( xFollowPageStyle ); + + //todo: creating a "First Page" style depends on HasTitlePage und _fFacingPage_ + if( m_bTitlePage ) + { + CopyLastHeaderFooter( true, rDM_Impl ); + PrepareHeaderFooterProperties( true ); + uno::Reference< beans::XPropertySet > xFirstPageStyle = GetPageStyle( + rDM_Impl.GetPageStyles(), rDM_Impl.GetTextFactory(), true ); + _ApplyProperties( xFirstPageStyle ); + + sal_Int32 nPaperBin = m_nFirstPaperBin >= 0 ? m_nFirstPaperBin : m_nPaperBin >= 0 ? m_nPaperBin : 0; + if( nPaperBin ) + xFollowPageStyle->setPropertyValue( sTrayIndex, uno::makeAny( nPaperBin ) ); + if( xColumns.is() ) + xFollowPageStyle->setPropertyValue( + rPropNameSupplier.GetName( PROP_TEXT_COLUMNS ), uno::makeAny( xColumns )); + } + + ApplyBorderToPageStyles( rDM_Impl.GetPageStyles( ), rDM_Impl.GetTextFactory( ), m_nBorderParams ); + + try + { + { + //now apply this break at the first paragraph of this section + uno::Reference< beans::XPropertySet > xRangeProperties; + if( m_bIsFirstSection ) + { + uno::Reference< container::XEnumerationAccess > xEnumAccess( rDM_Impl.GetBodyText( ), uno::UNO_QUERY_THROW ); + uno::Reference< container::XEnumeration > xEnum = xEnumAccess->createEnumeration( ); + xRangeProperties = uno::Reference< beans::XPropertySet >( xEnum->nextElement( ), uno::UNO_QUERY_THROW ); + } + else + xRangeProperties = uno::Reference< beans::XPropertySet >( m_xStartingRange, uno::UNO_QUERY_THROW ); + /* break type + 0 - No break 1 - New Colunn 2 - New page 3 - Even page 4 - odd page */ + xRangeProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_PAGE_DESC_NAME ), + uno::makeAny( m_bTitlePage ? m_sFirstPageStyleName : m_sFollowPageStyleName )); + // todo: page breaks with odd/even page numbering are not available - find out current page number to check how to change the number + // or add even/odd page break types + if(m_bPageNoRestart || m_nPageNumber >= 0) + { + sal_Int16 nPageNumber = m_nPageNumber >= 0 ? static_cast< sal_Int16 >(m_nPageNumber) : 1; + xRangeProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_PAGE_NUMBER_OFFSET ), + uno::makeAny( nPageNumber )); + } + } + } + catch( const uno::Exception& rEx) + { + OSL_FAIL( "Exception in SectionPropertyMap::CloseSectionGroup"); + (void)rEx; + } + } +} + + +void SectionPropertyMap::_ApplyProperties( uno::Reference< beans::XPropertySet > xStyle ) +{ + PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + PropertyMap::iterator aMapIter = begin(); + while( aMapIter != end()) + { + try + { + xStyle->setPropertyValue( rPropNameSupplier.GetName( aMapIter->first.eId ), aMapIter->second ); + } + catch( const uno::Exception& ) + { + OSL_FAIL( "Exception in <PageStyle>::setPropertyValue"); + } + ++aMapIter; + } +} +sal_Int32 lcl_AlignPaperBin( sal_Int32 nSet ) +{ + //default tray numbers are above 0xff + if( nSet > 0xff ) + nSet = nSet >> 8; + //there are some special numbers which can't be handled easily + //1, 4, 15, manual tray, upper tray, auto select? see ww8atr.cxx + //todo: find out appropriate conversion + return nSet; +} + + +void SectionPropertyMap::SetPaperBin( sal_Int32 nSet ) +{ + m_nPaperBin = lcl_AlignPaperBin( nSet ); +} + + +void SectionPropertyMap::SetFirstPaperBin( sal_Int32 nSet ) +{ + m_nFirstPaperBin = lcl_AlignPaperBin( nSet ); +} + + +StyleSheetPropertyMap::StyleSheetPropertyMap() : + mnCT_Spacing_line( 0 ), + mnCT_Spacing_lineRule( 0 ), + mbCT_TrPrBase_tblHeader( false ), + mnCT_TrPrBase_jc( 0 ), + mnCT_TcPrBase_vAlign( 0 ), + mnCT_TblWidth_w( 0 ), + mnCT_TblWidth_type( 0 ), + mbCT_Spacing_lineSet( false ), + mbCT_Spacing_lineRuleSet( false ), + mbCT_TrPrBase_tblHeaderSet( false ), + mbCT_TrPrBase_jcSet( false ), + mbCT_TcPrBase_vAlignSet( false ), + mbCT_TblWidth_wSet( false ), + mbCT_TblWidth_typeSet( false ), + mnListId( -1 ), + mnListLevel( -1 ), + mnOutlineLevel( -1 ) +{ +} + + +StyleSheetPropertyMap::~StyleSheetPropertyMap() +{ +} + + +ParagraphProperties::ParagraphProperties() : + m_bFrameMode( false ), + m_nDropCap(NS_ooxml::LN_Value_wordprocessingml_ST_DropCap_none), + m_nLines(0), + m_w(-1), + m_h(-1), + m_nWrap(-1), + m_hAnchor(-1), + m_vAnchor(text::RelOrientation::FRAME), + m_x(-1), + m_bxValid( false ), + m_y(-1), + m_byValid( false ), + m_hSpace(-1), + m_vSpace(-1), + m_hRule(-1), + m_xAlign(-1), + m_yAlign(-1), + m_bAnchorLock(false), + m_nDropCapLength(0) +{ +} + + +ParagraphProperties::ParagraphProperties(const ParagraphProperties& rCopy) : + m_bFrameMode ( rCopy.m_bFrameMode), + m_nDropCap ( rCopy.m_nDropCap), + m_nLines ( rCopy.m_nLines), + m_w ( rCopy.m_w), + m_h ( rCopy.m_h), + m_nWrap ( rCopy.m_nWrap), + m_hAnchor ( rCopy.m_hAnchor), + m_vAnchor ( rCopy.m_vAnchor), + m_x ( rCopy.m_x), + m_bxValid ( rCopy.m_bxValid), + m_y ( rCopy.m_y), + m_byValid ( rCopy.m_byValid), + m_hSpace ( rCopy.m_hSpace), + m_vSpace ( rCopy.m_vSpace), + m_hRule ( rCopy.m_hRule), + m_xAlign ( rCopy.m_xAlign), + m_yAlign ( rCopy.m_yAlign), + m_bAnchorLock( rCopy.m_bAnchorLock), + m_nDropCapLength( rCopy.m_nDropCapLength ), + m_sParaStyleName( rCopy.m_sParaStyleName), + m_xStartingRange( rCopy.m_xStartingRange ), + m_xEndingRange( rCopy.m_xEndingRange) +{ +} + + +ParagraphProperties::~ParagraphProperties() +{ +} + + +int ParagraphProperties::operator==(const ParagraphProperties& rCompare) +{ + return + m_bFrameMode == rCompare.m_bFrameMode && + m_nDropCap == rCompare.m_nDropCap && + m_nLines == rCompare.m_nLines && + m_w == rCompare.m_w && + m_h == rCompare.m_h && + m_nWrap == rCompare.m_nWrap && + m_hAnchor == rCompare.m_hAnchor && + m_vAnchor == rCompare.m_vAnchor && + m_x == rCompare.m_x && + m_bxValid == rCompare.m_bxValid && + m_y == rCompare.m_y && + m_byValid == rCompare.m_byValid && + m_hSpace == rCompare.m_hSpace && + m_vSpace == rCompare.m_vSpace && + m_hRule == rCompare.m_hRule && + m_xAlign == rCompare.m_xAlign && + m_yAlign == rCompare.m_yAlign && + m_bAnchorLock== rCompare.m_bAnchorLock; +} + + +ParagraphPropertyMap::ParagraphPropertyMap() +{ +} + + +ParagraphPropertyMap::~ParagraphPropertyMap() +{ +} + + +TablePropertyMap::TablePropertyMap() +{ +} + + +TablePropertyMap::~TablePropertyMap() +{ +} + + +bool TablePropertyMap::getValue( TablePropertyMapTarget eWhich, sal_Int32& nFill ) +{ + if( eWhich < TablePropertyMapTarget_MAX ) + { + if(m_aValidValues[eWhich].bValid) + nFill = m_aValidValues[eWhich].nValue; + return m_aValidValues[eWhich].bValid; + } + else + { + OSL_FAIL( "invalid TablePropertyMapTarget"); + return false; + } +} + + +void TablePropertyMap::setValue( TablePropertyMapTarget eWhich, sal_Int32 nSet ) +{ + if( eWhich < TablePropertyMapTarget_MAX ) + { + m_aValidValues[eWhich].bValid = true; + m_aValidValues[eWhich].nValue = nSet; + } + else + OSL_FAIL( "invalid TablePropertyMapTarget"); +} + + +void TablePropertyMap::insertTableProperties( const PropertyMap* pMap ) +{ +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->startElement("TablePropertyMap.insertTableProperties"); + pMap->dumpXml(dmapper_logger); +#endif + + const TablePropertyMap* pSource = dynamic_cast< const TablePropertyMap* >(pMap); + if( pSource ) + { + for( sal_Int32 eTarget = TablePropertyMapTarget_START; + eTarget < TablePropertyMapTarget_MAX; ++eTarget ) + { + if( pSource->m_aValidValues[eTarget].bValid ) + { + m_aValidValues[eTarget].bValid = true; + m_aValidValues[eTarget].nValue = pSource->m_aValidValues[eTarget].nValue; + } + } + } +#ifdef DEBUG_DOMAINMAPPER + dumpXml( dmapper_logger ); + dmapper_logger->endElement(); +#endif +} + + +}//namespace dmapper +}//namespace writerfilter + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/PropertyMap.hxx b/writerfilter/source/dmapper/PropertyMap.hxx new file mode 100644 index 000000000000..351fc81296da --- /dev/null +++ b/writerfilter/source/dmapper/PropertyMap.hxx @@ -0,0 +1,545 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef INCLUDED_DMAPPER_PROPERTYMAP_HXX +#define INCLUDED_DMAPPER_PROPERTYMAP_HXX + +#include <rtl/ustring.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/uno/Any.h> +#include <PropertyIds.hxx> +#include <boost/shared_ptr.hpp> +#include <map> +#include <vector> + +#include <resourcemodel/TagLogger.hxx> + +namespace com{namespace sun{namespace star{ + namespace beans{ + struct PropertyValue; + } + namespace container{ + class XNameAccess; + class XNameContainer; + } + namespace lang{ + class XMultiServiceFactory; + } + namespace text{ + class XTextRange; + class XTextColumns; + class XFootnote; + } + namespace table{ + struct BorderLine2; + } +}}} + +namespace writerfilter { +namespace dmapper{ +class DomainMapper_Impl; + +enum BorderPosition +{ + BORDER_LEFT, + BORDER_RIGHT, + BORDER_TOP, + BORDER_BOTTOM +}; + + +struct PropertyDefinition +{ + PropertyIds eId; + bool bIsTextProperty; + + PropertyDefinition( PropertyIds _eId, bool _bIsTextProperty ) : + eId( _eId ), + bIsTextProperty( _bIsTextProperty ){} + + bool operator== (const PropertyDefinition& rDef) const + { return rDef.eId == eId; } + bool operator< (const PropertyDefinition& rDef) const + { return eId < rDef.eId; } +}; +typedef std::map < PropertyDefinition, ::com::sun::star::uno::Any > _PropertyMap; +class PropertyMap : public _PropertyMap +{ + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > m_aValues; + //marks context as footnote context - ::text( ) events contain either the footnote character or can be ignored + //depending on sprmCSymbol + sal_Unicode m_cFootnoteSymbol; // 0 == invalid + sal_Int32 m_nFootnoteFontId; // negative values are invalid ids + ::rtl::OUString m_sFootnoteFontName; + ::com::sun::star::uno::Reference< ::com::sun::star::text::XFootnote > m_xFootnote; + +protected: + void Invalidate() + { + if(m_aValues.getLength()) + m_aValues.realloc( 0 ); + } + +public: + PropertyMap(); + virtual ~PropertyMap(); + + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > GetPropertyValues(); + bool hasEmptyPropertyValues() const {return !m_aValues.getLength();} + /** Add property, usually overwrites already available attributes. It shouldn't overwrite in case of default attributes + */ + void Insert( PropertyIds eId, bool bIsTextProperty, const ::com::sun::star::uno::Any& rAny, bool bOverwrite = true ); + using _PropertyMap::insert; + void insert(const boost::shared_ptr<PropertyMap> pMap, bool bOverwrite = true); + + const ::com::sun::star::uno::Reference< ::com::sun::star::text::XFootnote>& GetFootnote() const; + void SetFootnote( ::com::sun::star::uno::Reference< ::com::sun::star::text::XFootnote> xF ) { m_xFootnote = xF; } + + sal_Unicode GetFootnoteSymbol() const { return m_cFootnoteSymbol;} + void SetFootnoteSymbol(sal_Unicode cSet) { m_cFootnoteSymbol = cSet;} + + sal_Int32 GetFootnoteFontId() const { return m_nFootnoteFontId;} + void SetFootnoteFontId(sal_Int32 nSet) { m_nFootnoteFontId = nSet;} + + const ::rtl::OUString& GetFootnoteFontName() const { return m_sFootnoteFontName;} + void SetFootnoteFontName( const ::rtl::OUString& rSet ) { m_sFootnoteFontName = rSet;} + + virtual void insertTableProperties( const PropertyMap* ); + +#ifdef DEBUG_DOMAINMAPPER + virtual void dumpXml( const TagLogger::Pointer_t pLogger ) const; +#endif + +}; +typedef boost::shared_ptr<PropertyMap> PropertyMapPtr; + + + +class SectionPropertyMap : public PropertyMap +{ + //--> debug + sal_Int32 nSectionNumber; + //<-- debug + //'temporarily' the section page settings are imported as page styles + // empty strings mark page settings as not yet imported + + bool m_bIsFirstSection; + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > m_xStartingRange; + + ::rtl::OUString m_sFirstPageStyleName; + ::rtl::OUString m_sFollowPageStyleName; + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > m_aFirstPageStyle; + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > m_aFollowPageStyle; + + ::com::sun::star::table::BorderLine2* m_pBorderLines[4]; + sal_Int32 m_nBorderDistances[4]; + sal_Int32 m_nBorderParams; + + bool m_bTitlePage; + sal_Int16 m_nColumnCount; + sal_Int32 m_nColumnDistance; + ::std::vector< sal_Int32 > m_aColWidth; + ::std::vector< sal_Int32 > m_aColDistance; + + bool m_bSeparatorLineIsOn; + bool m_bEvenlySpaced; + bool m_bIsLandscape; + + bool m_bPageNoRestart; + sal_Int32 m_nPageNumber; + sal_Int32 m_nBreakType; + sal_Int32 m_nPaperBin; + sal_Int32 m_nFirstPaperBin; + + sal_Int32 m_nLeftMargin; + sal_Int32 m_nRightMargin; + sal_Int32 m_nTopMargin; + sal_Int32 m_nBottomMargin; + sal_Int32 m_nHeaderTop; + sal_Int32 m_nHeaderBottom; + + sal_Int32 m_nDzaGutter; + bool m_bGutterRTL; + bool m_bSFBiDi; + + sal_Int32 m_nGridType; + sal_Int32 m_nGridLinePitch; + sal_Int32 m_nDxtCharSpace; + + //line numbering + sal_Int32 m_nLnnMod; + sal_Int32 m_nLnc; + sal_Int32 m_ndxaLnn; + sal_Int32 m_nLnnMin; + + void _ApplyProperties( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > xStyle ); + ::com::sun::star::uno::Reference< com::sun::star::text::XTextColumns > ApplyColumnProperties( + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > xFollowPageStyle ); + void CopyLastHeaderFooter( bool bFirstPage, DomainMapper_Impl& rDM_Impl ); + void PrepareHeaderFooterProperties( bool bFirstPage ); + bool HasHeader( bool bFirstPage ) const; + bool HasFooter( bool bFirstPage ) const; + + void SetBorderDistance( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > xStyle, + PropertyIds eMarginId, PropertyIds eDistId, sal_Int32 nDistance, sal_Int32 nOffsetFrom ); + +public: + explicit SectionPropertyMap(bool bIsFirstSection); + ~SectionPropertyMap(); + + enum PageType + { + PAGE_FIRST, + PAGE_LEFT, + PAGE_RIGHT + }; + + void SetStart( const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange >& xRange ) + { + m_xStartingRange = xRange; + } + + const ::rtl::OUString& GetPageStyleName( bool bFirst ); + void SetPageStyleName( bool bFirst, const ::rtl::OUString& rName); + + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > GetPageStyle( + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& xStyles, + const ::com::sun::star::uno::Reference < ::com::sun::star::lang::XMultiServiceFactory >& xTextFactory, + bool bFirst ); + + void SetBorder( BorderPosition ePos, sal_Int32 nLineDistance, const ::com::sun::star::table::BorderLine2& rBorderLine ); + void SetBorderParams( sal_Int32 nSet ) { m_nBorderParams = nSet; } + + void SetColumnCount( sal_Int16 nCount ) { m_nColumnCount = nCount; } + void SetColumnDistance( sal_Int32 nDist ) { m_nColumnDistance = nDist; } + void AppendColumnWidth( sal_Int32 nWidth ) { m_aColWidth.push_back( nWidth ); } + void AppendColumnSpacing( sal_Int32 nDist ) {m_aColDistance.push_back( nDist ); } + + void SetTitlePage( bool bSet ) { m_bTitlePage = bSet; } + void SetSeparatorLine( bool bSet ) { m_bSeparatorLineIsOn = bSet; } + void SetEvenlySpaced( bool bSet ) { m_bEvenlySpaced = bSet; } + void SetLandscape( bool bSet ) { m_bIsLandscape = bSet; } + void SetPageNoRestart( bool bSet ) { m_bPageNoRestart = bSet; } + void SetPageNumber( sal_Int32 nSet ) { m_nPageNumber = nSet; } + void SetBreakType( sal_Int32 nSet ) { m_nBreakType = nSet; } + void SetPaperBin( sal_Int32 nSet ); + void SetFirstPaperBin( sal_Int32 nSet ); + + void SetLeftMargin( sal_Int32 nSet ) { m_nLeftMargin = nSet; } + void SetRightMargin( sal_Int32 nSet ) { m_nRightMargin = nSet; } + void SetTopMargin( sal_Int32 nSet ) { m_nTopMargin = nSet; } + void SetBottomMargin( sal_Int32 nSet ) { m_nBottomMargin = nSet; } + void SetHeaderTop( sal_Int32 nSet ) { m_nHeaderTop = nSet; } + void SetHeaderBottom( sal_Int32 nSet ) { m_nHeaderBottom = nSet; } + + void SetGutterRTL( bool bSet ) { m_bGutterRTL = bSet;} + void SetDzaGutter( sal_Int32 nSet ) {m_nDzaGutter = nSet; } + void SetSFBiDi( bool bSet ) { m_bSFBiDi = bSet;} + + void SetGridType(sal_Int32 nSet) { m_nGridType = nSet; } + void SetGridLinePitch( sal_Int32 nSet ) { m_nGridLinePitch = nSet; } + void SetDxtCharSpace( sal_Int32 nSet ) { m_nDxtCharSpace = nSet; } + + void SetLnnMod( sal_Int32 nValue ) { m_nLnnMod = nValue; } + void SetLnc( sal_Int32 nValue ) { m_nLnc = nValue; } + void SetdxaLnn( sal_Int32 nValue ) { m_ndxaLnn = nValue; } + void SetLnnMin( sal_Int32 nValue ) { m_nLnnMin = nValue; } + + //determine which style gets the borders + void ApplyBorderToPageStyles( + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& xStyles, + const ::com::sun::star::uno::Reference < ::com::sun::star::lang::XMultiServiceFactory >& xTextFactory, + sal_Int32 nValue ); + + void CloseSectionGroup( DomainMapper_Impl& rDM_Impl ); +}; +typedef boost::shared_ptr<SectionPropertyMap> SectionPropertyMapPtr; + + + +class ParagraphProperties +{ + bool m_bFrameMode; + sal_Int32 m_nDropCap; //drop, margin ST_DropCap + sal_Int32 m_nLines; //number of lines of the drop cap + sal_Int32 m_w; //width + sal_Int32 m_h; //height + sal_Int32 m_nWrap; // from ST_Wrap around, auto, none, notBeside, through, tight + sal_Int32 m_hAnchor; // page, from ST_HAnchor margin, page, text + sal_Int32 m_vAnchor; // around from ST_VAnchor margin, page, text + sal_Int32 m_x; //x-position + bool m_bxValid; + sal_Int32 m_y; //y-position + bool m_byValid; + sal_Int32 m_hSpace; //frame padding h + sal_Int32 m_vSpace; //frame padding v + sal_Int32 m_hRule; // from ST_HeightRule exact, atLeast, auto + sal_Int32 m_xAlign; // from ST_XAlign center, inside, left, outside, right + sal_Int32 m_yAlign; // from ST_YAlign bottom, center, inline, inside, outside, top + bool m_bAnchorLock; + + sal_Int8 m_nDropCapLength; //number of characters + + ::rtl::OUString m_sParaStyleName; + + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > m_xStartingRange; //start of a frame + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > m_xEndingRange; //end of the frame + +public: + ParagraphProperties(); + ParagraphProperties(const ParagraphProperties&); + ~ParagraphProperties(); + + int operator==(const ParagraphProperties&); //does not compare the starting/ending range, m_sParaStyleName and m_nDropCapLength + + void SetFrameMode() { m_bFrameMode = true; } + bool IsFrameMode()const { return m_bFrameMode; } + + void SetDropCap( sal_Int32 nSet ) { m_nDropCap = nSet; } + sal_Int32 GetDropCap()const { return m_nDropCap; } + + void SetLines( sal_Int32 nSet ) { m_nLines = nSet; } + sal_Int32 GetLines() const { return m_nLines; } + + void Setw( sal_Int32 nSet ) { m_w = nSet; } + sal_Int32 Getw() const { return m_w; } + + void Seth( sal_Int32 nSet ) { m_h = nSet; } + sal_Int32 Geth() const { return m_h; } + + void SetWrap( sal_Int32 nSet ) { m_nWrap = nSet; } + sal_Int32 GetWrap() const { return m_nWrap; } + + void SethAnchor( sal_Int32 nSet ) { m_hAnchor = nSet; } + sal_Int32 GethAnchor() const { return m_hAnchor;} + + void SetvAnchor( sal_Int32 nSet ) { m_vAnchor = nSet; } + sal_Int32 GetvAnchor() const { return m_vAnchor; } + + void Setx( sal_Int32 nSet ) { m_x = nSet; m_bxValid = true;} + sal_Int32 Getx() const { return m_x; } + bool IsxValid() const {return m_bxValid;} + + void Sety( sal_Int32 nSet ) { m_y = nSet; m_byValid = true;} + sal_Int32 Gety()const { return m_y; } + bool IsyValid() const {return m_byValid;} + + void SethSpace( sal_Int32 nSet ) { m_hSpace = nSet; } + sal_Int32 GethSpace()const { return m_hSpace; } + + void SetvSpace( sal_Int32 nSet ) { m_vSpace = nSet; } + sal_Int32 GetvSpace()const { return m_vSpace; } + + void SethRule( sal_Int32 nSet ) { m_hRule = nSet; } + sal_Int32 GethRule() const { return m_hRule; } + + void SetxAlign( sal_Int32 nSet ) { m_xAlign = nSet; } + sal_Int32 GetxAlign()const { return m_xAlign; } + + void SetyAlign( sal_Int32 nSet ) { m_yAlign = nSet; } + sal_Int32 GetyAlign()const { return m_yAlign; } + + void SetAnchorLock( bool bSet ) {m_bAnchorLock = bSet; } + + sal_Int8 GetDropCapLength() const { return m_nDropCapLength;} + void SetDropCapLength(sal_Int8 nSet) { m_nDropCapLength = nSet;} + + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > GetStartingRange() const { return m_xStartingRange; } + void SetStartingRange( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > xSet ) { m_xStartingRange = xSet; } + + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > GetEndingRange() const { return m_xEndingRange; } + void SetEndingRange( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > xSet ) { m_xEndingRange = xSet; } + + void SetParaStyleName( const ::rtl::OUString& rSet ) { m_sParaStyleName = rSet;} + const ::rtl::OUString& GetParaStyleName() const { return m_sParaStyleName;} + + +}; +typedef boost::shared_ptr<ParagraphProperties> ParagraphPropertiesPtr; +/*------------------------------------------------------------------------- + property map of a stylesheet + -----------------------------------------------------------------------*/ + +#define WW_OUTLINE_MAX sal_Int16( 9 ) + +class StyleSheetPropertyMap : public PropertyMap, public ParagraphProperties + +{ + //special table style properties + sal_Int32 mnCT_Spacing_line; + sal_Int32 mnCT_Spacing_lineRule; + + ::rtl::OUString msCT_Fonts_ascii; + bool mbCT_TrPrBase_tblHeader; + sal_Int32 mnCT_TrPrBase_jc; + sal_Int32 mnCT_TcPrBase_vAlign; + + sal_Int32 mnCT_TblWidth_w; + sal_Int32 mnCT_TblWidth_type; + + bool mbCT_Spacing_lineSet; + bool mbCT_Spacing_lineRuleSet; + + bool mbCT_TrPrBase_tblHeaderSet; + bool mbCT_TrPrBase_jcSet; + bool mbCT_TcPrBase_vAlignSet; + + bool mbCT_TblWidth_wSet; + bool mbCT_TblWidth_typeSet; + + sal_Int32 mnListId; + sal_Int16 mnListLevel; + + sal_Int16 mnOutlineLevel; +public: + explicit StyleSheetPropertyMap(); + ~StyleSheetPropertyMap(); + + void SetCT_Spacing_line( sal_Int32 nSet ) + {mnCT_Spacing_line = nSet; mbCT_Spacing_lineSet = true; } + void SetCT_Spacing_lineRule( sal_Int32 nSet ) + {mnCT_Spacing_lineRule = nSet; mbCT_Spacing_lineRuleSet = true; } + + void SetCT_Fonts_ascii( const ::rtl::OUString& rSet ) + {msCT_Fonts_ascii = rSet; } + void SetCT_TrPrBase_tblHeader( bool bSet ) + {mbCT_TrPrBase_tblHeader = bSet; mbCT_TrPrBase_tblHeaderSet = true; } + void SetCT_TrPrBase_jc( sal_Int32 nSet ) + {mnCT_TrPrBase_jc = nSet; mbCT_TrPrBase_jcSet = true; } + void SetCT_TcPrBase_vAlign( sal_Int32 nSet ) + {mnCT_TcPrBase_vAlign = nSet; mbCT_TcPrBase_vAlignSet = true; } + + void SetCT_TblWidth_w( sal_Int32 nSet ) + { mnCT_TblWidth_w = nSet; mbCT_TblWidth_wSet = true; } + void SetCT_TblWidth_type( sal_Int32 nSet ) + {mnCT_TblWidth_type = nSet; mbCT_TblWidth_typeSet = true; } + + bool GetCT_Spacing_line( sal_Int32& rToFill) const + { + if( mbCT_Spacing_lineSet ) + rToFill = mnCT_Spacing_line; + return mbCT_Spacing_lineSet; + } + bool GetCT_Spacing_lineRule(sal_Int32& rToFill) const + { + if( mbCT_Spacing_lineRuleSet ) + rToFill = mnCT_Spacing_lineRule; + return mbCT_Spacing_lineRuleSet; + } + + bool GetCT_Fonts_ascii(::rtl::OUString& rToFill) const + { + if( msCT_Fonts_ascii.getLength() > 0 ) + rToFill = msCT_Fonts_ascii; + return msCT_Fonts_ascii.getLength() > 0; + } + bool GetCT_TrPrBase_tblHeader(bool& rToFill) const + { + if( mbCT_TrPrBase_tblHeaderSet ) + rToFill = mbCT_TrPrBase_tblHeader; + return mbCT_TrPrBase_tblHeaderSet; + } + bool GetCT_TrPrBase_jc( sal_Int32& rToFill)const + { + if( mbCT_TrPrBase_jcSet ) + rToFill = mnCT_TrPrBase_jc; + return mbCT_TrPrBase_jcSet; + } + bool GetCT_TcPrBase_vAlign( sal_Int32& rToFill)const + { + if( mbCT_TcPrBase_vAlignSet ) + rToFill = mnCT_TcPrBase_vAlign; + return mbCT_TcPrBase_vAlignSet; + } + sal_Int32 GetListId() const { return mnListId; } + void SetListId(sal_Int32 nId) { mnListId = nId; } + + sal_Int16 GetListLevel() const { return mnListLevel; } + void SetListLevel(sal_Int16 nLevel) { mnListLevel = nLevel; } + + sal_Int16 GetOutlineLevel() const { return mnOutlineLevel; } + void SetOutlineLevel(sal_Int16 nLevel) + { + if ( nLevel < WW_OUTLINE_MAX ) + mnOutlineLevel = nLevel; + } +}; + + +class ParagraphPropertyMap : public PropertyMap, public ParagraphProperties +{ +public: + explicit ParagraphPropertyMap(); + ~ParagraphPropertyMap(); + +}; + + +class TablePropertyMap : public PropertyMap +{ +public: + enum TablePropertyMapTarget + { + TablePropertyMapTarget_START, + CELL_MAR_LEFT = TablePropertyMapTarget_START, + CELL_MAR_RIGHT, + CELL_MAR_TOP, + CELL_MAR_BOTTOM, + TABLE_WIDTH, + GAP_HALF, + LEFT_MARGIN, + HORI_ORIENT, + TablePropertyMapTarget_MAX + }; +private: + struct ValidValue + { + sal_Int32 nValue; + bool bValid; + ValidValue() : + nValue( 0 ), + bValid( false ){} + }; + ValidValue m_aValidValues[TablePropertyMapTarget_MAX]; + +public: + explicit TablePropertyMap(); + ~TablePropertyMap(); + + bool getValue( TablePropertyMapTarget eWhich, sal_Int32& nFill ); + void setValue( TablePropertyMapTarget eWhich, sal_Int32 nSet ); + + virtual void insertTableProperties( const PropertyMap* ); +}; +typedef boost::shared_ptr<TablePropertyMap> TablePropertyMapPtr; +} //namespace dmapper +} //namespace writerfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/PropertyMapHelper.cxx b/writerfilter/source/dmapper/PropertyMapHelper.cxx new file mode 100644 index 000000000000..aa4996a5c4a8 --- /dev/null +++ b/writerfilter/source/dmapper/PropertyMapHelper.cxx @@ -0,0 +1,126 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <com/sun/star/text/TableColumnSeparator.hpp> +#include <resourcemodel/TagLogger.hxx> +#include "PropertyMapHelper.hxx" + +#if OSL_DEBUG_LEVEL > 1 +namespace writerfilter +{ +namespace dmapper +{ + +using namespace ::com::sun::star; + +void lcl_DumpTableColumnSeparators(const TagLogger::Pointer_t pLogger, const uno::Any & rTableColumnSeparators) +{ + uno::Sequence<text::TableColumnSeparator> aSeq; + rTableColumnSeparators >>= aSeq; + + pLogger->startElement("property.TableColumnSeparators"); + + sal_uInt32 nLength = aSeq.getLength(); + for (sal_uInt32 n = 0; n < nLength; ++n) + { + pLogger->startElement("separator"); + + pLogger->attribute("position", aSeq[n].Position); + pLogger->attribute("visible", aSeq[n].IsVisible); + + pLogger->endElement(); + } + + pLogger->endElement(); +} + +void lcl_DumpPropertyValues(const TagLogger::Pointer_t pLogger, beans::PropertyValues & rValues) +{ + pLogger->startElement("propertyValues"); + + beans::PropertyValue * pValues = rValues.getArray(); + + for (sal_Int32 n = 0; n < rValues.getLength(); ++n) + { + pLogger->startElement("propertyValue"); + + pLogger->attribute("name", pValues[n].Name); + + try + { + sal_Int32 aInt = 0; + pValues[n].Value >>= aInt; + pLogger->attribute("value", aInt); + } + catch (...) + { + } + + if (pValues[n].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("TableColumnSeparators"))) + { + lcl_DumpTableColumnSeparators(pLogger, pValues[n].Value); + } + + pLogger->endElement(); + } + pLogger->endElement(); +} + +void lcl_DumpPropertyValueSeq(const TagLogger::Pointer_t pLogger, PropertyValueSeq_t & rPropValSeq) +{ + pLogger->startElement("PropertyValueSeq"); + + beans::PropertyValues * pValues = rPropValSeq.getArray(); + + for (sal_Int32 n = 0; n < rPropValSeq.getLength(); ++n) + { + lcl_DumpPropertyValues(pLogger, pValues[n]); + } + + pLogger->endElement(); +} + +void lcl_DumpPropertyValueSeqSeq(const TagLogger::Pointer_t pLogger, PropertyValueSeqSeq_t rPropValSeqSeq) +{ + pLogger->startElement("PropertyValueSeq"); + + PropertyValueSeq_t * pValues = rPropValSeqSeq.getArray(); + + for (sal_Int32 n = 0; n < rPropValSeqSeq.getLength(); ++n) + { + lcl_DumpPropertyValueSeq(pLogger, pValues[n]); + } + + pLogger->endElement(); +} + +} +} +#endif // DEBUG + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/PropertyMapHelper.hxx b/writerfilter/source/dmapper/PropertyMapHelper.hxx new file mode 100644 index 000000000000..cd825427bedd --- /dev/null +++ b/writerfilter/source/dmapper/PropertyMapHelper.hxx @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#if OSL_DEBUG_LEVEL > 1 +#include "PropertyMap.hxx" +#include <com/sun/star/beans/PropertyValues.hpp> + +namespace writerfilter +{ +namespace dmapper +{ + +void lcl_DumpTableColumnSeparators(const TagLogger::Pointer_t pLogger, + const uno::Any & rTableColumnSeparators); +void lcl_DumpPropertyValues(const TagLogger::Pointer_t pLogger, + beans::PropertyValues & rValues); + +typedef uno::Sequence<beans::PropertyValues> PropertyValueSeq_t; +void lcl_DumpPropertyValueSeq(const TagLogger::Pointer_t pLogger, + PropertyValueSeq_t & rPropValSeq); + +typedef uno::Sequence<PropertyValueSeq_t> PropertyValueSeqSeq_t; +void lcl_DumpPropertyValueSeqSeq(const TagLogger::Pointer_t pLogger, + PropertyValueSeqSeq_t & rPropValSeqSeq); +} +} +#endif // DEBUG + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/SectionColumnHandler.cxx b/writerfilter/source/dmapper/SectionColumnHandler.cxx new file mode 100644 index 000000000000..d1832e6cc009 --- /dev/null +++ b/writerfilter/source/dmapper/SectionColumnHandler.cxx @@ -0,0 +1,106 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include <SectionColumnHandler.hxx> +#include <PropertyMap.hxx> +#include <doctok/resourceids.hxx> +#include <ConversionHelper.hxx> +#include <ooxml/resourceids.hxx> + +#include "dmapperLoggers.hxx" + +namespace writerfilter { +namespace dmapper { + +using namespace ::com::sun::star; + + +SectionColumnHandler::SectionColumnHandler() : +LoggedProperties(dmapper_logger, "SectionColumnHandler"), +bEqualWidth( false ), +nSpace( 0 ), +nNum( 0 ), +bSep( false ) +{ +} + +SectionColumnHandler::~SectionColumnHandler() +{ +} + +void SectionColumnHandler::lcl_attribute(Id rName, Value & rVal) +{ + sal_Int32 nIntValue = rVal.getInt(); + switch( rName ) + { + case NS_ooxml::LN_CT_Columns_equalWidth: + bEqualWidth = (nIntValue != 0); + break; + case NS_ooxml::LN_CT_Columns_space: + nSpace = ConversionHelper::convertTwipToMM100( nIntValue ); + break; + case NS_ooxml::LN_CT_Columns_num: + nNum = nIntValue; + break; + case NS_ooxml::LN_CT_Columns_sep: + bSep = (nIntValue != 0); + break; + + case NS_ooxml::LN_CT_Column_w: + aTempColumn.nWidth = ConversionHelper::convertTwipToMM100( nIntValue ); + break; + case NS_ooxml::LN_CT_Column_space: + aTempColumn.nSpace = ConversionHelper::convertTwipToMM100( nIntValue ); + break; + default: + OSL_FAIL( "SectionColumnHandler: unknown attribute"); + } +} + +void SectionColumnHandler::lcl_sprm(Sprm & rSprm) +{ + switch( rSprm.getId()) + { + case NS_ooxml::LN_CT_Columns_col: + { + aTempColumn.nWidth = aTempColumn.nSpace = 0; + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + { + pProperties->resolve(*this); + aCols.push_back(aTempColumn); + } + } + break; + default: + OSL_FAIL( "SectionColumnHandler: unknown sprm"); + } +} +} //namespace dmapper +} //namespace writerfilter + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/SectionColumnHandler.hxx b/writerfilter/source/dmapper/SectionColumnHandler.hxx new file mode 100644 index 000000000000..3a420c74526f --- /dev/null +++ b/writerfilter/source/dmapper/SectionColumnHandler.hxx @@ -0,0 +1,79 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef INCLUDED_SECTIONCOLUMNHANDLER_HXX +#define INCLUDED_SECTIONCOLUMNHANDLER_HXX + +#include <WriterFilterDllApi.hxx> +#include <resourcemodel/LoggedResources.hxx> +#include <boost/shared_ptr.hpp> + + +namespace writerfilter { +namespace dmapper +{ +class PropertyMap; + +struct _Column +{ + sal_Int32 nWidth; + sal_Int32 nSpace; +}; + + +class WRITERFILTER_DLLPRIVATE SectionColumnHandler : public LoggedProperties +{ + bool bEqualWidth; + sal_Int32 nSpace; + sal_Int32 nNum; + bool bSep; + std::vector<_Column> aCols; + + _Column aTempColumn; + + // Properties + virtual void lcl_attribute(Id Name, Value & val); + virtual void lcl_sprm(Sprm & sprm); + +public: + SectionColumnHandler(); + virtual ~SectionColumnHandler(); + + bool IsEqualWidth() const { return bEqualWidth; } + sal_Int32 GetSpace() const { return nSpace; } + sal_Int32 GetNum() const { return nNum; } + bool IsSeparator() const { return bSep; } + + const std::vector<_Column>& GetColumns() const { return aCols;} + +}; +typedef boost::shared_ptr< SectionColumnHandler > SectionColumnHandlerPtr; +}} + +#endif // + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/SettingsTable.cxx b/writerfilter/source/dmapper/SettingsTable.cxx new file mode 100644 index 000000000000..10a4e2568229 --- /dev/null +++ b/writerfilter/source/dmapper/SettingsTable.cxx @@ -0,0 +1,232 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <stdio.h> +#include <rtl/ustring.hxx> +#include <resourcemodel/ResourceModelHelper.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <SettingsTable.hxx> +#include <resourcemodel/ResourceModelHelper.hxx> +#include <doctok/resourceids.hxx> +#include <ooxml/resourceids.hxx> +#include <ConversionHelper.hxx> + +#include "dmapperLoggers.hxx" + +namespace writerfilter { + +using resourcemodel::resolveSprmProps; + +namespace dmapper +{ + +struct SettingsTable_Impl +{ + DomainMapper& m_rDMapper; + const uno::Reference< lang::XMultiServiceFactory > m_xTextFactory; + + ::rtl::OUString m_sCharacterSpacing; + ::rtl::OUString m_sDecimalSymbol; + ::rtl::OUString m_sListSeparatorForFields; //2.15.1.56 listSeparator (List Separator for Field Code Evaluation) + + int m_nDefaultTabStop; + int m_nHyphenationZone; + + bool m_bNoPunctuationKerning; + bool m_doNotIncludeSubdocsInStats; // Do Not Include Content in Text Boxes, Footnotes, and Endnotes in Document Statistics) + bool m_bRecordChanges; + int m_nEdit; + bool m_bFormatting; + bool m_bEnforcement; + int m_nCryptProviderType; + int m_nCryptAlgorithmClass; + int m_nCryptAlgorithmType; + ::rtl::OUString m_sCryptAlgorithmSid; + int m_nCryptSpinCount; + ::rtl::OUString m_sCryptProvider; + ::rtl::OUString m_sAlgIdExt; + ::rtl::OUString m_sAlgIdExtSource; + ::rtl::OUString m_sCryptProviderTypeExt; + ::rtl::OUString m_sCryptProviderTypeExtSource; + ::rtl::OUString m_sHash; + ::rtl::OUString m_sSalt; + + SettingsTable_Impl( DomainMapper& rDMapper, const uno::Reference< lang::XMultiServiceFactory > xTextFactory ) : + m_rDMapper( rDMapper ) + , m_xTextFactory( xTextFactory ) + , m_nDefaultTabStop( 720 ) //default is 1/2 in + , m_nHyphenationZone(0) + , m_bNoPunctuationKerning(false) + , m_doNotIncludeSubdocsInStats(false) + , m_bRecordChanges(false) + , m_nEdit(NS_ooxml::LN_Value_wordprocessingml_ST_DocProtect_none) + , m_bFormatting(false) + , m_bEnforcement(false) + , m_nCryptProviderType(NS_ooxml::LN_Value_wordprocessingml_ST_CryptProv_rsaAES) + , m_nCryptAlgorithmClass(NS_ooxml::LN_Value_wordprocessingml_ST_AlgClass_hash) + , m_nCryptAlgorithmType(NS_ooxml::LN_Value_wordprocessingml_ST_AlgType_typeAny) + , m_nCryptSpinCount(0) + {} + +}; + +SettingsTable::SettingsTable(DomainMapper& rDMapper, const uno::Reference< lang::XMultiServiceFactory > xTextFactory) +: LoggedProperties(dmapper_logger, "SettingsTable") +, LoggedTable(dmapper_logger, "SettingsTable") +, m_pImpl( new SettingsTable_Impl(rDMapper, xTextFactory) ) +{ + +} + +SettingsTable::~SettingsTable() +{ + delete m_pImpl; +} + +void SettingsTable::lcl_attribute(Id nName, Value & val) +{ + (void) nName; + int nIntValue = val.getInt(); + (void)nIntValue; + ::rtl::OUString sValue = val.getString(); + (void)sValue; + +#if 0 //no values known, yet + + switch(Name) + { + case NS_ooxml::: + break; + default: + { + } + } +#endif +} + +void SettingsTable::lcl_sprm(Sprm& rSprm) +{ + sal_uInt32 nSprmId = rSprm.getId(); + + Value::Pointer_t pValue = rSprm.getValue(); + sal_Int32 nIntValue = pValue->getInt(); + (void)nIntValue; + rtl::OUString sStringValue = pValue->getString(); + + switch(nSprmId) + { + case NS_ooxml::LN_CT_Settings_zoom: // 92469; + case NS_ooxml::LN_CT_Settings_proofState: // 92489; + case NS_ooxml::LN_CT_Settings_attachedTemplate: // 92491; + case NS_ooxml::LN_CT_Settings_hdrShapeDefaults: // 92544; + case NS_ooxml::LN_CT_Settings_footnotePr: // 92545; + case NS_ooxml::LN_CT_Settings_endnotePr: // 92546; + case NS_ooxml::LN_CT_Settings_compat: // 92547; + case NS_ooxml::LN_CT_Settings_themeFontLang: // 92552; + case NS_ooxml::LN_CT_Settings_shapeDefaults: // 92560; + + //PropertySetValues - need to be resolved + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + pProperties->resolve(*this); + } + break; + case NS_ooxml::LN_CT_Settings_stylePaneFormatFilter: // 92493; + break; + case NS_ooxml::LN_CT_Settings_defaultTabStop: // 92505; + m_pImpl->m_nDefaultTabStop = nIntValue; + break; + case NS_ooxml::LN_CT_Settings_noPunctuationKerning: // 92526; + m_pImpl->m_bNoPunctuationKerning = nIntValue ? true : false; + break; + case NS_ooxml::LN_CT_Settings_characterSpacingControl: // 92527; + m_pImpl->m_sCharacterSpacing = sStringValue; // doNotCompress, compressPunctuation, compressPunctuationAndJapaneseKana + break; + case NS_ooxml::LN_CT_Settings_doNotIncludeSubdocsInStats: // 92554; // Do Not Include Content in Text Boxes, Footnotes, and Endnotes in Document Statistics) + m_pImpl->m_doNotIncludeSubdocsInStats = nIntValue? true : false; + break; + case NS_ooxml::LN_CT_Settings_decimalSymbol: // 92562; + m_pImpl->m_sDecimalSymbol = sStringValue; + break; + case NS_ooxml::LN_CT_Settings_listSeparator: // 92563; + m_pImpl->m_sListSeparatorForFields = sStringValue; + break; + case NS_ooxml::LN_CT_Settings_rsids: // 92549; revision save Ids - probably not necessary + break; + case NS_ooxml::LN_CT_Settings_hyphenationZone: // 92508; + m_pImpl->m_nHyphenationZone = nIntValue; + break; + case NS_ooxml::LN_CT_Compat_useFELayout: // 92422; + // useFELayout (Do Not Bypass East Asian/Complex Script Layout Code - support of old versions of Word - ignored) + break; + case NS_ooxml::LN_CT_Settings_trackRevisions: + { + m_pImpl->m_bRecordChanges = bool(rSprm.getValue( )->getInt( ) ); + } + break; + case NS_ooxml::LN_CT_Settings_documentProtection: + { + resolveSprmProps(*this, rSprm); + } + break; + default: + { +#ifdef DEBUG_DMAPPER_SETTINGS_TABLE + dmapper_logger->element("unhandled"); +#endif + } + } +} + +void SettingsTable::lcl_entry(int /*pos*/, writerfilter::Reference<Properties>::Pointer_t ref) +{ + ref->resolve(*this); +} +//returns default TabStop in 1/100th mm + + + +int SettingsTable::GetDefaultTabStop() const +{ + return ConversionHelper::convertTwipToMM100( m_pImpl->m_nDefaultTabStop ); +} + +void SettingsTable::ApplyProperties( uno::Reference< text::XTextDocument > xDoc ) +{ + uno::Reference< beans::XPropertySet> xDocProps( xDoc, uno::UNO_QUERY ); + + // Record changes value + xDocProps->setPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RecordChanges")), uno::makeAny( m_pImpl->m_bRecordChanges ) ); +} + + +}//namespace dmapper +} //namespace writerfilter + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/SettingsTable.hxx b/writerfilter/source/dmapper/SettingsTable.hxx new file mode 100644 index 000000000000..2b50d5112ee1 --- /dev/null +++ b/writerfilter/source/dmapper/SettingsTable.hxx @@ -0,0 +1,83 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef INCLUDED_SETTINGSTABLE_HXX +#define INCLUDED_SETTINGSTABLE_HXX + +#include <WriterFilterDllApi.hxx> +#include <resourcemodel/LoggedResources.hxx> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/text/XTextDocument.hpp> +#include <map> + +namespace com{ namespace sun{ namespace star{ +namespace lang{ +class XMultiServiceFactory; +struct Locale; +} +}}} + +namespace writerfilter { +namespace dmapper +{ +class DomainMapper; + +using namespace std; + +struct SettingsTable_Impl; + +class WRITERFILTER_DLLPRIVATE SettingsTable : public LoggedProperties, public LoggedTable +{ + SettingsTable_Impl *m_pImpl; + + public: + SettingsTable( DomainMapper& rDMapper, + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xTextFactory + ); + virtual ~SettingsTable(); + + //returns default TabStop in 1/100th mm + int GetDefaultTabStop() const; + + void ApplyProperties( uno::Reference< text::XTextDocument > xDoc ); + + private: + // Properties + virtual void lcl_attribute(Id Name, Value & val); + virtual void lcl_sprm(Sprm & sprm); + + // Table + virtual void lcl_entry(int pos, writerfilter::Reference<Properties>::Pointer_t ref); + +}; +typedef boost::shared_ptr< SettingsTable > SettingsTablePtr; +}} + +#endif // + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/StyleSheetTable.cxx b/writerfilter/source/dmapper/StyleSheetTable.cxx new file mode 100644 index 000000000000..85b5d3f108df --- /dev/null +++ b/writerfilter/source/dmapper/StyleSheetTable.cxx @@ -0,0 +1,1298 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include <resourcemodel/ResourceModelHelper.hxx> +#include <StyleSheetTable.hxx> +#include <dmapper/DomainMapper.hxx> +#include <NumberingManager.hxx> +#include <ConversionHelper.hxx> +#include <TblStylePrHandler.hxx> +#include <BorderHandler.hxx> +#include <doctok/resourceids.hxx> +#include <ooxml/resourceids.hxx> +#include <vector> +#include <com/sun/star/beans/XMultiPropertySet.hpp> +#include <com/sun/star/beans/XPropertyState.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/text/XChapterNumberingSupplier.hpp> +#include <com/sun/star/text/XTextDocument.hpp> +#include <com/sun/star/style/XStyleFamiliesSupplier.hpp> +#include <com/sun/star/style/XStyle.hpp> +#include <com/sun/star/text/WritingMode.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <map> +#include <stdio.h> +#include <rtl/ustrbuf.hxx> + +#include <dmapperLoggers.hxx> + +using namespace ::com::sun::star; +namespace writerfilter { +namespace dmapper +{ + +typedef ::std::map< ::rtl::OUString, ::rtl::OUString> StringPairMap_t; + + + +StyleSheetEntry::StyleSheetEntry() : + sStyleIdentifierI() + ,sStyleIdentifierD() + ,bIsDefaultStyle(false) + ,bInvalidHeight(false) + ,bHasUPE(false) + ,nStyleTypeCode(STYLE_TYPE_UNKNOWN) + ,sBaseStyleIdentifier() + ,sNextStyleIdentifier() + ,pProperties(new StyleSheetPropertyMap) +{ +#if OSL_DEBUG_LEVEL > 1 + nStyleTypeCode = STYLE_TYPE_PARA; +#endif +} + +StyleSheetEntry::~StyleSheetEntry() +{ +} + +TableStyleSheetEntry::TableStyleSheetEntry( StyleSheetEntry& rEntry, StyleSheetTable* pStyles ): + StyleSheetEntry( ), + m_pStyleSheet( pStyles ) +{ + + bIsDefaultStyle = rEntry.bIsDefaultStyle; + bInvalidHeight = rEntry.bInvalidHeight; + bHasUPE = rEntry.bHasUPE; + nStyleTypeCode = STYLE_TYPE_TABLE; + sBaseStyleIdentifier = rEntry.sBaseStyleIdentifier; + sNextStyleIdentifier = rEntry.sNextStyleIdentifier; + sStyleName = rEntry.sStyleName; + sStyleName1 = rEntry.sStyleName1; + + m_nColBandSize = 1; + m_nRowBandSize = 1; +} + +TableStyleSheetEntry::~TableStyleSheetEntry( ) +{ + m_pStyleSheet = NULL; +} + +void TableStyleSheetEntry::AddTblStylePr( TblStyleType nType, PropertyMapPtr pProps ) +{ + static const TblStyleType pTypesToFix[] = + { + TBL_STYLE_FIRSTROW, + TBL_STYLE_LASTROW, + TBL_STYLE_FIRSTCOL, + TBL_STYLE_LASTCOL + }; + + static const PropertyIds pPropsToCheck[] = + { + PROP_BOTTOM_BORDER, + PROP_TOP_BORDER, + PROP_RIGHT_BORDER, + PROP_LEFT_BORDER + }; + + int i = 0; + while ( i < 4 ) + { + if ( nType == pTypesToFix[i] ) + { + PropertyIds nChecked = pPropsToCheck[i]; + PropertyMap::iterator pCheckedIt = pProps->find( PropertyDefinition( nChecked, false ) ); + + PropertyIds nInsideProp = ( i < 2 ) ? META_PROP_HORIZONTAL_BORDER : META_PROP_VERTICAL_BORDER; + PropertyMap::iterator pInsideIt = pProps->find( PropertyDefinition( nInsideProp, false ) ); + + bool bHasChecked = pCheckedIt != pProps->end( ); + bool bHasInside = pInsideIt != pProps->end( ); + + if ( bHasChecked && bHasInside ) + { + // In this case, remove the inside border + pProps->erase( pInsideIt ); + } + + i = 4; // Stop looping stupidly + } + i++; + } + + // Append the tblStylePr + m_aStyles[nType] = pProps; +} + +PropertyMapPtr TableStyleSheetEntry::GetProperties( sal_Int32 nMask, StyleSheetEntryDequePtr pStack ) +{ + PropertyMapPtr pProps( new PropertyMap ); + + // First get the parent properties + StyleSheetEntryPtr pEntry = m_pStyleSheet->FindParentStyleSheet( sBaseStyleIdentifier ); + + if ( pEntry.get( ) ) + { + if (pStack.get() == NULL) + pStack.reset(new StyleSheetEntryDeque()); + + StyleSheetEntryDeque::const_iterator aIt = find(pStack->begin(), pStack->end(), pEntry); + + if (aIt != pStack->end()) + { + pStack->push_back(pEntry); + + TableStyleSheetEntry* pParent = static_cast<TableStyleSheetEntry *>( pEntry.get( ) ); + pProps->insert( pParent->GetProperties( nMask ), pStack ); + + pStack->pop_back(); + } + } + + // And finally get the mask ones + pProps->insert( GetLocalPropertiesFromMask( nMask ) ); + + return pProps; +} + +void lcl_mergeProps( PropertyMapPtr pToFill, PropertyMapPtr pToAdd, TblStyleType nStyleId ) +{ + static const PropertyIds pPropsToCheck[] = + { + PROP_BOTTOM_BORDER, + PROP_TOP_BORDER, + PROP_RIGHT_BORDER, + PROP_LEFT_BORDER, + }; + + bool pRemoveInside[] = + { + ( nStyleId == TBL_STYLE_FIRSTROW ), + ( nStyleId == TBL_STYLE_LASTROW ), + ( nStyleId == TBL_STYLE_LASTCOL ), + ( nStyleId == TBL_STYLE_FIRSTCOL ) + }; + + for ( unsigned i = 0 ; i != sizeof(pPropsToCheck) / sizeof(PropertyIds); i++ ) + { + PropertyIds nId = pPropsToCheck[i]; + PropertyDefinition aProp( nId, false ); + PropertyMap::iterator pIt = pToAdd->find( aProp ); + + if ( pIt != pToAdd->end( ) ) + { + PropertyMap::iterator pDestIt = pToFill->find( aProp ); + + if ( pRemoveInside[i] ) + { + // Remove the insideH and insideV depending on the cell pos + PropertyIds nInsideProp = ( i < 2 ) ? META_PROP_HORIZONTAL_BORDER : META_PROP_VERTICAL_BORDER; + pDestIt = pToFill->find( PropertyDefinition( nInsideProp, false ) ); + if ( pDestIt != pToFill->end( ) ) + pToFill->erase( pDestIt ); + } + } + } + + pToFill->insert( pToAdd ); +} + +PropertyMapPtr TableStyleSheetEntry::GetLocalPropertiesFromMask( sal_Int32 nMask ) +{ + // Order from right to left + static const TblStyleType aBitsOrder[] = + { + TBL_STYLE_SWCELL, + TBL_STYLE_SECELL, + TBL_STYLE_NWCELL, + TBL_STYLE_NECELL, + TBL_STYLE_BAND2HORZ, + TBL_STYLE_BAND1HORZ, + TBL_STYLE_BAND2VERT, + TBL_STYLE_BAND1VERT, + TBL_STYLE_LASTCOL, + TBL_STYLE_FIRSTCOL, + TBL_STYLE_LASTROW, + TBL_STYLE_FIRSTROW, + TBL_STYLE_UNKNOWN + }; + + // Get the properties applying according to the mask + PropertyMapPtr pProps( new PropertyMap( ) ); + short nBit = 0; + do + { + TblStyleType nStyleId = aBitsOrder[nBit]; + TblStylePrs::iterator pIt = m_aStyles.find( nStyleId ); + + short nTestBit = 1 << nBit; + sal_Int32 nBitMask = sal_Int32( nTestBit ); + if ( ( nMask & nBitMask ) && ( pIt != m_aStyles.end( ) ) ) + lcl_mergeProps( pProps, pIt->second, nStyleId ); + + nBit++; + } + while ( nBit < 13 ); + + return pProps; +} + + + +struct ListCharStylePropertyMap_t +{ + ::rtl::OUString sCharStyleName; + PropertyValueVector_t aPropertyValues; + + ListCharStylePropertyMap_t(const ::rtl::OUString& rCharStyleName, const PropertyValueVector_t& rPropertyValues): + sCharStyleName( rCharStyleName ), + aPropertyValues( rPropertyValues ) + {} +}; +typedef std::vector< ListCharStylePropertyMap_t > ListCharStylePropertyVector_t; + + +struct StyleSheetTable_Impl +{ + DomainMapper& m_rDMapper; + uno::Reference< text::XTextDocument> m_xTextDocument; + uno::Reference< beans::XPropertySet> m_xTextDefaults; + std::vector< StyleSheetEntryPtr > m_aStyleSheetEntries; + StyleSheetEntryPtr m_pCurrentEntry; + PropertyMapPtr m_pDefaultParaProps, m_pDefaultCharProps; + PropertyMapPtr m_pCurrentProps; + StringPairMap_t m_aStyleNameMap; + ListCharStylePropertyVector_t m_aListCharStylePropertyVector; + + StyleSheetTable_Impl(DomainMapper& rDMapper, uno::Reference< text::XTextDocument> xTextDocument); + + ::rtl::OUString HasListCharStyle( const PropertyValueVector_t& rCharProperties ); +}; + + +StyleSheetTable_Impl::StyleSheetTable_Impl(DomainMapper& rDMapper, uno::Reference< text::XTextDocument> xTextDocument ) : + m_rDMapper( rDMapper ), + m_xTextDocument( xTextDocument ), + m_pCurrentEntry(), + m_pDefaultParaProps(new PropertyMap), + m_pDefaultCharProps(new PropertyMap) +{ + //set font height default to 10pt + uno::Any aVal = uno::makeAny( double(10.) ); + m_pDefaultCharProps->Insert( PROP_CHAR_HEIGHT, true, aVal ); + m_pDefaultCharProps->Insert( PROP_CHAR_HEIGHT_ASIAN, true, aVal ); + m_pDefaultCharProps->Insert( PROP_CHAR_HEIGHT_COMPLEX, true, aVal ); +} + + +::rtl::OUString StyleSheetTable_Impl::HasListCharStyle( const PropertyValueVector_t& rPropValues ) +{ + ::rtl::OUString sRet; + ListCharStylePropertyVector_t::const_iterator aListVectorIter = m_aListCharStylePropertyVector.begin(); + while( aListVectorIter != m_aListCharStylePropertyVector.end() ) + { + //if size is identical + if( aListVectorIter->aPropertyValues.size() == rPropValues.size() ) + { + bool bBreak = false; + //then search for all contained properties + PropertyValueVector_t::const_iterator aList1Iter = rPropValues.begin(); + while( aList1Iter != rPropValues.end() && !bBreak) + { + //find the property + bool bElementFound = false; + PropertyValueVector_t::const_iterator aList2Iter = aListVectorIter->aPropertyValues.begin(); + while( aList2Iter != aListVectorIter->aPropertyValues.end() && !bBreak ) + { + if( aList2Iter->Name == aList1Iter->Name ) + { + bElementFound = true; + if( aList2Iter->Value != aList1Iter->Value ) + bBreak = true; + break; + } + ++aList2Iter; + } + //set break flag if property hasn't been found + if(!bElementFound ) + { + bBreak = true; + break; + } + ++aList1Iter; + } + if( !bBreak ) + return aListVectorIter->sCharStyleName; + } + ++aListVectorIter; + } + return sRet; +} + + +StyleSheetTable::StyleSheetTable(DomainMapper& rDMapper, uno::Reference< text::XTextDocument> xTextDocument) +: LoggedProperties(dmapper_logger, "StyleSheetTable") +, LoggedTable(dmapper_logger, "StyleSheetTable") +, m_pImpl( new StyleSheetTable_Impl(rDMapper, xTextDocument) ) +{ +} + + +StyleSheetTable::~StyleSheetTable() +{ + delete m_pImpl; +} + + +void StyleSheetTable::lcl_attribute(Id Name, Value & val) +{ + OSL_ENSURE( m_pImpl->m_pCurrentEntry, "current entry has to be set here"); + if(!m_pImpl->m_pCurrentEntry) + return ; + int nIntValue = val.getInt(); + (void)nIntValue; + ::rtl::OUString sValue = val.getString(); + + switch(Name) + { + case NS_rtf::LN_ISTD: + m_pImpl->m_pCurrentEntry->sStyleIdentifierD = ::rtl::OUString::valueOf(static_cast<sal_Int32>(nIntValue), 16); + break; + case NS_rtf::LN_STI: + { + ::rtl::OUString tempStyleIdentifier = GetStyleIdFromIndex(static_cast<sal_uInt32>(nIntValue)); + if (tempStyleIdentifier.getLength()) + m_pImpl->m_pCurrentEntry->sStyleIdentifierI = tempStyleIdentifier; + if (nIntValue == 0 || nIntValue == 65) + m_pImpl->m_pCurrentEntry->bIsDefaultStyle = true; + } + break; + case NS_rtf::LN_SGC: + m_pImpl->m_pCurrentEntry->nStyleTypeCode = (StyleType)nIntValue; + break; + case NS_rtf::LN_ISTDBASE: + if (static_cast<sal_uInt32>(nIntValue) != 0xfff) + m_pImpl->m_pCurrentEntry->sBaseStyleIdentifier = ::rtl::OUString::valueOf(static_cast<sal_Int32>(nIntValue), 16); + break; + case NS_rtf::LN_ISTDNEXT: + if (static_cast<sal_uInt32>(nIntValue) != 0xfff) + m_pImpl->m_pCurrentEntry->sNextStyleIdentifier = ::rtl::OUString::valueOf(static_cast<sal_Int32>(nIntValue), 16); + break; + case NS_rtf::LN_FSCRATCH: + case NS_rtf::LN_FINVALHEIGHT: + case NS_rtf::LN_FHASUPE: + case NS_rtf::LN_FMASSCOPY: + case NS_rtf::LN_CUPX: + case NS_rtf::LN_BCHUPE: + case NS_rtf::LN_FAUTOREDEF: + case NS_rtf::LN_FHIDDEN: + case NS_rtf::LN_UNUSED8_3: + //noone seems to care about it + break; + case NS_rtf::LN_XSTZNAME: + m_pImpl->m_pCurrentEntry->sStyleName1 = sValue; + if (m_pImpl->m_pCurrentEntry->sStyleIdentifierI.getLength()) + m_pImpl->m_pCurrentEntry->sStyleIdentifierI = sValue; + break; + case NS_rtf::LN_XSTZNAME1: + m_pImpl->m_pCurrentEntry->sStyleName = sValue; + if (m_pImpl->m_pCurrentEntry->sStyleIdentifierI.getLength()) + m_pImpl->m_pCurrentEntry->sStyleIdentifierI = sValue; + break; + case NS_rtf::LN_UPX: + resolveAttributeProperties(val); + break; + case NS_ooxml::LN_CT_Style_type: + { + StyleType nType = ( StyleType ) nIntValue; + if ( nType == STYLE_TYPE_TABLE ) + { + StyleSheetEntryPtr pEntry = m_pImpl->m_pCurrentEntry; + TableStyleSheetEntryPtr pTableEntry( new TableStyleSheetEntry( *pEntry.get( ), this ) ); + m_pImpl->m_pCurrentEntry = pTableEntry; + } + else + m_pImpl->m_pCurrentEntry->nStyleTypeCode = (StyleType)nIntValue; + } + break; + case NS_ooxml::LN_CT_Style_default: + m_pImpl->m_pCurrentEntry->bIsDefaultStyle = (nIntValue != 0); + break; + case NS_ooxml::LN_CT_Style_customStyle: + break; + case NS_ooxml::LN_CT_Style_styleId: + m_pImpl->m_pCurrentEntry->sStyleIdentifierI = sValue; + m_pImpl->m_pCurrentEntry->sStyleIdentifierD = sValue; + break; + case NS_ooxml::LN_CT_TblWidth_w: + dynamic_cast< StyleSheetPropertyMap* >( m_pImpl->m_pCurrentEntry->pProperties.get() )->SetCT_TblWidth_w( nIntValue ); + break; + case NS_ooxml::LN_CT_TblWidth_type: + dynamic_cast< StyleSheetPropertyMap* >( m_pImpl->m_pCurrentEntry->pProperties.get() )->SetCT_TblWidth_type( nIntValue ); + break; + default: + { +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->element("unhandled"); +#endif + } + break; + } +} + + +void StyleSheetTable::lcl_sprm(Sprm & rSprm) +{ + sal_uInt32 nSprmId = rSprm.getId(); + Value::Pointer_t pValue = rSprm.getValue(); + sal_Int32 nIntValue = pValue.get() ? pValue->getInt() : 0; + (void)nIntValue; + rtl::OUString sStringValue = pValue.get() ? pValue->getString() : rtl::OUString(); + + switch(nSprmId) + { + case NS_ooxml::LN_CT_Style_name: + //this is only a UI name! + m_pImpl->m_pCurrentEntry->sStyleName = sStringValue; + m_pImpl->m_pCurrentEntry->sStyleName1 = sStringValue; + break; + case NS_ooxml::LN_CT_Style_basedOn: + m_pImpl->m_pCurrentEntry->sBaseStyleIdentifier = sStringValue; + break; + case NS_ooxml::LN_CT_Style_next: + m_pImpl->m_pCurrentEntry->sNextStyleIdentifier = sStringValue; + break; + case NS_ooxml::LN_CT_Style_aliases: + case NS_ooxml::LN_CT_Style_link: + case NS_ooxml::LN_CT_Style_autoRedefine: + case NS_ooxml::LN_CT_Style_hidden: + case NS_ooxml::LN_CT_Style_uiPriority: + case NS_ooxml::LN_CT_Style_semiHidden: + case NS_ooxml::LN_CT_Style_unhideWhenUsed: + case NS_ooxml::LN_CT_Style_qFormat: + case NS_ooxml::LN_CT_Style_locked: + case NS_ooxml::LN_CT_Style_personal: + case NS_ooxml::LN_CT_Style_personalCompose: + case NS_ooxml::LN_CT_Style_personalReply: + case NS_ooxml::LN_CT_Style_rsid: + case NS_ooxml::LN_CT_Style_trPr: + case NS_ooxml::LN_CT_Style_tcPr: + break; + case NS_ooxml::LN_CT_Style_tblPr: //contains table properties + case NS_ooxml::LN_CT_Style_tblStylePr: //contains to table properties + case NS_ooxml::LN_CT_TblPrBase_tblInd: //table properties - at least width value and type + case NS_ooxml::LN_EG_RPrBase_rFonts: //table fonts + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + { + TblStylePrHandlerPtr pTblStylePrHandler( new TblStylePrHandler( m_pImpl->m_rDMapper ) ); + pProperties->resolve( *pTblStylePrHandler ); + + // Add the properties to the table style + TblStyleType nType = pTblStylePrHandler->getType( ); + PropertyMapPtr pProps = pTblStylePrHandler->getProperties( ); + StyleSheetEntry * pEntry = m_pImpl->m_pCurrentEntry.get(); + + if (nType == TBL_STYLE_UNKNOWN) + { + pEntry->pProperties->insert(pProps); + } + else + { + TableStyleSheetEntry * pTableEntry = dynamic_cast<TableStyleSheetEntry*>( pEntry ); + if (pTableEntry != NULL) + pTableEntry->AddTblStylePr( nType, pProps ); + } + } + break; + } + case NS_ooxml::LN_CT_PPrDefault_pPr: + case NS_ooxml::LN_CT_DocDefaults_pPrDefault: + m_pImpl->m_rDMapper.PushStyleSheetProperties( m_pImpl->m_pDefaultParaProps ); + resourcemodel::resolveSprmProps( m_pImpl->m_rDMapper, rSprm ); + m_pImpl->m_rDMapper.PopStyleSheetProperties(); + applyDefaults( true ); + break; + case NS_ooxml::LN_CT_RPrDefault_rPr: + case NS_ooxml::LN_CT_DocDefaults_rPrDefault: + m_pImpl->m_rDMapper.PushStyleSheetProperties( m_pImpl->m_pDefaultCharProps ); + resourcemodel::resolveSprmProps( m_pImpl->m_rDMapper, rSprm ); + m_pImpl->m_rDMapper.PopStyleSheetProperties(); + applyDefaults( false ); + break; + case NS_ooxml::LN_CT_TblPrBase_jc: //table alignment - row properties! + m_pImpl->m_pCurrentEntry->pProperties->Insert( PROP_HORI_ORIENT, false, + uno::makeAny( ConversionHelper::convertTableJustification( nIntValue ))); + break; + case NS_ooxml::LN_CT_TrPrBase_jc: //table alignment - row properties! + dynamic_cast< StyleSheetPropertyMap* >( m_pImpl->m_pCurrentEntry->pProperties.get() )->SetCT_TrPrBase_jc(nIntValue); + break; + case NS_ooxml::LN_CT_TblPrBase_tblBorders: //table borders, might be defined in table style + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + { + BorderHandlerPtr pBorderHandler( new BorderHandler(m_pImpl->m_rDMapper.IsOOXMLImport()) ); + pProperties->resolve(*pBorderHandler); + m_pImpl->m_pCurrentEntry->pProperties->insert( pBorderHandler->getProperties(), true ); + } + } + break; + case NS_ooxml::LN_CT_TblPrBase_tblStyleRowBandSize: + case NS_ooxml::LN_CT_TblPrBase_tblStyleColBandSize: + { + StyleSheetEntry* pEntry = m_pImpl->m_pCurrentEntry.get( ); + TableStyleSheetEntry *pTEntry = static_cast<TableStyleSheetEntry*>( pEntry ); + if ( pTEntry ) + { + if ( nSprmId == NS_ooxml::LN_CT_TblPrBase_tblStyleRowBandSize ) + pTEntry->m_nRowBandSize = nIntValue; + else + pTEntry->m_nColBandSize = nIntValue; + } + } + break; + case NS_ooxml::LN_CT_TblPrBase_tblCellMar: + //no cell margins in styles + break; + case NS_ooxml::LN_CT_Style_pPr: + // no break + case NS_ooxml::LN_CT_Style_rPr: + // no break + default: + { + if (!m_pImpl->m_pCurrentEntry) + break; + + TablePropertiesHandlerPtr pTblHandler( new TablePropertiesHandler( true ) ); + pTblHandler->SetProperties( m_pImpl->m_pCurrentEntry->pProperties ); + if ( !pTblHandler->sprm( rSprm ) ) + { + m_pImpl->m_rDMapper.PushStyleSheetProperties( m_pImpl->m_pCurrentEntry->pProperties ); + + PropertyMapPtr pProps(new PropertyMap()); + m_pImpl->m_rDMapper.sprmWithProps( rSprm, pProps ); + + m_pImpl->m_pCurrentEntry->pProperties->insert(pProps); + + m_pImpl->m_rDMapper.PopStyleSheetProperties( ); + } + } + break; +} +} + + +void StyleSheetTable::lcl_entry(int /*pos*/, writerfilter::Reference<Properties>::Pointer_t ref) +{ + //create a new style entry + OSL_ENSURE( !m_pImpl->m_pCurrentEntry, "current entry has to be NULL here"); + StyleSheetEntryPtr pNewEntry( new StyleSheetEntry ); + m_pImpl->m_pCurrentEntry = pNewEntry; + m_pImpl->m_rDMapper.PushStyleSheetProperties( m_pImpl->m_pCurrentEntry->pProperties ); + ref->resolve(*this); + //append it to the table + m_pImpl->m_rDMapper.PopStyleSheetProperties(); + if( !m_pImpl->m_rDMapper.IsOOXMLImport() || m_pImpl->m_pCurrentEntry->sStyleName.getLength() >0) + { + m_pImpl->m_pCurrentEntry->sConvertedStyleName = ConvertStyleName( m_pImpl->m_pCurrentEntry->sStyleName ); + m_pImpl->m_aStyleSheetEntries.push_back( m_pImpl->m_pCurrentEntry ); + } + else + { + //TODO: this entry contains the default settings - they have to be added to the settings + } + + StyleSheetEntryPtr pEmptyEntry; + m_pImpl->m_pCurrentEntry = pEmptyEntry; +} +/*------------------------------------------------------------------------- + sorting helper + -----------------------------------------------------------------------*/ +typedef std::vector< beans::PropertyValue > _PropValVector; +class PropValVector : public _PropValVector +{ +public: + PropValVector(){} + + void Insert( beans::PropertyValue aVal ); + uno::Sequence< uno::Any > getValues(); + uno::Sequence< ::rtl::OUString > getNames(); +}; +void PropValVector::Insert( beans::PropertyValue aVal ) +{ + _PropValVector::iterator aIt = begin(); + while(aIt != end()) + { + if(aIt->Name > aVal.Name) + { + insert( aIt, aVal ); + return; + } + ++aIt; + } + push_back( aVal ); +} +uno::Sequence< uno::Any > PropValVector::getValues() +{ + uno::Sequence< uno::Any > aRet( size() ); + uno::Any* pValues = aRet.getArray(); + sal_Int32 nVal = 0; + _PropValVector::iterator aIt = begin(); + while(aIt != end()) + { + pValues[nVal++] = aIt->Value; + ++aIt; + } + return aRet; +} +uno::Sequence< ::rtl::OUString > PropValVector::getNames() +{ + uno::Sequence< ::rtl::OUString > aRet( size() ); + ::rtl::OUString* pNames = aRet.getArray(); + sal_Int32 nVal = 0; + _PropValVector::iterator aIt = begin(); + while(aIt != end()) + { + pNames[nVal++] = aIt->Name; + ++aIt; + } + return aRet; +} + + +void StyleSheetTable::ApplyStyleSheets( FontTablePtr rFontTable ) +{ + try + { + uno::Reference< style::XStyleFamiliesSupplier > xStylesSupplier( m_pImpl->m_xTextDocument, uno::UNO_QUERY_THROW ); + uno::Reference< lang::XMultiServiceFactory > xDocFactory( m_pImpl->m_xTextDocument, uno::UNO_QUERY_THROW ); + uno::Reference< container::XNameAccess > xStyleFamilies = xStylesSupplier->getStyleFamilies(); + uno::Reference<container::XNameContainer> xCharStyles; + uno::Reference<container::XNameContainer> xParaStyles; + + PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + xStyleFamilies->getByName(rPropNameSupplier.GetName( PROP_CHARACTER_STYLES )) >>= xCharStyles; + xStyleFamilies->getByName(rPropNameSupplier.GetName( PROP_PARAGRAPH_STYLES )) >>= xParaStyles; + if(xCharStyles.is() && xParaStyles.is()) + { + std::vector< StyleSheetEntryPtr >::iterator aIt = m_pImpl->m_aStyleSheetEntries.begin(); + while( aIt != m_pImpl->m_aStyleSheetEntries.end() ) + { + StyleSheetEntryPtr pEntry = *aIt; + if( pEntry->nStyleTypeCode == STYLE_TYPE_CHAR || pEntry->nStyleTypeCode == STYLE_TYPE_PARA ) + { + bool bParaStyle = pEntry->nStyleTypeCode == STYLE_TYPE_PARA; + bool bInsert = false; + uno::Reference< container::XNameContainer > xStyles = bParaStyle ? xParaStyles : xCharStyles; + uno::Reference< style::XStyle > xStyle; + ::rtl::OUString sConvertedStyleName = ConvertStyleName( pEntry->sStyleName ); + if(xStyles->hasByName( sConvertedStyleName )) + xStyles->getByName( sConvertedStyleName ) >>= xStyle; + else + { + bInsert = true; + xStyle = uno::Reference< style::XStyle >(xDocFactory->createInstance( + bParaStyle ? + rPropNameSupplier.GetName( PROP_SERVICE_PARA_STYLE ) : + rPropNameSupplier.GetName( PROP_SERVICE_CHAR_STYLE )), + uno::UNO_QUERY_THROW); + } + if( pEntry->sBaseStyleIdentifier.getLength() ) + { + try + { + //TODO: Handle cases where a paragraph <> character style relation is needed + StyleSheetEntryPtr pParent = FindStyleSheetByISTD( pEntry->sBaseStyleIdentifier ); + if (pParent.get() != NULL) + xStyle->setParentStyle(ConvertStyleName( pParent->sStyleName )); + } + catch( const uno::RuntimeException& ) + { + OSL_FAIL( "Styles parent could not be set"); + } + } + else if( bParaStyle ) + { + //now it's time to set the default parameters - for paragraph styles + //Fonts: Western first entry in font table + //CJK: second entry + //CTL: third entry, if it exists + + sal_uInt32 nFontCount = rFontTable->size(); + if( !m_pImpl->m_rDMapper.IsOOXMLImport() && nFontCount > 2 ) + { + uno::Any aTwoHundredFortyTwip = uno::makeAny(12.); + // font size to 240 twip (12 pts) for all if not set + pEntry->pProperties->Insert(PROP_CHAR_HEIGHT, true, aTwoHundredFortyTwip, false); + // western font not already set -> apply first font + const FontEntry::Pointer_t pWesternFontEntry(rFontTable->getFontEntry( 0 )); + rtl::OUString sWesternFontName = pWesternFontEntry->sFontName; + pEntry->pProperties->Insert(PROP_CHAR_FONT_NAME, true, uno::makeAny( sWesternFontName ), false); + + // CJK ... apply second font + const FontEntry::Pointer_t pCJKFontEntry(rFontTable->getFontEntry( 2 )); + pEntry->pProperties->Insert(PROP_CHAR_FONT_NAME_ASIAN, true, uno::makeAny( pCJKFontEntry->sFontName ), false); + pEntry->pProperties->Insert(PROP_CHAR_HEIGHT_ASIAN, true, aTwoHundredFortyTwip, false); + // CTL ... apply third font, if available + if( nFontCount > 3 ) + { + const FontEntry::Pointer_t pCTLFontEntry(rFontTable->getFontEntry( 3 )); + pEntry->pProperties->Insert(PROP_CHAR_FONT_NAME_COMPLEX, true, uno::makeAny( pCTLFontEntry->sFontName ), false); + pEntry->pProperties->Insert(PROP_CHAR_HEIGHT_COMPLEX, true, aTwoHundredFortyTwip, false); + } + } + // Widow/Orphan -> set both to two if not already set + uno::Any aTwo = uno::makeAny(sal_Int8(2)); + pEntry->pProperties->Insert(PROP_PARA_WIDOWS, true, aTwo, false); + pEntry->pProperties->Insert(PROP_PARA_ORPHANS, true, aTwo, false); + // Left-to-right direction if not already set + pEntry->pProperties->Insert(PROP_WRITING_MODE, true, uno::makeAny( sal_Int16(text::WritingMode_LR_TB) ), false); + // font color COL_AUTO if not already set + pEntry->pProperties->Insert(PROP_CHAR_COLOR, true, uno::makeAny( sal_Int32(0xffffffff) ), false); + } + + uno::Sequence< beans::PropertyValue > aPropValues = pEntry->pProperties->GetPropertyValues(); + bool bAddFollowStyle = false; + if(bParaStyle && !pEntry->sNextStyleIdentifier.getLength() ) + { + bAddFollowStyle = true; + } + //remove Left/RightMargin values from TOX heading styles + if( bParaStyle ) + { + // Set the outline levels + const StyleSheetPropertyMap* pStyleSheetProperties = dynamic_cast<const StyleSheetPropertyMap*>(pEntry ? pEntry->pProperties.get() : 0); + if ( pStyleSheetProperties ) + { + aPropValues.realloc( aPropValues.getLength( ) + 1 ); + + beans::PropertyValue aLvlVal( rPropNameSupplier.GetName( PROP_OUTLINE_LEVEL ), 0, + uno::makeAny( sal_Int16( pStyleSheetProperties->GetOutlineLevel( ) + 1 ) ), + beans::PropertyState_DIRECT_VALUE ); + aPropValues[ aPropValues.getLength( ) - 1 ] = aLvlVal; + + if ( pStyleSheetProperties->GetOutlineLevel( ) == 0 ) + { + aPropValues.realloc( aPropValues.getLength( ) + 1 ); + beans::PropertyValue aStyleVal( rPropNameSupplier.GetName( PROP_NUMBERING_STYLE_NAME ), 0, + uno::makeAny( rtl::OUString() ), + beans::PropertyState_DIRECT_VALUE ); + aPropValues[ aPropValues.getLength( ) - 1 ] = aStyleVal; + } + } + + uno::Reference< beans::XPropertyState >xState( xStyle, uno::UNO_QUERY_THROW ); + if( sConvertedStyleName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Contents Heading" ) ) || + sConvertedStyleName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "User Index Heading" ) ) || + sConvertedStyleName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Index Heading" ) )) + { + //left margin is set to NULL by default + uno::Reference< beans::XPropertyState >xState1( xStyle, uno::UNO_QUERY_THROW ); + xState1->setPropertyToDefault(rPropNameSupplier.GetName( PROP_PARA_LEFT_MARGIN )); + } + else if( sConvertedStyleName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Text body" ) ) ) + xState->setPropertyToDefault(rPropNameSupplier.GetName( PROP_PARA_BOTTOM_MARGIN )); + else if( sConvertedStyleName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Heading 1" ) ) || + sConvertedStyleName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Heading 2" ) ) || + sConvertedStyleName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Heading 3" ) ) || + sConvertedStyleName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Heading 4" ) ) || + sConvertedStyleName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Heading 5" ) ) || + sConvertedStyleName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Heading 6" ) ) || + sConvertedStyleName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Heading 7" ) ) || + sConvertedStyleName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Heading 8" ) ) || + sConvertedStyleName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Heading 9" ) ) ) + { + xState->setPropertyToDefault(rPropNameSupplier.GetName( PROP_CHAR_WEIGHT )); + xState->setPropertyToDefault(rPropNameSupplier.GetName( PROP_CHAR_WEIGHT_ASIAN )); + xState->setPropertyToDefault(rPropNameSupplier.GetName( PROP_CHAR_WEIGHT_COMPLEX )); + xState->setPropertyToDefault(rPropNameSupplier.GetName( PROP_CHAR_POSTURE )); + xState->setPropertyToDefault(rPropNameSupplier.GetName( PROP_CHAR_POSTURE_ASIAN )); + xState->setPropertyToDefault(rPropNameSupplier.GetName( PROP_CHAR_POSTURE_COMPLEX )); + xState->setPropertyToDefault(rPropNameSupplier.GetName( PROP_CHAR_PROP_HEIGHT )); + xState->setPropertyToDefault(rPropNameSupplier.GetName( PROP_CHAR_PROP_HEIGHT_ASIAN )); + xState->setPropertyToDefault(rPropNameSupplier.GetName( PROP_CHAR_PROP_HEIGHT_COMPLEX)); + + } + } + + if(bAddFollowStyle || aPropValues.getLength()) + { + PropValVector aSortedPropVals; + for( sal_Int32 nProp = 0; nProp < aPropValues.getLength(); ++nProp) + { + // Don't add the style name properties + bool bIsParaStyleName = aPropValues[nProp].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ParaStyleName" ) ); + bool bIsCharStyleName = aPropValues[nProp].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CharStyleName" ) ); + if ( !bIsParaStyleName && !bIsCharStyleName ) + { + aSortedPropVals.Insert( aPropValues[nProp] ); + } + } + if(bAddFollowStyle) + { + //find the name of the Next style + std::vector< StyleSheetEntryPtr >::iterator aNextStyleIt = m_pImpl->m_aStyleSheetEntries.begin(); + for( ; aNextStyleIt != m_pImpl->m_aStyleSheetEntries.end(); ++aNextStyleIt ) + { + if( ( *aNextStyleIt )->sStyleName.getLength() && + ( *aNextStyleIt )->sStyleName == pEntry->sNextStyleIdentifier) + { + beans::PropertyValue aNew; + aNew.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FollowStyle")); + aNew.Value = uno::makeAny(ConvertStyleName( ( *aNextStyleIt )->sStyleIdentifierD )); + aSortedPropVals.Insert( aNew ); + break; + } + } + } + + try + { + uno::Reference< beans::XMultiPropertySet > xMultiPropertySet( xStyle, uno::UNO_QUERY_THROW); + xMultiPropertySet->setPropertyValues( aSortedPropVals.getNames(), aSortedPropVals.getValues() ); + } + catch( const lang::WrappedTargetException& rWrapped) + { + (void) rWrapped; + rtl::OString aMessage("Some style properties could not be set"); +#if OSL_DEBUG_LEVEL > 0 + beans::UnknownPropertyException aUnknownPropertyException; + + if( rWrapped.TargetException >>= aUnknownPropertyException ) + { + aMessage += rtl::OString(": " ); + ::rtl::OString sTemp; + aUnknownPropertyException.Message.convertToString(&sTemp, RTL_TEXTENCODING_ASCII_US, 0 ); + aMessage += sTemp; + } +#endif + OSL_FAIL( aMessage.getStr()); + } + catch( const uno::Exception& rEx) + { + (void) rEx; + OSL_FAIL( "Some style properties could not be set"); + } + } + if(bInsert) + { + xStyles->insertByName( sConvertedStyleName, uno::makeAny( xStyle) ); + } + } + ++aIt; + } + } + } + catch( uno::Exception& rEx) + { + (void)rEx; + OSL_FAIL( "Styles could not be imported completely"); + } +} + + +const StyleSheetEntryPtr StyleSheetTable::FindStyleSheetByISTD(const ::rtl::OUString& sIndex) +{ + StyleSheetEntryPtr pRet; + for( sal_uInt32 nPos = 0; nPos < m_pImpl->m_aStyleSheetEntries.size(); ++nPos ) + { + if( m_pImpl->m_aStyleSheetEntries[nPos]->sStyleIdentifierD == sIndex) + { + pRet = m_pImpl->m_aStyleSheetEntries[nPos]; + break; + } + } + return pRet; +} + + +const StyleSheetEntryPtr StyleSheetTable::FindStyleSheetByStyleName(const ::rtl::OUString& sIndex) +{ + StyleSheetEntryPtr pRet; + for( sal_uInt32 nPos = 0; nPos < m_pImpl->m_aStyleSheetEntries.size(); ++nPos ) + { + if( m_pImpl->m_aStyleSheetEntries[nPos]->sStyleName == sIndex) + { + pRet = m_pImpl->m_aStyleSheetEntries[nPos]; + break; + } + } + return pRet; +} + + +const StyleSheetEntryPtr StyleSheetTable::FindStyleSheetByConvertedStyleName(const ::rtl::OUString& sIndex) +{ + StyleSheetEntryPtr pRet; + for( sal_uInt32 nPos = 0; nPos < m_pImpl->m_aStyleSheetEntries.size(); ++nPos ) + { + if( m_pImpl->m_aStyleSheetEntries[nPos]->sConvertedStyleName == sIndex) + { + pRet = m_pImpl->m_aStyleSheetEntries[nPos]; + break; + } + } + return pRet; +} + + + +const StyleSheetEntryPtr StyleSheetTable::FindParentStyleSheet(::rtl::OUString sBaseStyle) +{ + if( !sBaseStyle.getLength() ) + { + StyleSheetEntryPtr pEmptyPtr; + return pEmptyPtr; + } + if( m_pImpl->m_pCurrentEntry) + sBaseStyle = m_pImpl->m_pCurrentEntry->sBaseStyleIdentifier; + + return FindStyleSheetByISTD( sBaseStyle ); +} + + +static const sal_Char* const aStyleNamePairs[] = +{ + "Normal", "Standard", + "heading 1", "Heading 1", + "heading 2", "Heading 2", + "heading 3", "Heading 3", + "heading 4", "Heading 4", + "heading 5", "Heading 5", + "heading 6", "Heading 6", + "heading 7", "Heading 7", + "heading 8", "Heading 8", + "heading 9", "Heading 9", + "Heading1", "Heading 1", + "Heading2", "Heading 2", + "Heading3", "Heading 3", + "Heading4", "Heading 4", + "Heading5", "Heading 5", + "Heading6", "Heading 6", + "Heading7", "Heading 7", + "Heading8", "Heading 8", + "Heading9", "Heading 9", + "Heading 1", "Heading 1", + "Heading 2", "Heading 2", + "Heading 3", "Heading 3", + "Heading 4", "Heading 4", + "Heading 5", "Heading 5", + "Heading 6", "Heading 6", + "Heading 7", "Heading 7", + "Heading 8", "Heading 8", + "Heading 9", "Heading 9", + "Index 1", "Index 1", + "Index 2", "Index 2", + "Index 3", "Index 3", + "Index 4", "", + "Index 5", "", + "Index 6", "", + "Index 7", "", + "Index 8", "", + "Index 9", "", + "TOC 1", "Contents 1", + "TOC 2", "Contents 2", + "TOC 3", "Contents 3", + "TOC 4", "Contents 4", + "TOC 5", "Contents 5", + "TOC 6", "Contents 6", + "TOC 7", "Contents 7", + "TOC 8", "Contents 8", + "TOC 9", "Contents 9", + "TOC Heading", "Contents Heading", + "TOCHeading", "Contents Heading", + "toc 1", "Contents 1", + "toc 2", "Contents 2", + "toc 3", "Contents 3", + "toc 4", "Contents 4", + "toc 5", "Contents 5", + "toc 6", "Contents 6", + "toc 7", "Contents 7", + "toc 8", "Contents 8", + "toc 9", "Contents 9", + "TOC1", "Contents 1", + "TOC2", "Contents 2", + "TOC3", "Contents 3", + "TOC4", "Contents 4", + "TOC5", "Contents 5", + "TOC6", "Contents 6", + "TOC7", "Contents 7", + "TOC8", "Contents 8", + "TOC9", "Contents 9", + "Normal Indent", "", + "Footnote Text", "Footnote", + "Annotation Text", "", + "Header", "Header", + "header", "Header", + "Footer", "Footer", + "footer", "Footer", + "Index Heading", "Index Heading", + "Caption", "", + "Table of Figures", "", + "Envelope Address", "Addressee", + "Envelope Return", "Sender", + "Footnote Reference", "Footnote anchor", + "Annotation Reference", "", + "Line Number", "Line numbering", + "Page Number", "Page Number", + "Endnote Reference", "Endnote anchor", + "Endnote Text", "Endnote Symbol", + "Table of Authorities", "", + "Macro Text", "", + "TOA Heading", "", + "List", "List", + "List 2", "", + "List 3", "", + "List 4", "", + "List 5", "", + "List Bullet", "", + "List Bullet 2", "", + "List Bullet 3", "", + "List Bullet 4", "", + "List Bullet 5", "", + "List Number", "", + "List Number 2", "", + "List Number 3", "", + "List Number 4", "", + "List Number 5", "", + "Title", "Title", + "Closing", "", + "Signature", "Signature", + "Default Paragraph Font", "", + "DefaultParagraphFont", "Default Paragraph Font", + "Body Text", "Text body", + "BodyText", "Text body", + "BodyTextIndentItalic", "Text body indent italic", + "Body Text Indent", "Text body indent", + "BodyTextIndent", "Text body indent", + "BodyTextIndent2", "Text body indent2", + "List Continue", "", + "List Continue 2", "", + "List Continue 3", "", + "List Continue 4", "", + "List Continue 5", "", + "Message Header", "", + "Subtitle", "Subtitle", + "Salutation", "", + "Date", "", + "Body Text First Indent", "Body Text Indent", + "Body Text First Indent 2", "", + "Note Heading", "", + "Body Text 2", "", + "Body Text 3", "", + "Body Text Indent 2", "", + "Body Text Indent 3", "", + "Block Text", "", + "Hyperlink", "Internet link", + "Followed Hyperlink", "Visited Internet Link", + "Strong", "Strong Emphasis", + "Emphasis", "Emphasis", + "Document Map", "", + "Plain Text", "", + "NoList", "No List", + "AbstractHeading", "Abstract Heading", + "AbstractBody", "Abstract Body", + "PageNumber", "page number" + "TableNormal", "Normal Table", + "DocumentMap", "Document Map" +}; + + +::rtl::OUString StyleSheetTable::ConvertStyleName( const ::rtl::OUString& rWWName, bool bExtendedSearch) +{ + ::rtl::OUString sRet( rWWName ); + if( bExtendedSearch ) + { + //search for the rWWName in the IdentifierD of the existing styles and convert the sStyleName member + std::vector< StyleSheetEntryPtr >::iterator aIt = m_pImpl->m_aStyleSheetEntries.begin(); + //TODO: performance issue - put styles list into a map sorted by it's sStyleIdentifierD members + while( aIt != m_pImpl->m_aStyleSheetEntries.end() ) + { + if( rWWName == ( *aIt )->sStyleIdentifierD ) + sRet = ( *aIt )->sStyleName; + ++aIt; + } + } + if(!m_pImpl->m_aStyleNameMap.size()) + { + for( sal_uInt32 nPair = 0; nPair < sizeof(aStyleNamePairs) / sizeof( sal_Char*) / 2; ++nPair) + { + m_pImpl->m_aStyleNameMap.insert( StringPairMap_t::value_type( + ::rtl::OUString::createFromAscii(aStyleNamePairs[2 * nPair]), + ::rtl::OUString::createFromAscii(aStyleNamePairs[2 * nPair + 1]) )); + } + } + StringPairMap_t::iterator aIt = m_pImpl->m_aStyleNameMap.find( sRet ); + if(aIt != m_pImpl->m_aStyleNameMap.end() && aIt->second.getLength()) + sRet = aIt->second; + return sRet; +} + +::rtl::OUString StyleSheetTable::GetStyleIdFromIndex(const sal_uInt32 sti) +{ + ::rtl::OUString sRet; + if (sti >= (sizeof(aStyleNamePairs) / sizeof( sal_Char*) / 2)) + sRet = ::rtl::OUString(); + else + sRet = ::rtl::OUString::createFromAscii(aStyleNamePairs[2 * sti]); + return sRet; +} + +void StyleSheetTable::resolveSprmProps(Sprm & rSprm) +{ + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + pProperties->resolve(*this); +} + +void StyleSheetTable::resolveAttributeProperties(Value & val) +{ + writerfilter::Reference<Properties>::Pointer_t pProperties = val.getProperties(); + if( pProperties.get()) + pProperties->resolve(*this); +} + + +void StyleSheetTable::applyDefaults(bool bParaProperties) +{ + try{ + if(!m_pImpl->m_xTextDefaults.is()) + { + m_pImpl->m_xTextDefaults = uno::Reference< beans::XPropertySet>( + m_pImpl->m_rDMapper.GetTextFactory()->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.Defaults"))), + uno::UNO_QUERY_THROW ); + } + PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + if( bParaProperties && m_pImpl->m_pDefaultParaProps.get() && m_pImpl->m_pDefaultParaProps->size()) + { + PropertyMap::iterator aMapIter = m_pImpl->m_pDefaultParaProps->begin(); + for( ; aMapIter != m_pImpl->m_pDefaultParaProps->end(); ++aMapIter ) + { + try + { + m_pImpl->m_xTextDefaults->setPropertyValue(rPropNameSupplier.GetName( aMapIter->first.eId ), aMapIter->second); + } + catch( const uno::Exception& ) + { + OSL_FAIL( "setPropertyValue exception"); + } + } + } + if( !bParaProperties && m_pImpl->m_pDefaultCharProps.get() && m_pImpl->m_pDefaultCharProps->size()) + { + PropertyMap::iterator aMapIter = m_pImpl->m_pDefaultCharProps->begin(); + for( ; aMapIter != m_pImpl->m_pDefaultCharProps->end(); ++aMapIter ) + { + try + { + m_pImpl->m_xTextDefaults->setPropertyValue(rPropNameSupplier.GetName( aMapIter->first.eId ), aMapIter->second); + } + catch( const uno::Exception& ) + { + OSL_FAIL( "setPropertyValue exception"); + } + } + } + } + catch( const uno::Exception& ) + { + } +} + + +::rtl::OUString StyleSheetTable::getOrCreateCharStyle( PropertyValueVector_t& rCharProperties ) +{ + //find out if any of the styles already has the required properties then return it's name + ::rtl::OUString sListLabel = m_pImpl->HasListCharStyle(rCharProperties); + if( sListLabel.getLength() ) + return sListLabel; + const char cListLabel[] = "ListLabel "; + uno::Reference< style::XStyleFamiliesSupplier > xStylesSupplier( m_pImpl->m_xTextDocument, uno::UNO_QUERY_THROW ); + uno::Reference< container::XNameAccess > xStyleFamilies = xStylesSupplier->getStyleFamilies(); + uno::Reference<container::XNameContainer> xCharStyles; + xStyleFamilies->getByName(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharacterStyles"))) >>= xCharStyles; + //search for all character styles with the name sListLabel + <index> + sal_Int32 nStyleFound = 0; + uno::Sequence< ::rtl::OUString > aStyleNames = xCharStyles->getElementNames(); + const ::rtl::OUString* pStyleNames = aStyleNames.getConstArray(); + for( sal_Int32 nStyle = 0; nStyle < aStyleNames.getLength(); ++nStyle ) + { + if( pStyleNames[nStyle].matchAsciiL( cListLabel, sizeof( cListLabel ) - 1 )) + { + ::rtl::OUString sSuffix = pStyleNames[nStyle].copy( sizeof( cListLabel ) - 1 ); + sal_Int32 nSuffix = sSuffix.toInt32(); + if( nSuffix > 0 ) + { + if( nSuffix > nStyleFound ) + nStyleFound = nSuffix; + } + } + } + sListLabel = ::rtl::OUString::createFromAscii( cListLabel ); + sListLabel += ::rtl::OUString::valueOf( ++nStyleFound ); + //create a new one otherwise + uno::Reference< lang::XMultiServiceFactory > xDocFactory( m_pImpl->m_xTextDocument, uno::UNO_QUERY_THROW ); + PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + try + { + uno::Reference< style::XStyle > xStyle( xDocFactory->createInstance( + rPropNameSupplier.GetName( PROP_SERVICE_CHAR_STYLE )), uno::UNO_QUERY_THROW); + uno::Reference< beans::XPropertySet > xStyleProps(xStyle, uno::UNO_QUERY_THROW ); + PropertyValueVector_t::const_iterator aCharPropIter = rCharProperties.begin(); + while( aCharPropIter != rCharProperties.end()) + { + try + { + xStyleProps->setPropertyValue( aCharPropIter->Name, aCharPropIter->Value ); + } + catch( const uno::Exception& rEx ) + { + (void)rEx; + OSL_FAIL( "Exception in StyleSheetTable::getOrCreateCharStyle - Style::setPropertyValue"); + } + ++aCharPropIter; + } + xCharStyles->insertByName( sListLabel, uno::makeAny( xStyle) ); + m_pImpl->m_aListCharStylePropertyVector.push_back( ListCharStylePropertyMap_t( sListLabel, rCharProperties )); + } + catch( const uno::Exception& rEx ) + { + (void)rEx; + OSL_FAIL( "Exception in StyleSheetTable::getOrCreateCharStyle"); + } + + return sListLabel; +} + +}//namespace dmapper +}//namespace writerfilter + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/StyleSheetTable.hxx b/writerfilter/source/dmapper/StyleSheetTable.hxx new file mode 100644 index 000000000000..8f3811b5066a --- /dev/null +++ b/writerfilter/source/dmapper/StyleSheetTable.hxx @@ -0,0 +1,161 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef INCLUDED_STYLESHEETTABLE_HXX +#define INCLUDED_STYLESHEETTABLE_HXX + +#include "TblStylePrHandler.hxx" + +#include <WriterFilterDllApi.hxx> +#include <dmapper/DomainMapper.hxx> +#include <com/sun/star/lang/XComponent.hpp> +#include <PropertyMap.hxx> +#include <FontTable.hxx> +#include <resourcemodel/LoggedResources.hxx> + +namespace com{ namespace sun { namespace star { namespace text{ + class XTextDocument; +}}}} + + +namespace writerfilter { +namespace dmapper +{ + + +enum StyleType +{ + STYLE_TYPE_UNKNOWN, + STYLE_TYPE_PARA, + STYLE_TYPE_CHAR, + STYLE_TYPE_TABLE, + STYLE_LIST +}; + +struct StyleSheetTable_Impl; +class StyleSheetEntry +{ +public: + ::rtl::OUString sStyleIdentifierI; + ::rtl::OUString sStyleIdentifierD; + bool bIsDefaultStyle; + bool bInvalidHeight; + bool bHasUPE; //universal property expansion + StyleType nStyleTypeCode; //sgc + ::rtl::OUString sBaseStyleIdentifier; + ::rtl::OUString sNextStyleIdentifier; + ::rtl::OUString sStyleName; + ::rtl::OUString sStyleName1; + PropertyMapPtr pProperties; + ::rtl::OUString sConvertedStyleName; + + StyleSheetEntry(); + virtual ~StyleSheetEntry(); +}; + +typedef boost::shared_ptr<StyleSheetEntry> StyleSheetEntryPtr; +typedef ::std::deque<StyleSheetEntryPtr> StyleSheetEntryDeque; +typedef boost::shared_ptr<StyleSheetEntryDeque> StyleSheetEntryDequePtr; + +class DomainMapper; +class StyleSheetTable : + public LoggedProperties, + public LoggedTable +{ + StyleSheetTable_Impl *m_pImpl; + +public: + StyleSheetTable( DomainMapper& rDMapper, + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextDocument> xTextDocument ); + virtual ~StyleSheetTable(); + + void ApplyStyleSheets( FontTablePtr rFontTable ); + const StyleSheetEntryPtr FindStyleSheetByISTD(const ::rtl::OUString& sIndex); + const StyleSheetEntryPtr FindStyleSheetByStyleName(const ::rtl::OUString& rIndex); + const StyleSheetEntryPtr FindStyleSheetByConvertedStyleName(const ::rtl::OUString& rIndex); + // returns the parent of the one with the given name - if empty the parent of the current style sheet is returned + const StyleSheetEntryPtr FindParentStyleSheet(::rtl::OUString sBaseStyle); + + ::rtl::OUString ConvertStyleName( const ::rtl::OUString& rWWName, bool bExtendedSearch = false ); + ::rtl::OUString GetStyleIdFromIndex(const sal_uInt32 sti); + + ::rtl::OUString getOrCreateCharStyle( PropertyValueVector_t& rCharProperties ); + +private: + // Properties + virtual void lcl_attribute(Id Name, Value & val); + virtual void lcl_sprm(Sprm & sprm); + + // Table + virtual void lcl_entry(int pos, writerfilter::Reference<Properties>::Pointer_t ref); + + void resolveAttributeProperties(Value & val); + void resolveSprmProps(Sprm & sprm_); + void applyDefaults(bool bParaProperties); +}; +typedef boost::shared_ptr< StyleSheetTable > StyleSheetTablePtr; + + +class WRITERFILTER_DLLPRIVATE TableStyleSheetEntry : + public StyleSheetEntry +{ +private: + typedef std::map<TblStyleType, PropertyMapPtr> TblStylePrs; + + StyleSheetTable* m_pStyleSheet; + TblStylePrs m_aStyles; + +public: + + short m_nColBandSize; + short m_nRowBandSize; + + // Adds a new tblStylePr to the table style entry. This method + // fixes some possible properties conflicts, like borders ones. + void AddTblStylePr( TblStyleType nType, PropertyMapPtr pProps ); + + // Gets all the properties + // + corresponding to the mask, + // + from the parent styles + // + // @param mask mask describing which properties to return + // @param pStack already processed StyleSheetEntries + PropertyMapPtr GetProperties( sal_Int32 nMask, StyleSheetEntryDequePtr pStack = StyleSheetEntryDequePtr()); + + TableStyleSheetEntry( StyleSheetEntry& aEntry, StyleSheetTable* pStyles ); + virtual ~TableStyleSheetEntry( ); + +protected: + PropertyMapPtr GetLocalPropertiesFromMask( sal_Int32 nMask ); +}; +typedef boost::shared_ptr<TableStyleSheetEntry> TableStyleSheetEntryPtr; + +}} + +#endif // + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/TDefTableHandler.cxx b/writerfilter/source/dmapper/TDefTableHandler.cxx new file mode 100644 index 000000000000..c0a2f9c8add6 --- /dev/null +++ b/writerfilter/source/dmapper/TDefTableHandler.cxx @@ -0,0 +1,281 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include <TDefTableHandler.hxx> +#include <PropertyMap.hxx> +#include <ConversionHelper.hxx> +#include <ooxml/resourceids.hxx> +#include <doctok/resourceids.hxx> +#include <com/sun/star/table/BorderLine2.hpp> +#include <com/sun/star/text/TableColumnSeparator.hpp> +#include <com/sun/star/text/VertOrientation.hpp> + +#include "dmapperLoggers.hxx" + +namespace writerfilter { +namespace dmapper { + +using namespace ::com::sun::star; + + + +TDefTableHandler::TDefTableHandler(bool bOOXML) : +LoggedProperties(dmapper_logger, "TDefTableHandler"), +m_nLineWidth(0), +m_nLineType(0), +m_nLineColor(0), +m_nLineDistance(0), +m_bOOXML( bOOXML ) +{ +} + + +TDefTableHandler::~TDefTableHandler() +{ +} + + +void TDefTableHandler::lcl_attribute(Id rName, Value & rVal) +{ + sal_Int32 nIntValue = rVal.getInt(); + (void)nIntValue; + (void)rName; + switch( rName ) + { + case NS_rtf::LN_cellx: + // nIntValue contains the vert. line position + //TODO: nIntValue is wrong for negative values! + if( nIntValue > 0x7fff ) + nIntValue -= 0xffff; + m_aCellBorderPositions.push_back( ConversionHelper::convertTwipToMM100( nIntValue ) ); + break; + case NS_rtf::LN_tc: + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rVal.getProperties(); + if( pProperties.get()) + { + pProperties->resolve( *this ); + } + } + break; + //from LN_tc + case NS_rtf::LN_FFIRSTMERGED: + case NS_rtf::LN_FMERGED: + case NS_rtf::LN_FVERTICAL: + case NS_rtf::LN_FBACKWARD: + case NS_rtf::LN_FROTATEFONT: + case NS_rtf::LN_FVERTMERGE: + case NS_rtf::LN_FVERTRESTART: + break; + case NS_rtf::LN_VERTALIGN: + //TODO: m_aCellVertAlign is just a temporary solution! 0 - top 1 - center 2 - bottom + m_aCellVertAlign.push_back( nIntValue ); + break; + case NS_rtf::LN_FUNUSED: + case NS_rtf::LN_CellPrefferedSize: + break; + case NS_rtf::LN_BRCTOP: + case NS_rtf::LN_BRCLEFT: + case NS_rtf::LN_BRCBOTTOM: + case NS_rtf::LN_BRCRIGHT: + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rVal.getProperties(); + localResolve( rName, pProperties ); + } + break; + //from LN_BRCXXXX - handled within the BorderHandler + case NS_rtf::LN_DPTLINEWIDTH: // 0x2871 + // width of a single line in 1/8 pt, max of 32 pt -> twip * 5 / 2. + m_nLineWidth = ConversionHelper::convertTwipToMM100( nIntValue * 5 / 2 ); + break; + case NS_rtf::LN_BRCTYPE: // 0x2872 + m_nLineType = nIntValue; + break; + case NS_ooxml::LN_CT_Border_color: + case NS_rtf::LN_ICO: // 0x2873 + m_nLineColor = nIntValue; + break; + case NS_rtf::LN_DPTSPACE: // 0x2874 + m_nLineDistance = nIntValue; + break; + case NS_rtf::LN_FSHADOW: // 0x2875 + //if 1 then line has shadow - unsupported + case NS_rtf::LN_FFRAME: // 0x2876 + case NS_rtf::LN_UNUSED2_15: // 0x2877 + // ignored + break; + case NS_ooxml::LN_CT_Border_themeColor: + case NS_ooxml::LN_CT_Border_themeTint: + case NS_ooxml::LN_CT_Border_themeShade: + // ignored + break; + default: + OSL_FAIL("unknown attribute"); + } +} + + +void TDefTableHandler::localResolve(Id rName, writerfilter::Reference<Properties>::Pointer_t pProperties) +{ + if( pProperties.get()) + { + m_nLineWidth = m_nLineType = m_nLineColor = m_nLineDistance = 0; + pProperties->resolve( *this ); + table::BorderLine2 aBorderLine; + ConversionHelper::MakeBorderLine( m_nLineWidth, m_nLineType, m_nLineColor, + aBorderLine, m_bOOXML ); + + switch( rName ) + { + case NS_ooxml::LN_CT_TcBorders_top: + case NS_rtf::LN_BRCTOP: + m_aTopBorderLines.push_back(aBorderLine); + break; + case NS_ooxml::LN_CT_TcBorders_left: + case NS_rtf::LN_BRCLEFT: + m_aLeftBorderLines.push_back(aBorderLine); + break; + case NS_ooxml::LN_CT_TcBorders_bottom: + case NS_rtf::LN_BRCBOTTOM: + m_aBottomBorderLines.push_back(aBorderLine); + break; + case NS_ooxml::LN_CT_TcBorders_right: + case NS_rtf::LN_BRCRIGHT: + m_aRightBorderLines.push_back(aBorderLine); + break; + case NS_ooxml::LN_CT_TcBorders_insideH: + m_aInsideHBorderLines.push_back(aBorderLine); + break; + case NS_ooxml::LN_CT_TcBorders_insideV: + m_aInsideVBorderLines.push_back(aBorderLine); + break; + default:; + } + } +} + + +void TDefTableHandler::lcl_sprm(Sprm & rSprm) +{ + switch( rSprm.getId() ) + { + case NS_ooxml::LN_CT_TcBorders_top: + case NS_ooxml::LN_CT_TcBorders_left: + case NS_ooxml::LN_CT_TcBorders_bottom: + case NS_ooxml::LN_CT_TcBorders_right: + case NS_ooxml::LN_CT_TcBorders_insideH: + case NS_ooxml::LN_CT_TcBorders_insideV: + case NS_ooxml::LN_CT_TcBorders_tl2br: + case NS_ooxml::LN_CT_TcBorders_tr2bl: + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + localResolve( rSprm.getId(), pProperties ); + } + break; + default:; + } +} + + +PropertyMapPtr TDefTableHandler::getRowProperties() const +{ + PropertyMapPtr pPropertyMap(new PropertyMap); + + // Writer only wants the separators, Word provides also the outer border positions + if( m_aCellBorderPositions.size() > 2 ) + { + //determine table width + double nFullWidth = m_aCellBorderPositions[m_aCellBorderPositions.size() - 1] - m_aCellBorderPositions[0]; + //the positions have to be distibuted in a range of 10000 + const double nFullWidthRelative = 10000.; + uno::Sequence< text::TableColumnSeparator > aSeparators( m_aCellBorderPositions.size() - 2 ); + text::TableColumnSeparator* pSeparators = aSeparators.getArray(); + for( sal_uInt32 nBorder = 1; nBorder < m_aCellBorderPositions.size() - 1; ++nBorder ) + { + sal_Int16 nRelPos = + sal::static_int_cast< sal_Int16 >(double(m_aCellBorderPositions[nBorder]) * nFullWidthRelative / nFullWidth ); + + pSeparators[nBorder - 1].Position = nRelPos; + pSeparators[nBorder - 1].IsVisible = sal_True; + } + pPropertyMap->Insert( PROP_TABLE_COLUMN_SEPARATORS, false, uno::makeAny( aSeparators ) ); + } + + return pPropertyMap; +} + + +void TDefTableHandler::fillCellProperties( + size_t nCell, ::boost::shared_ptr< TablePropertyMap > pCellProperties ) const +{ + if( m_aCellBorderPositions.size() > nCell ) + { + sal_Int16 nVertOrient = text::VertOrientation::NONE; + switch( m_aCellVertAlign[nCell] ) //0 - top 1 - center 2 - bottom + { + case 1: nVertOrient = text::VertOrientation::CENTER; break; + case 2: nVertOrient = text::VertOrientation::BOTTOM; break; + default:; + } + pCellProperties->Insert( PROP_VERT_ORIENT, false, uno::makeAny( nVertOrient ) ); + } + if( m_aTopBorderLines.size() > nCell ) + pCellProperties->Insert( PROP_TOP_BORDER, false, uno::makeAny( m_aTopBorderLines[nCell] ) ); + if( m_aLeftBorderLines.size() > nCell ) + pCellProperties->Insert( PROP_LEFT_BORDER, false, uno::makeAny( m_aLeftBorderLines[nCell] ) ); + if( m_aBottomBorderLines.size() > nCell ) + pCellProperties->Insert( PROP_BOTTOM_BORDER, false, uno::makeAny( m_aBottomBorderLines[nCell] ) ); + if( m_aRightBorderLines.size() > nCell ) + pCellProperties->Insert( PROP_RIGHT_BORDER, false, uno::makeAny( m_aRightBorderLines[nCell] ) ); + if( m_aInsideHBorderLines.size() > nCell ) + pCellProperties->Insert( META_PROP_HORIZONTAL_BORDER, false, uno::makeAny( m_aInsideHBorderLines[nCell] ) ); + if( m_aInsideVBorderLines.size() > nCell ) + pCellProperties->Insert( META_PROP_VERTICAL_BORDER, false, uno::makeAny( m_aInsideVBorderLines[nCell] ) ); +} + + +sal_Int32 TDefTableHandler::getTableWidth() const +{ + sal_Int32 nWidth = 0; + if( m_aCellBorderPositions.size() > 1 ) + { + //determine table width + nWidth = m_aCellBorderPositions[m_aCellBorderPositions.size() - 1] - m_aCellBorderPositions[0]; + } + return nWidth; +} + + +size_t TDefTableHandler::getCellCount() const +{ + return m_aCellVertAlign.size(); +} + +} //namespace dmapper +} //namespace writerfilter + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/TDefTableHandler.hxx b/writerfilter/source/dmapper/TDefTableHandler.hxx new file mode 100644 index 000000000000..8bbf07993fc3 --- /dev/null +++ b/writerfilter/source/dmapper/TDefTableHandler.hxx @@ -0,0 +1,89 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef INCLUDED_TDEFTABLEHANDLER_HXX +#define INCLUDED_TDEFTABLEHANDLER_HXX + +#include <WriterFilterDllApi.hxx> +#include <resourcemodel/LoggedResources.hxx> +#include <boost/shared_ptr.hpp> +#include <vector> +namespace com{ namespace sun{ namespace star{namespace table { + struct BorderLine2; +}}}} + +namespace writerfilter { +namespace dmapper +{ +class PropertyMap; +class TablePropertyMap; +class WRITERFILTER_DLLPRIVATE TDefTableHandler : public LoggedProperties +{ +public: + +private: + ::std::vector<sal_Int32> m_aCellBorderPositions; + ::std::vector<sal_Int32> m_aCellVertAlign; + + ::std::vector< ::com::sun::star::table::BorderLine2 > m_aLeftBorderLines; + ::std::vector< ::com::sun::star::table::BorderLine2 > m_aRightBorderLines; + ::std::vector< ::com::sun::star::table::BorderLine2 > m_aTopBorderLines; + ::std::vector< ::com::sun::star::table::BorderLine2 > m_aBottomBorderLines; + ::std::vector< ::com::sun::star::table::BorderLine2 > m_aInsideHBorderLines; + ::std::vector< ::com::sun::star::table::BorderLine2 > m_aInsideVBorderLines; + ::std::vector< ::com::sun::star::table::BorderLine2 > m_aTl2brBorderLines; + ::std::vector< ::com::sun::star::table::BorderLine2 > m_aTr2blBorderLines; + + //values of the current border + sal_Int32 m_nLineWidth; + sal_Int32 m_nLineType; + sal_Int32 m_nLineColor; + sal_Int32 m_nLineDistance; + + bool m_bOOXML; + + void localResolve(Id Name, writerfilter::Reference<Properties>::Pointer_t pProperties); + + // Properties + virtual void lcl_attribute(Id Name, Value & val); + virtual void lcl_sprm(Sprm & sprm); + +public: + TDefTableHandler( bool bOOXML ); + virtual ~TDefTableHandler(); + + size_t getCellCount() const; + void fillCellProperties( size_t nCell, ::boost::shared_ptr< TablePropertyMap > pCellProperties) const; + ::boost::shared_ptr<PropertyMap> getRowProperties() const; + sal_Int32 getTableWidth() const; +}; +typedef boost::shared_ptr< TDefTableHandler > TDefTableHandlerPtr; +}} + +#endif // + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/TablePropertiesHandler.cxx b/writerfilter/source/dmapper/TablePropertiesHandler.cxx new file mode 100644 index 000000000000..451694d23019 --- /dev/null +++ b/writerfilter/source/dmapper/TablePropertiesHandler.cxx @@ -0,0 +1,230 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +#include "BorderHandler.hxx" +#include "CellColorHandler.hxx" +#include "CellMarginHandler.hxx" +#include "ConversionHelper.hxx" +#include "MeasureHandler.hxx" +#include "TablePropertiesHandler.hxx" +#include "TDefTableHandler.hxx" + +#include <ooxml/resourceids.hxx> +#include <doctok/sprmids.hxx> + +#include <com/sun/star/text/SizeType.hpp> +#include <com/sun/star/text/VertOrientation.hpp> +#include <dmapperLoggers.hxx> + + +namespace writerfilter { +namespace dmapper { + + TablePropertiesHandler::TablePropertiesHandler( bool bOOXML ) : + m_pTableManager( NULL ), + m_bOOXML( bOOXML ) + { + } + + + TablePropertiesHandler::~TablePropertiesHandler( ) + { + // Do not delete the table manager... this will be done somewhere else + m_pTableManager = NULL; + } + + bool TablePropertiesHandler::sprm(Sprm & rSprm) + { +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->startElement("TablePropertiesHandler.sprm"); + dmapper_logger->attribute("sprm", rSprm.toString()); +#endif + + bool bRet = true; + sal_uInt32 nSprmId = rSprm.getId(); + Value::Pointer_t pValue = rSprm.getValue(); + sal_Int32 nIntValue = ((pValue.get() != NULL) ? pValue->getInt() : 0); + switch( nSprmId ) + { + case NS_ooxml::LN_CT_TrPrBase_jc: //90706 + case NS_ooxml::LN_CT_TblPrBase_jc: + case 0x5400: // sprmTJc + { + //table justification 0: left, 1: center, 2: right + sal_Int16 nOrient = ConversionHelper::convertTableJustification( nIntValue ); + TablePropertyMapPtr pTableMap( new TablePropertyMap ); + pTableMap->setValue( TablePropertyMap::HORI_ORIENT, nOrient ); + insertTableProps( pTableMap ); + } + break; + case 0x9601: // sprmTDxaLeft + break; + case 0x9602: // sprmTDxaGapHalf + { + //m_nGapHalf = ConversionHelper::convertTwipToMM100( nIntValue ); + TablePropertyMapPtr pPropMap( new TablePropertyMap ); + pPropMap->setValue( TablePropertyMap::GAP_HALF, ConversionHelper::convertTwipToMM100( nIntValue ) ); + insertTableProps(pPropMap); + } + break; + case NS_ooxml::LN_CT_TrPrBase_trHeight: //90703 + { + //contains unit and value + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + { //contains attributes x2902 (LN_unit) and x17e2 (LN_trleft) + MeasureHandlerPtr pMeasureHandler( new MeasureHandler ); + pProperties->resolve(*pMeasureHandler); + TablePropertyMapPtr pPropMap( new TablePropertyMap ); + pPropMap->Insert( PROP_SIZE_TYPE, false, uno::makeAny( pMeasureHandler->GetRowHeightSizeType() )); + pPropMap->Insert( PROP_HEIGHT, false, uno::makeAny(pMeasureHandler->getMeasureValue() )); + insertRowProps(pPropMap); + } + } + break; + case 0x3403: // sprmTFCantSplit + case NS_sprm::LN_TCantSplit: // 0x3644 + { + //row can't break across pages if nIntValue == 1 + TablePropertyMapPtr pPropMap( new TablePropertyMap ); + pPropMap->Insert( PROP_IS_SPLIT_ALLOWED, false, uno::makeAny(sal_Bool( nIntValue == 1 ? sal_False : sal_True ) )); + insertRowProps(pPropMap); + } + break; + case 0x9407: // sprmTDyaRowHeight + { + // table row height - negative values indicate 'exact height' - positive 'at least' + TablePropertyMapPtr pPropMap( new TablePropertyMap ); + bool bMinHeight = true; + sal_Int16 nHeight = static_cast<sal_Int16>( nIntValue ); + if( nHeight < 0 ) + { + bMinHeight = false; + nHeight *= -1; + } + pPropMap->Insert( PROP_SIZE_TYPE, false, uno::makeAny(bMinHeight ? text::SizeType::MIN : text::SizeType::FIX )); + pPropMap->Insert( PROP_HEIGHT, false, uno::makeAny(ConversionHelper::convertTwipToMM100( nHeight ))); + insertRowProps(pPropMap); + } + break; + case NS_ooxml::LN_CT_TcPrBase_vAlign://90694 + { + sal_Int16 nVertOrient = text::VertOrientation::NONE; + switch( nIntValue ) //0 - top 1 - center 3 - bottom + { + case 1: nVertOrient = text::VertOrientation::CENTER; break; + case 3: nVertOrient = text::VertOrientation::BOTTOM; break; + default:; + }; + TablePropertyMapPtr pCellPropMap( new TablePropertyMap() ); + pCellPropMap->Insert( PROP_VERT_ORIENT, false, uno::makeAny( nVertOrient ) ); + //todo: in ooxml import the value of m_ncell is wrong + cellProps( pCellPropMap ); + } + break; + case NS_ooxml::LN_CT_TblPrBase_tblBorders: //table borders, might be defined in table style + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + { + BorderHandlerPtr pBorderHandler( new BorderHandler(m_bOOXML) ); + pProperties->resolve(*pBorderHandler); + TablePropertyMapPtr pTablePropMap( new TablePropertyMap ); + pTablePropMap->insert( pBorderHandler->getProperties() ); + +#ifdef DEBUG_DOMAINMAPPER + pTablePropMap->dumpXml( dmapper_logger ); +#endif + insertTableProps( pTablePropMap ); + } + } + break; + case NS_ooxml::LN_CT_TcPrBase_tcBorders ://cell borders + //contains CT_TcBorders_left, right, top, bottom + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + { + //in OOXML there's one set of borders at each cell (if there is any) + TDefTableHandlerPtr pTDefTableHandler( new TDefTableHandler( m_bOOXML )); + pProperties->resolve( *pTDefTableHandler ); + TablePropertyMapPtr pCellPropMap( new TablePropertyMap ); + pTDefTableHandler->fillCellProperties( 0, pCellPropMap ); + cellProps( pCellPropMap ); + } + } + break; + case NS_ooxml::LN_CT_TblPrBase_shd: + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + { + CellColorHandlerPtr pCellColorHandler( new CellColorHandler); + pProperties->resolve( *pCellColorHandler ); + TablePropertyMapPtr pTablePropMap( new TablePropertyMap ); + insertTableProps( pCellColorHandler->getProperties() ); + } + } + break; + case 0xd61a : // sprmTCellTopColor + case 0xd61b : // sprmTCellLeftColor + case 0xd61c : // sprmTCellBottomColor + case 0xd61d : // sprmTCellRightColor + case NS_ooxml::LN_CT_TcPrBase_shd: + { + // each color sprm contains as much colors as cells are in a row + //LN_CT_TcPrBase_shd: cell shading contains: LN_CT_Shd_val, LN_CT_Shd_fill, LN_CT_Shd_color + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + { + CellColorHandlerPtr pCellColorHandler( new CellColorHandler ); + pProperties->resolve( *pCellColorHandler ); + cellProps( pCellColorHandler->getProperties()); + } + } + break; +//OOXML table properties + case NS_ooxml::LN_CT_TblPrBase_tblCellMar: //cell margins + { + //contains LN_CT_TblCellMar_top, LN_CT_TblCellMar_left, LN_CT_TblCellMar_bottom, LN_CT_TblCellMar_right + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + { + CellMarginHandlerPtr pCellMarginHandler( new CellMarginHandler ); + pProperties->resolve( *pCellMarginHandler ); + TablePropertyMapPtr pMarginProps( new TablePropertyMap ); + if( pCellMarginHandler->m_bTopMarginValid ) + pMarginProps->setValue( TablePropertyMap::CELL_MAR_TOP, pCellMarginHandler->m_nTopMargin ); + if( pCellMarginHandler->m_bBottomMarginValid ) + pMarginProps->setValue( TablePropertyMap::CELL_MAR_BOTTOM, pCellMarginHandler->m_nBottomMargin ); + if( pCellMarginHandler->m_bLeftMarginValid ) + pMarginProps->setValue( TablePropertyMap::CELL_MAR_LEFT, pCellMarginHandler->m_nLeftMargin ); + if( pCellMarginHandler->m_bRightMarginValid ) + pMarginProps->setValue( TablePropertyMap::CELL_MAR_RIGHT, pCellMarginHandler->m_nRightMargin ); + insertTableProps(pMarginProps); + } + } + break; + case NS_ooxml::LN_CT_TblPrBase_tblInd: + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if (pProperties.get()) + { + MeasureHandlerPtr pHandler(new MeasureHandler); + TablePropertyMapPtr pTblIndMap(new TablePropertyMap); + sal_uInt32 nTblInd = pHandler->getMeasureValue(); + pTblIndMap->setValue( TablePropertyMap::LEFT_MARGIN, nTblInd); + insertTableProps(pTblIndMap); + } + } + break; + default: bRet = false; + } + +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->endElement(); +#endif + + return bRet; + } +}} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/TablePropertiesHandler.hxx b/writerfilter/source/dmapper/TablePropertiesHandler.hxx new file mode 100644 index 000000000000..27af1d8c50e7 --- /dev/null +++ b/writerfilter/source/dmapper/TablePropertiesHandler.hxx @@ -0,0 +1,86 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +#ifndef INCLUDED_TABLEPROPERTIESHANDLER_HXX +#define INCLUDED_TABLEPROPERTIESHANDLER_HXX + +#include <PropertyMap.hxx> + +#include <resourcemodel/TableManager.hxx> +#include <WriterFilterDllApi.hxx> +#include <resourcemodel/WW8ResourceModel.hxx> + +#include <boost/shared_ptr.hpp> + +#include <vector> + +namespace writerfilter { +namespace dmapper { + + +typedef ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > Handle_t; +typedef TableManager<Handle_t , TablePropertyMapPtr > DomainMapperTableManager_Base_t; + +class TablePropertiesHandler +{ +private: + vector< PropertyMapPtr > m_rPropertiesStack; + PropertyMapPtr m_pCurrentProperties; + DomainMapperTableManager_Base_t *m_pTableManager; + bool m_bOOXML; + +public: + TablePropertiesHandler( bool bOOXML ); + virtual ~TablePropertiesHandler( ); + + bool sprm(Sprm & sprm); + + inline void SetTableManager( DomainMapperTableManager_Base_t *pTableManager ) + { + m_pTableManager = pTableManager; + }; + + inline void SetProperties( PropertyMapPtr pProperties ) + { + m_pCurrentProperties = pProperties; + }; + +private: + + inline void cellProps( TablePropertyMapPtr pProps ) + { + if ( m_pTableManager ) + m_pTableManager->cellProps( pProps ); + else + m_pCurrentProperties->insert( pProps, true ); + }; + + inline void cellPropsByCell( unsigned int i, TablePropertyMapPtr pProps ) + { + if ( m_pTableManager ) + m_pTableManager->cellPropsByCell( i, pProps ); + else + m_pCurrentProperties->insert( pProps, true ); + }; + + inline void insertRowProps( TablePropertyMapPtr pProps ) + { + if ( m_pTableManager ) + m_pTableManager->insertRowProps( pProps ); + else + m_pCurrentProperties->insert( pProps, true ); + }; + + inline void insertTableProps( TablePropertyMapPtr pProps ) + { + if ( m_pTableManager ) + m_pTableManager->insertTableProps( pProps ); + else + m_pCurrentProperties->insert( pProps, true ); + }; +}; +typedef boost::shared_ptr<TablePropertiesHandler> TablePropertiesHandlerPtr; + +} } + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/TblStylePrHandler.cxx b/writerfilter/source/dmapper/TblStylePrHandler.cxx new file mode 100644 index 000000000000..cf8bda4a85cc --- /dev/null +++ b/writerfilter/source/dmapper/TblStylePrHandler.cxx @@ -0,0 +1,93 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +#include <TblStylePrHandler.hxx> +#include <PropertyMap.hxx> +#include <ooxml/resourceids.hxx> +#include <dmapperLoggers.hxx> +#include <resourcemodel/QNameToString.hxx> + +#include "dmapperLoggers.hxx" + +namespace writerfilter { +namespace dmapper { + +TblStylePrHandler::TblStylePrHandler( DomainMapper & rDMapper ) : +LoggedProperties(dmapper_logger, "TblStylePrHandler"), +m_rDMapper( rDMapper ), +m_pTablePropsHandler( new TablePropertiesHandler( true ) ), +m_nType( TBL_STYLE_UNKNOWN ), +m_pProperties( new PropertyMap ) +{ +} + +TblStylePrHandler::~TblStylePrHandler( ) +{ + delete m_pTablePropsHandler, m_pTablePropsHandler = NULL; +} + +void TblStylePrHandler::lcl_attribute(Id rName, Value & rVal) +{ +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->startElement("TblStylePrHandler.attribute"); + dmapper_logger->attribute("name", (*QNameToString::Instance())(rName)); + dmapper_logger->chars(rVal.toString()); + dmapper_logger->endElement(); +#endif + + switch ( rName ) + { + case NS_ooxml::LN_CT_TblStyleOverrideType: + { + // The tokenid should be the same in the model.xml than + // in the TblStyleType enum + m_nType = TblStyleType( rVal.getInt( ) ); + } + break; + } +} + +void TblStylePrHandler::lcl_sprm(Sprm & rSprm) +{ +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->startElement("TblStylePrHandler.sprm"); + dmapper_logger->attribute("sprm", rSprm.toString()); +#endif + + Value::Pointer_t pValue = rSprm.getValue(); + switch ( rSprm.getId( ) ) + { + case NS_ooxml::LN_CT_PPrBase: + case NS_ooxml::LN_EG_RPrBase: + case NS_ooxml::LN_CT_TblPrBase: + case NS_ooxml::LN_CT_TrPrBase: + case NS_ooxml::LN_CT_TcPrBase: + resolveSprmProps( rSprm ); + break; + default: + // Tables specific properties have to handled here + m_pTablePropsHandler->SetProperties( m_pProperties ); + bool bRet = m_pTablePropsHandler->sprm( rSprm ); + + if ( !bRet ) + { + // The DomainMapper can handle some of the properties + m_rDMapper.PushStyleSheetProperties( m_pProperties, true ); + m_rDMapper.sprm( rSprm ); + m_rDMapper.PopStyleSheetProperties( true ); + } + } + +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->endElement(); +#endif +} + +void TblStylePrHandler::resolveSprmProps(Sprm & rSprm) +{ + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + pProperties->resolve(*this); +} + +}} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/TblStylePrHandler.hxx b/writerfilter/source/dmapper/TblStylePrHandler.hxx new file mode 100644 index 000000000000..b665aeb4be29 --- /dev/null +++ b/writerfilter/source/dmapper/TblStylePrHandler.hxx @@ -0,0 +1,67 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +#ifndef INCLUDED_TBLSTYLEPRHANDLER_HXX +#define INCLUDED_TBLSTYLEPRHANDLER_HXX + +#include "TablePropertiesHandler.hxx" + +#include <dmapper/DomainMapper.hxx> +#include <WriterFilterDllApi.hxx> +#include <resourcemodel/LoggedResources.hxx> +#include <boost/shared_ptr.hpp> + +namespace writerfilter { +namespace dmapper { + +class DomainMapper; +class PropertyMap; + +enum TblStyleType +{ + TBL_STYLE_UNKNOWN, + TBL_STYLE_WHOLETABLE, + TBL_STYLE_FIRSTROW, + TBL_STYLE_LASTROW, + TBL_STYLE_FIRSTCOL, + TBL_STYLE_LASTCOL, + TBL_STYLE_BAND1VERT, + TBL_STYLE_BAND2VERT, + TBL_STYLE_BAND1HORZ, + TBL_STYLE_BAND2HORZ, + TBL_STYLE_NECELL, + TBL_STYLE_NWCELL, + TBL_STYLE_SECELL, + TBL_STYLE_SWCELL +}; + +class WRITERFILTER_DLLPRIVATE TblStylePrHandler : public LoggedProperties +{ +private: + DomainMapper & m_rDMapper; + TablePropertiesHandler * m_pTablePropsHandler; + + TblStyleType m_nType; + PropertyMapPtr m_pProperties; + + // Properties + virtual void lcl_attribute(Id Name, Value & val); + virtual void lcl_sprm(Sprm & sprm); + +public: + TblStylePrHandler( DomainMapper & rDMapper ); + virtual ~TblStylePrHandler( ); + + inline PropertyMapPtr getProperties() { return m_pProperties; }; + inline TblStyleType getType() { return m_nType; }; + +private: + + void resolveSprmProps(Sprm & rSprm); +}; + +typedef boost::shared_ptr< TblStylePrHandler > TblStylePrHandlerPtr; + +}} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/ThemeTable.cxx b/writerfilter/source/dmapper/ThemeTable.cxx new file mode 100644 index 000000000000..c3e2790882c3 --- /dev/null +++ b/writerfilter/source/dmapper/ThemeTable.cxx @@ -0,0 +1,219 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <ThemeTable.hxx> +#ifndef INCLUDED_RESOURCESIDS +#include <doctok/resourceids.hxx> +#include <ooxml/resourceids.hxx> +#endif +#include "dmapperLoggers.hxx" + +#if DEBUG_DOMAINMAPPER +#include <resourcemodel/QNameToString.hxx> +#endif + +namespace writerfilter { +namespace dmapper +{ + +struct ThemeTable_Impl +{ + ThemeTable_Impl() : + m_currentThemeFontId(0), + m_currentFontThemeEntry() {} + std::map<sal_uInt32, std::map<sal_uInt32, ::rtl::OUString> > m_themeFontMap; + sal_uInt32 m_currentThemeFontId; + std::map<sal_uInt32, ::rtl::OUString> m_currentFontThemeEntry; +}; + +ThemeTable::ThemeTable() +: LoggedProperties(dmapper_logger, "ThemeTable") +, LoggedTable(dmapper_logger, "ThemeTable") +, m_pImpl( new ThemeTable_Impl ) +{ + +} + +ThemeTable::~ThemeTable() +{ + delete m_pImpl; +} + +void ThemeTable::lcl_attribute(Id Name, Value & val) +{ +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->startElement("ThemeTable.attribute"); + dmapper_logger->attribute("name", (*QNameToString::Instance())(Name)); + dmapper_logger->attribute("value", val.toString()); +#endif + ::rtl::OUString sValue = val.getString(); + switch(Name) + { + case NS_ooxml::LN_CT_TextFont_typeface: + if (sValue.getLength()) + m_pImpl->m_currentFontThemeEntry[m_pImpl->m_currentThemeFontId] = sValue; + break; + default: + { +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->element("unhandled"); +#endif + } + } +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->endElement(); +#endif +} + +void ThemeTable::lcl_sprm(Sprm& rSprm) +{ +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->startElement("ThemeTable.sprm"); + dmapper_logger->chars(rSprm.toString()); +#endif + + sal_uInt32 nSprmId = rSprm.getId(); + (void)nSprmId; + + Value::Pointer_t pValue = rSprm.getValue(); + sal_Int32 nIntValue = pValue->getInt(); + (void)nIntValue; + rtl::OUString sStringValue = pValue->getString(); + + switch(nSprmId) + { + case NS_ooxml::LN_CT_BaseStyles_fontScheme: + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + pProperties->resolve(*this); + } + break; + case NS_ooxml::LN_CT_FontScheme_majorFont: + case NS_ooxml::LN_CT_FontScheme_minorFont: + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + m_pImpl->m_currentFontThemeEntry = std::map<sal_uInt32, rtl::OUString>(); + if( pProperties.get()) + pProperties->resolve(*this); + m_pImpl->m_themeFontMap[nSprmId] = m_pImpl->m_currentFontThemeEntry; + } + break; + case NS_ooxml::LN_CT_FontCollection_latin: + case NS_ooxml::LN_CT_FontCollection_ea: + case NS_ooxml::LN_CT_FontCollection_cs: + { + m_pImpl->m_currentThemeFontId = nSprmId; + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + pProperties->resolve(*this); + } + break; + default: + { +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->element("unhandled"); +#endif + } + } +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->endElement(); +#endif +} + +void ThemeTable::lcl_entry(int /*pos*/, writerfilter::Reference<Properties>::Pointer_t ref) +{ +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->startElement("ThemeTable.entry"); +#endif + + ref->resolve(*this); + +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->endElement(); +#endif +} + +const ::rtl::OUString ThemeTable::getFontNameForTheme(const Id id) const +{ + std::map<sal_uInt32, ::rtl::OUString> tmpThemeFontMap; + switch (id) + { + case NS_ooxml::LN_Value_ST_Theme_majorEastAsia: + case NS_ooxml::LN_Value_ST_Theme_majorBidi: + case NS_ooxml::LN_Value_ST_Theme_majorAscii: + case NS_ooxml::LN_Value_ST_Theme_majorHAnsi: + tmpThemeFontMap = m_pImpl->m_themeFontMap[NS_ooxml::LN_CT_FontScheme_majorFont]; + break; + case NS_ooxml::LN_Value_ST_Theme_minorEastAsia: + case NS_ooxml::LN_Value_ST_Theme_minorBidi: + case NS_ooxml::LN_Value_ST_Theme_minorAscii: + case NS_ooxml::LN_Value_ST_Theme_minorHAnsi: + tmpThemeFontMap = m_pImpl->m_themeFontMap[NS_ooxml::LN_CT_FontScheme_minorFont]; + break; + default: + return ::rtl::OUString(); + } + + switch (id) + { + case NS_ooxml::LN_Value_ST_Theme_majorAscii: + case NS_ooxml::LN_Value_ST_Theme_majorHAnsi: + case NS_ooxml::LN_Value_ST_Theme_minorAscii: + case NS_ooxml::LN_Value_ST_Theme_minorHAnsi: + { + std::map<sal_uInt32, ::rtl::OUString>::const_iterator Iter = tmpThemeFontMap.find(NS_ooxml::LN_CT_FontCollection_latin); + if (Iter != tmpThemeFontMap.end()) + return (Iter)->second; + return ::rtl::OUString(); + } + case NS_ooxml::LN_Value_ST_Theme_majorBidi: + case NS_ooxml::LN_Value_ST_Theme_minorBidi: + { + std::map<sal_uInt32, ::rtl::OUString>::const_iterator Iter = tmpThemeFontMap.find(NS_ooxml::LN_CT_FontCollection_cs); + if (Iter != tmpThemeFontMap.end()) + return (Iter)->second; + return ::rtl::OUString(); + } + case NS_ooxml::LN_Value_ST_Theme_majorEastAsia: + case NS_ooxml::LN_Value_ST_Theme_minorEastAsia: + { + std::map<sal_uInt32, ::rtl::OUString>::const_iterator Iter = tmpThemeFontMap.find(NS_ooxml::LN_CT_FontCollection_ea); + if (Iter != tmpThemeFontMap.end()) + return (Iter)->second; + return ::rtl::OUString(); + } + default: + return ::rtl::OUString(); + } +} + +}//namespace dmapper +} //namespace writerfilter + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/ThemeTable.hxx b/writerfilter/source/dmapper/ThemeTable.hxx new file mode 100644 index 000000000000..0bd7bd9d584e --- /dev/null +++ b/writerfilter/source/dmapper/ThemeTable.hxx @@ -0,0 +1,66 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef INCLUDED_THEMETABLE_HXX +#define INCLUDED_THEMETABLE_HXX + +#include <WriterFilterDllApi.hxx> +#include <resourcemodel/LoggedResources.hxx> +#include <com/sun/star/lang/XComponent.hpp> +#include <map> + +namespace writerfilter { +namespace dmapper +{ + +struct ThemeTable_Impl; + +class WRITERFILTER_DLLPRIVATE ThemeTable : public LoggedProperties, public LoggedTable +{ + ThemeTable_Impl *m_pImpl; + +public: + ThemeTable(); + virtual ~ThemeTable(); + + const ::rtl::OUString getFontNameForTheme(const Id id) const; + + private: + // Properties + virtual void lcl_attribute(Id Name, Value & val); + virtual void lcl_sprm(Sprm & sprm); + + // Table + virtual void lcl_entry(int pos, writerfilter::Reference<Properties>::Pointer_t ref); +}; +typedef boost::shared_ptr< ThemeTable > ThemeTablePtr; +}} + +#endif // + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/WrapPolygonHandler.cxx b/writerfilter/source/dmapper/WrapPolygonHandler.cxx new file mode 100644 index 000000000000..2aabc1a375a9 --- /dev/null +++ b/writerfilter/source/dmapper/WrapPolygonHandler.cxx @@ -0,0 +1,216 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <com/sun/star/drawing/PointSequence.hpp> + +#include <ooxml/resourceids.hxx> +#include <resourcemodel/ResourceModelHelper.hxx> + +#include "ConversionHelper.hxx" +#include "WrapPolygonHandler.hxx" +#include "dmapperLoggers.hxx" + +namespace writerfilter { + +using resourcemodel::resolveSprmProps; + +namespace dmapper { + +WrapPolygon::WrapPolygon() +{ +} + +WrapPolygon::~WrapPolygon() +{ +} + +void WrapPolygon::addPoint(const awt::Point & rPoint) +{ + mPoints.push_back(rPoint); +} + +WrapPolygon::Points_t::const_iterator WrapPolygon::begin() const +{ + return mPoints.begin(); +} + +WrapPolygon::Points_t::const_iterator WrapPolygon::end() const +{ + return mPoints.end(); +} + +WrapPolygon::Points_t::iterator WrapPolygon::begin() +{ + return mPoints.begin(); +} + +WrapPolygon::Points_t::iterator WrapPolygon::end() +{ + return mPoints.end(); +} + +size_t WrapPolygon::size() const +{ + return mPoints.size(); +} + +WrapPolygon::Pointer_t WrapPolygon::move(const awt::Point & rPoint) +{ + WrapPolygon::Pointer_t pResult(new WrapPolygon); + + Points_t::iterator aIt = begin(); + Points_t::iterator aItEnd = end(); + + while (aIt != aItEnd) + { + awt::Point aPoint(aIt->X + rPoint.X, aIt->Y + rPoint.Y); + pResult->addPoint(aPoint); + aIt++; + } + + return pResult; +} + +WrapPolygon::Pointer_t WrapPolygon::scale(const Fraction & rFractionX, const Fraction & rFractionY) +{ + WrapPolygon::Pointer_t pResult(new WrapPolygon); + + Points_t::iterator aIt = begin(); + Points_t::iterator aItEnd = end(); + + while (aIt != aItEnd) + { + awt::Point aPoint(Fraction(aIt->X) * rFractionX, Fraction(aIt->Y) * rFractionY); + pResult->addPoint(aPoint); + aIt++; + } + + return pResult; +} + +WrapPolygon::Pointer_t WrapPolygon::correctWordWrapPolygon(const awt::Size & rSrcSize, const awt::Size & rDstSize) +{ + WrapPolygon::Pointer_t pResult; + + const sal_uInt32 nWrap100Percent = 21600; + + Fraction aMove(nWrap100Percent, rSrcSize.Width); + aMove = aMove * Fraction(15, 1); + awt::Point aMovePoint(aMove, 0); + pResult = move(aMovePoint); + + Fraction aScaleX(nWrap100Percent, Fraction(nWrap100Percent) + aMove); + Fraction aScaleY(nWrap100Percent, Fraction(nWrap100Percent) - aMove); + pResult = pResult->scale(aScaleX, aScaleY); + + Fraction aScaleDestX(rDstSize.Width, nWrap100Percent); + Fraction aScaleDestY(rDstSize.Height, nWrap100Percent); + pResult = pResult->scale(aScaleDestX, aScaleDestY); + + return pResult; +} + +drawing::PointSequenceSequence WrapPolygon::getPointSequenceSequence() const +{ + drawing::PointSequenceSequence aPolyPolygon(1L); + drawing::PointSequence * pPolygon = aPolyPolygon.getArray(); + pPolygon->realloc(size()); + + sal_uInt32 n = 0; + Points_t::const_iterator aIt = begin(); + Points_t::const_iterator aItEnd = end(); + + while (aIt != aItEnd) + { + (*pPolygon)[n] = *aIt; + ++n; + aIt++; + } + + return aPolyPolygon; +} + +WrapPolygonHandler::WrapPolygonHandler() +: LoggedProperties(dmapper_logger, "WrapPolygonHandler") +, mpPolygon(new WrapPolygon) +{ +} + +WrapPolygonHandler::~WrapPolygonHandler() +{ +} + +void WrapPolygonHandler::lcl_attribute(Id Name, Value & val) +{ + sal_Int32 nIntValue = val.getInt(); + + switch(Name) + { + case NS_ooxml::LN_CT_Point2D_x: + /* WRITERFILTERSTATUS: done: 100, planned: 0.5, spent: 0 */ + mnX = nIntValue; + break; + case NS_ooxml::LN_CT_Point2D_y: + /* WRITERFILTERSTATUS: done: 100, planned: 0.5, spent: 0 */ + mnY = nIntValue; + break; + default: +#ifdef DEBUG_WRAP_POLYGON_HANDLER + dmapper_logger->element("unhandled"); +#endif + break; + } +} + +void WrapPolygonHandler::lcl_sprm(Sprm & _sprm) +{ + switch (_sprm.getId()) + { + case NS_ooxml::LN_CT_WrapPath_lineTo: + case NS_ooxml::LN_CT_WrapPath_start: + /* WRITERFILTERSTATUS: done: 100, planned: 0.5, spent: 0 */ + { + resolveSprmProps(*this, _sprm); + + awt::Point aPoint(mnX, mnY); + mpPolygon->addPoint(aPoint); + } + break; + default: +#ifdef DEBUG_WRAP_POLYGON_HANDLER + dmapper_logger->element("unhandled"); +#endif + break; + } +} + +WrapPolygon::Pointer_t WrapPolygonHandler::getPolygon() +{ + return mpPolygon; +} + +}} diff --git a/writerfilter/source/dmapper/WrapPolygonHandler.hxx b/writerfilter/source/dmapper/WrapPolygonHandler.hxx new file mode 100644 index 000000000000..4883ccb3081b --- /dev/null +++ b/writerfilter/source/dmapper/WrapPolygonHandler.hxx @@ -0,0 +1,92 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef WRAP_POLYGON_HANDLER_HXX +#define WRAP_POLYGON_HANDLER_HXX + +#include <deque> +#include <com/sun/star/drawing/PointSequenceSequence.hpp> +#include <resourcemodel/LoggedResources.hxx> +#include <resourcemodel/Fraction.hxx> + +namespace writerfilter { +namespace dmapper { + +using namespace ::com::sun::star; +using resourcemodel::Fraction; + +class WrapPolygon +{ +public: + typedef ::std::deque<awt::Point> Points_t; + typedef ::boost::shared_ptr<WrapPolygon> Pointer_t; + +private: + Points_t mPoints; + +public: + WrapPolygon(); + virtual ~WrapPolygon(); + + void addPoint(const awt::Point & rPoint); + + Points_t::const_iterator begin() const; + Points_t::const_iterator end() const; + Points_t::iterator begin(); + Points_t::iterator end(); + + size_t size() const; + + WrapPolygon::Pointer_t move(const awt::Point & rMove); + WrapPolygon::Pointer_t scale(const Fraction & rFractionX, const Fraction & rFractionY); + WrapPolygon::Pointer_t correctWordWrapPolygon(const awt::Size & rSrcSize, const awt::Size & rDstSize); + drawing::PointSequenceSequence getPointSequenceSequence() const; +}; + +class WrapPolygonHandler : public LoggedProperties +{ +public: + WrapPolygonHandler(); + virtual ~WrapPolygonHandler(); + + WrapPolygon::Pointer_t getPolygon(); + +private: + WrapPolygon::Pointer_t mpPolygon; + + sal_uInt32 mnX; + sal_uInt32 mnY; + + // Properties + virtual void lcl_attribute(Id Name, Value & val); + virtual void lcl_sprm(Sprm & sprm); + +}; + +}} + +#endif // WRAP_POLYGON_HANDLER_HXX diff --git a/writerfilter/source/dmapper/dmapperLoggers.hxx b/writerfilter/source/dmapper/dmapperLoggers.hxx new file mode 100644 index 000000000000..f771a9717790 --- /dev/null +++ b/writerfilter/source/dmapper/dmapperLoggers.hxx @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef INCLUDED_DMAPPER_LOGGERS_HXX +#define INCLUDED_DMAPPER_LOGGERS_HXX + +#include <resourcemodel/TagLogger.hxx> + +namespace writerfilter { + namespace dmapper { + extern TagLogger::Pointer_t dmapper_logger; + } +} + +#endif // INCLUDED_DMAPPER_LOGGERS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/genclass.xsl b/writerfilter/source/dmapper/genclass.xsl new file mode 100644 index 000000000000..1a985172cf58 --- /dev/null +++ b/writerfilter/source/dmapper/genclass.xsl @@ -0,0 +1,702 @@ +<?xml version="1.0" encoding="utf-8"?> +<xsl:stylesheet + version="1.0" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:rng="http://relaxng.org/ns/structure/1.0" + xmlns:xalan="http://xml.apache.org/xalan" + exclude-result-prefixes = "xalan" + xml:indent="true"> + <xsl:output method="text" version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="no"/> + + <xsl:template match="/"> + <xsl:for-each select="/model/class"> + <xsl:choose> + <xsl:when test="$filetype='inc'"> + <xsl:call-template name="incfile"/> + </xsl:when> + <xsl:when test="$filetype='impl'"> + <xsl:call-template name="implfile"/> + </xsl:when> + </xsl:choose> + </xsl:for-each> + </xsl:template> + + <xsl:template name="license"> + <xsl:text>/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/
</xsl:text> + </xsl:template> + + <xsl:template name="memberid"> + <xsl:variable name="member"> + <xsl:choose> + <xsl:when test="@member"> + <xsl:value-of select="@member"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="@name"/> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:for-each select="ancestor::class/member[@name=$member]"> + <xsl:choose> + <xsl:when test="@type='bool'"> + <xsl:text>m_b</xsl:text> + </xsl:when> + <xsl:when test="@type='OUString'"> + <xsl:text>m_s</xsl:text> + </xsl:when> + <xsl:when test="@type='sal_uInt32'"> + <xsl:text>m_n</xsl:text> + </xsl:when> + <xsl:otherwise> + <xsl:text>m_</xsl:text> + </xsl:otherwise> + </xsl:choose> + </xsl:for-each> + <xsl:call-template name="capfirst"> + <xsl:with-param name="string" select="$member"/> + </xsl:call-template> + </xsl:template> + + <xsl:template name="incfile"> + <xsl:call-template name="license"/> + <xsl:for-each select="//class"> + <xsl:variable name="includeguard"> + <xsl:text>INCLUDED_</xsl:text> + <xsl:value-of select="@name"/> + <xsl:text>_HXX</xsl:text> + </xsl:variable> + <xsl:text>#ifndef </xsl:text> + <xsl:value-of select="$includeguard"/> + <xsl:text>
#define </xsl:text> + <xsl:value-of select="$includeguard"/> + <xsl:text>
#include <resourcemodel/WW8ResourceModel.hxx></xsl:text> + <xsl:text>
#include <rtl/ustring.hxx></xsl:text> + <xsl:text>
namespace writerfilter {</xsl:text> + <xsl:text>
namespace dmapper {</xsl:text> + <xsl:call-template name="classdecl"/> + <xsl:text>
}}</xsl:text> + <xsl:text>
#endif //</xsl:text> + <xsl:value-of select="$includeguard"/> + <xsl:text>
</xsl:text> + </xsl:for-each> + </xsl:template> + + <xsl:template name="implfile"> + <xsl:call-template name="license"/> + <xsl:for-each select="//class"> + <xsl:text>#include "</xsl:text> + <xsl:value-of select="@name"/> + <xsl:text>.hxx"
</xsl:text> + <xsl:text>
#include <ooxml/resourceids.hxx></xsl:text> + <xsl:text>
#ifdef DEBUG_DOMAINMAPPER</xsl:text> + <xsl:text>
#include <resourcemodel/QNameToString.hxx></xsl:text> + <xsl:text>
#include "dmapperLoggers.hxx"</xsl:text> + <xsl:text>
#endif</xsl:text> + <xsl:text>
namespace writerfilter {</xsl:text> + <xsl:text>
namespace dmapper {
</xsl:text> + <xsl:call-template name="classimpl"/> + <xsl:text>}}
</xsl:text> + </xsl:for-each> + </xsl:template> + + <xsl:template name="classdecl"> + <xsl:text>
class </xsl:text> + <xsl:value-of select="@name"/> + <xsl:if test="parent"> + <xsl:text> : public </xsl:text> + </xsl:if> + <xsl:for-each select="parent"> + <xsl:if test="position() > 1"> + <xsl:text>, </xsl:text> + </xsl:if> + <xsl:value-of select="@name"/> + </xsl:for-each> + <xsl:text>
{</xsl:text> + <xsl:text>
public:</xsl:text> + <xsl:call-template name="typedefs"/> + <xsl:text>
 // constructor</xsl:text> + <xsl:text>
 </xsl:text> + <xsl:value-of select="@name"/> + <xsl:text>();</xsl:text> + <xsl:text>
 // destructor</xsl:text> + <xsl:text>
 virtual ~</xsl:text> + <xsl:value-of select="@name"/> + <xsl:text>();
</xsl:text> + <xsl:call-template name="memberfuncdecls"/> + <xsl:for-each select="sprm"> + <xsl:text>
 // sprm</xsl:text> + <xsl:text>
 void sprm(Sprm & r_sprm);</xsl:text> + <xsl:text>
 void resolveSprm(Sprm & r_sprm);
</xsl:text> + </xsl:for-each> + <xsl:for-each select="attribute"> + <xsl:text>
 // attribute</xsl:text> + <xsl:text>
 void attribute(Id name, Value & val);
</xsl:text> + </xsl:for-each> + <xsl:text>
private:</xsl:text> + <xsl:call-template name="memberdecls"/> + <xsl:text>
};

</xsl:text> + </xsl:template> + + <xsl:template name="type"> + <xsl:param name="name"/> + <xsl:choose> + <xsl:when test="$name='OUString'"> + <xsl:text>::rtl::OUString</xsl:text> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$name"/> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <xsl:template name="typedefs"> + <xsl:text>
 // typedefs</xsl:text> + <xsl:for-each select="typedef"> + <xsl:text>
 typedef </xsl:text> + <xsl:choose> + <xsl:when test="@type = 'shared_ptr'"> + <xsl:text>::boost::shared_ptr<</xsl:text> + <xsl:value-of select="ancestor::class/@name"/> + <xsl:text>></xsl:text> + </xsl:when> + <xsl:otherwise> + </xsl:otherwise> + </xsl:choose> + <xsl:for-each select="vector"> + <xsl:text>::std::vector<</xsl:text> + <xsl:call-template name="cctype"/> + <xsl:text>></xsl:text> + </xsl:for-each> + <xsl:text> </xsl:text> + <xsl:value-of select="@name"/> + <xsl:text>;</xsl:text> + </xsl:for-each> + <xsl:text>
</xsl:text> + </xsl:template> + + <xsl:template name="settername"> + <xsl:text>set</xsl:text> + <xsl:call-template name="capfirst"> + <xsl:with-param name="string" select="@name"/> + </xsl:call-template> + </xsl:template> + + <xsl:template name="gettername"> + <xsl:text>get</xsl:text> + <xsl:call-template name="capfirst"> + <xsl:with-param name="string" select="@name"/> + </xsl:call-template> + </xsl:template> + + <xsl:template name="pushbackname"> + <xsl:value-of select="@name"/> + <xsl:text>PushBack</xsl:text> + </xsl:template> + + <xsl:template name="settersig"> + <xsl:param name="classname"/> + <xsl:variable name="impl"> + <xsl:if test="string-length($classname) > 0"> + <xsl:text>true</xsl:text> + </xsl:if> + </xsl:variable> + <xsl:text>void </xsl:text> + <xsl:if test="string-length($classname) > 0"> + <xsl:value-of select="$classname"/> + <xsl:text>::</xsl:text> + </xsl:if> + <xsl:call-template name="settername"/> + <xsl:text>(</xsl:text> + <xsl:call-template name="constcctyperef"> + <xsl:with-param name="impl" select="$impl"/> + </xsl:call-template> + <xsl:text> </xsl:text> + <xsl:call-template name="paramname"/> + <xsl:text>)</xsl:text> + </xsl:template> + + <xsl:template name="gettersig"> + <xsl:param name="classname"/> + <xsl:variable name="impl"> + <xsl:if test="string-length($classname) > 0"> + <xsl:text>true</xsl:text> + </xsl:if> + </xsl:variable> + <xsl:variable name="type" select="@type"/> + <xsl:call-template name="constcctyperef"> + <xsl:with-param name="impl" select="$impl"/> + </xsl:call-template> + <xsl:text> </xsl:text> + <xsl:if test="string-length($classname) > 0"> + <xsl:value-of select="$classname"/> + <xsl:text>::</xsl:text> + </xsl:if> + <xsl:call-template name="gettername"/> + <xsl:text>() const</xsl:text> + </xsl:template> + + <xsl:template name="pushbacksig"> + <xsl:param name="classname"/> + <xsl:variable name="pushback"> + <xsl:call-template name="pushbackname"/> + </xsl:variable> + <xsl:variable name="type" select="@type"/> + <xsl:for-each select="ancestor::class/typedef[@name=$type]"> + <xsl:for-each select="vector"> + <xsl:text>void </xsl:text> + <xsl:if test="string-length($classname) > 0"> + <xsl:value-of select="$classname"/> + <xsl:text>::</xsl:text> + </xsl:if> + <xsl:value-of select="$pushback"/> + <xsl:text>(</xsl:text> + <xsl:call-template name="constcctyperef"> + <xsl:with-param name="deep">true</xsl:with-param> + </xsl:call-template> + <xsl:text> r_Element</xsl:text> + <xsl:text>)</xsl:text> + </xsl:for-each> + </xsl:for-each> + </xsl:template> + + <xsl:template name="memberfuncdecls"> + <xsl:for-each select="member"> + <xsl:text>
 // member: </xsl:text> + <xsl:value-of select="@name"/> + <xsl:text>
 </xsl:text> + <xsl:call-template name="settersig"/> + <xsl:text>;</xsl:text> + <xsl:text>
 </xsl:text> + <xsl:call-template name="gettersig"/> + <xsl:text>;
 </xsl:text> + <xsl:variable name="pushback"> + <xsl:call-template name="pushbacksig"/> + </xsl:variable> + <xsl:if test="string-length($pushback) > 0"> + <xsl:value-of select="$pushback"/> + <xsl:text>;
</xsl:text> + </xsl:if> + </xsl:for-each> + </xsl:template> + + <xsl:template name="memberdecls"> + <xsl:for-each select="member"> + <xsl:text>
 </xsl:text> + <xsl:call-template name="cctype"/> + <xsl:text> </xsl:text> + <xsl:call-template name="memberid"/> + <xsl:text>;</xsl:text> + </xsl:for-each> + </xsl:template> + + <xsl:template name="cctype"> + <xsl:param name="deep"/> + <xsl:param name="impl"/> + <xsl:variable name="type" select="@type"/> + <xsl:variable name="try1"> + <xsl:if test="$deep='true'"> + <xsl:for-each select="ancestor::class/typedef[@name=$type]"> + <xsl:for-each select="vector"> + <xsl:call-template name="cctype"> + <xsl:with-param name="impl" select="$impl"/> + <xsl:with-param name="deep" select="$deep"/> + </xsl:call-template> + </xsl:for-each> + </xsl:for-each> + </xsl:if> + </xsl:variable> + <xsl:choose> + <xsl:when test="string-length($try1) > 0"> + <xsl:value-of select="$try1"/> + </xsl:when> + <xsl:when test="@type='OUString'"> + <xsl:text>rtl::OUString</xsl:text> + </xsl:when> + <xsl:otherwise> + <xsl:if test="$impl='true'"> + <xsl:for-each select="ancestor::class"> + <xsl:variable name="classname" select="@name"/> + <xsl:for-each select="typedef[@name=$type]"> + <xsl:value-of select="$classname"/> + <xsl:text>::</xsl:text> + </xsl:for-each> + </xsl:for-each> + </xsl:if> + <xsl:value-of select="@type"/> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <xsl:template name="constcctype"> + <xsl:param name="impl"/> + <xsl:choose> + <xsl:when test="@type='bool' or @type='sal_uInt32'"> + <xsl:value-of select="@type"/> + </xsl:when> + <xsl:otherwise> + <xsl:text>const </xsl:text> + <xsl:call-template name="cctype"> + <xsl:with-param name="impl" select="$impl"/> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <xsl:template name="constcctyperef"> + <xsl:param name="impl"/> + <xsl:choose> + <xsl:when test="@type='bool' or @type='sal_uInt32'"> + <xsl:value-of select="@type"/> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="constcctype"> + <xsl:with-param name="impl" select="$impl"/> + </xsl:call-template> + <xsl:text> &</xsl:text> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <xsl:template name="capfirst"> + <xsl:param name="string"/> + <xsl:variable name="first" select="translate(substring($string, 1,1), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/> + <xsl:value-of select="concat($first, substring($string, 2))"/> + </xsl:template> + + <xsl:template name="paramname"> + <xsl:choose> + <xsl:when test="@type='OUString'"> + <xsl:text>r_s</xsl:text> + <xsl:call-template name="capfirst"> + <xsl:with-param name="string" select="@name"/> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:text>r_</xsl:text> + <xsl:value-of select="@name"/> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <xsl:template name="setterimpl"> + <xsl:call-template name="settersig"> + <xsl:with-param name="classname" select="ancestor::class/@name"/> + </xsl:call-template> + <xsl:text>
{</xsl:text> + <xsl:text>
 </xsl:text> + <xsl:call-template name="memberid"/> + <xsl:text> = </xsl:text> + <xsl:call-template name="paramname"/> + <xsl:text>;</xsl:text> + <xsl:text>
}

</xsl:text> + </xsl:template> + + <xsl:template name="getterimpl"> + <xsl:call-template name="gettersig"> + <xsl:with-param name="classname" select="ancestor::class/@name"/> + </xsl:call-template> + <xsl:text>
{</xsl:text> + <xsl:text>
 return </xsl:text> + <xsl:call-template name="memberid"/> + <xsl:text>;</xsl:text> + <xsl:text>
}

</xsl:text> + </xsl:template> + + <xsl:template name="pushbackimpl"> + <xsl:variable name="sig"> + <xsl:call-template name="pushbacksig"> + <xsl:with-param name="classname" select="ancestor::class/@name"/> + </xsl:call-template> + </xsl:variable> + <xsl:if test="string-length($sig) > 0"> + <xsl:value-of select="$sig"/> + <xsl:text>
{</xsl:text> + <xsl:text>
 </xsl:text> + <xsl:call-template name="memberid"/> + <xsl:text>.push_back(r_Element);</xsl:text> + <xsl:text>
}

</xsl:text> + </xsl:if> + </xsl:template> + + <xsl:template name="getvalue"> + <xsl:param name="valuePrefix"/> + <xsl:choose> + <xsl:when test="@type='OUString'"> + <xsl:value-of select="$valuePrefix"/> + <xsl:text>getString()</xsl:text> + </xsl:when> + <xsl:when test="@type='bool' or @type='sal_uInt32'"> + <xsl:value-of select="$valuePrefix"/> + <xsl:text>getInt()</xsl:text> + </xsl:when> + <xsl:when test="@type"> + <xsl:variable name="type" select="@type"/> + <xsl:for-each select="ancestor::class/typedef[@name=$type]"> + <xsl:call-template name="getvalue"> + <xsl:with-param name="valuePrefix" select="$valuePrefix"/> + </xsl:call-template> + </xsl:for-each> + </xsl:when> + <xsl:otherwise> + <xsl:variable name="member"> + <xsl:choose> + <xsl:when test="@member"> + <xsl:value-of select="@member"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="@name"/> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:for-each select="ancestor::class/member[@name=$member]"> + <xsl:call-template name="getvalue"> + <xsl:with-param name="valuePrefix" select="$valuePrefix"/> + </xsl:call-template> + </xsl:for-each> + </xsl:otherwise> + </xsl:choose> + <xsl:for-each select="vector"> + <xsl:call-template name="getvalue"> + <xsl:with-param name="valuePrefix" select="$valuePrefix"/> + </xsl:call-template> + </xsl:for-each> + </xsl:template> + + <xsl:template name="sprmactionset"> + <xsl:param name="valuePrefix"/> + <xsl:text>
 {</xsl:text> + <xsl:text>
 </xsl:text> + <xsl:call-template name="memberid"/> + <xsl:text> = </xsl:text> + <xsl:call-template name="getvalue"> + <xsl:with-param name="valuePrefix" select="$valuePrefix"/> + </xsl:call-template> + <xsl:text>;
 }</xsl:text> + </xsl:template> + + <xsl:template name="sprmactionpushback"> + <xsl:param name="valuePrefix"/> + <xsl:text>
 {</xsl:text> + <xsl:text>
 </xsl:text> + <xsl:call-template name="memberid"/> + <xsl:text>.push_back(</xsl:text> + <xsl:call-template name="getvalue"> + <xsl:with-param name="valuePrefix" select="$valuePrefix"/> + </xsl:call-template> + <xsl:text>);</xsl:text> + <xsl:text>;
 }</xsl:text> + </xsl:template> + + <xsl:template name="sprmactionresolve"> + <xsl:text>
 {</xsl:text> + <xsl:text>
 resolveSprm(r_Sprm);</xsl:text> + <xsl:text>
 }</xsl:text> + </xsl:template> + + <xsl:template name="sprmaction"> + <xsl:param name="valuePrefix"/> + <xsl:choose> + <xsl:when test="@action='set'"> + <xsl:call-template name="sprmactionset"> + <xsl:with-param name="valuePrefix" select="$valuePrefix"/> + </xsl:call-template> + </xsl:when> + <xsl:when test="@action='pushback'"> + <xsl:call-template name="sprmactionpushback"> + <xsl:with-param name="valuePrefix" select="$valuePrefix"/> + </xsl:call-template> + </xsl:when> + <xsl:when test="@action='resolve'"> + <xsl:call-template name="sprmactionresolve"/> + </xsl:when> + <xsl:otherwise/> + </xsl:choose> + </xsl:template> + + <xsl:template name="sprmimpl"> + <xsl:for-each select="sprm"> + <xsl:text>
void </xsl:text> + <xsl:variable name="classname" select="ancestor::class/@name"/> + <xsl:value-of select="$classname"/> + <xsl:text>::sprm(Sprm & r_Sprm)</xsl:text> + <xsl:text>
{</xsl:text> + <xsl:text>
#ifdef DEBUG_DOMAINMAPPER</xsl:text> + <xsl:text>
 dmapper_logger->startElement("</xsl:text> + <xsl:value-of select="$classname"/> + <xsl:text>.sprm");</xsl:text> + <xsl:text>
 dmapper_logger->chars(r_Sprm.toString());</xsl:text> + <xsl:text>
#endif</xsl:text> + <xsl:text>
 switch(r_Sprm.getId())</xsl:text> + <xsl:text>
 {</xsl:text> + <xsl:for-each select="element"> + <xsl:text>
 case </xsl:text> + <xsl:value-of select="@id"/> + <xsl:text>:</xsl:text> + <xsl:call-template name="sprmaction"> + <xsl:with-param name="valuePrefix">r_Sprm.getValue()-></xsl:with-param> + </xsl:call-template> + <xsl:text>
 break;</xsl:text> + </xsl:for-each> + <xsl:text>
 default:</xsl:text> + <xsl:text>
#ifdef DEBUG_DOMAINMAPPER</xsl:text> + <xsl:text>
 dmapper_logger->element("unhandled");</xsl:text> + <xsl:text>
#endif DEBUG_DOMAINMAPPER</xsl:text> + <xsl:text>
 break;</xsl:text> + <xsl:text>
 }</xsl:text> + <xsl:text>
#ifdef DEBUG_DOMAINMAPPER</xsl:text> + <xsl:text>
 dmapper_logger->endElement("</xsl:text> + <xsl:value-of select="$classname"/> + <xsl:text>.sprm");</xsl:text> + <xsl:text>
#endif</xsl:text> + <xsl:text>
}
</xsl:text> + <xsl:text>
void </xsl:text> + <xsl:value-of select="ancestor::class/@name"/> + <xsl:text>::resolveSprm(Sprm & r_Sprm)</xsl:text> + <xsl:text>
{</xsl:text> + <xsl:text>
 writerfilter::Reference<Properties>::Pointer_t pProperties = r_Sprm.getProps();</xsl:text> + <xsl:text>
 if( pProperties.get())</xsl:text> + <xsl:text>
 pProperties->resolve(*this);</xsl:text> + <xsl:text>
}
</xsl:text> + </xsl:for-each> + </xsl:template> + + <xsl:template name="attrimpl"> + <xsl:for-each select="attribute"> + <xsl:text>
void </xsl:text> + <xsl:variable name="classname" select="ancestor::class/@name"/> + <xsl:value-of select="$classname"/> + <xsl:text>::</xsl:text> + <xsl:text>attribute(Id name, Value & val)</xsl:text> + <xsl:text>
{</xsl:text> + <xsl:text>
#ifdef DEBUG_DOMAINMAPPER</xsl:text> + <xsl:text>
 dmapper_logger->startElement("</xsl:text> + <xsl:value-of select="$classname"/> + <xsl:text>.attribute");</xsl:text> + <xsl:text>
 dmapper_logger->attribute("name", (*QNameToString::Instance())(name));</xsl:text> + <xsl:text>
 dmapper_logger->attribute("value", val.toString());</xsl:text> + <xsl:text>
 dmapper_logger->endElement("</xsl:text> + <xsl:value-of select="$classname"/> + <xsl:text>.attribute");</xsl:text> + <xsl:text>
#endif</xsl:text> + <xsl:text>
 switch (name)</xsl:text> + <xsl:text>
 {</xsl:text> + <xsl:for-each select="attribute"> + <xsl:text>
 case </xsl:text> + <xsl:value-of select="@id"/> + <xsl:text>:</xsl:text> + <xsl:call-template name="sprmactionset"> + <xsl:with-param name="valuePrefix">val.</xsl:with-param> + </xsl:call-template> + <xsl:text>
 break;</xsl:text> + </xsl:for-each> + <xsl:text>
 default:</xsl:text> + <xsl:text>
#ifdef DEBUG_DOMAINMAPPER</xsl:text> + <xsl:text>
 dmapper_logger->element("unhandled");</xsl:text> + <xsl:text>
#endif DEBUG_DOMAINMAPPER</xsl:text> + <xsl:text>
 break;</xsl:text> + <xsl:text>
 }</xsl:text> + <xsl:text>
}

</xsl:text> + </xsl:for-each> + </xsl:template> + + <xsl:template name="constructorimpl"> + <xsl:text>
</xsl:text> + <xsl:value-of select="@name"/> + <xsl:text>::</xsl:text> + <xsl:value-of select="@name"/> + <xsl:text>()</xsl:text> + <xsl:variable name="memberinits"> + <xsl:for-each select="member[@type='sal_uInt32' or @type='bool']"> + <xsl:if test="position() > 1"> + <xsl:text>,</xsl:text> + <xsl:text>
 </xsl:text> + </xsl:if> + <xsl:call-template name="memberid"/> + <xsl:choose> + <xsl:when test="@type='sal_uInt32'"> + <xsl:text>(0)</xsl:text> + </xsl:when> + <xsl:when test="@type='bool'"> + <xsl:text>(false)</xsl:text> + </xsl:when> + </xsl:choose> + </xsl:for-each> + </xsl:variable> + <xsl:if test="string-length($memberinits) > 0"> + <xsl:text>
: </xsl:text> + <xsl:value-of select="$memberinits"/> + </xsl:if> + <xsl:text>
{</xsl:text> + <xsl:text>
}

</xsl:text> + </xsl:template> + + <xsl:template name="destructorimpl"> + <xsl:text>
</xsl:text> + <xsl:value-of select="@name"/> + <xsl:text>::~</xsl:text> + <xsl:value-of select="@name"/> + <xsl:text>()</xsl:text> + <xsl:text>
{</xsl:text> + <xsl:text>
}

</xsl:text> + </xsl:template> + + <xsl:template name="classimpl"> + <xsl:variable name="classname" select="@name"/> + <xsl:variable name="comment"> + <xsl:text>class: </xsl:text> + <xsl:value-of select="$classname"/> + </xsl:variable> + <xsl:variable name="commentfill"> + <xsl:value-of select="translate($comment, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ: ', + '******************************************************')"/> + </xsl:variable> + <xsl:text>
/***</xsl:text> + <xsl:value-of select="$commentfill"/> + <xsl:text>*</xsl:text> + <xsl:text>
 * </xsl:text> + <xsl:value-of select="$comment"/> + <xsl:text> *</xsl:text> + <xsl:text>
 **</xsl:text> + <xsl:value-of select="$commentfill"/> + <xsl:text>**/
</xsl:text> + <xsl:call-template name="constructorimpl"/> + <xsl:call-template name="destructorimpl"/> + <xsl:for-each select="member"> + <xsl:text>// member: </xsl:text> + <xsl:value-of select="$classname"/> + <xsl:text>::</xsl:text> + <xsl:value-of select="@name"/> + <xsl:text>
</xsl:text> + <xsl:call-template name="setterimpl"/> + <xsl:call-template name="getterimpl"/> + <xsl:call-template name="pushbackimpl"/> + </xsl:for-each> + <xsl:call-template name="sprmimpl"/> + <xsl:call-template name="attrimpl"/> + </xsl:template> +</xsl:stylesheet> diff --git a/writerfilter/source/dmapper/makefile.mk b/writerfilter/source/dmapper/makefile.mk new file mode 100644 index 000000000000..a4b000411b4e --- /dev/null +++ b/writerfilter/source/dmapper/makefile.mk @@ -0,0 +1,78 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* +PRJ=..$/.. +PRJNAME=writerfilter +TARGET=dmapper +GEN_HID=TRUE + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ---------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/inc$/writerfilter.mk + +# --- Files ------------------------------------- + +SLOFILES= \ + $(SLO)$/BorderHandler.obj \ + $(SLO)$/CellColorHandler.obj \ + $(SLO)$/CellMarginHandler.obj \ + $(SLO)$/ConversionHelper.obj \ + $(SLO)$/DomainMapper.obj \ + $(SLO)$/DomainMapperTableHandler.obj \ + $(SLO)$/DomainMapperTableManager.obj \ + $(SLO)$/DomainMapper_Impl.obj \ + $(SLO)$/FFDataHandler.obj \ + $(SLO)$/FontTable.obj \ + $(SLO)$/FormControlHelper.obj \ + $(SLO)$/GraphicHelpers.obj \ + $(SLO)$/GraphicImport.obj \ + $(SLO)$/MeasureHandler.obj \ + $(SLO)$/ModelEventListener.obj \ + $(SLO)$/NumberingManager.obj \ + $(SLO)$/OLEHandler.obj \ + $(SLO)$/PageBordersHandler.obj \ + $(SLO)$/PropertyIds.obj \ + $(SLO)$/PropertyMap.obj \ + $(SLO)$/PropertyMapHelper.obj \ + $(SLO)$/SectionColumnHandler.obj \ + $(SLO)$/SettingsTable.obj \ + $(SLO)$/StyleSheetTable.obj \ + $(SLO)$/TDefTableHandler.obj \ + $(SLO)$/TablePropertiesHandler.obj \ + $(SLO)$/TblStylePrHandler.obj \ + $(SLO)$/ThemeTable.obj \ + $(SLO)$/WrapPolygonHandler.obj \ + + +# --- Targets ---------------------------------- + +.INCLUDE : target.mk + + + |